开发者

Filtering email addresses in an array -php

I have a php array containing email addresses as array(email_address1 => name1, email2 => name2) format.

I need to check that开发者_运维技巧 emails are valid and I can foreach and

foreach($arr as $email => $name) { 
   $new = array();
   if(filter_var($email, FILTER_VALIDATE_EMAIL)) {
   $new[$email] = $name;
  }
return $new;
}

Can I achieve the above using array_filter? what would be the syntax??

array_filter($emails_arr, 'filter_var') ?? how about FILTER_VALIDATE_EMAIL parameter?

thanks.


Since you are using the eMails as array keys, you cannot use array_filter and filter_var together directly. You'd have to write a callback function that you can pass to array_filter that operates on the array keys instead of the values; in which case you can just as well stick with your foreach solution.

Note that me@the.foo and mary@had.a.little.la.mb are both considered valid by filter_var, because it will only test syntax and not semantics.


You can create your own function filter_email($email) that just calls filter_var($email, FILTER_VALIDATE_EMAIL).

Keep in mind that this check just confirms that the email adress has a valid format, not that it is valid.


If possible use DNS / MX validation. Maybe consider using a class for that? A good choice would be http://framework.zend.com/manual/en/zend.validate.set.html#zend.validate.set.email_address

$emails = array(
    'me@the.re' => "user from beyond",
    'lalala' => "Lala user",
    'mary@had.a.little.la.mb' => "Mary with lamb"
);
$validator = new Zend_Validate_EmailAddress(
                 Zend_Validate_Hostname::ALLOW_DNS |
                 Zend_Validate_Hostname::ALLOW_LOCAL,
                 true); // enable DNS checking and lastly enable MX checking
foreach($emails as $email => $name){
    if ($validator->isValid($email)) {
        $validEmails[$email] => $name
    } else {
        foreach ($validator->getMessages() as $message) {
            echo "$message\n";
        }
    }
}

Try that :)


You can also use filter_var_array :

$result = array_intersect_key($arr, array_fill_keys(filter_var_array(array_keys($arr), FILTER_VALIDATE_EMAIL), ''));

array_keys : gets an array which contains all the keys of your input

filter_var_array : filter an array of values

array_fill_keys : creates an array which keys are the value of the first input array and values are the second parameter

array_intersect_key : returns all values from the first parameter which key correspond to a key from one of the other parameters


This would require all kinds of obscure use of nested functions, like in Arkh's answer. I think you're better off, for maintainability purposes, to just using a loop. The foreach is a really great way of adding a little more semantic meaning to code involving iterators.


You can use this:

return array_filter(array_map('trim', $emails), function ($email) {
           return (filter_var($email, FILTER_VALIDATE_EMAIL)) 
               ? true
               : false;
        });

But as @Gordon wrote

Note that me@the.foo and mary@had.a.little.la.mb are both considered valid by filter_var, because it will only test syntax and not semantics.

So, you can check the syntax, but you should do some validator check for that. E.g. Zend2/Symfony2 or Laravel Validators?

*You can check also domain of: email

    list($name, $emailDomain) = explode('@', $email);
    unset($name);
    if (!checkdnsrr($emailDomain, 'MX')) {
        return false;
    }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜