•
•
•
•
What is DaniWeb IT Discussion Community?
You're currently browsing the PHP section within the Web Development category of DaniWeb, a massive community of 423,508 software developers, web developers, Internet marketers, and tech gurus who are all enthusiastic about making contacts, networking, and learning from each other. In fact, there are 4,686 IT professionals currently interacting right now! Registration is free, only takes a minute and lets you enjoy all of the interactive features of the site.
Please support our PHP advertiser: Lunarpages PHP Web Hosting
Views: 1995 | Replies: 1
![]() |
•
•
Join Date: Jul 2007
Posts: 1
Reputation:
Rep Power: 0
Solved Threads: 0
Yes, there are many posts out there about badword filters, and most seem to fall short of something you'd want to turn loose on a corporate website. I've created a fairly elegant badword solution, and I wish to share it with the development community. I'm looking to optimize it a bit more, because as the list of badwords I use grows, the process time could get pretty ugly.
A little more explanation about this particular script - One of my clients has a fairly complex comment form on their website that allows the option to comment, get the newsletter, etc - and then emails the necessary details to their person who handles such things. Recently, the emails were coming fast and furious with spam for lewd websites, prescription medications, and such. Of course, this needed to stop.
As there is no message board to check, and no obvious verification to see if the message was indeed sent or received (just a static thank-you splash page) - there was no need to try and replace bad words with characters, or warn the offending user/bot that anything was amiss - the messages just needed to be sent to the circular bin. As we weren't interested in keeping the messages around, a little delicacy was needed to keep partial matches from flagging the messages. This was the first feature of my script that I noticed most do not contain - many will display words like class as cl***. As the message would then be flagged as containing bad words, this approach wouldn't work.
So, a little wrangling with regular expressions later, I have a script that only matches whole words from my badwords list. Now, the occasional swear isn't going to matter, so if a couple masked words or swears next to tags make it through, it's ok. If you need to further filter for those instances, then by all means replace tags with whitespace before doing the string comparison.
Other features that are in this script that may or may not be included in other examples bouncing around the web:
* bad words are loaded from a text file
* additional block for [url] tags implemented
* result is transparent - offender doesn't know he's blocked.
And here's the script. If there are ideas on how to tidy some things up, I'll happily give them a shot. I'm currently considering switching from preg_match() to eregi(), and also creating the badwords expression from the entire badwords file, using the | operator and a loop. This way there's only one preg_match() call needed, instead of looping it. I'm also sure some of my control expressions could be a little more elegant, but this is a good first crack, I believe. If I make any major changes, I'll post them as replies.
A little more explanation about this particular script - One of my clients has a fairly complex comment form on their website that allows the option to comment, get the newsletter, etc - and then emails the necessary details to their person who handles such things. Recently, the emails were coming fast and furious with spam for lewd websites, prescription medications, and such. Of course, this needed to stop.
As there is no message board to check, and no obvious verification to see if the message was indeed sent or received (just a static thank-you splash page) - there was no need to try and replace bad words with characters, or warn the offending user/bot that anything was amiss - the messages just needed to be sent to the circular bin. As we weren't interested in keeping the messages around, a little delicacy was needed to keep partial matches from flagging the messages. This was the first feature of my script that I noticed most do not contain - many will display words like class as cl***. As the message would then be flagged as containing bad words, this approach wouldn't work.
So, a little wrangling with regular expressions later, I have a script that only matches whole words from my badwords list. Now, the occasional swear isn't going to matter, so if a couple masked words or swears next to tags make it through, it's ok. If you need to further filter for those instances, then by all means replace tags with whitespace before doing the string comparison.
Other features that are in this script that may or may not be included in other examples bouncing around the web:
* bad words are loaded from a text file
* additional block for [url] tags implemented
* result is transparent - offender doesn't know he's blocked.
And here's the script. If there are ideas on how to tidy some things up, I'll happily give them a shot. I'm currently considering switching from preg_match() to eregi(), and also creating the badwords expression from the entire badwords file, using the | operator and a loop. This way there's only one preg_match() call needed, instead of looping it. I'm also sure some of my control expressions could be a little more elegant, but this is a good first crack, I believe. If I make any major changes, I'll post them as replies.
php Syntax (Toggle Plain Text)
// Filtering Function function filterBadWords($str,$badWordsFile) { $badFlag = 0; if(!is_file($badWordsFile)) { echo "ERROR: file missing: ".$badWordsFile; exit; } else { $badWordsFH = fopen($badWordsFile,"r"); $badWordsArray = explode("\n", fread($badWordsFH, filesize($badWordsFile))); fclose($badWordsFH); } foreach ($badWordsArray as $badWord) { if(!$badWord) continue; else { $regexp = "/\b".$badWord."\b/i"; if(preg_match($regexp,$str)) $badFlag = 1; } } if(preg_match("/\[url/",$str)) $badFlag = 1; return $badFlag; }
php Syntax (Toggle Plain Text)
// Function Call/Usage if (filterBadWords($message,"badwords.txt") == 0) { mail("mail@destination.com", $subject, $message, $from); } header("Location: http://www.siteurl.com/index.php?p=Thank_You");
// badwords.txt word1 word2 word3
A better solution for yourself would be just to mask the bad words (unless you really don't want to send the email).
Just do a preg_replace of *@!>&^ (or however many characters are in the badword).
Nothing much wrong with your code though, just a few logic changes might benefit yourself.
You are not validating your mail() function either. I suggest wrapping it in an IF statement or use the @ character eg: @mail(..);
Cheers
Just do a preg_replace of *@!>&^ (or however many characters are in the badword).
Nothing much wrong with your code though, just a few logic changes might benefit yourself.
You are not validating your mail() function either. I suggest wrapping it in an IF statement or use the @ character eg: @mail(..);
Cheers
GardCMS :: Open Source CMS :: Gardcms.org
![]() |
•
•
•
•
•
•
•
•
DaniWeb PHP Marketplace
•
•
•
•
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
Similar Threads
- learning php (PHP)
- Just introducing myself (Community Introductions)
- Problems using a php generator (PHP)
- Simple Banned Words Filter (PHP)
- WINDOWS vs LINUX (Windows NT / 2000 / XP / 2003)
- My HiJack This log (Viruses, Spyware and other Nasties)
- Redirection to http://th.msie.cc/index.php?aid=20038 (Viruses, Spyware and other Nasties)
Other Threads in the PHP Forum
- Previous Thread: read second line or record of csv file
- Next Thread: increment time with for looping


Linear Mode