How to restrict public email id for registration in PHP? - php

I have a registration form that uses any kind of emails for registration. I want to restrict it to company mail id's only. In other words, no free email service provider's mail id would work for registration.

How about a white/black list of domains like the following:
$domainWhitelist = ['companydomain.org', 'companydomain.com'];
$domainBlacklist = ['gmail.com', 'hotmail.com'];
$domain = array_pop(explode('#', $email));
//white list
if(in_array($domain, $domainWhitelist)) {
//allowed
}
//black list
if(!in_array($domain, $domainBlacklist)) {
//allowed
}

Since you have not provided any additional information as to how E-mail addresses are being defined and/or entered into a form or not, am submitting the following using PHP's preg_match() function, along with b and i pattern delimiters and an array.
b - word boundary
i - case insensitive
http://php.net/manual/en/function.preg-match.php
The following will match against "gmail" or "Gmail" etc. should someone want to trick the system.
Including Hotmail, Yahoo. You can add to the array.
<?php
$_POST['email'] = "email#Gmail.com";
$data = $_POST['email'];
if(preg_match("/\b(hotmail|gmail|yahoo)\b/i", $data)){
echo " Found free Email service.";
exit;
}
else{
echo "No match found for free Email service.";
exit;
}
Actually, you can use:
if(preg_match("/(hotmail|gmail|yahoo)/i", $data))
instead of:
if(preg_match("/\b(hotmail|gmail|yahoo)\b/i", $data))
which gave the same results.

Related

Laravel: Check for email service provider domain and it subdomain

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

Regex for specific domain name

I am a regex noob but I wish to write a regex to check for email for domain name xyz.com.it if user key in abc.com or other TLD domain names, it will pass. If user keys in xyz after the # then, only xyz.com.it will pass, others like xyz.net.it or xyz.net will not pass.Any idea how to do it?
I had tried
var regex = /^([a-zA-Z0-9_.+-])+\#(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9]{2,4})+$/;
var regexEmail = regex.test($('#email').val());
that only validates normal email
Now instead of using regex you can simply use strstr function of PHP like as
$email = "xyz#xyz.com";
$email2 = "xyz#xyz.net";
$valid_domain = "#xyz.com";
function checkValidDomain($email, $valid_domain){
if(!filter_var($email,FILTER_VALIDATE_EMAIL) !== false){
if(strstr($email,"#") == $valid_domain){
return "Valid";
}else{
return "Invalid";
}
}else{
return "Invalid Email";
}
}
echo checkValidDomain($email, $valid_domain);// Valid
echo checkValidDomain($email2, $valid_domain);// Invalid
Why I didn't used regex over here you can read many of those threads on SO too Email validation using regular expression in PHP and Using a regular expression to validate an email address

How to check email id's with specific domain from the array of email id's in PHP?

I've an array of email ids. I want to check each and every email id for it's domain.
Actually, I've to parse over this array whenever there is email id found with no '.edu' domain, error message should be thrown as 'Please enter valid .edu id' and further emails from the array should not be checked.
How should I achieve this in efficient and reliable way?
Following is my code of array which contains the email ids. The array could be empty, contain single element or multiple element. It should work for all of these scenarios with proper validation and error messages.
$aVals = $request_data;
$aVals['invite_emails'] = implode(', ', $aVals['invite_emails']);
$aVals['invite_emails'] contains the list of email ids received in request.
Please let me know if you need any further information regarding my requirement if it's not clear to you.
Thanks in advance.
You can do something like this,
Updated:
// consider $aVals['invite_emails'] being your array of email ids
// $aVals['invite_emails'] = array("rajdeep#mit.edu", "subhadeep#gmail.com");
if(!empty($aVals['invite_emails'])){ //checks if the array is empty
foreach($aVals['invite_emails'] as $email){ // loop through each email
$domains = explode(".",explode("#",$email)[1]); // extract the top level domains from the email address
if(!in_array("edu", $domains)){ // check if edu domain exists or not
echo "Please enter valid .edu id";
break; // further emails from the array will not be checked
}
}
}
As the email id is always composed by 3 chars, You can also do something like this:
foreach($aVals['invite_emails'] as $email){
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
// valid email
if(substr($email, -3) != "edu") {
echo "Please enter valid .edu id";
}
}
}

Find first position where pattern matching failed.

i am trying to find the common errors users have while entering email ids. I can always validate EMAIL using PHP Email Filter
$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 pattern matching
$email = test_input($_POST["email"]);
if (!preg_match("/([\w\-]+\#[\w\-]+\.[\w\-]+)/",$email))
{
$emailErr = "Invalid email format";
}
I agree that these are not full proof ways to validate emails. However they should capture 80% of cases.
What I want is - Which position email became invalid? if its a space, at what position user had entered space. or did it fail because of "." in the end?
Any pointers?
-Ajay
PS : I have seen other thread regarding email validations. I can add complexity and make it 100%. concern here is to capture the most common mistakes made by people when entering Email ID.
This is difficult because sometimes it's not always a single character that makes an email address invalid. The example you give could easily be solved by:
$position = strpos('someone#exa mple.com', ' ');
However, it seems you are not interested in an all encompassing solution but rather something that will catch the majority of character based errors. I would take the approach of using the regular expression but capture each section of the email address in a sub pattern for further validation. For example:
$matches = null;
$result = preg_match("/(([\w\-]+)\#([\w\-]+)\.([\w\-]+))/", $email, $matches);
var_dump($matches);
By capturing sections of the regex validation in sub patterns you could then dive further into each section and run similar or different tests to determine where the user went wrong. For example you could try and match up the TLD of the email address against a whitelist. Of course there are also much more robust email validators in frameworks like Zend or Symfony that will tell you more specifically WHY an email address is not valid, but in terms of knowing which specific character position is at fault (assuming it's a character that is at fault) I think a combination of tactics would work best.
There is no way I know of in Java to report back the point at which a regex failed. What you could do is start building a set of common errors (as described by Manu) that you can check for (this might or might not use regex expressions). Then categorize into these known errors and 'other', counting the frequency of each. When an 'other' error occurs, develop a regex that would catch it.
If you want some assistance with tracking down why the regex failed you could use a utility such as regexbuddy, shown in this answer.
Just implement some checks on your own:
Point at the end:
if(substr($email, -1) == '.')
echo "Please remove the point at the end of you email";
Spaces found:
$spacePos = strpos($email, ' ');
if(spacePos !== false)
echo "Please remove the space at pos: ".$spacePos;
And so on...
First of all, I would like to say that the reason your example fails is not the space. It is the lack of '.' in former part and lack of '#' in the latter part.
If you input
'someone#example.co m' or 's omeone#example.com', it will success.
So you may need 'begin with' and 'end with' pattern to check strictly.
There is no exist method to check where a regular expression match fails as I know since check only gives the matches, but if you really want to find it out , we can do something by 'break down' the regular expression.
Let's take a look at your example check.
preg_match ("/^[\w\-]+\#[\w\-]+\.[\w\-]+$/",'someone#example.com.');
If it fails, you can check where its 'sub expression' successes and find out where the problem is:
$email = "someone#example.com.";
if(!preg_match ("/^[\w\-]+\#[\w\-]+\.[\w\-]+$/",$email)){ // fails because the final '.'
if(preg_match("/^[\w\-]+\#[\w\-]+\./",$email,$matches)){ // successes
$un_match = "[\w\-]+"; // What is taken from the tail of the regular expression.
foreach ($matches as $match){
$email_tail = str_replace($match,'',$email); // The email without the matching part. in this case : 'com.'
if(preg_match('/^'.$un_match.'/',$email_tail,$match_tails)){ // Check and delete the part that tail match the sub expression. In this example, 'com' matches /[\w\-]+/ but '.' doesn't.
$result = str_replace($match_tails[0],'',$email_tail);
}else{
$result = $email_tail;
}
}
}
}
var_dump($result); // you will get the last '.'
IF you understand the upper example, then we can make our solution more common, for instance, something like below:
$email = 'som eone#example.com.';
$pattern_chips = array(
'/^[\w\-]+\#[\w\-]+\./' => '[\w\-]+',
'/^[\w\-]+\#[\w\-]+/' => '\.',
'/^[\w\-]+\#/' => '[\w\-]+',
'/^[\w\-]+/' => '\#',
);
if(!preg_match ("/^[\w\-]+\#[\w\-]+\.[\w\-]+$/",$email)){
$result = $email;
foreach ($pattern_chips as $pattern => $un_match){
if(preg_match($pattern,$email,$matches)){
$email_tail = str_replace($matches[0],'',$email);
if(preg_match('/^'.$un_match.'/',$email_tail,$match_tails)){
$result = str_replace($match_tails[0],'',$email_tail);
}else{
$result = $email_tail;
}
break;
}
}
if(empty($result)){
echo "There has to be something more follows {$email}";
}else{
var_dump($result);
}
}else{
echo "success";
}
and you will get output:
string ' eone#example.com.' (length=18)

PHP: Email Parsing - Multiple Recipients

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']
}

Categories