Jak zweryfikować wiadomość e-mail w PHP?

120

Jak mogę sprawdzić, czy wartość wejściowa to prawidłowy adres e-mail przy użyciu php5. Teraz używam tego kodu

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

ale pokazuje przestarzały błąd. Jak mogę rozwiązać ten problem. Proszę pomóż mi.

uczeń
źródło
3
Prawidłowa odpowiedź została już podana, ale w odniesieniu do przestarzałego problemu: Używanie wyrażeń regularnych POSIX (które eregisą funkcją) jest przestarzałe. Zamiast tego użyj PCRE .
Felix Kling
3
Nawiasem mówiąc, Twoje wyrażenie regularne jest całkowicie błędne. Niektóre całkowicie prawidłowe adresy zostaną oznaczone jako nieprawidłowe przez Twoją funkcję. Filtrowanie adresów e-mail za pomocą wyrażenia regularnego to koszmar.
Artefact2
Powinieneś użyć standardu RFC 822 i tutaj jest dobry artykuł Parsing Email Adresses in PHP, który to wyjaśnia.
kta

Odpowiedzi:

275

Możesz użyć tej filter_var()funkcji, która daje wiele przydatnych opcji sprawdzania poprawności i oczyszczania.

filter_var($email, FILTER_VALIDATE_EMAIL)

Jeśli nie chcesz zmieniać kodu, który opierał się na Twojej funkcji, po prostu wykonaj:

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

Uwaga : W przypadku innych zastosowań (gdzie potrzebujesz Regex), przestarzała eregrodzina funkcji (POSIX Regex Functions) powinna zostać zastąpiona pregrodziną ( PCRE Regex Functions ). Istnieje niewielka ilość różnic, przeczytanie instrukcji powinno wystarczyć.

Aktualizacja 1 : Jak wskazał @binaryLV :

PHP 5.3.3 i 5.2.14 zawierało błąd związany z FILTER_VALIDATE_EMAIL, który powodował segfault podczas sprawdzania poprawności dużych wartości. Proste i bezpieczne obejście tego problemu jest używane strlen() wcześniej filter_var(). Nie jestem pewien co do wersji 5.3.4 final, ale napisano, że problem dotyczy również niektórych wersji 5.3.4-snapshot.

Ten błąd został już naprawiony.

Aktualizacja 2 : Ta metoda zostanie oczywiście zweryfikowana bazmega@kapajako prawidłowy adres e-mail, ponieważ w rzeczywistości jest to prawidłowy adres e-mail. Ale przez większość czasu w Internecie, chcemy także adres e-mail, aby mieć TDU: [email protected]. Jak zasugerowano w tym poście na blogu (link opublikowany przez @Istiaque Ahmed ), możesz rozszerzyć filter_var()o wyrażenie regularne, które sprawdzi istnienie kropki w części domeny (nie będzie jednak sprawdzać poprawnej nazwy TLD):

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

Jak zauważył @Eliseo Ocampos , ten problem istnieje tylko przed PHP 5.3, w tej wersji zmienili wyrażenie regularne i teraz robi to sprawdzenie, więc nie musisz.

kapa
źródło
4
+1 To powiedziawszy, warto wspomnieć, że jest to dostępne tylko w PHP 5.2.x i nowszych. :-)
John Parker
5
@middaparka: Ponieważ OP otrzymuje przestarzałą wiadomość dla eregi, wygląda na to, że używa PHP 5.3. Ale tak, ważne jest, aby o tym wspomnieć (dla innych)).
Felix Kling
8
PHP 5.3.3 i 5.2.14 zawierało błąd ( bugs.php.net/52929 ) FILTER_VALIDATE_EMAIL, z którym związany był błąd segfault podczas sprawdzania poprawności dużych wartości. Proste i bezpieczne obejście tego problemu jest używane strlen()wcześniej filter_val(). Nie jestem pewien co do wersji 5.3.4 final, ale napisano, że problem dotyczy również niektórych wersji 5.3.4-snapshot.
binaryLV
1
@binaryLV filter_vallub filter_var?
Istiaque Ahmed
3
@kapa, Właściwie nie potrzebujesz już więcej sprawdzać kropki w części domeny. Zobacz svn.php.net/viewvc/php/php-src/branches/PHP_5_3/ext/filter/…
Eliseo
9

Zobacz uwagi na http://www.php.net/manual/en/function.ereg.php :

Note:

Od PHP 5.3.0 rozszerzenie regex jest przestarzałe na rzecz rozszerzenia PCRE . Wywołanie tej funkcji spowoduje wyświetlenie powiadomienia E_DEPRECATED. Zobacz listę różnic, aby uzyskać pomoc dotyczącą konwersji na PCRE.

Note:

preg_match () , która używa składni wyrażeń regularnych zgodnej z Perlem, jest często szybszą alternatywą dla ereg ().

Sean Kelleher
źródło
7

To jest stary post, ale podzielę się jednym moim rozwiązaniem, ponieważ nikt wcześniej nie wspomniał tutaj o jednym problemie.

Nowy adres e-mail może zawierać UTF-8 znaków lub nazw domen, takich jak specjalne .live, .newsitp

Stwierdzam również, że niektóre adresy e-mail mogą znajdować się na cyrylicy i we wszystkich przypadkach standardowe wyrażenie regularne lub filter_var()zawiedzie.

Dlatego stworzyłem na to rozwiązanie:

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

Ta funkcja działa doskonale we wszystkich sprawach i formatach wiadomości e-mail.

Ivijan Stefan Stipić
źródło
3

Zawsze używam tego:

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;
}
rozpad
źródło
1
@unbreak Wypróbowałem Twój kod i stwierdziłem, że jeśli przekażesz e-mail jako, alex@.to zawsze zwraca prawdę, jeśli nie jest to prawidłowy adres e-mail.
Subhajit
1

Posługiwać się:

var_dump(filter_var('[email protected]', FILTER_VALIDATE_EMAIL));
$validator = new EmailValidator();
$multipleValidations = new MultipleValidationWithAnd([
    new RFCValidation(),
    new DNSCheckValidation()
]);
$validator->isValid("[email protected]", $multipleValidations); //true
rzymski
źródło
0

Dane użytkownika są bardzo ważne dla dobrego programisty, więc nie pytaj wielokrotnie o te same dane, użyj logiki, aby poprawić niektóre podstawowe błędy w danych.

Przed walidacją e-maila: Najpierw musisz usunąć wszystkie niedozwolone znaki z e-maila.

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

następnie potwierdź swój adres e-mail za pomocą tej filter_var()funkcji.

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

Np

<?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
źródło