1
if(strpos($string, "A Bad Word") != false){
    echo 'This word is not allowed';
}
if(strpos($string, "A Bad Word") != false){
    echo 'This word is not allowed';
}

Okay, so I am trying to check the submit data to see if there are inappropriate words. Instead of making 5 instances, is there a more efficient way?

hakre
  • 193,403
  • 52
  • 435
  • 836
Strawberry
  • 66,024
  • 56
  • 149
  • 197

7 Answers7

6

I'm sure there's a more clever way to do this in general.

If you just want to be more concise, then it's probably best to loop over some bad words, instead of adding repetitive, almost identical, conditionals (ifs):

<?PHP
$banned = array('bad','words','like','these');

$looksLikeSpam = false;
foreach($banned as $naughty){
    if (strpos($string,$naugty) !== false){
        $looksLikeSpam=true;
    }
}

if ($looksLikeSpam){
   echo "You're GROSS!  Just... ew!";
   die();
}

Edit: Also, note that in your question-code, you test strpos != false. You really want !==, since strpos() will return 0 if the first word, is, say, PENIS. 0 will be cast to false. See where I'm going here?

Also, you probably want to use stripos(), to be case-insensitive (unless you only care if if people SHOUT offensive words) :-)

timdev
  • 61,857
  • 6
  • 82
  • 92
  • Also, note the difference between `!== false` and `!= false` in the original question. – Matthew Scharley Sep 21 '09 at 02:43
  • Yup, thanks matt -- was just adding some clarification about that! – timdev Sep 21 '09 at 02:45
  • +1, but should it be mentioned that this a wildly naive way to go about preventing spam? – Terry G Lorber Sep 21 '09 at 02:52
  • I got a question for this though, what if I wanted to add a different message for each word? A loop wouldn't work, right? e.g. IF the word is PENIS, the message would say, What's that? If the word was VAGINA, the message would say, Who is? – Strawberry Sep 21 '09 at 02:52
  • @Terry what would be a better way? – Strawberry Sep 21 '09 at 02:53
  • 1
    @Doug - then use an associative array, the keys would be the bad words, the values would hold the data, and adjust the code accordingly. – timdev Sep 21 '09 at 03:02
  • 1
    @Doug - Better ways include using a CAPTCHA (recaptcha is nice), or possibly tying into something like akismet. – timdev Sep 21 '09 at 03:03
  • 1
    @Doug: Word based blacklists are fraught with danger. What if I wanted to make a post about Great Tits? http://wikipedia.com/wiki/Great_Tits Ooops. +1 for recaptcha though. – Matthew Scharley Sep 21 '09 at 03:21
  • You should break the loop once you've got a match. – Ed S. Oct 20 '12 at 18:26
2

Yes, you could make an array of badwords and build a regex out of it. This would also make handling case-insensitivity easy.

$badwords = array('staircase', 'tuna', 'pillow');
$badwords_regex = '/' . implode('|', $badwords) . '/i';

$contains_badwords = preg_match($badwords_regex, $text);
Paige Ruten
  • 172,675
  • 36
  • 177
  • 197
2

No, it's crap. There is a whole branch of computing science concerning string searching algorithms. Heck, Knuth even dedicated half of TAOCP Volume 3 to it.

Boyer-Moore is a good algorithm, now used in many applications involving searching for multiple needles in a haystack.

Ether
  • 53,118
  • 13
  • 86
  • 159
1

You need to be careful with word boundaries, or else people will complain about not being able to enter words like "shuttlecock".

I hope you (or your client) realises that automatic "naughty word" filtering does not remove the need for moderating. There are lots of ways to be offensive without using any of the supposedly naughty words. Even deciding what is or is not offensive depends on the cultural context.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • Ah, the classic Scunthorpe problem. [http://en.wikipedia.org/wiki/Scunthorpe_problem] – Rob Oct 04 '09 at 18:27
0

You could combine them as a single regular expression and then use preg_grep() to confirm their existence

Brian Barnes
  • 1,009
  • 7
  • 15
0

Use an array of values and iterate over the array, checking the submitted word each time. If a match is found break out of the loop and return true.

Charles Ritchie
  • 2,283
  • 2
  • 16
  • 21
0

You might use PHP in_array function rather than a loop, if you're checking one word. A regex would be better if you're checking a whole sentence though.

http://us2.php.net/manual/en/function.in-array.php

$bad_word_array=array('weenis','dolt','wanker');

$passed=in_array($suspected_word,$bad_word_array);
Jim
  • 22,354
  • 6
  • 52
  • 80
JAL
  • 21,295
  • 1
  • 48
  • 66