2011-05-02 79 views
97

Cómo puedo validar el valor de entrada es una dirección de correo electrónico válida utilizando php5. Ahora estoy usando este código¿Cómo validar un correo electrónico en PHP?

function isValidEmail($email){ 
    $pattern = "^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$"; 

    if (eregi($pattern, $email)){ 
     return true; 
    } 
    else { 
     return false; 
    }  
} 

pero muestra un error obsoleto. ¿Cómo puedo solucionar este problema? Por favor, ayúdame.

+3

Ya se dio la respuesta correcta, pero con respecto al problema * obsoleto *: el uso de las expresiones regulares POSIX (de las cuales 'eregi' es una función) está en desuso. Use [PCRE] (http://www.php.net/manual/en/book.pcre.php) en su lugar. –

+3

Por cierto, tu expresión regular es totalmente incorrecta. Algunas direcciones totalmente válidas serán marcadas como inválidas por tu función. Filtrar las direcciones de correo electrónico con una expresión regular es una pesadilla. – Artefact2

+0

Debe usar el estándar [RFC 822] (http://tools.ietf.org/html/rfc822) y aquí hay un buen artículo [Analizando las direcciones de correo electrónico en PHP] (http://www.iamcal.com/publish/ articles/php/parsing_email) que lo explica. – kta

Respuesta

242

Puede usar la función filter_var(), que le ofrece una gran cantidad de valiosas opciones de validación y sanitización.

filter_var($email, FILTER_VALIDATE_EMAIL) 

Si no desea cambiar su código que se basó en su función, simplemente do:

function isValidEmail($email){ 
    return filter_var($email, FILTER_VALIDATE_EMAIL) !== false; 
} 

Nota: Para otros usos (donde se necesita expresiones regulares), la familia ereg función obsoleta (Funciones POSIX expresiones regulares) debe ser reemplazado por el preg familia (PCRE Regex Functions). Hay una pequeña cantidad de diferencias, leer el Manual debería ser suficiente.

Update 1: Como se ha señalado por @binaryLV:

PHP 5.3.3 y 5.2.14 tenían un bug relacionada con FILTER_VALIDATE_EMAIL, que resultó en segfault al validar valores grandes. Solución simple y segura para esto es usar strlen() antes de filter_var(). No estoy seguro acerca de 5.3.4 final, pero es escrito que algunas versiones 5.3.4-snapshot también se vieron afectadas.

Este error ya se ha solucionado.

Actualización 2: Este método, por supuesto, validar [email protected] como una dirección de correo electrónico válida, ya que en realidad se trata de una dirección de correo electrónico válida. Pero la mayoría de las veces en Internet, también quiere que la dirección de correo electrónico tenga un TLD: [email protected]. Como se sugiere en este blog post (enlace publicado por @Istiaque Ahmed), puede aumentar filter_var() con una expresión regular que va a comprobar la existencia de un punto en la parte del dominio (no será comprobar si hay una válida TLD sin embargo):

function isValidEmail($email) { 
    return filter_var($email, FILTER_VALIDATE_EMAIL) 
     && preg_match('/@.+\./', $email); 
} 

Como señaló @Eliseo Ocampos, este problema solo existe antes de PHP 5.3, in that version they changed the regex y ahora lo hace, por lo que no es necesario.

+4

+1 Dicho esto, es posible que desee mencionar que esto solo está disponible en PHP 5.2.xy superior. :-) –

+5

@middaparka: Como OP obtiene un mensaje obsoleto para 'eregi', parece que está usando PHP 5.3. Pero sí, es importante mencionarlo (para otros)). –

+0

@middaparka Gracias, lo agregué. Lo dejé fuera por la misma razón que explicó @Felix, pero sí, otros podrían estar interesados. – kapa

9

Ver las notas en http://www.php.net/manual/en/function.ereg.php:

Note: 

A partir de PHP 5.3.0, la extensión de expresiones regulares está en desuso en favor de PCRE extension. Llamar a esta función emitirá un aviso E_DEPRECATED . Consulte the list of differences para obtener ayuda sobre la conversión a PCRE.

Note: 

preg_match(), que utiliza una sintaxis regular compatible con Perl expresión , es a menudo una alternativa más rápida a ereg().

+0

+1 Estaba trabajando en incorporar esto a mi respuesta también. – kapa

3

Siempre lo uso:

function validEmail($email){ 
    // First, we check that there's one @ symbol, and that the lengths are right 
    if (!preg_match("/^[^@]{1,64}@[^@]{1,255}$/", $email)) { 
     // Email invalid because wrong number of characters in one section, or wrong number of @ symbols. 
     return false; 
    } 
    // Split it into sections to make life easier 
    $email_array = explode("@", $email); 
    $local_array = explode(".", $email_array[0]); 
    for ($i = 0; $i < sizeof($local_array); $i++) { 
     if (!preg_match("/^(([A-Za-z0-9!#$%&'*+\/=?^_`{|}~-][A-Za-z0-9!#$%&'*+\/=?^_`{|}~\.-]{0,63})|(\"[^(\\|\")]{0,62}\"))$/", $local_array[$i])) { 
      return false; 
     } 
    } 
    if (!preg_match("/^\[?[0-9\.]+\]?$/", $email_array[1])) { // Check if domain is IP. If not, it should be valid domain name 
     $domain_array = explode(".", $email_array[1]); 
     if (sizeof($domain_array) < 2) { 
      return false; // Not enough parts to domain 
     } 
     for ($i = 0; $i < sizeof($domain_array); $i++) { 
      if (!preg_match("/^(([A-Za-z0-9][A-Za-z0-9-]{0,61}[A-Za-z0-9])|([A-Za-z0-9]+))$/", $domain_array[$i])) { 
       return false; 
      } 
     } 
    } 

    return true; 
} 
+0

guau, ¡tu método es muy minucioso! –

4

Ésta es antiguo puesto, pero voy a compartir uno mi solución porque nadie menciona aquí un problema antes.

Nueva dirección de correo electrónico puede contener caracteres UTF-8 o nombres de dominio especiales como .live, etc. .news

También me parece que alguna dirección de correo electrónico puede estar en cirílico y en todos los casos de expresiones regulares estándar o filter_var() fallará.

Por eso hice una solución para ello:

function valid_email($email) 
{ 
    if(is_array($email) || is_numeric($email) || is_bool($email) || is_float($email) || is_file($email) || is_dir($email) || is_int($email)) 
     return false; 
    else 
    { 
     $email=trim(strtolower($email)); 
     if(filter_var($email, FILTER_VALIDATE_EMAIL)!==false) return $email; 
     else 
     { 
      $pattern = '/^(?!(?:(?:\\x22?\\x5C[\\x00-\\x7E]\\x22?)|(?:\\x22?[^\\x5C\\x22]\\x22?)){255,})(?!(?:(?:\\x22?\\x5C[\\x00-\\x7E]\\x22?)|(?:\\x22?[^\\x5C\\x22]\\x22?)){65,}@)(?:(?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x5E-\\x7E]+)|(?:\\x22(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F]|(?:\\x5C[\\x00-\\x7F]))*\\x22))(?:\\.(?:(?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x5E-\\x7E]+)|(?:\\x22(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F]|(?:\\x5C[\\x00-\\x7F]))*\\x22)))*@(?:(?:(?!.*[^.]{64,})(?:(?:(?:xn--)?[a-z0-9]+(?:-+[a-z0-9]+)*\\.){1,126}){1,}(?:(?:[a-z][a-z0-9]*)|(?:(?:xn--)[a-z0-9]+))(?:-+[a-z0-9]+)*)|(?:\\[(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){7})|(?:(?!(?:.*[a-f0-9][:\\]]){7,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?)))|(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){5}:)|(?:(?!(?:.*[a-f0-9]:){5,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3}:)?)))?(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))(?:\\.(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))){3}))\\]))$/iD'; 
      return (preg_match($pattern, $email) === 1) ? $email : false; 
     } 
    } 
} 

Esta función de trabajo perfectamente para todos los casos y formatos de correo electrónico.

Cuestiones relacionadas