views:

90

answers:

4

I am trying to create a script that will only execute its actions if the email address the user enters is from a specific domain. I created a regex that seems to work when testing it via regex utility, but when its used in my PHP script, it tells me that valid emails are invalid. In this case, I want any email that is from @secondgearsoftware.com, @secondgearllc.com or asia.secondgearsoftware.com to echo success and all others to be rejected.

$pattern = '/\b[A-Z0-9\._%+-]+@((secondgearsoftware|secondgearllc|euro\.secondgearsoftware|asia\.secondgearsoftware)+\.)+com/';
$email = urldecode($_POST['email']);
if (preg_match($pattern, $email))
{
    echo 'success';
}
else
{
    echo 'opposite success';
}

I am not really sure what's futzed with the pattern. Any help would be appreciated.

+1  A: 

You probably need to use /\b[A-Z0-9\._%+-]+@((euro\.|asia\.)secondgearsoftware|secondgearllc)\.com/i (note the i at the end) in order to make the regex case-insensitive. I also dropped the +s as they allow for infinite repetition which doesn't make sense in this case.

Tim Pietzcker
+1  A: 

Your regular expression is a bit off (it will allow [email protected]) and can be simplified:

$pattern = '/@((euro\.|asia\.)?secondgearsoftware|secondgearllc)\.com$/i';

I've made it case-insensitive and anchored it to the end of the string.

There doesn't seem to be a need to check what's before the "@" - you should have a proper validation routine for that if necessary, but it seems you just want to check if the email address belongs to one of these domains.

Greg
A: 

I suggest you drop the regex and simply use stristr to check if it matches. Something like this should work:

<?php
// Fill out as needed
$domains = array('secondgearsoftware.com', 'secondgearllc.com');

$email = urldecode($_POST['email']);
$found = false;
for(i=0;i<count($domains);i++)
{
    if ($domains[i] == stristr($email, $domains[i]))
        $found = true;
}

if ($found) ...
?>

The function stristr returns the e-mail address from the part where it found a match to the end, which should be the same as the match in this case. Technically there could be something prior to the domains (fkdskjfsdksfks.secondgeartsoftware.com), but you can just insert "@domainneeded.com" to prevent this. This code is also slightly longer, but easily extended with new domains without worrying about regex.

Christian P.
Much cleaner. Thanks! only thing is your i variables should be $i, no?
Justin Williams
This is wrong. This will allow any weird composition of the domain names even in the user name part. Do not use this if you want real protection.
BYK
@Justin: Too much C programming on my part. Use $i ofcourse ;)@BYK: If you entered secondgearsoftware.com@somethingelse, stristr would return it all, and the == comparison would return false. The only case where it returns true is if the LAST part of the e-mail address is the same as the domain, hence doing what the user asked.
Christian P.
way too much c programming... use foreach no $i needed... foreach($domains as $domain){
ftrotter
+1  A: 

Here's an easy to maintain solution using regular expressions

$domains = array(
    'secondgearsoftware',
    'secondgearllc',
    'euro\.secondgearsoftware',
    'asia\.secondgearsoftware'
);
preg_match("`@(" .implode("|", $domains). ")\.com$`i", $userProvidedEmail);

Here's a couple of tests:

$tests = array(
    '[email protected]',
    '[email protected]',
    '[email protected]',
    '[email protected]',
    '[email protected]',
    '[email protected]',
    '[email protected]',
    '[email protected]'
);

foreach ( $tests as $test ) { 
    echo preg_match("`@(" .implode("|", $domains). ")\.com$`i", $test), 
         " <- $test\n";
}

Result (1 is passing of course)

1 <- [email protected]
1 <- [email protected]
0 <- [email protected]
0 <- [email protected]
0 <- [email protected]
1 <- [email protected]
0 <- [email protected]
1 <- [email protected]
Justin Johnson
This is easy to use but it introduces a performance hit because of the additional array construction and implode function.
BYK
This implementation is advantageous and necessary in cases where the list of valid domains is mutable or generalization is necessary. Otherwise, if the list of valid domains is not subject to change often, I would just hard code it. But, being that the list is small, performance concerns are negligible.
Justin Johnson