¿Cómo validar un correo electrónico en PHP?

120

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

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.

aprendiz
fuente
3
Ya se dio la respuesta correcta, pero con respecto al problema en desuso : el uso de expresiones regulares POSIX (que eregies una función de) está en desuso. Utilice PCRE en su lugar.
Felix Kling
3
Por cierto, tu expresión regular es totalmente incorrecta. Algunas direcciones totalmente válidas serán marcadas como inválidas por su función. Filtrar direcciones de correo electrónico con una expresión regular es una pesadilla.
Artefact2
Debe usar el estándar RFC 822 y aquí hay un buen artículo Análisis de direcciones de correo electrónico en PHP que lo explica.
kta

Respuestas:

275

Puede usar la filter_var()función, que le brinda muchas opciones útiles de validación y desinfección.

filter_var($email, FILTER_VALIDATE_EMAIL)

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

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

Nota : Para otros usos (donde necesite Regex), la eregfamilia de funciones obsoletas (POSIX Regex Functions) debe ser reemplazada por la pregfamilia ( PCRE Regex Functions ). Hay una pequeña cantidad de diferencias, leer el manual debería ser suficiente.

Actualización 1 : como lo señaló @binaryLV :

PHP 5.3.3 y 5.2.14 tenían un error relacionado con FILTER_VALIDATE_EMAIL, que resultó en segfault al validar valores grandes. La solución alternativa simple y segura para esto se está utilizando strlen() antes filter_var(). No estoy seguro acerca de 5.3.4 final, pero está escrito que algunas versiones de instantáneas 5.3.4 también se vieron afectadas.

Este error ya se ha solucionado.

Actualización 2 : Este método, por supuesto, validará bazmega@kapacomo una dirección de correo electrónico válida, porque de hecho es una dirección de correo electrónico válida. Pero la mayor parte del tiempo en Internet, también se desea que la dirección de correo electrónico y tiene un TLD: [email protected]. Como se sugiere en esta publicación de blog (enlace publicado por @Istiaque Ahmed ), puede aumentar filter_var()con una expresión regular que verificará la existencia de un punto en la parte del dominio ( aunque no verificará un TLD válido ):

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, en esa versión cambiaron la expresión regular y ahora hace esta verificación, por lo que no es necesario.

kapa
fuente
4
+1 Dicho esto, es posible que desee mencionar que esto solo está disponible en PHP 5.2.xy superior. :-)
John Parker
5
@middaparka: A medida que el OP recibe un mensaje obsoleto eregi, parece que está usando PHP 5.3. Pero eso sí, es importante mencionarlo (para otros)).
Felix Kling
8
PHP 5.3.3 y 5.2.14 tenían un error ( bugs.php.net/52929 ) relacionado FILTER_VALIDATE_EMAIL, que resultó en segfault al validar valores grandes. La solución alternativa simple y segura para esto se está utilizando strlen()antes filter_val(). No estoy seguro acerca de 5.3.4 final, pero está escrito que algunas versiones de instantáneas 5.3.4 también se vieron afectadas.
binaryLV
1
@binaryLV, filter_valo filter_var?
Istiaque Ahmed
3
@kapa, en realidad no necesitas más para buscar un punto en la parte del dominio. Ver svn.php.net/viewvc/php/php-src/branches/PHP_5_3/ext/filter/…
Eliseo Ocampos
7

Esta es una publicación antigua, pero compartiré una de mi solución porque nadie mencionó aquí un problema antes.

La nueva dirección de correo electrónico puede contener caracteres UTF-8 o nombres de dominio especiales como .live, .newsetc.

También encuentro que algunas direcciones de correo electrónico pueden estar en cirílico y en todos los casos expresiones regulares estándar o filter_var()fallarán.

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 funciona perfectamente para todos los casos y formatos de correo electrónico.

Ivijan Stefan Stipić
fuente
3

Yo siempre uso esto:

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;
}
romper
fuente
1
@unbreak Probé su código y descubrí que si pasa un correo electrónico como alex@., siempre devuelve verdadero cuando no es una dirección de correo electrónico válida.
Subhajit
0

Los datos del usuario son muy importantes para un buen desarrollador, así que no preguntes una y otra vez por los mismos datos, usa algo de lógica para corregir algún error básico en los datos.

Antes de la validación del correo electrónico: primero debe eliminar todos los caracteres ilegales del correo electrónico.

//This will Remove all illegal characters from email
$email = filter_var($email, FILTER_SANITIZE_EMAIL);

después de eso, valide su dirección de correo electrónico utilizando esta filter_var()función.

filter_var($email, FILTER_VALIDATE_EMAIL)) // To Validate the email

Por ejemplo

<?php
$email = "[email protected]";

// Remove all illegal characters from email
$email = filter_var($email, FILTER_SANITIZE_EMAIL);

// Validate email
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
    echo $email." is a valid email address";
} else {
    echo $email." is not a valid email address";
}
?>
MUFAzmi
fuente