2
I know there are services that do this, but I would like to know how they do this kind of test, to find out if the email is really valid, not only through a PHP filter, for example:
function validEmail($email) {
if (filter_var($email, FILTER_VALIDATE_EMAIL) !== false) {
return true;
}
return false;
}
$listaEMails = array(
'fakemail@gmail',
'[email protected]',
'[email protected]',
'[email protected]',
);
foreach($listaEMails as $k => $email) {
if (!validEmail($email)) {
unset($listaEMails[$k]);
}
}
echo "Emails verdadeiros: <pre>";
print_r($listaEMails);
But using some server ping that checks the IP, like:
@servidor.com.br (IP: 200.123.432.231)
I don’t know if this actually works:
$domain = array_pop(explode("@", $email));
filter_var(gethostbyname($domain), FILTER_VALIDATE_IP);
or
checkdnsrr($domain, "MX");
I think it could be something like, but a way to ping the server?
function nsLookupPing($domain) {
$app ="nslookup $domain";
exec($app, $result);
if ($result[5] == '' || !isset($result[5])) {
return false;
}
return true;
}
Edited from here:
The answer of @ederwander solved halfway, what I’m not getting, is to capture this output that he spoke, see in the example below, I’m making the following request GET: [email protected]
, using the following class I’ve assembled:
class ValidateEmail
{
private $email;
private $domain;
private $socket;
public function __construct($email)
{
$this->email = $email;
$domain = @array_pop(explode("@", $email));
$this->domain = $domain;
}
private function pesoExchanger($a, $b)
{
return $a["exchanger_num"] - $b["exchanger_num"];
}
private function validEmail()
{
if (filter_var($this->email, FILTER_VALIDATE_EMAIL) !== false) {
return true;
}
return false;
}
public function getDomain()
{
return $this->domain;
}
public function getMail()
{
return $this->email;
}
public function nsLookupPing()
{
if (!$this->validEmail()) {
//retorna falso, e a mensagem de email inválido
return array('status'=> false, 'msg' => 'Email inválido');
}
//captura o domínio do email
$domain = $this->getDomain();
//verifica se o domínio é válido numa conexão do tipo MX
exec("nslookup -type=mx {$domain}", $result);
if (!isset($result[4])) {
//se não houver um retorno válido na linha 4, significa que ele não é um domínio válido
return array('status'=> false, 'msg' => 'Email com domínio inválido');
}
if ($result[4] == '' || preg_match('/No answer/', $result[4])) {
//se não houver um retorno válido na linha 4, mesmo sendo setado, ele enviará uma resposta de erro
return array('status'=> false, 'msg' => 'Email com domínio inválido, motivo: '.$result[4]);
}
//aqui continua para a fase de validação (conforme explicação de: @ederwander)
$exchanger_num = array();
//copia o array para uma outra variável e retira as 4 primeiras linhas
$n_results = $result;
unset($n_results[0]);
unset($n_results[1]);
unset($n_results[2]);
unset($n_results[3]);
//verifica se mesmo removendo as 4 linhas, ainda existe 1 ou mais hosts
if (!count($n_results)) {
return array('status'=> false, 'msg' => "Erro de E-mail inválido! Não há um 'mail exchanger' definido para nenhum peso.");
}
// faz um laço pegando todos os hosts que contiverem um peso exchanger
foreach ($n_results as $k => $result_exchanger) {
if (preg_match('/ exchanger = /', $result_exchanger)) {
//captura o conteúdo original do servidor e o valor após o exchange
list($srv_original, $restante) = explode(' exchanger = ', $result_exchanger);
//quebra nos espaços
$first = explode(' ',$restante);
//remove a informação mail de exchange capturando o primeiro servidor de entrada
$original_srv = str_replace(' mail','', $srv_original);
//lista todos os servidores com seus respectivos pesos
$srv = $result[4];
$exchanger_num[] = array(
'srv_original' => $original_srv ,
'srv_fornecido' => @array_pop(explode(' ',$srv)),
'exchanger_num' => (int) $first[0]
);
}
}
//ordena pelo menor peso
usort($exchanger_num, array($this, "pesoExchanger"));
$other_exchangers = $exchanger_num;
unset($other_exchangers[0]);
//retorna todos os servidores, deixando o mais leve como preferido
return array(
'light_exchanger' => $exchanger_num[0],
'other_exchangers' => $other_exchangers,
'status' => true,
'msg' => 'Servidor de e-mail válido'
);
}
private function extractExchangerLightEmail()
{
$data = $this->nsLookupPing();
if (isset($data['light_exchanger']) && $data['status']) {
return $data['light_exchanger'];
}
}
public function verifyNSLookupPing()
{
//extrai o servidor com peso mais leve
$data = $this->extractExchangerLightEmail();
//verifica se há um servidor fornecido
if (isset($data['srv_fornecido'])) {
$host = $data['srv_fornecido'];
//verifica para ver se existe um cliente de email válido através de um socket tcp, na porta 25
$fp = stream_socket_client("tcp://{$host}:25", $errno, $errstr, 30);
if (!$fp) {
//se ocorrer erro, retorna uma exceção
return array('status' => false, 'msg'=>"O servidor do E-mail é inválido, erro: $errstr ($errno)");
} else {
$result = $this->socketValidation($host, 25);
if($result) {
return array('status' => $result['status'], 'msg'=>$result['msg']);
}
}
}
return array('status' => false, 'msg'=>"Não ocorreu uma conexão para o Servidor do e-mail");
}
private function socketValidation($host, $port = 25)
{
$address = gethostbyname($host);
$command = "ping -c 1 " . $address;
$r = exec($command);
if ($r[0]=="r") {
$this->socket = socket_create (AF_INET, SOCK_STREAM, 0);
if ($this->socket < 0) {
$status = false;
$msg = "Falha de socket: " . socket_strerror($this->socket);
} else {
$status = true;
$msg = "O servidor de e-mail é válido!";
}
return array('status' => $status,
'msg' => $msg
);
} else {
return array('status' =>false,
'msg' => "Não foi possível criar um socket para testar o servidor"
);
}
}
}
$email = $_GET['email'];
if (isset($email)) {
$verifyMail = new ValidateEmail($email);
$saida = $verifyMail->verifyNSLookupPing();
var_dump($saida);
}
Only in the terminal that appears this output, I believe that this is a private value:
220 mx.google.com ESMTP j11si51572042qgd.1 - gsmtp
Validate IP of an email list ? or know if a particular email address exists ??
– ederwander
No, validate if the email can receive message, if it exists and if the server exists?
– Ivan Ferrer
I wonder if you can ping an email (like send something and receive a reply), without having to send a message.
– Ivan Ferrer
exec("telnet {$host} 25", $result_telnet)
This is not the correct way to do, how will you send the rest of the commands? how will you get the return of each line? , You have to work purely with sockets in your code in order to send and catch every expected return....– ederwander
another detail you are looking for
Connected to
, there is no such message in telnet return to gmail...– ederwander
I still don’t have a "email" validation itself, only from the server.
– Ivan Ferrer
@Ivanferrer does not exist secure email validation without sending and monitoring feedback. And even doing so, there may still be some extreme cases of failure.
– Bacco