PHP reading lines from file and compare them - php

I am trying to read all lines from a file and than see if a given string contains any of these lines.
My code
$mails = file('blacklist.txt');
$email = "hendrik#anonbox.net";
$fail = false;
foreach($mails as $mail) {
if(strpos($email, $mail) > 0) {
$fail = true;
}
}
if($fail) {
echo "Fail";
} else {
echo "you can use that";
}
The blacklist.txt can be found here http://pastebin.com/aJyVkcNx.
I would expect strpos return a position for at least one string in the blacklist, but it does not. I am guessing that somehow I am generating not the kind of values within the $mails as I am expecting.
EDIT this is print_r($mails) http://pastebin.com/83ZqVwHx
EDIT2 some clarification: I want to see if a domain is within an email, even if the mail contains subdomain.domain.tld. And I tried to use !== false instead of my > 0 which yielded the same result.

You need to parse the email well since you're checking the domain of the email address if its inside the blacklist. Example:
$email = "hendrik#foo.anonbox.net";
if(filter_var($email, FILTER_VALIDATE_EMAIL)) {
preg_match('/#.*?([^.]+[.]\w{3}|[^.])$/', $email, $matches);
if(!empty($matches) && isset($matches[1])) {
$domain = $matches[1];
} else {
// not good email
exit;
}
// THIS IS FOR SAMPLES SAKE, i know youre using file()
$blacklist = explode("\n", file_get_contents('http://pastebin.com/raw.php?i=aJyVkcNx'));
foreach($blacklist as $email) {
if(stripos($email, $domain) !== false) {
echo 'you are blacklisted';
exit;
}
}
}
// his/her email is ok continue

strpos returns FALSE if the string was not found.'
Simply use this :
$fail = false;
foreach($mails as $mail) {
if(strpos($email, $mail) === false) {
$fail = true;
}
}
Or even better use this:
$blacklist = file_get_contents('blacklist.txt');
$email = "hendrik#anonbox.net";
if(strpos($email, $blacklist) === false){
echo "fail";
} else {
echo "This email is not blacklisted";
}

You have found the common pitfall with the strpos function. The return value of the strpos function refers to the position at which it found the string. In this instance, if the string begins at the first character, it will return 0. Note that 0 !== false.
The correct way to use the function is:
if(strpos($email, $mail) !== false){
// the string was found, potentially at position 0
}
However, this function may not be necessary at all; if you are simply checking if $mail is the same as $email, instead of seeing if the string exists within a larger string, then just use:
if($mail == $email){
// they are the same
}

Though you might still use foreach, that’s array reduce pattern:
function check_against($carry, $mail, $blacklisted) {
return $carry ||= strpos($mail, $blacklisted) !== false;
};
var_dump(array_reduce($mails, "check_against", $email_to_check));
Hope it helps.

Yet another way to solve this. Works fine:
$blacklist = file_get_contents('blacklist.txt');
$email = "hendrik#x.ip6.li";
$domain = substr(trim($email), strpos($email, '#')+1);
if(strpos($blacklist, $domain)){
echo "Your email has been blacklisted!";
}else{
echo "You are all good to go! not blacklisted :-)";
}
Goodluck!

Related

Loop until the request response message equals to "true" in php

I'm trying to make a php script that would make a loop that would get the contents of my site/server and if the text response is for example "false" then it would do the same thing, basically will loop until the site's text response will echo "true".
This is what i tried:
$getcontents = file_get_contents("http://example.com/script.php"); // it will echo false
if (strpos($getcontents , 'false')) {
$getcontents = file_get_contents("http://example.com/script.php");
else if (strpos($getcontents , 'false')) {
$getcontents = file_get_contents("http://example.com/script.php");
}
else if (strpos($getcontents , 'true')) {
echo "finished".;
}
I'm not sure if this is the right way or even if it is possible and i apologize in advance if i did not explain myself very well. Thank you for attention!
You could use a regular while loop.
$getcontents = 'false'; //set value to allow loop to start
while(strpos($getcontents , 'false') !== false) {
$getcontents = file_get_contents("http://example.com/script.php");
}
echo "finished";
This will loop until $getcontents does not contain false.
You could also use a recursive function like this.
function check_for_false() {
$getcontents = file_get_contents("http://example.com/script.php");
if(strpos($getcontents , 'false') !== false) {
check_for_false();
} else if(strpos($getcontents , 'true') !== false) {
echo "finished";
} else {
echo "response didn't contain \"true\" or \"false\"";
}
}
This function should keep calling itself until $getcontents contains the word true, and does not contain false.

Preg allowing Blank records

I have the below code for matching an email address using regular expression rules.
It works well, but I've recently noticed that it seems to match a "Blank" email address.
if (preg_match("/.* <.*#.*\..*>/i",$this->to,$matches)) {
$this->email_to = preg_replace("/.*<(.*)>.*/","$1",$this->to);
} else {
$this->email_to = $this->to;
}
My understanding of the preg_match is:-
Looks for any character, except a line break
< anycharacter#anything.anything >
Case-insensitive?
Following those rules, I can't quite work out why it matches a blank / no email address if someone can give some guidance.
Thank you.
No needs for preg_match + preg_replace.
if (empty($this->to)) {
$this->email_to = 'Is empty'; # assign what you want
} elseif (preg_match("/<(.+?#.+?\..+?)>/", $this->to, $matches)) {
$this->email_to = $matches[1];
} else {
$this->email_to = $this->to;
}
I don't know why it behaves like that but an easy solution is to ask if the string is blank
if (preg_match("/.* <.*#.*\..*>/i",$this->to,$matches)) {
if ($matches != ""){
$this->email_to = preg_replace("/.*<(.*)>.*/","$1",$this->to);
} else { $this->email_to = $this->to; }
} else {
$this->email_to = $this->to;
}

Check if an array element is in a string

This question has been asked before about strings, however *none of the questions I've reviewed (not mods do not remove or tell us this is a duplicate please) actually answer my question.
I have a landing page with a simple signup via email box. Recently people have been abusing it by entering foreign characters such as *, #, $, % and also using profanity on purpose (you can always tell). I have an array of banned characters and words I'm using as follows
$banned = array("f**k", "f******", "blah", "*", "#", "$", "%");
I can tell for sure someone has been purposely trying again and again to get through it because I've missed out some characters and suddenly a bunch of addresses have been entered making no sense at all. I need to know how to use a For loop to go through and find if the following contains any of the banned words in the array
$email = $_POST['email'];
I have tried using
$arrlen = count($banned);
for($i=0; $i < $arrlen; $i++) {
if(stripos($email, $banned[$i] !== false) {
echo 'Banned word or character!';
}
else {
echo 'Email signed up!';
}
}
This did not work at all! I tried an old function is_str_contain but the error of function does not exist came back.
I tried the normal strpos as well, still no joy.
I've been tinkering at the idea since I didn't have a ready-made piece of code to help out.
The following works:
$banned = array("badword1", "badword2", "blah", "*", "#", "$", "%");
$_POST['email'] = "emailbadword1#example.com";
$email = $_POST['email'];
foreach ($banned as $ban) {
if (stripos($email, $ban) !== FALSE) {
echo "Match found.";
return true;
}
}
echo "No match found.";
return false;
Plus, as I mentioned in comments; you should be using a confirmation method sent via email if you're not already doing so. If that person does not confirm their email address, then "stop the presses".
Using regular expressions ?
if( !preg_match( '/(\b' . implode( '\b|\b', $banned ) . '\b)/i',
$_POST['email'] )) {
echo "Match found";
}
try like this
$banned = array("****", "*******", "blah", "*", "#", "$", "%");
$email = $_POST['email'];
foreach ($email as $em) {
//if (strstr($em, $banned)) { // mine version
if (strpos($em, $banned) !== FALSE) { // Yoshi version
echo "Match found";
return true;
}
}
echo "Not found!";
return false;
You can use stripos as
foreach ($banned as $v) {
if (stripos($email,$v) > -1){
echo 'Banned word or character!';
}else{
echo 'Email signed up!';
}
}
You will need to iterate through each banned word and look if your email contains any of the banned word/character.
$banned = array("****", "*******", "blah", "*", "#", "$", "%");
$email = $_POST['email'];
$banned = false;
for($i=0; $i < count($banned); $i++) {
if(strrpos($email, $banned[$i]) != FALSE ) {
$banned = true;
break;
}
}
echo $banned ? 'Banned word or character!' : 'Email signed up!'

Validate E-mail Domains [duplicate]

This question already has answers here:
How to validate an Email in PHP?
(7 answers)
How to validate an email address in PHP
(15 answers)
Closed 9 years ago.
I want to validate the e-mail domain but I don't want to worry about any possible subdomain that may appears.
For example:
#abc.com
#a.abc.com
#b.abc.com
...
These should all be valid.
Also, I have a list of domains to validate, such as abc.com, xyz.com... how is the best way to validate e-mail domains from a list, including subdomains?
Thanks.
I decided to rewrite this to be more friendly so that you aren't restricted on what type of domain scheme you whitelist.
$whitelist = array("abc.com", "xyz.com", "specific.subdomain.com", "really.specific.subdomain.com"); //You can add basically whatever you want here because it checks for one of these strings to be at the end of the $email string.
$email = "#d.xyz.com";
function validateEmailDomain($email, $domains) {
foreach ($domains as $domain) {
$pos = strpos($email, $domain, strlen($email) - strlen($domain));
if ($pos === false)
continue;
if ($pos == 0 || $email[(int) $pos - 1] == "#" || $email[(int) $pos - 1] == ".")
return true;
}
return false;
}
So, you'd use this like:
if (validateEmailDomain($email, $whitelist))
//Do something.
You can also validate the domain using dns:
function validEmail($email)
{
$allowedDomains = array('abc.com');
list($user, $domain) = explode('#', $email);
if (checkdnsrr($domain, 'MX') && in_array($domain, $allowedDomains))
{
return true;
}
return false;
}
I wrote this function a while back. It may fill the requirements on what you're looking for. It does two things, validates the email address is a valid address and then validates if the domain name is a valid name against it's MX record in DNS.
function validate_email($email) {
// Check email syntax
if(preg_match('/^([a-zA-Z0-9\._\+-]+)\#((\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,7}|[0-9]{1,3})(\]?))$/', $email, $matches)) {
$user = $matches[1];
$domain = $matches[2];
// Check availability of DNS MX records
if(getmxrr($domain, $mxhosts, $mxweight)) {
for($i=0;$i<count($mxhosts);$i++){
$mxs[$mxhosts[$i]] = $mxweight[$i];
}
// Sort the records
asort($mxs);
$mailers = array_keys($mxs);
} elseif(checkdnsrr($domain, 'A')) {
$mailers[0] = gethostbyname($domain);
} else {
$mailers = array();
}
$total = count($mailers);
// Added to still catch domains with no MX records
if($total == 0 || !$total) {
$error = "No MX record found for the domain.";
}
} else {
$error = "Address syntax not correct.";
}
return ($error ? $error : TRUE);
}
I wrote a simple example of the regular expression with the ability to check the list of domain.
<?php
$email = 'shagtv#a.xyz.com';
$domains = array('abc.com', 'xyz.com');
$pattern = "/^[a-z0-9._%+-]+#[a-z0-9.-]*(" . implode('|', $domains) . ")$/i";
if (preg_match($pattern, $email)) {
echo 'valid';
} else {
echo 'not valid';
}
?>
Well you should use some code like this:
<?php
$subject = "abcdef";
$pattern = '/^def/';
preg_match($pattern, substr($subject,3), $matches, PREG_OFFSET_CAPTURE);
print_r($matches);
?>
or this:
<?php
$email = "someone#exa mple.com";
if(!filter_var($email, FILTER_VALIDATE_EMAIL))
{
echo "E-mail is not valid";
}
else
{
echo "E-mail is valid";
}
?>
or this that you have to do a little modify with this page.
Hope it helps!
Very similar to this post: PHP Check domain of email being registered is a 'school.edu' address
However, you need to take it one step further. Once you have that split, look at parse_url
http://php.net/manual/en/function.parse-url.php and grab the HOST part.

make an ifnot statement and if statement in one line

I'm trying to make an if statement with 2 conditions. One that checks if one variable is NOT present & does NOT matches the word "good2go" and the other that checks to make sure "body" variable is present. I'm trying to trip the error message here. Here is what I have and what I've tried, and none of it seems to work.
if (stripos($_POST['check'], 'good2go') == FALSE && $_POST['body']) {
$error = true; }
if (!$_POST['check'] == 'good2go' && $_POST['body']) {
$error = true; }
if (!stripos($_POST['check'], 'good2go') && $_POST['body']) {
$error = true; }
if ((!stripos($_POST['check'], 'good2go')) && $_POST['body']) {
$error = true; }
How do I get this to work?
here's the entire code of contact_us.php this has the validation code and the email code.
$error = false;
if (isset($_GET['action']) && ($_GET['action'] == 'send')) {
// Winnie the pooh check
//$t = tep_db_prepare_input($_POST['verify']);
if (!isset($_POST['check']) && !$_POST['check']=='good2go' && isset($_POST['body'])) {
$error = true;
} else { // Winnie the pooh Check
$name = tep_db_prepare_input($_POST['name']);
$email_address = tep_db_prepare_input($_POST['email']);
//IP recorder start
$ipaddress = $_SERVER["REMOTE_ADDR"];
$ip = "\n\nIP: " . $ipaddress;
$content = "\n\nName: ".$name."\n\nComments: ".$_POST['enquiry'];
$product = tep_db_prepare_input($_POST['product']);
if ($product) {
$product_text = "\n\nProduct Interest: ".$product; }
$content_ip = $content . $product_text. $ip;
$enquiry = tep_db_prepare_input($content_ip);
//IP recorder end
}
// BOF: Remove blank emails
// if (tep_validate_email($email_address)) {
// tep_mail(STORE_OWNER, STORE_OWNER_EMAIL_ADDRESS, EMAIL_SUBJECT, $enquiry, $name, $email_address);
// tep_redirect(tep_href_link(FILENAME_CONTACT_US, 'action=success'));
// } else {
// $error = true;
// $messageStack->add('contact', ENTRY_EMAIL_ADDRESS_CHECK_ERROR);
if (! tep_validate_email($email_address)) {
$error = true;
$messageStack->add('contact', ENTRY_EMAIL_ADDRESS_CHECK_ERROR);
}
if ($enquiry == '') {
$error = true;
$messageStack->add('contact', ENTRY_EMAIL_CONTENT_CHECK_ERROR);
}
if ($error == false) {
tep_mail(STORE_OWNER, STORE_OWNER_EMAIL_ADDRESS, EMAIL_SUBJECT, $enquiry, $name, $email_address);
tep_redirect(tep_href_link(FILENAME_CONTACT_US, 'action=success'));
// EOF: Remove blank emails
}
}
Solution to your updated problem:
if (!isset($_POST['check']) || !$_POST['check']=='good2go' || !isset($_POST['body'])) {
$error = true;
}
The reason for the pipes vs ampersands is that you want to throw an error if ANY of the fields has issue. Also, you want to check if body is NOT set vs IS set. Glad this worked out for you!
and the other that checks to make sure "body" variable is not present.
if(stripos($_POST['check'], "good2go") !== false && !isset($_POST['body'])){
//code here
}
According to PHP docs regarding the stripos function:
This function may return Boolean FALSE, but may also return a non-Boolean value which evaluates to FALSE. Please read the section on Booleans for more information. Use the === operator for testing the return value of this function.
So you need to change the first line to:
// Doing stripos checks you MUST use === (not ==)
if (stripos($_POST['check'], 'good2go') !== FALSE && $_POST['body']) {
$error = true; }
And to check if there is no $_POST['body'] you can change the above to:
if (stripos($_POST['check'], 'good2go') !== FALSE && (!isset($_POST['body'])) {
-- Update --
According to your comment, you need $_POST['check'] to equal 'good2go', then you shouldn't be using stripos as it will check for the existence of good2go regardless if it's exactly equal, or part of a string; 'wow this hamburger is good2go'.
So I would change the conditional to:
if (((isset($_POST['body'])) && (strlen($_POST['body']) > 0)) && ((!isset($_POST['check'])) || ($_POST['check'] !== 'good2go'))) {
// Post body has a value and Post check DOES NOT equal good2go, someone is hax0rin!
}
You may want to read up on Cross-site request forgery as it seems right inline with what you are working on.
One that checks if one variable is present & matches the word "good2go"
isset($_POST['check']) AND $_POST['check'] == 'good2go'
and the other that checks to make sure "body" variable is not present.
!isset($_POST['body'])
so, just put them together
if (isset($_POST['check']) AND $_POST['check'] == 'good2go' AND !isset($_POST['body'])) {
$error = true;
}
try this:
if(!empty($_POST['check']) && $_POST['check']=='good2go' && empty($_POST['body'])) { $error=true; }
Consider using empty instead of isset if your $_POST['body'] can be present with an empty value.
No need for all those unneeded functions. What you are trying to achieve is:
if (isset($_POST['check']) && $_POST['check']=='good2go' && !isset($_POST['body']) {
// your code
}
However, As per the title of the question: Use a ternary statement. Syntax is as such
$var = <condition> ? <true> : <false>;

Categories