[PHP] Ingevoerde data checken op woorden!

Pagina: 1
Acties:
  • 224 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

  • intermusic
  • Registratie: September 2002
  • Laatst online: 25-03 14:05

intermusic

Marc Hoekstra

Topicstarter
In de database heb ik een lijst met scheldwoorden.

Ik heb een invoerveld (TEXTAREA).
Nou wil ik de tekst die daar ingevoerd is checken op scheldwoorden uit de database.
Als er een woord uit de lijst in de tekst staat, plaats ik het bericht niet.

Wat is de beste en snelste manier om dat te doen?

1. Op de reeds in de database opgeslagen text een query uitvoeren zoals deze:
SELECT id FROM message WHERE bericht LIKE "%scheldwoord%"

2. In PHP een check maken waarbij PHP elk woord van de text langs gaat om te
kijken of het een scheldwoord is.

Bij voorbaat dank.

Marc Hoekstra

Acties:
  • 0 Henk 'm!

  • OZ-Gump
  • Registratie: November 2002
  • Laatst online: 14-05-2024

OZ-Gump

terug van weggeweest

hmmzz... eerlijk gezegd ben ik niet zo thuis in PHP, maar aangezien je vraagt wat het snelst is lijkt het mij het snelst de tekst te controleren voor je het opslaat, omdat je anders eerst de tekst opslaat, dan controleert en, indien nodig, weer weghaalt.
Als je de tekst controleert voor het opslaan kun je ervoor kiezen de tekst niet eens op te slaan en dat lijkt me dan een stukkie sneller...

My personal website


Acties:
  • 0 Henk 'm!

  • intermusic
  • Registratie: September 2002
  • Laatst online: 25-03 14:05

intermusic

Marc Hoekstra

Topicstarter
Daar zit wel een kern van waarheid in, maar 1 keer een text opslaan of verwijderen in een database kost erg weinig tijd.
Het gaat erom of een te controleren tekst sneller gecontroleerd kan worden door de database of door php.

Als je bijv. 500 scheldwoorden hebt, moet je 500 keer een query doen op de database als je het met de 'LIKE' query doet. Misschien kan dit met php sneller.

Acties:
  • 0 Henk 'm!

  • Arnaud
  • Registratie: Mei 2000
  • Laatst online: 16-09 07:24
De beste methode (met zéér acceptabele snelheid) is volgens mij als volgt:
Schrijf in PHP een functie die alle scheldwoorden uit de database in een array stopt. Ga hier vervolgens in een loop doorheen en voorkom het schrijven naar de database als er een scheldwoord wordt gevonden. Dit kost je 1 select-query per post.
Als deze functie goed functioneert gebruik je hem eenmalig om alle bestaande post te doorlopen via een loop (bijvoorbeeld 100.000 select-queries voor 100.000 posts) en verwijder je de posts uit de database die een scheldwoord bevatten. Dit kost je bijvoorbeeld 5.000 delete-queries.

Acties:
  • 0 Henk 'm!

  • OZ-Gump
  • Registratie: November 2002
  • Laatst online: 14-05-2024

OZ-Gump

terug van weggeweest

Het lijkt me dat, wanneer je met PHP werkt, je toch een query zult moeten hebben die alle 500 scheldwoorden bevat. Als je dan wil controleren zul je elk woord langs alle 500 woorden moeten halen om te kijken of het een scheldwoord is. Daar gaat volgens mij ook wel wat tijd in zitten ;)
Ik denk dus dat er voor allebei de mogelijkheden wel iets te zeggen is. Maar volgens mij is de opsla-en-dan-controleren-methode makkelijker te maken en in de toekomst makkelijker uitbreidbaar dan die andere. Ik laat het hierbij en laat de echt slimme opmerkingen voor mensen die meer met PHP gedaan hebben...

My personal website


Acties:
  • 0 Henk 'm!

  • Orphix
  • Registratie: Februari 2000
  • Niet online
Persoonlijk denk ik dat je met regular expressions in PHP het snelst uit bent. Die queries moeten de tekst aldoor opnieuw doorlopen, een slimme RE engine zal verschillende opties direct kunnen controleren of verwerpen.
Een voorbeeld zou zijn
PHP:
1
2
3
4
if(preg_match("/(potver|jeminee|bareuh)/i", $message))
{
// verwijder bericht
}

De pattern zou je dan dynamisch op kunnen bouwen uit een database evt.

En ik zou altijd checken _voordat_ je het bericht in de database zet (dus on submit). Die eenmalige verwijdering van de al bestaande teksten zou je ook met die queries kunnen doen natuurlijk, die tijd die dat kost boeit dan niet zoveel.

[ Voor 34% gewijzigd door Orphix op 03-12-2002 11:18 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Arnaud schreef op 03 December 2002 @ 11:13:
De beste methode (met zéér acceptabele snelheid) is volgens mij als volgt:
Schrijf in PHP een functie die alle scheldwoorden uit de database in een array stopt. Ga hier vervolgens in een loop doorheen en voorkom het schrijven naar de database als er een scheldwoord wordt gevonden. Dit kost je 1 select-query per post.
Als deze functie goed functioneert gebruik je hem eenmalig om alle bestaande post te doorlopen via een loop (bijvoorbeeld 100.000 select-queries voor 100.000 posts) en verwijder je de posts uit de database die een scheldwoord bevatten. Dit kost je bijvoorbeeld 5.000 delete-queries.
hmms.. tja.. ik heb zelf een spellingscontrole script gemaakt met 178.000 suggestiewoorden. Ik heb toen ook al die woorden in een array gezet en ben daar doorheen gelopen

PHP:
1
2
3
4
5
6
7
foreach($woord_array as $index => $woord)
{
      foreach($ingevulde_woorden as $index2 => $woord2
     {
            // vergelijking
     }
}


Dat bleek dus niet echt de juiste weg te zijn want bij een tekst met ongeveer 40 woorden had hij zo'n 7 miljoen vergelijkingen nodig.. en daar doet zelfs PHP ook wel even over. Ik heb het weten te verkorten door de $woord_array anders in te delen en nog wat truukjes... maar voor kleinere woordlijsten is het wel bruikbaar denk ik..

en voor de topicstarter.. kijk ook eens naar de levenshtein functie van PHP. Makkelijk voor het fileren van scheldwoorden met een letter anders...

Acties:
  • 0 Henk 'm!

  • intermusic
  • Registratie: September 2002
  • Laatst online: 25-03 14:05

intermusic

Marc Hoekstra

Topicstarter
Orphix schreef op 03 December 2002 @ 11:15:

PHP:
1
2
3
4
if(preg_match("/(potver|jeminee|bareuh)/i", $message))
{
// verwijder bericht
}
Dat is perfect.
Ik heb er ff mee zitten prutsen alleen hoe krijg ik het nou op een goeie manier voormekaar dat ik i.p.v. potver|jeminee|bareuh een string van maak ($lijst)?

Acties:
  • 0 Henk 'm!

Verwijderd

PHP:
1
$string=join('|',$lijst)


en je kunt preg_match gebruiken met een 3e parameter voor een array met gevonden matches. Da's handig als je iemand wilt vertellen welk woord niet is toegestaan.

[ Voor 71% gewijzigd door Verwijderd op 03-12-2002 13:32 ]


Acties:
  • 0 Henk 'm!

  • Freee!!
  • Registratie: December 2002
  • Laatst online: 12:59

Freee!!

Trotse papa van Toon en Len!

intermusic schreef op 03 december 2002 @ 10:49:
Als er een woord uit de lijst in de tekst staat, plaats ik het bericht niet.
Slightly of topic:
Misschien een idee om het bericht wel te plaatsen, maar de aanstootgevende woorden te vervangen, als is het maar door "<GECENSUREERD>". Dat voorkomt gezeur van 'Waarom is mijn bericht niet geplaatst?' en wijst de persoon meteen terecht.

The problem with common sense is that sense never ain't common - From the notebooks of Lazarus Long

GoT voor Behoud der Nederlandschen Taal [GvBdNT


Acties:
  • 0 Henk 'm!

  • intermusic
  • Registratie: September 2002
  • Laatst online: 25-03 14:05

intermusic

Marc Hoekstra

Topicstarter
Heb ik aan gedacht en is me ook gelukt na wat knutselen:

PHP:
1
2
3
4
5
6
7
8
9
10
11
$sqlbadword = "SELECT word FROM badword";
$resultbadword = mysql_query($sqlbadword) or die(mysql_error());
$numbadword = mysql_num_rows($resultbadword);
//plaats alles in een array
for ($i = 0; $i < $numbadword; $i++) {
    $array1[] = mysql_result($resultbadword,$i,"word");
}

$message = "dit is potver en jeminee";
$newmessage = str_replace($array1, "censuur", $message, $found);
//wegschrijven bericht $newmessage


Dit is een erg snelle manier om de tekst te controleren.
Maar eigenlijk wil ik nu nog wel de vieze woorden die gefilterd zijn op het scherm laten zien.

Acties:
  • 0 Henk 'm!

  • rednek
  • Registratie: Juli 1999
  • Laatst online: 01-09 17:44
8)7 8) 8) 8) Waarom doen jullie toch zo moeilijk.
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
$result = mysql_query("select badword from badwordlijst");
while ($row = mysql_fetch_array($result)){
// houw er wel rekening mee dat je dit moet doen als een bericht word gepost 
// anders neemt je " forum " ore what ever veels te veel resources in.
$gepostte_text = str_replace("$row[badword]","***********","$gepostte_text");
}

// Het kan ook volgens mij zo " weet niet zeker.
// dit kan omdat str_replace mixed is. 
// mixed str_replace ( mixed search, mixed replace, mixed subject) 
$result = mysql_query("select badword from badwordlijst");
$row = mysql_fetch_array($result);
$gepostte_text = str_replace("$row[badword]","***********","$gepostte_text");

Acties:
  • 0 Henk 'm!

Verwijderd

Ik heb voor de grap een testscriptje gemaakt dat een string (willekeurig bericht uit deze draad ge-copy/pasted) 1000 keer op het woord blaat controleerd. Dit gaat in zo'n 0,03 secondes (zie ook http://jurjen.websuit.nl/test.php). Ik denk dat je prima op die woorden kan controleren na het posten. Voordeel is dat je de gebruiker ook een melding kan geven dat hij die woorden moet verwijderen...

Acties:
  • 0 Henk 'm!

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

tja, dit is redelijk zinloze censuur, hoor. Ik kan namelijk nog steeds "p o t v e r k u t" o.i.d. invullen. Ga dat maar 's uitwerken :Y)

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


Acties:
  • 0 Henk 'm!

Verwijderd

hehe, iedereen probeert zinnige oplossingen aan te dragen en drm beukt het hele idee de grond in ;)

maar daar ben ik het niet helemaal mee eens... Je zou het nog zo kunnen uitbreiden dat als iemand de eerste keer een scheldwoord erin zet, dat hij dan een flag krijgt, zodat de post handmatig gechecked kan worden. bovendien geeft het toch een waaschuwing af... en waarschijnlijk gaat het alleen om "echte" scheldwoorden. potverdikkie zal waarschijnlijk niet gecensureerd worden ;)

Acties:
  • 0 Henk 'm!

Verwijderd

drm schreef op 03 December 2002 @ 16:51:
tja, dit is redelijk zinloze censuur, hoor. Ik kan namelijk nog steeds "p o t v e r k u t" o.i.d. invullen. Ga dat maar 's uitwerken :Y)
:X !!

Zoals ik al zei...

Acties:
  • 0 Henk 'm!

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

dj_delta:
:X !!

Zoals ik al zei...
't Probleem met levenshtein is, dat je daar als uitgangspunt neemt dat je een woord in een ander woord wilt veranderen. Als jij dus als scheldwoord 'lul' in de database hebt staan, en ik tik 'lol' in, dan is de levenshtein difference tussen die twee even groot, als voor 't verschil tussen 'gatverdamme' en 'gtverdamme'.

Daar komt bij, dat je nog steeds met 't probleem zit, dat je op woorden wilt checken. Hoe ga je definieren dat 'p o t v e r' 1 woord is, en 'hallo sjaak' 2, terwijl er resp. 5 en 2 whitespaces in beide strings voorkomt?
jurriebur:
maar daar ben ik het niet helemaal mee eens... Je zou het nog zo kunnen uitbreiden dat als iemand de eerste keer een scheldwoord erin zet, dat hij dan een flag krijgt, zodat de post handmatig gechecked kan worden. bovendien geeft het toch een waaschuwing af... en waarschijnlijk gaat het alleen om "echte" scheldwoorden. potverdikkie zal waarschijnlijk niet gecensureerd worden ;)
't gaat natuurlijk niet om 't woord 'potverdikkie', maar om 't idee. Ik denk dat je op deze manier ergens een controle wilt automatiseren, die eigenlijk niet te automatiseren valt, zonder erg ingewikkelde oplossingen te gaan gebruiken (als een goede grammaticale e/o spellings-analyzer), waarmee je eigenlijk je doel voorbijstreeft.

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


Acties:
  • 0 Henk 'm!

  • Freee!!
  • Registratie: December 2002
  • Laatst online: 12:59

Freee!!

Trotse papa van Toon en Len!

drm schreef op 03 december 2002 @ 16:51:
tja, dit is redelijk zinloze censuur, hoor. Ik kan namelijk nog steeds "p o t v e r k u t" o.i.d. invullen. Ga dat maar 's uitwerken :Y)
Dit is een bekend probleem, één oplossing hiervoor is het eerst uitfilteren van spaties (en HTML codes), dan controleren ==> niks gevonden, oorspronkelijke tekst posten.

Kijk ook eens op www.fark.com. Mike onderhoudt het filter als ik me niet vergis.

[ Voor 21% gewijzigd door Freee!! op 03-12-2002 17:22 . Reden: Problemen met links ]

The problem with common sense is that sense never ain't common - From the notebooks of Lazarus Long

GoT voor Behoud der Nederlandschen Taal [GvBdNT


Acties:
  • 0 Henk 'm!

Verwijderd

drm schreef op 03 December 2002 @ 17:17:
't Probleem met levenshtein is, dat je daar als uitgangspunt neemt dat je een woord in een ander woord wilt veranderen. Als jij dus als scheldwoord 'lul' in de database hebt staan, en ik tik 'lol' in, dan is de levenshtein difference tussen die twee even groot, als voor 't verschil tussen 'gatverdamme' en 'gtverdamme'.
[...]
Maar het voorkomt wel dingen als kûthoér, kúthóér enz. en dat is al wel weer een stapje dichterbij.. :)

Acties:
  • 0 Henk 'm!

  • jsiegmund
  • Registratie: Januari 2002
  • Laatst online: 11:31
Kun je niet beter bij het invoeren een SELECT uitvoeren die alle scheldwoorden nagaat?
Zodat een vergelijk van de woorden in de database met de in te voeren tekst al aangeeft of en een woord verboden is of niet. Als de query geen resultaten oplevert kan de INSERT uitgevoerd worden, in het andere geval wordt de gebruiker erop gewezen door de resultaten van de query weer te geven (dus de woorden die verboden zijn), zijnde als sterretjes in zijn bericht of anders. Is dit een idee? Ik zie namelijk allemaal wel leuke PHP vergelijkingen e.d. om het probleem op te lossen, maar volgens mij is dat alsnog met de resultaten van een SQL query, waarom niet 2 vliegen in 1 klap slaan?

Acties:
  • 0 Henk 'm!

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

Hoe wou je dat dan in een query stoppen?

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


Acties:
  • 0 Henk 'm!

Verwijderd

drm schreef op 03 December 2002 @ 17:17:
't gaat natuurlijk niet om 't woord 'potverdikkie', maar om 't idee. Ik denk dat je op deze manier ergens een controle wilt automatiseren, die eigenlijk niet te automatiseren valt, zonder erg ingewikkelde oplossingen te gaan gebruiken (als een goede grammaticale e/o spellings-analyzer), waarmee je eigenlijk je doel voorbijstreeft.
dat begrijp ik, maar zoals je al zegt, dit soort dingen zijn niet te automatiseren in een simpele post actie, dus zul je moeten roeien met wat je hebt, oftewel, simpel op woorden nakijken... hoe groter deze woordenlijst (waar je dus ook "k u t", "t e r i n g" etc. in kan zetten), hoe kleiner de kans dat ze er langs komen. Bovendien gaat het meer om het idee denk ik, want het geeft toch een signaal af dat je dit soort woorden niet op je forum/gastenboek of wat dan ook wilt hebben. De meeste woorden worden wel afgevangen, de rest... ach...

Acties:
  • 0 Henk 'm!

  • jsiegmund
  • Registratie: Januari 2002
  • Laatst online: 11:31
drm schreef op 03 december 2002 @ 19:39:
Hoe wou je dat dan in een query stoppen?
verzameling maken van de woorden in een array, en die checken door met WHERE woord IN (SELECT * FROM scheldwoorden)
waarbij woord dan natuurlijk de hele verzameling woorden voorstelt. moet toch te doen zijn? Al gebruik je een temp table. of iets dergelijks, beter dat soort dingen niet eens in je systeem opnemen dan er later weer uitfilteren

Acties:
  • 0 Henk 'm!

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

't idee is juist de zooi niet in de database zetten als er vieze zooi in staat, lijkt mij...

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


Acties:
  • 0 Henk 'm!

Verwijderd

en die select van scheldwoonden hoeft ook niet bij elke post als je gewoon die array een keer per dag ofso update is dat toch genoeg?

zie cron jobs
Pagina: 1