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;
}
精彩评论