2010-09-16 20 views
31

Sau khi đọc các bài viết khác nhau, tôi quyết định không sử dụng REGEX để kiểm tra xem email có hợp lệ không và chỉ cần sử dụng hàm filter_var sẵn có của PHP. Nó dường như hoạt động tốt, cho đến khi nó bắt đầu nói với tôi một email không hợp lệ vì tôi đã có một số trong đó.Bộ lọc PHP của PHP_var FILTER_VALIDATE_EMAIL có thực sự hoạt động không?

tức là [email protected] hoạt động, trong khi [email protected] thì không.

Tôi có thiếu gì đó hoặc là filter_var($email, FILTER_VALIDATE_EMAIL) thực sự không hiệu quả?

+0

kiểm tra sự tồn tại của dấu chấm trong địa chỉ email cũng là cần thiết. http://www.electrictoolbox.com/php-email-validation-filter-var-updated/ –

+0

@willdanceforfun Câu hỏi của bạn không chính xác. 'name2 @ domain.com' hoạt động tốt trên tất cả các phiên bản của PHP có hỗ trợ' filter_var() '. Bằng chứng: http://3v4l.org/joLvm – Brad

Trả lời

33

Cụm từ thông dụng được sử dụng trong mã bộ lọc PHP 5.3.3 dựa trên blog của Michael Rushton về số Email Address Validation. Nó dường như làm việc cho trường hợp bạn đề cập đến.

Bạn cũng có thể kiểm tra một số tùy chọn trong Comparing E-mail Address Validating Regular Expressions (regexp hiện được sử dụng trong PHP là một trong những thử nghiệm).

Sau đó, bạn có thể chọn một regexp bạn thích tốt hơn và sử dụng nó trong một cuộc gọi đến preg_match().

Hoặc bạn có thể lấy regexp và thay thế tệp trong tệp PHP/ext/filter/logical_filter.c, hàm php_filter_validate_email() và xây dựng lại PHP.

+2

Điều đó về bao gồm nó :) – Andy

+0

Liên kết tới blog của Michael Rushton giờ đây đưa bạn đến một trang trống: ( – Matteo

+0

@Matteo, bạn có thể tìm thấy cùng một mã trong nguồn PHP. Hoặc tìm blog của Michael Rushton trong máy rút tiền: https : //web.archive.org/web/20150910045413/http: //squiloople.com/2009/12/20/email-address-validation –

5

[email protected] dường như làm việc tốt: http://codepad.org/5HDgMW5i

Nhưng tôi đã chắc chắn nhìn thấy mọi người phàn nàn nó có vấn đề, ngay cả trên SO. Trong khả năng tất cả, nó có vấn đề, nhưng như vậy sẽ là một giải pháp regex. Thông số địa chỉ email rất, rất phức tạp (RFC XXXX).

Đó là lý do tại sao giải pháp duy nhất để xác minh email bạn nên dựa vào là gửi email đến địa chỉ và hành động yêu cầu (ví dụ: nếu đó là tập lệnh đăng ký yêu cầu họ nhấp vào liên kết xác minh).

+0

Cảm ơn vì điều đó. Tôi sẽ gửi một email xác nhận nó sẽ chỉ được tốt đẹp để có một cái gì đó tại chỗ để đảm bảo mọi người không vô tình ném vào các nhân vật rõ ràng là sai. – willdanceforfun

+3

@Keen Tôi không nói ném ra xác nhận regex ra ngoài cửa sổ; bạn có thể xác nhận nó và nếu nó không cảnh báo người dùng (ví dụ: "máy tính cho biết email của bạn không hợp lệ, nhưng nó không thông minh lắm. Bạn có chắc chắn muốn sử dụng email này không?") – NullUserException

+0

Đó là một ý tưởng tuyệt vời! – 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

Vui lòng không chỉ cung cấp mã làm câu trả lời của bạn. –

Các vấn đề liên quan