Làm thế nào để xác thực một Email trong PHP?


120

Làm cách nào để xác thực giá trị đầu vào là địa chỉ email hợp lệ bằng php5. Bây giờ tôi đang sử dụng mã này

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

nhưng nó hiển thị lỗi không được dùng nữa. Làm cách nào để khắc phục sự cố này. Làm ơn giúp tôi.


3
Câu trả lời chính xác đã được đưa ra, nhưng về vấn đề không được dùng nữa : Việc sử dụng biểu thức chính quy POSIX ( eregilà một hàm của) không được dùng nữa. Sử dụng PCRE thay thế.
Felix Kling

3
Nhân tiện, regex của bạn hoàn toàn sai. Một số địa chỉ hoàn toàn hợp lệ sẽ được chức năng của bạn đánh dấu là không hợp lệ. Lọc địa chỉ email bằng regex là một cơn ác mộng.
Artefact

Bạn nên sử dụng tiêu chuẩn RFC 822 và đây là một bài viết hay về Phân tích cú pháp địa chỉ email bằng PHP giải thích điều đó.
kta

Câu trả lời:


275

Bạn có thể sử dụng filter_var()chức năng này, cung cấp cho bạn nhiều tùy chọn xác nhận và khử trùng tiện dụng.

filter_var($email, FILTER_VALIDATE_EMAIL)

Nếu bạn không muốn thay đổi mã dựa trên chức năng của mình, chỉ cần làm:

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

Lưu ý : Đối với các mục đích sử dụng khác (khi bạn cần Regex), họ ereghàm không dùng nữa (Chức năng Regex POSIX) sẽ được thay thế bằng preghọ ( Chức năng PCRE Regex ). Có một số khác biệt nhỏ, chỉ cần đọc Sách hướng dẫn là đủ.

Cập nhật 1 : Như được chỉ ra bởi @binaryLV :

PHP 5.3.3 và 5.2.14 có một lỗi liên quan đến FILTER_VALIDATE_EMAIL, dẫn đến lỗi segfault khi xác thực các giá trị lớn. Giải pháp đơn giản và an toàn cho điều này là sử dụng strlen() trước đây filter_var(). Tôi không chắc chắn về phiên bản 5.3.4 cuối cùng, nhưng có thông tin cho rằng một số phiên bản ảnh chụp nhanh 5.3.4 cũng bị ảnh hưởng.

Lỗi này đã được sửa.

Cập nhật 2 : Phương thức này tất nhiên sẽ xác thực bazmega@kapanhư một địa chỉ email hợp lệ, vì thực tế nó là một địa chỉ email hợp lệ. Nhưng phần lớn thời gian trên Internet, bạn cũng muốn địa chỉ email để có một TLD: bazmega@kapa.com. Như được đề xuất trong bài đăng blog này (liên kết được đăng bởi @Istiaque Ahmed ), bạn có thể tăng cường filter_var()bằng regex sẽ kiểm tra sự tồn tại của dấu chấm trong phần miền ( mặc dù sẽ không kiểm tra TLD hợp lệ ):

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

Như @Eliseo Ocampos đã chỉ ra, vấn đề này chỉ tồn tại trước PHP 5.3, trong phiên bản đó họ đã thay đổi regex và bây giờ nó thực hiện kiểm tra này, vì vậy bạn không cần phải làm như vậy.


4
+1 Điều đó nói rằng, bạn có thể muốn đề cập rằng điều này chỉ khả dụng trong PHP 5.2.x trở lên. :-)
John Parker

5
@middaparka: Khi OP nhận được thông báo không dùng nữa eregi, có vẻ như anh ta đang sử dụng PHP 5.3. Nhưng có, điều quan trọng là phải đề cập đến nó (cho những người khác)).
Felix Kling

8
PHP 5.3.3 và 5.2.14 có một lỗi ( bug.php.net/52929 ) liên quan đến FILTER_VALIDATE_EMAIL, dẫn đến segfault khi xác thực các giá trị lớn. Giải pháp đơn giản và an toàn cho điều này là sử dụng strlen()trước đây filter_val(). Tôi không chắc chắn về phiên bản 5.3.4 cuối cùng, nhưng có thông tin cho rằng một số phiên bản ảnh chụp nhanh 5.3.4 cũng bị ảnh hưởng.
binaryLV

1
@binaryLV filter_valhoặc filter_var?
Istiaque Ahmed

3
@kapa, Thực ra bạn không cần phải kiểm tra dấu chấm trong phần miền nữa. Xem svn.php.net/viewvc/php/php-src/braches/PHP_5_3/ext/filter/…
Eliseo Ocampos

9

Xem ghi chú tại http://www.php.net/manual/en/ Chức năng.ereg.php :

Note:

Kể từ phiên bản PHP 5.3.0, phần mở rộng regex không được dùng nữa để thay thế cho phần mở rộng PCRE . Gọi hàm này sẽ đưa ra thông báo E_DEPRECATED. Xem danh sách các điểm khác biệt để được trợ giúp về việc chuyển đổi sang PCRE.

Note:

Preg_match () , sử dụng cú pháp biểu thức chính quy tương thích với Perl, thường là một thay thế nhanh hơn cho ereg ().


7

Đây là bài viết cũ nhưng tôi sẽ chia sẻ một giải pháp của tôi vì không ai đề cập ở đây một vấn đề trước đây.

Địa chỉ email mới có thể chứa các ký tự UTF-8 hoặc các tên miền đặc biệt như .live, .newsv.v.

Ngoài ra, tôi thấy rằng một số địa chỉ email có thể có trên Cyrilic và trong mọi trường hợp, regex tiêu chuẩn hoặc filter_var()sẽ bị lỗi.

Đó là lý do tại sao tôi đưa ra giải pháp cho nó:

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

Chức năng này hoạt động hoàn hảo cho mọi trường hợp và định dạng email.


3

Tôi luôn sử dụng cái này:

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

1
@unbreak Tôi đã thử mã của bạn và nhận thấy rằng nếu bạn chuyển email như vậy alex@.thì nó luôn trả về true khi đó không phải là địa chỉ email hợp lệ.
Subhajit


1

Sử dụng:

var_dump(filter_var('bob@example.com', FILTER_VALIDATE_EMAIL));
$validator = new EmailValidator();
$multipleValidations = new MultipleValidationWithAnd([
    new RFCValidation(),
    new DNSCheckValidation()
]);
$validator->isValid("example@example.com", $multipleValidations); //true

0

Dữ liệu người dùng rất quan trọng đối với một nhà phát triển giỏi, vì vậy đừng hỏi đi hỏi lại cùng một dữ liệu, hãy sử dụng một số logic để sửa một số lỗi cơ bản trong dữ liệu.

Trước khi xác thực Email: Đầu tiên bạn phải xóa tất cả các ký tự bất hợp pháp khỏi email.

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

sau đó xác thực địa chỉ email của bạn bằng filter_var()chức năng này .

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

Ví dụ

<?php
$email = "john.doe@example.com";

// 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";
}
?>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.