views:

132

answers:

5

Hello,

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.

A: 

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.

dbemerlin
+1  A: 

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(
    '[email protected]' => "user from beyond",
    'lalala' => "Lala user",
    '[email protected]' => "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 :)

DJRayon
+1  A: 

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 [email protected] and [email protected] are both considered valid by filter_var, because it will only test syntax and not semantics.

Gordon
A: 

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

Arkh
A: 

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.

Andrew Noyes
Obscure ? These functions are screaming "chain us plz" everytime you check the php doc in the array section.But yeah, not really maintainable and foreach looks more logic.
Arkh
Sure, but all these functions do is mask the behavior of the code, which is a loop. `array_map` is great for quickly prototyping things and writing lean code, but decoding an `array_map` call with several different function return values as its arguments, all manipulating the same data source, isn't readable.
Andrew Noyes