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