2010-09-16 4 views
31

Après avoir lu divers articles, j'ai décidé de ne pas utiliser REGEX pour vérifier si un e-mail est valide et utiliser simplement la fonction intégrée filter_var de PHP. Ça a semblé fonctionner, jusqu'à ce qu'il commence à me dire qu'un email était invalide parce que j'avais un numéro dedans.Le filtre filter_var de PHP FILTER_VALIDATE_EMAIL fonctionne-t-il réellement?

c.-à-d. [email protected] fonctionne, tandis que [email protected] ne fonctionne pas.

Ai-je raté quelque chose ou le filter_var($email, FILTER_VALIDATE_EMAIL) est-il vraiment inefficace?

+0

http://www.electrictoolbox.com/php-email-validation-filter-var-updated/ –

+0

@willdanceforfun Votre question est inexacte. 'name2 @ domain.com' fonctionne correctement sur toutes les versions de PHP qui supportent' filter_var() '. Preuve: http://3v4l.org/joLvm – Brad

Répondre

33

L'expression régulière utilisée dans le code du filtre PHP 5.3.3 est basée sur le blog de Michael Rushton à propos de Email Address Validation. Cela semble fonctionner pour le cas que vous mentionnez.

Vous pouvez également vérifier certaines des options dans Comparing E-mail Address Validating Regular Expressions (l'expression rationnelle actuellement utilisée dans PHP est l'un de ceux testés).

Ensuite, vous pouvez choisir une expression rationnelle que vous aimez mieux, et l'utiliser dans un appel à preg_match().

Ou bien vous pourriez prendre l'expression rationnelle et remplacer celle dans le fichier PHP/ext/filter/logical_filter.c, la fonction php_filter_validate_email(), et reconstruire PHP. Il est également nécessaire de tester l'existence d'un point dans l'adresse électronique

+2

Cela couvre environ :) – Andy

+0

Le lien vers le blog de Michael Rushton vous amène maintenant à une page vide :( – Matteo

+0

@Matteo, vous pouvez trouver le même code dans la source PHP Ou trouver le blog de Michael Rushton dans la machine de wayback: https : //web.archive.org/web/20150910045413/http: //squiloople.com/2009/12/20/email-address-validation –

5

[email protected] semble bien fonctionner: http://codepad.org/5HDgMW5i

Mais j'ai vraiment vu des gens se plaindre, il a eu des problèmes, même sur le SO. Selon toute vraisemblance, il y a des problèmes, mais il en ira de même pour une solution regex. Les spécifications de l'adresse e-mail sont très, très compliquées (RFC XXXX). C'est pourquoi la seule solution pour vérifier les emails sur lesquels vous devriez compter est d'envoyer un email à l'adresse et de demander une action (par exemple: s'il s'agit d'un script d'enregistrement, demandez-leur de cliquer sur un lien de vérification).

+0

Merci pour cela. Je vais envoyer un e-mail de validation, il serait bien d'avoir quelque chose en place pour s'assurer que les gens ne jettent pas accidentellement des caractères manifestement mauvais. – willdanceforfun

+3

@Keen Je ne dis pas jeter la validation regex par la fenêtre; vous pouvez le valider et s'il échoue avertir l'utilisateur (par exemple: "l'ordinateur dit que votre email est invalide, mais il n'est pas très intelligent. Êtes-vous sûr que vous voulez utiliser cet email?") – NullUserException

+0

C'est une bonne idée! – willdanceforfun

1
function isValidEmail($email, $checkDNS = false) 
{ 

    $valid = (
      /* Preference for native version of function */ 
      function_exists('filter_var') and filter_var($email, FILTER_VALIDATE_EMAIL) 
      ) || (
       /* The maximum length of an e-mail address is 320 octets, per RFC 2821. */ 
       strlen($email) <= 320 
       /* 
       * The regex below is based on a regex by Michael Rushton. 
       * However, it is not identical. I changed it to only consider routeable 
       * addresses as valid. Michael's regex considers [email protected] a valid address 
       * which conflicts with section 2.3.5 of RFC 5321 which states that: 
       * 
       * Only resolvable, fully-qualified domain names (FQDNs) are permitted 
       * when domain names are used in SMTP. In other words, names that can 
       * be resolved to MX RRs or address (i.e., A or AAAA) RRs (as discussed 
       * in Section 5) are permitted, as are CNAME RRs whose targets can be 
       * resolved, in turn, to MX or address RRs. Local nicknames or 
       * unqualified names MUST NOT be used. 
       * 
       * This regex does not handle comments and folding whitespace. While 
       * this is technically valid in an email address, these parts aren't 
       * actually part of the address itself. 
       */ 
       and preg_match_all(
        '/^(?!(?:(?:\\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', 
        $email) 
      ); 

    if($valid) 
    { 
     if($checkDNS && ($domain = end(explode('@',$email, 2)))) 
     { 
      /* 
      Note: 
      Adding the dot enforces the root. 
      The dot is sometimes necessary if you are searching for a fully qualified domain 
      which has the same name as a host on your local domain. 
      Of course the dot does not alter results that were OK anyway. 
      */ 
      return checkdnsrr($domain . '.', 'MX'); 
     } 
     return true; 
    } 
    return false; 
} 


//----------------------------------------------------------------- 

    var_dump(isValidEmail('[email protected]', true)); 
    // bool(true) 
+6

Veuillez ne pas fournir le code comme réponse. –

Questions connexes