Comment valider un email en PHP?

120

Comment puis-je valider la valeur d'entrée est une adresse e-mail valide en utilisant php5. Maintenant j'utilise ce code

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; 
     }    
} 

mais il montre une erreur obsolète. Comment puis-je résoudre ce problème. Aidez-moi, s'il vous plaît.

apprenant
la source
3
La bonne réponse a déjà été donnée, mais concernant le problème obsolète : l'utilisation des expressions régulières POSIX (qui eregiest une fonction de) est obsolète. Utilisez plutôt PCRE .
Felix Kling
3
Au fait, votre regex est totalement fausse. Certaines adresses totalement valides seront marquées comme invalides par votre fonction. Filtrer les adresses e-mail avec une regex est un cauchemar.
Artefact2
Vous devriez utiliser la norme RFC 822 et voici un bon article Analyse des adresses e-mail en PHP qui l'explique.
kta

Réponses:

275

Vous pouvez utiliser la filter_var()fonction, qui vous offre de nombreuses options pratiques de validation et de désinfection.

filter_var($email, FILTER_VALIDATE_EMAIL)

Si vous ne voulez pas changer votre code qui reposait sur votre fonction, faites simplement:

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

Remarque : Pour les autres utilisations (où vous avez besoin de Regex), la eregfamille de fonctions obsolète (POSIX Regex Functions) doit être remplacée par la pregfamille ( PCRE Regex Functions ). Il y a un petit nombre de différences, la lecture du manuel devrait suffire.

Mise à jour 1 : Comme indiqué par @binaryLV :

PHP 5.3.3 et 5.2.14 avaient un bogue lié à FILTER_VALIDATE_EMAIL, qui entraînait une erreur de segmentation lors de la validation de grandes valeurs. Une solution de contournement simple et sûre pour cela consiste à utiliser strlen() avant filter_var(). Je ne suis pas sûr de la version 5.3.4 final, mais il est écrit que certaines versions de snapshot 5.3.4 ont également été affectées.

Ce bogue a déjà été corrigé.

Mise à jour 2 : Cette méthode sera bien sûr valider bazmega@kapacomme une adresse email valide, car en fait c'est une adresse email valide. Mais la plupart du temps sur l'Internet, vous pouvez également l'adresse e - mail pour avoir un TLD: [email protected]. Comme suggéré dans ce billet de blog (lien posté par @Istiaque Ahmed ), vous pouvez augmenter filter_var()avec une regex qui vérifiera l'existence d'un point dans la partie domaine (ne vérifiera cependant pas un TLD valide ):

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

Comme @Eliseo Ocampos l'a souligné, ce problème n'existe qu'avant PHP 5.3, dans cette version, ils ont changé l'expression régulière et maintenant il effectue cette vérification, vous n'avez donc pas à le faire.

kapa
la source
4
+1 Cela dit, vous voudrez peut-être mentionner que cela n'est disponible que dans PHP 5.2.x et supérieur. :-)
John Parker
5
@middaparka: Comme l'OP reçoit un message obsolète pour eregi, il semble qu'il utilise PHP 5.3. Mais oui, il est important de le mentionner (pour les autres)).
Felix Kling
8
PHP 5.3.3 et 5.2.14 avaient un bogue ( bugs.php.net/52929 ) lié à FILTER_VALIDATE_EMAIL, qui entraînait une erreur de segmentation lors de la validation de grandes valeurs. Une solution de contournement simple et sûre pour cela consiste à utiliser strlen()avant filter_val(). Je ne suis pas sûr de la version 5.3.4 final, mais il est écrit que certaines versions de snapshot 5.3.4 ont également été affectées.
binaryLV
1
@binaryLV, filter_valou filter_var?
Istiaque Ahmed
3
@kapa, En fait, vous n'avez plus besoin de rechercher un point dans la partie domaine. Voir svn.php.net/viewvc/php/php-src/branches/PHP_5_3/ext/filter/…
Eliseo Ocampos
9

Consultez les notes sur http://www.php.net/manual/en/function.ereg.php :

Note:

Depuis PHP 5.3.0, l'extension regex est obsolète au profit de l' extension PCRE . L'appel de cette fonction émettra un avis E_DEPRECATED. Consultez la liste des différences pour obtenir de l'aide sur la conversion vers PCRE.

Note:

preg_match () , qui utilise une syntaxe d'expression régulière compatible Perl, est souvent une alternative plus rapide à ereg ().

Sean Kelleher
la source
7

C'est un ancien article mais je vais partager une de mes solutions car personne ne mentionne ici un problème auparavant.

La nouvelle adresse e-mail peut contenir des caractères UTF-8 ou des noms de domaine spéciaux tels que .live, .newsetc.

De plus, je trouve que certaines adresses e-mail peuvent être en cyrilique et dans tous les cas les regex standard ou filter_var()échoueront.

C'est pourquoi j'ai fait une solution pour cela:

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;
        }
    }
}

Cette fonction fonctionne parfaitement pour tous les cas et formats de courrier électronique.

Ivijan Stefan Stipić
la source
3

J'utilise toujours ceci:

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;
}
défaire
la source
1
@unbreak J'ai essayé votre code et j'ai trouvé que si vous transmettez un e-mail comme, alex@.il renvoie toujours vrai là où ce n'est pas une adresse e-mail valide.
Subhajit le
0

Les données utilisateur sont très importantes pour un bon développeur, alors ne demandez pas encore et encore les mêmes données, utilisez une logique pour corriger une erreur de base dans les données.

Avant la validation de l'e-mail: vous devez d'abord supprimer tous les caractères illégaux de l'e-mail.

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

après cela, validez votre adresse e-mail à l'aide de cette filter_var()fonction.

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

Pour par exemple

<?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
la source