Last active
October 30, 2020 00:46
-
-
Save PEKTOP/81608ae9d5e40e3d7f94 to your computer and use it in GitHub Desktop.
Verify Email address
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use RuntimeException; | |
class VerifyEmail | |
{ | |
/** | |
* @var string | |
*/ | |
protected $email_user = ''; | |
/** | |
* @var string | |
*/ | |
protected $email_domain = ''; | |
/** | |
* @var array | |
*/ | |
protected $mx_records = []; | |
/** | |
* @var resource | |
*/ | |
protected $fsock = false; | |
/** | |
* @var int | |
*/ | |
protected $port = 25; | |
/** | |
* @var int | |
*/ | |
protected $connection_timeout = 2; | |
/** | |
* @var int | |
*/ | |
protected $stream_timeout = 1; | |
/** | |
* @var string | |
*/ | |
protected $sock_host = 'localhost'; | |
/** | |
* @var bool | |
*/ | |
protected $verified = false; | |
/** | |
* @return bool | |
* | |
* @throws RuntimeException | |
*/ | |
protected function verifyDNS() | |
{ | |
if ($this->email_domain === '') { | |
throw new RuntimeException('Parameter `email_domain` is empty.'); | |
} | |
return checkdnsrr($this->email_domain, 'MX'); | |
} | |
/** | |
* @return array | |
* | |
* @throws RuntimeException | |
*/ | |
protected function retrieveMX() | |
{ | |
if ($this->email_domain === '') { | |
throw new RuntimeException('Parameter `email_domain` is empty.'); | |
} | |
getmxrr($this->email_domain, $hosts, $weights); | |
$unique_weights = array_unique($weights); | |
if(count($unique_weights) !== count($hosts)) { | |
$weights = range(1, count($hosts)); | |
} | |
$mx_records = array_combine($weights, $hosts); | |
ksort($mx_records); | |
return $mx_records; | |
} | |
/** | |
* @return bool | |
* | |
* @throws RuntimeException | |
*/ | |
protected function createConnection() | |
{ | |
if (count($this->mx_records) === 0) { | |
throw new RuntimeException('Parameter `mx_records` is empty.'); | |
} | |
$errno = 0; | |
$error = ''; | |
foreach($this->mx_records as $mx_host) { | |
if($this->fsock = @fsockopen($mx_host, $this->port, $errno, $error, $this->connection_timeout)) { | |
$this->sock_host = $mx_host; | |
stream_set_blocking($this->fsock, 1); | |
break; | |
} | |
} | |
if ($this->fsock) { | |
return true; | |
} | |
throw new RuntimeException($error, $errno); | |
} | |
/** | |
* @return void | |
*/ | |
protected function closeConnection() | |
{ | |
if ($this->fsock) { | |
fclose($this->fsock); | |
} | |
} | |
/** | |
* @param string $message | |
* @param bool $check | |
* @return void | |
* | |
* @throws RuntimeException | |
*/ | |
protected function send($message, $check = false) | |
{ | |
if ($this->fsock) { | |
stream_set_timeout($this->fsock, $this->stream_timeout); | |
fwrite($this->fsock, $message."\n", strlen($message."\n")); | |
$response = null; | |
while(true) { | |
$buffer = fread($this->fsock, 1024); | |
if ($buffer === false) { | |
throw new RuntimeException('Host '.$this->sock_host.' does not responding.'); | |
} | |
$response .= $buffer; | |
if ($buffer === '') { | |
break; | |
} | |
} | |
if ($check) { | |
$this->verified = (stripos($response, '250') === 0); | |
} | |
} else { | |
throw new RuntimeException('Socket connection not found.'); | |
} | |
} | |
/** | |
* @param string $email_to | |
* @param string $email_from | |
* @return bool | |
* | |
* @throws RuntimeException | |
*/ | |
public function check($email_to, $email_from) | |
{ | |
list($this->email_user, $this->email_domain) = explode('@', $email_to); | |
if ($this->verifyDNS()) { | |
$this->mx_records = $this->retrieveMX(); | |
if ($this->createConnection()) { | |
$this->send('HELO '.$this->sock_host); | |
$this->send('MAIL FROM: <'.$email_from.'>', true); | |
$this->send('RCPT TO: <'.$email_to.'>', true); | |
$this->send('QUIT'); | |
$this->closeConnection(); | |
} | |
} | |
return $this->verified; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment