Come convalidare un'e-mail in PHP?


120

Come posso convalidare il valore di input è un indirizzo e-mail valido utilizzando php5. Ora sto usando questo codice

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

ma mostra un errore obsoleto. Come posso risolvere questo problema. Mi aiuti per favore.


3
La risposta corretta è già stata data, ma per quanto riguarda il problema deprecato : l'utilizzo delle espressioni regolari POSIX (che eregiè una funzione di) è deprecato. Usa invece PCRE .
Felix Kling

3
A proposito, la tua regex è totalmente sbagliata. Alcuni indirizzi totalmente validi saranno contrassegnati come non validi dalla tua funzione. Filtrare gli indirizzi e-mail con un'espressione regolare è un incubo.
Artefact2

Dovresti usare lo standard RFC 822 ed ecco un buon articolo Parsing Email Adresses in PHP che lo spiega.
kta

Risposte:


275

È possibile utilizzare la filter_var()funzione, che offre molte utili opzioni di convalida e sanificazione.

filter_var($email, FILTER_VALIDATE_EMAIL)

Se non vuoi cambiare il codice che si basa sulla tua funzione, fai semplicemente:

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

Nota : per altri usi (dove è necessario Regex), la eregfamiglia di funzioni obsoleta (Funzioni Regex POSIX) dovrebbe essere sostituita dalla pregfamiglia ( Funzioni Regex PCRE ). Ci sono poche differenze, la lettura del Manuale dovrebbe essere sufficiente.

Aggiornamento 1 : come sottolineato da @binaryLV :

PHP 5.3.3 e 5.2.14 avevano un bug relativo a FILTER_VALIDATE_EMAIL, che causava un segfault durante la convalida di valori grandi. Soluzione semplice e sicura per questo sta usando strlen() prima filter_var(). Non sono sicuro della 5.3.4 finale, ma è scritto che anche alcune versioni 5.3.4 snapshot sono state interessate.

Questo bug è già stato risolto.

Aggiornamento 2 : questo metodo ovviamente convaliderà bazmega@kapacome un indirizzo email valido, perché in realtà è un indirizzo email valido. Ma la maggior parte del tempo su Internet, si vuole anche l'indirizzo e-mail per avere un TLD: bazmega@kapa.com. Come suggerito in questo post del blog (link pubblicato da @Istiaque Ahmed ), puoi aumentare filter_var()con una regex che verificherà l'esistenza di un punto nella parte del dominio (non controllerà però un TLD valido ):

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

Come ha sottolineato @Eliseo Ocampos , questo problema esiste solo prima di PHP 5.3, in quella versione hanno cambiato la regex e ora fa questo controllo, quindi non devi.


4
+1 Detto questo, potresti menzionare che questo è disponibile solo in PHP 5.2.xe versioni successive. :-)
John Parker

5
@middaparka: poiché l'OP riceve un messaggio deprecato per eregi, sembra che stia usando PHP 5.3. Ma sì, è importante menzionarlo (per altri)).
Felix Kling

8
PHP 5.3.3 e 5.2.14 avevano un bug ( bugs.php.net/52929 ) correlato a FILTER_VALIDATE_EMAIL, che causava un segfault durante la convalida di valori grandi. Soluzione semplice e sicura per questo sta usando strlen()prima filter_val(). Non sono sicuro della 5.3.4 finale, ma è scritto che anche alcune versioni 5.3.4 snapshot sono state interessate.
binaryLV

1
@binaryLV filter_valo filter_var?
Istiaque Ahmed

3
@kapa, in realtà non hai più bisogno di controllare la presenza di un punto nella parte del dominio. Vedi svn.php.net/viewvc/php/php-src/branches/PHP_5_3/ext/filter/…
Eliseo Ocampos


7

Questo è un vecchio post ma condividerò una mia soluzione perché nessuno ha menzionato qui un problema prima.

Il nuovo indirizzo e-mail può contenere caratteri UTF-8 o nomi di dominio speciali come .live, .newsecc.

Inoltre trovo che alcuni indirizzi e-mail possono essere in cirillico e in tutti i casi regex standard o filter_var()non funzioneranno.

Ecco perché ho creato una soluzione per questo:

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

Questa funzione funziona perfettamente per tutti i casi e formati di posta elettronica.


3

Lo uso sempre:

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 Ho provato il tuo codice e ho scoperto che se passi l'email come alex@.allora, restituisce sempre true dove non è un indirizzo email valido.
Subhajit



0

I dati degli utenti sono molto importanti per un buon sviluppatore, quindi non chiedere più e più volte gli stessi dati, usa una logica per correggere alcuni errori di base nei dati.

Prima della convalida dell'e- mail: per prima cosa devi rimuovere tutti i caratteri illegali dall'e-mail.

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

dopodiché convalida il tuo indirizzo email utilizzando questa filter_var()funzione.

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

Per es

<?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";
}
?>
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.