indirizzo email formalmente valido e esistente

borgo italia

Super Moderatore
Membro dello Staff
SUPER MOD
MOD
4 Feb 2008
16.046
150
63
PR
www.borgo-italia.it
piccola funzione per verificare un indirizzo email.
verifica che sia formalmente corretto e, in una certa misura, verifica che esista.
in una certa misura perchè, pur esistendo il dominio, non è detto che l'indirizzo esista, comunque un certo grado di sicurezza in più la da
PHP:
<?php
function valida_email($email){
	//per prima cosa valido formalmente l'indirizzo
	if(!filter_var($email, FILTER_VALIDATE_EMAIL)){
		return false;//non formalmente valido
	}else{
		//l'indirizzo è formalmente valido e quindi lo divido
		$divisa=explode('@',$email);
		//list($prefisso, $dominio) = split("@",$email);
		//verifico che sia possibile utilizzare getmxrr e che il dominio esita
		//ho letto che su piattaforma windows getmxrr ha dei problemi
		if(function_exists("getmxrr") && getmxrr($divisa[1], $mxhosts)){
			//un elenco dei record MX trovati è posto nell'array $mxhosts.
			return true;//è stato possibile usare getmxrr e il dominio esiste
		}elseif (@fsockopen($divisa[1], 25, $err_nu, $err_str, 5)){
        	return true;//non posso usare getmxrr ma il dominio esiste
		}else{
        	return false;//il dominio non esiste
		}
	}
}
//TEST.......
//l'array: valida inesistente errata .. il dubbio
$em=array("[email protected]","[email protected]","info#borgo-italia.it","[email protected]", "[email protected]");
foreach($em as $e){
	if(valida_email($e)){
		echo "$e valida e esitente<br />";
	}else{
		echo "$e non è formalmente valida o non è esitente<br />";
	}
}
?>
come detto, provando il test, risulta:
[email protected] valida e esitente
[email protected] non è formalmente valida o non è esitente
info#borgo-italia.it non è formalmente valida o non è esitente
[email protected] valida e esitente
[email protected] valida e esitente
dove di sicuro [email protected] non esiste e [email protected] è probabile che non esista
 

MarcoGrazia

Utente Attivo
15 Dic 2009
852
20
28
62
Udine
www.stilisticamente.com
Per rendere "più sicuro" un indirizzo email il sito di PHP consiglia questa procedura:
PHP:
$c = '([email protected])';
$sanitized_c = filter_var($c, FILTER_SANITIZE_EMAIL);
if (filter_var($sanitized_c, FILTER_VALIDATE_EMAIL)) {
echo "Email sicura: $sanitized_c";     //   [email protected]
}
In pratica prima si "sanitizza" un indirizzo email alla ricerca di eventuali caratteri spuri come ad esempio parentesi tonde, dopo il filtro di sanitizzazione l'indirizzo sarà reso senza parentesi, ma potevano essere altri caratteri non compresi nell'elenco dell'RFC relativa ( vedi: http://www.faqs.org/rfcs/rfc2822.html ).
Poi una volta tolto tutto ciò che non ci deve essere si verifica se ciò che resta è ancora valido.
Nell'esempio di cui sopra preso dalla pagina di esempi di PHP l'email è resa semplicemente senza parentesi e valida.
Quindi la prima parte del tuo esempio lo modificherei così:
PHP:
function valida_email($email){ 
    //per prima cosa valido formalmente l'indirizzo 
    $email =  filter_var($email, FILTER_SANITIZE_EMAIL);
    if(!filter_var($email, FILTER_VALIDATE_EMAIL)){ 
        return false;  //non formalmente valido 
    }else{
Mentre sulla verifica dei records MX io non mi pronuncio dato che l'argomento è vasto, resta il fatto che è purtroppo semplice mascherarli, però è anche vero che una persona reale che intende contattarci per un motivo reale (incontrarci, chiederci/offrirci un lavoro) di solito non fa queste cose, di solito semplicemente sbaglia a scrivere il proprio indirizzo :D
Magari un upgrade alla funzione potrebbe essere uno che evidenzi gli errori di battitura, purtroppo però SANITIZE_EMAIL non ha un feedback relativamente ai caratteri inseriti malamente, li toglie e basta.
Magari con un approccio diverso, magari tramite regex si può fare.
 

Shyson

Utente Attivo
19 Ago 2012
1.179
1
38
piccola funzione per verificare un indirizzo email.
verifica che sia formalmente corretto e, in una certa misura, verifica che esista.
in una certa misura perchè, pur esistendo il dominio, non è detto che l'indirizzo esista, comunque un certo grado di sicurezza in più la da
PHP:
<?php
function valida_email($email){
	//per prima cosa valido formalmente l'indirizzo
	if(!filter_var($email, FILTER_VALIDATE_EMAIL)){
		return false;//non formalmente valido
	}else{
		//l'indirizzo è formalmente valido e quindi lo divido
		$divisa=explode('@',$email);
		//list($prefisso, $dominio) = split("@",$email);
		//verifico che sia possibile utilizzare getmxrr e che il dominio esita
		//ho letto che su piattaforma windows getmxrr ha dei problemi
		if(function_exists("getmxrr") && getmxrr($divisa[1], $mxhosts)){
			//un elenco dei record MX trovati è posto nell'array $mxhosts.
			return true;//è stato possibile usare getmxrr e il dominio esiste
		}elseif (@fsockopen($divisa[1], 25, $err_nu, $err_str, 5)){
        	return true;//non posso usare getmxrr ma il dominio esiste
		}else{
        	return false;//il dominio non esiste
		}
	}
}
//TEST.......
//l'array: valida inesistente errata .. il dubbio
$em=array("[email protected]","[email protected]","info#borgo-italia.it","[email protected]", "[email protected]");
foreach($em as $e){
	if(valida_email($e)){
		echo "$e valida e esitente<br />";
	}else{
		echo "$e non è formalmente valida o non è esitente<br />";
	}
}
?>
come detto, provando il test, risulta:

dove di sicuro [email protected] non esiste e [email protected] è probabile che non esista

Per sapere se esiste un indirizzo email, la miglior cosa da fare è inviarsi un avviso. Visto che quando non esiste di solito torna un MAILER-DAEMON, si può fare anche il contrario, credo.

Si può prendere spunto da questo http://www.verificaemail.com/verifica_email.php
 

flameseeker

Utente Attivo
27 Nov 2013
699
0
0
Riporto una considerazione in proposito che scrissi in un altro topic.
Credo sia inutile eseguire tutta questa caterva di controlli che rischiano solo di bloccare utenti che fanno soltanto uso di mail provider che, magari, gestiscono le caselle di alias in un modo non proprio verificabile (vedi esempio @tin.it), anche perché servizi di mail temporanee come 10minutemail sono ormai ingrado di superare da un pò di tempo questo tipo di controlli e le blacklist servono a poco se non sono continuamente aggiornate.

Chiaro, dipende dalle esigenze, ma se si vuol evitare di ricevere spam ci sono sempre alternative come il captcha (o altri escamotage più accessibili) per difendersi dagli invii di dati a puro fine di spam.

Detto questo, c'è anche da considerare che per l'iscrizione ad un servizio, un altro valido mezzo è l'attivazione dell'account tramite link spedito via email. Se dopo ti inondano di spam il problema tange relativamente poiché periodicamente gli account mai attivati possono essere eliminati senza problemi da un job pianificato in automatico.

A questo punto, personalmente, la soluzione che in genere adotto e/o che mi sento di consigliare è un qualcosa che si limiti a:
  • verificare l'esistenza del record MX del DNS della email;
  • verificare la validità sintattica della email;
  • sanitizzare la stringa dell'email.
Riassunta al volo, la funzione risultante potrebbe essere qualcosa di simile a questa:
PHP:
function is_email($email) {

	$mailSplit = explode('@', $email);
	$sanitizedEmail = filter_var($email, FILTER_SANITIZE_EMAIL);

	return checkdnsrr(array_pop($mailSplit), 'MX') && 
		filter_var($email, FILTER_VALIDATE_EMAIL) == $sanitizedEmail?
			$sanitizedEmail : false;
}



var_dump(is_email('[email protected]'));  // string(10) "[email protected]"
var_dump(is_email('[email protected]'));  // string(18) "[email protected]"
var_dump(is_email('[email protected]'));  // bool(false)
var_dump(is_email('invalìd"[email protected]'));  // bool(false)

Nota a margine: fate attenzione, perché l'output generato è si sanitizzato ma i caratteri ammessi dalla RFC 2822 possono far alterare la formulazione delle vostre richieste SQL se non fate uso dei prepared statements.
 

Shyson

Utente Attivo
19 Ago 2012
1.179
1
38
Beh, allora posso continuare ad usare il mio che dalle prove che ho fatto sembra affidabile:

PHP:
//Valida email (Campo non obbligatorio)
if ($suoemail) { 
if (!preg_match("/^[^.-]([.]?[^.-]+)*([-][^.-])?([.]?[^.-])*@(.*)[^.](\.[a-z]{2,6})$/",$suoemail)) {  
echo "Inserire un'email valida";
 }
}
 

flameseeker

Utente Attivo
27 Nov 2013
699
0
0
A dire il vero no, la tua funzione presenta alcuni problemi di validazione.
Sotto questo aspetto il filter_var di PHP agisce in maniera impeccabile e ti consiglio di usare, se non la funzione che ho esposto io, qualcosa di molto simile logicamente parlando in quanto esegue un ottima validazione sintattica ed unisce un controllo base quantomeno sulla presenza del record MX nei DNS.

Se vuoi invece scrivere da te il parser di validazione allora la tua funzione non centra alcuni punti, come la corretta lunghezza delle stringhe e il corretto range di caratteri ammessi (a questo fine dovresti ben documentarti leggendo le specifiche elencate nella RFC 2822 linkata nel mio post precedente).
 

Shyson

Utente Attivo
19 Ago 2012
1.179
1
38
A dire il vero no, la tua funzione presenta alcuni problemi di validazione.
Sotto questo aspetto il filter_var di PHP agisce in maniera impeccabile e ti consiglio di usare, se non la funzione che ho esposto io, qualcosa di molto simile logicamente parlando in quanto esegue un ottima validazione sintattica ed unisce un controllo base quantomeno sulla presenza del record MX nei DNS.

Se vuoi invece scrivere da te il parser di validazione allora la tua funzione non centra alcuni punti, come la corretta lunghezza delle stringhe e il corretto range di caratteri ammessi (a questo fine dovresti ben documentarti leggendo le specifiche elencate nella RFC 2822 linkata nel mio post precedente).

Vediamo un attimo, la lunghezza totale della mail la controllo con questa:
PHP:
if (strlen($suoemail) > 320) { 
echo "EMAIL: max 320 caratteri";
}

poi, i caratteri accettati sono quelli normalmente accettati, ma non tutti i server sono uguali:

In base allo standard RFC-2822 l’username dev’essere:

1.Username: [^.-]([.]?[^.-]+)*([-][^.-])?([.]?[^.-])*

1. minimo un solo carattere iniziale
2. accetta il punto . molte volte ma non consecutive, non vicino al trattino e non all'inizio o alla fine
3. accetta il trattino - una sola volta, non vicino al punto e non all'inizio o alla fine

2. "@"

3. Dominio: così accetta qualsiasi cosa: (\.[a-z]{2,6})
 

flameseeker

Utente Attivo
27 Nov 2013
699
0
0
Vediamo un attimo, la lunghezza totale della mail la controllo con questa:
PHP:
if (strlen($suoemail) > 320) { 
echo "EMAIL: max 320 caratteri";
}

Già questa presenta il problema che non ti dice se effettivamente la parte locale dell'indirizzo è lunga massimo i suoi 64 caratteri, puoi facilmente ritrovarti come valide email con parte locale lunga 90 caratteri e dominio lungo 10 (ma può succedere anche il problema inverso).

In base allo standard RFC-2822 l’username dev’essere:
..
1. minimo un solo carattere iniziale
2. accetta il punto . molte volte ma non consecutive, non vicino al trattino e non all'inizio o alla fine
3. accetta il trattino - una sola volta, non vicino al punto e non all'inizio o alla fine

la gestione del punto è corretta quella del trattino no ( [email protected] è considerata sintatticamente valida ) e gli unici caratteri speciali che la parte locale (o lo username) può contenere sono: ! # $ % & ' * + – / = ? ^ _ ` { | } ~

La tua funzione invece prende come valida anche un email di questo tipo: ciao€@email.it

Sono tutti controlli e implementazioni già disponibili nel filter_var, personalmente trovo poco sensato riscriverli.
 

Shyson

Utente Attivo
19 Ago 2012
1.179
1
38
Già questa presenta il problema che non ti dice se effettivamente la parte locale dell'indirizzo è lunga massimo i suoi 64 caratteri, puoi facilmente ritrovarti come valide email con parte locale lunga 90 caratteri e dominio lungo 10 (ma può succedere anche il problema inverso).



la gestione del punto è corretta quella del trattino no ( [email protected] è considerata sintatticamente valida ) e gli unici caratteri speciali che la parte locale (o lo username) può contenere sono: ! # $ % & ' * + – / = ? ^ _ ` { | } ~

La tua funzione invece prende come valida anche un email di questo tipo: ciao€@email.it

Sono tutti controlli e implementazioni già disponibili nel filter_var, personalmente trovo poco sensato riscriverli.

Dal 11 luglio 2012 chiunque voglia registrare un dominio contenente un carattere accentato può farlo. I caratteri ammessi sono : (opzione valida solo per i domini .IT)

Riguardo al trattino multiplo non credo che tutti i server lo accettino, per sicurezza nell'user ne ho messo uno.

Il controllo della lunghezza lo faccio in js:
PHP:
//Conta lunghezza username 
function contaUser(user) {
var max = 64;
var at = user.value.indexOf("@");
var tmp = user.value.split("@");
if( tmp[0].length > max ) {
user.value = tmp[0].substring(0,max) + ( tmp[1] ? "@" + tmp[1] : at >= 0 ? "@" : "" );
document.getElementById('contaUser').innerHTML = "&bull;&nbsp;&nbsp;Username: max 64 caratteri";
return false;
}
else {
document.getElementById('contaUser').innerHTML = "";
}
return true;
}

Questi sono indirizzi validi, anche se può sembrare strano:

[email protected]
[email protected]
[email protected]
[email protected]
• user@[IPv6:2001:db8:1ff::a0b:dbd0]
• "much.unusual"@example.com
• "[email protected]"@example.com
• "very.(),:;<>[]\".VERY.\"very@\\ \"very\".unusual"@strange.example.com
• 0@a
• postbox@com(top-level domains are valid hostnames)
• !#$%&'*+-/=?^_`{}|[email protected]
• "()<>[]:,;@\\\"!#$%&'*+-/=?^_`{}|~?^_`{}|~.a"@example.org
• ""@example.org
 
Ultima modifica:

flameseeker

Utente Attivo
27 Nov 2013
699
0
0
Mai fidarsi dei controlli lato client, sono tutti facilmente aggirabili.

Gli indirizzi che citi non hanno nulla di strano, rientrano nelle specifiche previste dove è scritto chiaramente che la parte locale può essere una dot-atom con le regole che ti ho esposto prima (prendo un esempio dal tuo elenco)
o una quoted string:
"()<>[]:,;@\\\"!#$%&'*+-/=?^_`{}|~?^_`{}|~.a"@example.org

Per la dot-atom sono valide delle regole, per la quoted string lo sono delle altre e la tua funzione non fa distinzione: ammette caratteri non validi nella dot-atom e non controlla la validità sintattica di una quoted string (che ad esempio chiede le quotes obbligatorie all'inizio e alla fine).

Ripeto: secondo me ha poco senso reinventare da se la ruota quando PHP ha già un implementazione nativa per questo genere di controlli.
 
Ultima modifica:

Shyson

Utente Attivo
19 Ago 2012
1.179
1
38
Mai fidarsi dei controlli lato client, sono tutti facilmente aggirabili.

Gli indirizzi che citi non hanno nulla di strano, rientrano nelle specifiche previste dove è scritto chiaramente che la parte locale può essere una dot-atom con le regole che ti ho esposto prima (prendo un esempio dal tuo elenco)

o una quoted string:


Per la dot-atom sono valide delle regole, per la quoted string lo sono delle altre e la tua funzione non fa distinzione: ammette caratteri non validi nella dot-atom e non controlla la validità sintattica di una quoted string (che ad esempio chiede le quotes obbligatorie all'inizio e alla fine).

Ripeto: secondo me ha poco senso reinventare da se la ruota quando PHP ha già un implementazione nativa per questo genere di controlli.

Il controllo lunghezza l'ho messo in js perché non lo fare in php.

Proverò FILTER_VALIDATE_EMAIL. Addirittura gmail e yahoo non accettano nemmeno un trattino.


 
Discussioni simili
Autore Titolo Forum Risposte Data
V [PHP]indirizzo email è protetto dagli spambots PHP 4
MarcoGrazia Verifica di un indirizzo email Snippet PHP 0
CristianB72 [PHP] Controllo sintassi indirizzo email non funziona PHP 13
braccobaldo Indirizzo email e concorrenza sleale? Leggi, Normative e Fisco 0
J Scritp invio email convalida indirizzo PHP 13
felino Validità indirizzo email PHP 16
borgo italia validare un indirizzo email Snippet PHP 0
anton Nascondere indirizzo email agli spambot in un form php PHP 21
Vale2 Nascondere un indirizzo email agli spambot Snippet Javascript 0
Athene Validare un indirizzo email PHP 2
S Inviare contenuto form a un indirizzo email HTML e CSS 1
G Form mail con indirizzo email del mittente PHP 3
R Inviare file tramite un form a un indirizzo email tramite pagina php PHP 1
R Inviare dati form a indirizzo email PHP 23
A Inviare immagine a un indirizzo email PHP 2
S inviare dati a 1 indirizzo email Classic ASP 1
I asp | includere un file, indirizzo depositato in un db Classic ASP 0
P Errore nell'indirizzo degli elementi HTML e CSS 2
elpirata Ricavare e stampare indirizzo ip da array associativo PHP 0
A [PHP] Bloccare utente tramite indirizzo IP PHP 3
I Url rewrite con .htaccess funziona ma poi mostra indirizzo "reale" nella barra di navigazione Apache 1
V [HTML] indirizzo htm zoneminder IP Cam e Videosorveglianza 0
A [Javascript] indirizzo con variabili $_GET Javascript 1
utente Form mail php - indirizzo ip PHP 9
S Concatenare due campi di un form per creare un indirizzo web valido Javascript 7
W Estrapolare un indirizzo mail di un form durante l'invio PHP 5
T Condizioni multiple in htaccess per accesso a sub folder basato su indirizzo IP Apache 0
G Validazione indirizzo mail PHP 1
Lucia Fiore cambiare variabili <a in <a href='indirizzo'> HTML e CSS 1
N Recupero indirizzo mail PHP 1
M Script Google Maps per ricavare coordinate di un indirizzo PHP 0
K Cambio indirizzo dominio e reindirizzamento 301 Domini 1
S [risolto] Creare una mappa Google per ogni indirizzo Javascript 14
R Configurare Apache per supportare più siti SSL su un singolo indirizzo IP Apache 0
felino PHPMailer: Indirizzo IP e Immagine PHP 6
S php memorizzare l indirizzo ip quando uno si registra PHP 4
G Aprire indirizzo IP con desktop remoto PHP 3
C Problema: salvare indirizzo file in un database(mancanza delle backslash nel percorso) PHP 13
asevenx conta numero di click riconoscendo indirizzo ip PHP 1
Mauro Guardiani cerco webmaster per problemi reCAPTCHA e limite indirizzo ip. Offerte e Richieste di Lavoro e/o Collaborazione 0
M login con indirizzo a pagine diverse PHP 10
L Indirizzo ip + nome PHP 8
F Creare un indirizzo youtube valido Social Media Marketing 1
F Phpmailer e l'indirizzo del mittente PHP 3
max_400 Arrotondare indirizzo ip PHP 4
G Ricavare indirizzo virtuale da indirizzo fisico Classic ASP 0
max_400 Nascondere indirizzo o visualiz. un altro oppure Proteggere pagina php ricevente PHP 6
U indirizzo senza pagina PHP 2
borgo italia outlook: impossibile bloccare indirizzo di posta Windows e Software 5
I Salvare indirizzo immagine in database PHP 6

Discussioni simili