I want to validate the e-mail domain using php, because some users trying to submit contact form using dummy email ids like: aa#bb.com
TRY with checkdnsrr extract the domain name from the email address and pass to the checkdnsrr.
Returns TRUE if domain name are found; returns FALSE if no domain name
were found or if an error occurred.
$domainname = "domain.com";
checkdnsrr($domainname , "A");
If you only want to validate the syntax of the domain name section you could split the email on the # and run this regex on the second part (after running it through the idn_to_ascii() function for intenational domain names):
/
^
(?(DEFINE)(?<part>(?:xn--)?[a-z\d](?:[a-z\d-]*[a-z\d])?))
(?(DEFINE)(?<subpart>(?:xn--)?[a-z\d_](?:[a-z\d_-]*[a-z\d])?))
(?:(?&subpart)\.)*
(?&part)
(?:\.[a-z]+|\.xn--[a-z\d]+){1,2}
$
/xigm
https://regex101.com/library/PAKVdK
You will need to check if there is a MX record for that domain.
Consider this script in addition to you regex validation
https://davidwalsh.name/php-email-validator
Be aware that this will not 'really' validate emails completely. User could be invalid.
If you don't want to go through all the hassle of doing the validations by yourself, just use the free API plan from MailboxValidator.
They have some sample codes to help you with integration.
http://www.mailboxvalidator.com/api-single-validation
<?php
$apiKey = 'Enter_License_Key';
$params['format'] = 'json';
$params['email'] = 'Enter_Email';
$query = '';
foreach($params as $key=>$value){
$query .= '&' . $key . '=' . rawurlencode($value);
}
$try = 0;
do {
////////////
//For https request, please make sure you have enabled php_openssl.dll extension.
//
//How to enable https
//- Uncomment ;extension=php_openssl.dll by removing the semicolon in your php.ini, and restart the apache.
//
//In case you have difficulty to modify the php.ini, you can always make the http request instead of https.
////////////
$result = file_get_contents('https://api.mailboxvalidator.com/v1/validation/single?key=' . $apiKey . $query);
} while(!$result && $rty++ < 3);
$data = json_decode($result);
print_r($data);
?>
Related
I wants restrict user to not to add some popular email service provider domain like gmail.com, yahoo.com, ymail.com, hotmail.com
for that I have created an array
$invalidDomain = ['gmail.com', 'yahoo.com', 'ymail.com', 'hotmail.com']
and then check user input with in_array
if(in_array($insertDomain, $invalidDomain)){
//restrict
}
but now I also want to check for gmail.co.in, hotmail.co.uk
how can I?
You can use regular expressions to achieve this - it will give you more flexibility eg: if you would like to exclude gmail.co.uk but allow gmail.com. See the code snippet below:
$insertDomain = "gmail.com";
$invalidDomain = ['gmail\.[a-zA-Z\.]{2,}', 'yahoo\.[a-zA-Z\.]{2,}', 'ymail\.[a-zA-Z\.]{2,}', 'hotmail\.[a-zA-Z\.]{2,}'];
// join regexp
if (preg_match('/^'.implode("$|^", $invalidDomain).'$/', $insertDomain)) {
// restrict
echo $insertDomain."\n";
}
Used this type of code
$invalidDomain = ['gmail', 'yahoo', 'ymail', 'hotmail']
and finally in the condition
//$insertDomain = "gmail";
if(in_array($insertDomain, $invalidDomain)){
//restrict
}
You could use PHP's parse_url to determine what domain is being used http://php.net/manual/en/function.parse-url.php
The output array would contain host index that would give you the domain / sub-domain used within the string you pass as an argument to that function .i.e.
$partials = parse_url('https://google.com/?id=123');
$insertDomain = $partials['host']; // google.com
I'm building a php system which allow users to resend their invoices that need to be rechecked,
My problem is i need to make a condition to my system so it can't accept any url expect urls that looks like the following example
$url = http://mydomain.com/$id/invoice/$num
http://mydomain.com/murad/invoice/6589445564555
http://mydomain.com/ludmilla/invoice/9764564252
code:
} elseif(preg_match("|^http(s)?://(www.)?mydomain.com/([a-z]+)/(.*)?$|i", $url)){
$msg = '<div class="msg"><div class="error">'.$lang['er_01'].'</div></div>';
but it didn't work , Can i know how to make it work correctly ?
AFAIK, you need to reverse the test and change a bit the regex, try this:
} elseif( ! preg_match("|^http(s)?://(www.)?mydomain.com/([a-z]+)/invoice/(\d+)$|i", $url) ){
$msg = '<div class="msg"><div class="error">'.$lang['er_01'].'</div></div>';
I dont wan't reinvent wheel, but i couldnt find any library that would do this perfectly.
In my script users can save URLs, i want when they give me list like:
google.com
www.msn.com
http://bing.com/
and so on...
I want to be able to save in database in "correct format".
Thing i do is I check is it there protocol, and if it's not present i add it and then validate URL against RegExp.
For PHP parse_url any URL that contains protocol is valid, so it didnt help a lot.
How guys you are doing this, do you have some idea you would like to share with me?
Edit:
I want to filter out invalid URLs from user input (list of URLs). And more important, to try auto correct URLs that are invalid (ex. doesn't contains protocol). Ones user enter list, it should be validated immediately (no time to open URLs to check those they really exist).
It would be great to extract parts from URL, like parse_url do, but problem with parse_url is, it doesn't work well with invalid URLs. I tried to parse URL with it, and for parts that are missing (and are required) to add default ones (ex. no protocol, add http). But parse_url for "google.com" wont return "google.com" as hostname but as path.
This looks like really common problem to me, but i could not find available solution on internet (found some libraries that will standardize URL, but they wont fix URL if it is invalid).
Is there some "smart" solution to this, or I should stick with my current:
Find first occurrence of :// and validate if it's text before is valid protocol, and add protocol if missing
Found next occurrence of / and validate is hostname is in valid format
For good measure validate once more via RegExp whole URL
I just have feeling I will reject some valid URLs with this, and for me is better to have false positive, that false negative.
I had the same problem with parse_url as OP, this is my quick and dirty solution to auto-correct urls(keep in mind that the code in no way are perfect or cover all cases):
Results:
http:/wwww.example.com/lorum.html => http://www.example.com/lorum.html
gopher:/ww.example.com => gopher://www.example.com
http:/www3.example.com/?q=asd&f=#asd =>http://www3.example.com/?q=asd&f=#asd
asd://.example.com/folder/folder/ =>http://example.com/folder/folder/
.example.com/ => http://example.com/
example.com =>http://example.com
subdomain.example.com => http://subdomain.example.com
function url_parser($url) {
// multiple /// messes up parse_url, replace 2+ with 2
$url = preg_replace('/(\/{2,})/','//',$url);
$parse_url = parse_url($url);
if(empty($parse_url["scheme"])) {
$parse_url["scheme"] = "http";
}
if(empty($parse_url["host"]) && !empty($parse_url["path"])) {
// Strip slash from the beginning of path
$parse_url["host"] = ltrim($parse_url["path"], '\/');
$parse_url["path"] = "";
}
$return_url = "";
// Check if scheme is correct
if(!in_array($parse_url["scheme"], array("http", "https", "gopher"))) {
$return_url .= 'http'.'://';
} else {
$return_url .= $parse_url["scheme"].'://';
}
// Check if the right amount of "www" is set.
$explode_host = explode(".", $parse_url["host"]);
// Remove empty entries
$explode_host = array_filter($explode_host);
// And reassign indexes
$explode_host = array_values($explode_host);
// Contains subdomain
if(count($explode_host) > 2) {
// Check if subdomain only contains the letter w(then not any other subdomain).
if(substr_count($explode_host[0], 'w') == strlen($explode_host[0])) {
// Replace with "www" to avoid "ww" or "wwww", etc.
$explode_host[0] = "www";
}
}
$return_url .= implode(".",$explode_host);
if(!empty($parse_url["port"])) {
$return_url .= ":".$parse_url["port"];
}
if(!empty($parse_url["path"])) {
$return_url .= $parse_url["path"];
}
if(!empty($parse_url["query"])) {
$return_url .= '?'.$parse_url["query"];
}
if(!empty($parse_url["fragment"])) {
$return_url .= '#'.$parse_url["fragment"];
}
return $return_url;
}
echo url_parser('http:/wwww.example.com/lorum.html'); // http://www.example.com/lorum.html
echo url_parser('gopher:/ww.example.com'); // gopher://www.example.com
echo url_parser('http:/www3.example.com/?q=asd&f=#asd'); // http://www3.example.com/?q=asd&f=#asd
echo url_parser('asd://.example.com/folder/folder/'); // http://example.com/folder/folder/
echo url_parser('.example.com/'); // http://example.com/
echo url_parser('example.com'); // http://example.com
echo url_parser('subdomain.example.com'); // http://subdomain.example.com
It's not 100% foolproof, but a 1 liner.
$URL = (((strpos($URL,'https://') === false) && (strpos($URL,'http://') === false))?'http://':'' ).$URL;
EDIT
There was apparently a problem with my initial version if the hostname contain http.
Thanks Trent
I'm trying to edit a config file using a html form. The edit (settings.php) file looks like this:
$config['foo'] = FALSE;
$config['maintenance'] = FALSE; //this line is that what it matters
$config['bar'] = FALSE;
The idea here is change the of $config['maintenance'], so once the form is submitted (there is a checkbox named maintenance in order to set the status to true or false according to its state), I get the checkbox value as:
$status = ($_POST['maintenance'] === 'on')? "TRUE" : "FALSE";
I have debugged $status var value and everything goes fine to here. Now, I am using the regex below to find the correct line at file:
\$config\[(\s+)?(\'|")maintenance(\'|")(\s+)?\](\s+)?=(\s+)?(false|FALSE|true|TRUE);/
Initially "works" good, because I am not sure, but let me finish the explanation...
According with the code above, now I proceed to do the replacement:
//read the content and replace it
$content = preg_replace(
'/\$config\[(\s+)?(\'|")maintenance(\'|")(\s+)?\](\s+)?=(\s+)?(false|FALSE|true|TRUE);/',
'$config["maintenance"] = ' . $status . ';',
file_get_contents($file)
);
//set the new content
file_put_contents($file, $content);
When I run it the first time with the checkbox checked it works and the result is as follow:
$config['foo'] = FALSE;
$config["maintenance"] = TRUE;
$config['bar'] = FALSE;
However, no matter what I select in the checkbox, the file does not show any changes. Can you guide me to the right direction to find the bug? Thank you
Edit.
This is the html markup
<label>
<input type="checkbox" name="maintenance" /> in maintenance mode
</label>
Try this:
$status = (isset($_POST['maintenance'])) ? 'TRUE' : 'FALSE';
and:
$content = preg_replace(
'/\$config\[\s*[\'"]maintenance[\'"]\s*\]\s*=\s*(false|true);/i',
'$config["maintenance"] = ' . $status . ';',
file_get_contents($file)
);
However the code you posted works fine for me, you should do more debugging like:
error_reporting(-1);
or checking $content before and after replace. Check your error logs (or search for error message if you have display_errors set to on). There can be anything wrong. (e.g. file permissions).
Also consider:
full rewriting of config file instead of just replacing one line - it might be prone to errors.
acquiring locks while writing/read to/from the file
I am piping email that get's sent to my server to a PHP script. The script parses the email so I can assign variables.
My problem is once in awhile somebody will include my email address to an email that's getting sent to multiple recipients and my script will only get the first one. I need it to find my email address then assign it to a variable.
Here is what the email array looks like: http://pastebin.com/0gdQsBYd
Using the example above I would need to get the 4th recipient: my_user_email#mydomain.com
Here is the code I am using to get the "To -> name" and "To -> address"
# Get the name and email of the recipient
$toName = $results['To'][0]['name'];
$toEmail = $results['To'][0]['address'];
I assume I need to do a foreach($results['To'] as $to) then a preg_match but I am not good with regular expressions to find the email I want.
Some help is appreciated. Thank you.
Instead of usin preg_match inside foreach loop you can use strstr like below
Supposing you are looking for my_user_email#mydomain.com use following code
foreach($results['To'] as $to)
{
// gets value occuring before the #, if you change the 3 rd parameter to false returns domain name
$user = strstr($to, '#', true) ;
if($user == 'my_user_email')
{
//your action code goes here
}
}
example:
<?php
$email = 'name#example.com';
$domain = strstr($email, '#');
echo $domain; // prints #example.com
$user = strstr($email, '#', true); // As of PHP 5.3.0
echo $user; // prints name
?>
Actually, you do not need to use a regexp at all. Instead you can use a PHP for statement that loops through your array of To addresses.
$count = count($root['To']);
for ($i=0; $i < $count; $i++) {
//Do something with your To array here using $root['To'][$i]['address']
}