Skip to content

Instantly share code, notes, and snippets.

@PEKTOP
Last active October 30, 2020 00:46
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PEKTOP/81608ae9d5e40e3d7f94 to your computer and use it in GitHub Desktop.
Save PEKTOP/81608ae9d5e40e3d7f94 to your computer and use it in GitHub Desktop.
Verify Email address
<?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