Вы здесь

Суровая проверка валидности e-mail на PHP

Возникла задача проверять валидность вводимого в форме e-mail адреса.

Поиск выдал кучу ссылок на проверку валидности написания самого адреса. Кто как не извращается, хотя для этого есть встроенная функция.
Мне же, требовалась более суровая проверка, ну хотябы на существование релея. А раз уж и до релея добрались, то почему бы не проверить и существование на нем пользователя?
Понятно, что многие релеи не выдают 550 если пользователя нет, но попытка — не пытка. Даже если на левого пользователя мы получим ответ 250, мы хотябы попытались и убедились в том, что релей есть и он живой.

Скрипт с комментами.

<?
function check_email($email) {
  /**
   * Имя, которым скрипт представляется релею.
   */

  $mymxhost = "mx.example.com";
  /**
   * Проверяем валидность написания email.
   */

  if(function_exists('filter_var')){
      if(!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        return false;
      }
  }

  /**
   * Выкусываем имя хоста из email
   */

  preg_match('/^[^@]+@([a-zA-Z0-9._-]+\.[a-zA-Z]+)$/',$email, $host);

  /**
   * Проверяем наличие MX записи для хоста.
   */

  getmxrr($host[1], &$mxhosts);
  if(!count($mxhosts)) {
    return false;
  }

  /**
   * Парсим массив MX записей и коннектимся к хосту.
   */

  foreach($mxhosts as $host) {
    if($fp=pfsockopen($host,25)) {
      /**
       * Читаем приглашение от хоста.
       * Ожидаем строки "220 HELO ...." в течении 30 секунд.
       */

      $string=read_string($fp,30);
      if(substr($string,0,3)!="220") {
        /**
         * Если ответа не получили или получили не приветсвие,
         * закрываем соединение.
         */

        fclose($fp);
        return false;
      }

      /**
       * Отправляем приветсвие и ждем ответа от сервера в течении 5 секунд.
       */

      fwrite($fp,"HELO $mymxhost\n");
      $string=read_string($fp,5);
      if(substr($string,0,3)!="250") {
        /**
         * Если ответа не получили или получили что отличное от 250,
         * закрываем соединение.
         * Возможные причины отказа:
         * Отсутсвие PTR запси для вашего хоста
         * Отсутствие  А и/или MX записи для хоста,
         * которым вы представляетесь ($mymxhost)
         */

        fclose($fp);
        return false;
      }

      /**
       * Отправляем на сервер строку MAIL FROM: и ждем ответа
       * от сервера в течении 5 секунд.
       */

      fwrite($fp,"MAIL FROM: <>\n");
      $string=read_string($fp,5);
      if(substr($string,0,3)!="250") {
        /**
         * Если ответа не получили или получили что отличное от 250,
         * закрываем соединение.
         * Возможные причины отказа:
         * Сервер получатель отказывается принимать пустое поле MAIL FROM.
         * По RFC такие поля должны приниматься для обработки reverse connect,
         * что мы и пытаемся сделать.
         */

        fclose($fp);
        return false;
      }

      /**
       * Отправляем на сервер строку RCPT TO: и ждем ответа
       * от сервера в течении 5 секунд.
       * Если получили в ответ 250 - то сервер ответил,
       * что пользователь у него есть
       * (хотя это не значит, что он есть на самом деле).
       */

      fwrite($fp,"RCPT TO: <".$email.">\n");

      $string=read_string($fp,5);
      if(substr($string,0,3)!="250") {
        fclose($fp);
        return false;
      }
      else {
        fclose($fp);
        return true;
      }
    }
  }
}

 

/**
* Читаем строку возврата. Если ничего не вернулось,
* ждем 1 секунду и читаем снова.
* Если через $timeout секунд ничего не вернулось, то возвращаем false.
*/

function read_string($fp,$timeout) {
  $string="";
  for($i=1;$i<$timeout;$i++){
    $string=fread($fp, 128);
    if($string!=""){
      return $string;
    }
    sleep(1);
  }
  return false;
}

 
Категория: 
© 2009-2104 CTPAHHuK.RU