I am building an automatic word moderation for the Discussion Forum that I am creating for a project. The automatic word moderation that I have right now works perfectly fine except if the input is not the exact same word as I put on the array. So say 'happy' is the word that I've put on the array, 'Happy' with the capital H will not be detected. Below is the code that I used.
if (isset($_POST['submit'])) {
$banned = array('shit','fuck','bastard','cunt', 'fuck you', 'piss');
$entry = $_POST['reply_content'];
mb_strtolower($banned);
foreach($banned as $word):
if (strpos($entry, $word) !== false){
echo 'Please use a more appropriate language.';
exit;
}
endforeach;
}
stripos() is what you need then, instead of strpos().
The i is for case insensitivity.
http://php.net/manual/en/function.stripos.php
There's always a way around the filter (H4PPY), but this will ignore caps and block the word anyway
if (isset($_POST['submit'])) {
$banned = array('shit','fuck','bastard','cunt', 'fuck you', 'piss');
$entry = strtolower(htmlentities(($_POST['reply_content'])));
mb_strtolower($banned);
foreach($banned as $word):
if($word == $entry) {
echo 'Please use a more appropriate language.';
exit;
}
endforeach;
}
Related
see this code below:
comes from: http://www.damnsemicolon.com/php/php-parse-email-body-email-piping
//get rid of any quoted text in the email body
$body_array = explode("\n",$body);
$message = "";
foreach($body_array as $key => $value){
//remove hotmail sig
if($value == "_________________________________________________________________"){
break;
//original message quote
} elseif(preg_match("/^-*(.*)Original Message(.*)-*/i",$value,$matches)){
break;
//check for date wrote string
} elseif(preg_match("/^On(.*)wrote:(.*)/i",$value,$matches)) {
break;
//check for From Name email section
} elseif(preg_match("/^On(.*)$fromName(.*)/i",$value,$matches)) {
break;
//check for To Name email section
} elseif(preg_match("/^On(.*)$toName(.*)/i",$value,$matches)) {
break;
//check for To Email email section
} elseif(preg_match("/^(.*)$toEmail(.*)wrote:(.*)/i",$value,$matches)) {
break;
//check for From Email email section
} elseif(preg_match("/^(.*)$fromEmail(.*)wrote:(.*)/i",$value,$matches)) {
break;
//check for quoted ">" section
} elseif(preg_match("/^>(.*)/i",$value,$matches)){
break;
//check for date wrote string with dashes
} elseif(preg_match("/^---(.*)On(.*)wrote:(.*)/i",$value,$matches)){
break;
//add line to body
} else {
$message .= "$value\n";
}
}
//compare before and after
echo "$body<br><br><br>$message";
$body contains the complete email body including quoted area if this is a reply, this loop removes quoted area to get new reply as $message. But as suggested there, loop is slow and better to use preg_replace instead. so how can I do?
replace patterns with what? should I remove foreach loop too? I created below without foreach loop but seems wrong? please advice.
$patterns = array(
"_________________________________________________________________",
"/^-*(.*)Original Message(.*)-*/i",
"/^On(.*)wrote:(.*)/i",
"/^On(.*)$fromName(.*)/i",
"/^On(.*)$toName(.*)/i",
"/^(.*)$toEmail(.*)wrote:(.*)/i",
"/^(.*)$fromEmail(.*)wrote:(.*)/i",
"/^>(.*)/i",
"/^---(.*)On(.*)wrote:(.*)/i");
$message = preg_replace($patterns, '', $body);
You already narrowed it down to a workable solution. Only a few things to fix:
As #mario commented, you need to set the /m modifier for ^s to match at the beggining of each line.
Your first pattern needs to be enclosed with delimiters, and anchored to ^ and to the end of line to mantain the same meaning as in the original code.
Include the newline chars in order to remove the whole line.
Make sure the variables $fromName, $fromEmail, etc. are set.
Once you get a match, match everything from there to the end of the body with (?s:.*).
Code:
$patterns = array(
"/^_{30,}$(?s:.*)/m",
"/^.*Original Message(?s:.*)/im",
"/^(?:---.*)?On .* wrote:(?s:.*)/im",
"/^On .* $fromName(?s:.*)/im",
"/^On .* $toName(?s:.*)/im",
"/^.*$toEmail(.*)wrote:(?s:.*)/im",
"/^.*$fromEmail.* wrote:(?s:.*)/im",
"/^>.*/ims",
);
$message = preg_replace($patterns, '', $body);
echo "$body<br><br><br>$message";
Run this code here
A word of advice:
Take into account that it will also strip lines like:
only thing I wrote: ...
Good evening.
I'm making an IRC bot that responds when you mention him. What I want to know is how to make him reply when someone actually says his name. This is what I have so far ($match[3] is the message that someone said on a channel and yes, stripos is because I want it case-insensitive ):
if (stripos($match[3], "ircBot") !== false) {
$isMentioned = true;
}else { $isMentioned = false; }
while this does in fact detect if someone said his name, it only works if he's mentioned at the very beginning of the message so for example:
"ircBot is at the beginning of this sentance" would make $isMentioned true
"There's ircBot in between this sentance" would make $isMentioned false
"At the end of this sentance is ircBot" would make $isMentioned false
I want it to return true if "ircBot" is anywhere inside $match[3] and not just the beginning
You have to look for word boundaries to avoid someone called MircBot
// using in_array
$isMentioned = in_array('ircbot', preg_split('/\s+/', mb_strtolower($match[3])));
// using regex word boundaries
$isMentioned = preg_match('/\b(ircBot)\b/i', $match[3]);
http://3v4l.org/lh3JT
Use stristr instead
if (stristr($match[3], "ircBot") !== false) {
$isMentioned = true;
}else { $isMentioned = false; }
I think your error is somewhere else, e.g. the construction of $match[3]. This works fine:
$isMentioned = stripos('This is in the middle of ircBot the string','ircbot') !== false;
echo( $isMentioned ? 'Is Mentioned' : 'Sad ignored bot');
We are trying to display whether a file contains a specific string or not:
Here we read the file:
$myFile = "filename.txt";
$fh = fopen($myFile,'r');
$theData = fread($fh, filesize("filename.txt"));
fclose($fh);
filename.txt contains "Offline"
Here we are trying to compare the strings:
if(strcmp($theData,"Online")==0){
echo "Online"; }
elseif(strcmp($theData,"Offline")==0) {
echo "Offline"; }
else {
echo "This IF is not working." }
We have tried using regular if without the strcomp, but it did not work either. I'm thinking that an IF cannot compare the results from the fread to a regular string. Perhaps we will need to try another method.
Any Ideas?
Use preg_match()
$string = "your-string";
$pattern = "/\boffline\b/i";
// The \b in the pattern indicates a word boundary, so only the distinct
// word "offline" is matched; if you want to match even partial word "offline"
// within some word, change the pattern to this /offline/i
if(preg_match($pattern, $string)) {
echo "A match was found.";
}
You can use strpos() as well (it is faster in this case)
$string = 'your-stringoffline';
$find = 'offline';
$pos = strpos($string, $find);
if($pos !== false){
echo "The string '$find' was found in the string '$string' at position $pos";
}else{
echo "The string '$find' was not found in the string '$string'";
}
regex is very slow when used to search in long strings. use strpos
$strFile = file_get_contents("filename.txt"); // load file
if(strpos($strFile, 'Online')!==false){ // check if "Online" exists
echo "We are Online";
}
elseif(strpos($strFile, 'Offline')!==false){ // check if "Offline" exists
echo "We are Offline";
}
else{ // other cases
echo "Status is unknown";
}
I put another way to do that (depending what it is inside the file), although it is not the best it may be useful in some circumstances
if (exec("grep Offline filename.txt") === 'Offline')
echo 'Offline';
else
echo 'Online';
Byee
Are you checked the value contains in $theData ?
Try something like this:
if(strcmp($theData,"Online") === 0)
echo $theData." is equal to string Online using case sensisive";
else if(strcmp($theData,"Offline") === 0)
echo $theData." is equal to string Offline using case sensisive";
else
echo $theData." This IF is not working.";
Here the doc for more infos: http://php.net//manual/en/function.strcmp.php
Or using the hex494D49's method: (Not tested)
function isStringAreTheSame($initialString, $stringToCompare) {
$pattern = "/\b".$initialString."\b/";
return preg_match($pattern, $stringToCompare);
}
I have a .txt file where I would like to find an EXACT match of a single email entered in a form.
The present directives (see below) I used, work for a standard form. But when I use it in conjunction with an AJAX call and jQuery, it confirms it exists by just finding the first occurrence.
For example:
If that person enters "bobby#" it says not found, good.
If someone enters their full Email address and it exists in the file, it says "found", very good.
Now, if someone enters just "bobby", it says "found", not good.
I used the following three examples below with the same results.
if ( !preg_match("/\b{$email}\b/i", $emails )) {
echo "Sorry, not found";
}
and...
if ( !preg_match( "/(?:^|\W){$email}(?:\W|$)/", $emails )) {
echo "Sorry, not found";
}
and...
if ( !preg_match('/^'.$email.'$/', $emails )) {
echo "Sorry, not found";
}
my AJAX
$.ajax({
type: "POST",
url: "email_if_exist.php",
data: "email="+ usr,
success: function(msg){
my text file
Bobby Brown bobby#somewhere.com
Guy Slim guy#somewhere.com
Slim Jim slim#somewhere.com
I thought of using a jQuery function to only accept a full email address, but with no success partly because I didn't know where to put it in the script.
I've spent a lot of time in searching for a solution to this and I am now asking for some help.
Cheers.
Because your text file contains "bobby" in it, any regex such as you are suggesting will always find "bobby". I would suggest checking for the presence of the # symbol BEFORE you run the regex, as any valid email will always have # in it. Try something like this:
if (strpos($email,'#')) {
if ( !preg_match("/\b{$email}\b/i", $emails )) {
echo "Sorry, not found";
}
}
EDIT: Looking at this 4 years later... I would make the regex match to the end of the line, using the m modifier to specify multiline so the $ matches newline or EOF. The PHP line would be:
if ( !preg_match("/\b{$email}$/im", $emails )) {
If you're just checking to see if the user exists, this should work:
$users = trim(preg_replace('/\s\s+/', ' ', $users));
$userArray = explode(' ', $users);
$exists = in_array($email, $userArray);
Where $users is referencing to the example file and $email is referencing to the queried e-mail.
This replaces all newlines (and double spaces) with spaces and then splits by spaces into an array, then, if the e-mail exists in the array, the user exists.
Hope I helped!
'/^'.$email.'$/' is quite close. Since you want the check being "true" only if the full email address is on the file you should include in the pattern the "limits" of the email: Whitespace before and end_of_the_line after if:
'/ '.$email.'$/'
(Yes, I've just changed ^ -start of line- for a whitespace)
If your text file filled with lines that every line ending with the email,
so you can regex with testing and match by your "email + end od line"
like that:
if( preg_match("/.+{$email}[\n|\r\n|\r]/", $textFileEmails) )
{
/// code
}
The code would validate first using php core functions whether the email is correct or not and then check for the occurrence.
$email = 'bobby#somewhere.com';
$found = false;
//PHP has a built-in function to validate an email
if(filter_var($email, FILTER_VALIDATE_EMAIL)){
//Grab lines from the file
$lines = file('myfile.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach ($lines as $line) {
//Grab words from the line
$words = explode(" ", $line);
//If email found within the words set the flag as true.
if(in_array($email, $words)) {
$found = true;
//If the aim is only to find the email, we can break out here.
break;
}
}
}
if(false === $found) {
echo 'Not found!';
} else {
echo 'Found you!';
}
If you file is formatted as your example first_name, last_name, email#address.tdl
it's really easy to break it up on load to search.
I don't know why you would use preg_match for this bit your if you were advised to use preg use it to verify the email address. You're better off using indexOf method in php (strpos) to search the file but the below method works for your fixed file format.
Object Orientated File Reader and searcher
class Search{
private $users = array();
public function __construct($password_file){
$file = file_get_contents($password_file);
$lines = explode("\n", $file);
$users = array();
foreach($lines as $line){
$users = expode(" ", $line);
}
foreach($users as $user){
$this->users[] = array("first_name" => $user[0], "last_name" => $user[1], "email" => $user[2])
}
}
public function searchByEmail($email){
foreach($this->users as $key => $user){
if($user['email'] == $email){
// return user array
return $user;
// or you could return user id
//return $key;
}
}
return false;
}
}
Then to use
$search = new Search($passwdFile);
$user = $search->searchByEmail($_POST['email']);
echo ($user)? "found":"Sorry, not found";
Using preg_match to validate email then check
If you want to use preg and your own file search system.
function validateEmail($email) {
$v = "/[a-zA-Z0-9_-.+]+#[a-zA-Z0-9-]+.[a-zA-Z]+/";
return (bool)preg_match($v, $email);
}
then use like
if(validateEmail($_POST['email'])){
echo (strpos($_POST['email'], $emails) !== false)? "found":"Sorry, not found";
}
I have a coming soon form at a website where user fills out an email form and it will be emailed to me. However, a spammer has hit the site and is spamming the form with goatse and so on. IP ban isn't helping so I need to stop the form sending it if it contains goatse or something. Here's the mailer.
<?php
$SPOSTI =$_POST[sposti];
if ($SPOSTI=="")
{
return false;
}
if ($SPOSTI=="goatse.fr")
{
return false;
}
if ($SPOSTI=="http://www.goatse.info/hello.jpg")
{
return false;
}
else
{
$to = "xxx#gmail.com";
$subject = "xxx";
$message = "$_POST[sposti] haluaa tiedon kun kotisivut.name avautuu.
$_POST[ip]";
$from = "$_POST[sposti]";
$headers = "From:" . $from;
mail($to,$subject,$message,$headers);
}
?>
Is there someway to block it from executing the code if the email contains a certain word (goatse in this case)
You need to use exit or die instead of return false which works inside functions/methods:
if ( $SPOSTI =="" || strpos('goatse', $SPOSTI) !== FALSE)
{
exit();
}
strpos() will let you find a substring, but I really recommend a captcha security system as the attacker could simply switch to another annoying word.
Goatse's arn't your problem here, it's the security.
You can use stristr http://php.net/manual/de/function.stristr.php to achive this. I would recommend to using a captcha, since it is more efficient. A popular solution is reCaptcha: https://developers.google.com/recaptcha/docs/php Another, weaker possibility is to add a security question to your form, for instance "What is five plus five in numbers?".
Try the following:
function is_spam($array, $block_pattern){
$block = false;
foreach($array as $k => $v){
if(preg_match('/.*' . $block_pattern . '.*/', $k) ||
preg_match('/.*' . $block_pattern . '.*/', $v)){
$block = true;
break;
}
}
return $block;
}
Usage: is_spam($_POST, 'goatse');
Returns: true if 'goatse' is found in $_POST
The function will search all keys and values of $array for the $block_pattern string and will return true if the pattern is found.