За последние 24 часа нас посетили 24430 программистов и 1656 роботов. Сейчас ищут 958 программистов ...

PHP и smtp. Скрипт (сокет). (Решено)

Тема в разделе "PHP для новичков", создана пользователем dcc0, 5 июл 2014.

  1. dcc0

    dcc0 Активный пользователь

    С нами с:
    27 июн 2014
    Сообщения:
    217
    Симпатии:
    4
    Доброго дня. Изучаю код для отправки почты (сокеты).
    Не могу понять, зачем в функции цикл.
    Так ли он необходим?

    Правильно ли я понимаю, что цикл тут нужен для ожидания ответа сервера? Т.е. на случай,
    если сервер ответит не сразу.
    (Для практических целей использую Sendmail, понять хочу для себя(в учебных целях).

    Код (PHP):
    1. <?php
    2. function get_data($smtp_conn)
    3. {
    4. $data="";
    5. while($str = fgets($smtp_conn,515)) {
    6. $data .= $str;
    7. if(substr($str,3,1) == " ") { break; }
    8. }
    9. return $data;
    10. }
    11.  
    12. $header="Date: ".date("D, j M Y G:i:s")." +0700\r\n"; 
    13. $header.="From: =?windows-1251?Q?".str_replace("+","_",str_replace("%","=",urlencode('Максим')))."?= <login@mail.ru>\r\n"; 
    14. $header.="X-Mailer: The Bat! (v3.99.3) Professional\r\n"; 
    15. $header.="Reply-To: =?windows-1251?Q?".str_replace("+","_",str_replace("%","=",urlencode('Максим')))."?= <login@mail.ru>\r\n";
    16. $header.="X-Priority: 3 (Normal)\r\n";
    17. $header.="Message-ID: <172562218.".date("YmjHis")."@mail.ru>\r\n";
    18. $header.="To: =?windows-1251?Q?".str_replace("+","_",str_replace("%","=",urlencode('Сергей')))."?= <qwe@asd.ru>\r\n";
    19. $header.="Subject: =?windows-1251?Q?".str_replace("+","_",str_replace("%","=",urlencode('проверка')))."?=\r\n";
    20. $header.="MIME-Version: 1.0\r\n";
    21. $header.="Content-Type: text/plain; charset=windows-1251\r\n";
    22. $header.="Content-Transfer-Encoding: 8bit\r\n";
    23.  
    24. $text="привет, проверка связи.";
    25.  
    26. $smtp_conn = fsockopen("smtp.mail.ru", 25,$errno, $errstr, 10);
    27. if(!$smtp_conn) {print "соединение с серверов не прошло"; fclose($smtp_conn); exit;}
    28. $data = get_data($smtp_conn);
    29. fputs($smtp_conn,"EHLO mail.ru\r\n");
    30. $code = substr(get_data($smtp_conn),0,3);
    31. if($code != 250) {print "ошибка приветсвия EHLO"; fclose($smtp_conn); exit;}
    32. fputs($smtp_conn,"AUTH LOGIN\r\n");
    33. $code = substr(get_data($smtp_conn),0,3);
    34. if($code != 334) {print "сервер не разрешил начать авторизацию"; fclose($smtp_conn); exit;}
    35.  
    36. fputs($smtp_conn,base64_encode("login")."\r\n");
    37. $code = substr(get_data($smtp_conn),0,3);
    38. if($code != 334) {print "ошибка доступа к такому юзеру"; fclose($smtp_conn); exit;}
    39.  
    40.  
    41. fputs($smtp_conn,base64_encode("password")."\r\n");
    42. $code = substr(get_data($smtp_conn),0,3);
    43. if($code != 235) {print "не правильный пароль"; fclose($smtp_conn); exit;}
    44.  
    45. fputs($smtp_conn,"MAIL FROM:login@mail.ru\r\n");
    46. $code = substr(get_data($smtp_conn),0,3);
    47. if($code != 250) {print "сервер отказал в команде MAIL FROM"; fclose($smtp_conn); exit;}
    48.  
    49. fputs($smtp_conn,"RCPT TO:qwe@asd.ru\r\n");
    50. $code = substr(get_data($smtp_conn),0,3);
    51. if($code != 250 AND $code != 251) {print "Сервер не принял команду RCPT TO"; fclose($smtp_conn); exit;}
    52.  
    53. fputs($smtp_conn,"DATA\r\n");
    54. $code = substr(get_data($smtp_conn),0,3);
    55. if($code != 354) {print "сервер не принял DATA"; fclose($smtp_conn); exit;}
    56.  
    57. fputs($smtp_conn,$header."\r\n".$text."\r\n.\r\n");
    58. $code = substr(get_data($smtp_conn),0,3);
    59. if($code != 250) {print "ошибка отправки письма"; fclose($smtp_conn); exit;}
    60.  
    61. fputs($smtp_conn,"QUIT\r\n");
    62. fclose($smtp_conn);
    63. ?>
    Будет ли критично и неверно, если убрать цикл и проверки каждого кода, например, следующим образом:

    Код (PHP):
    1. function ch_code(&$a, $smtp_conn) {
    2.  
    3. $a=fgets($smtp_conn,625);  
    4. $a=substr($a,0,3);
    5.  
    6. }
    7. $smtp_conn = fsockopen("smtp.rambler.ru", 25,$errno, $errstr, 10);
    8. ch_code($a, $smtp_conn);
    9.  
    10. if(!$smtp_conn) {print "Connection Lost"; fclose($smtp_conn); exit;}
    11.  
    12. fputs($smtp_conn,"HELO rambler.ru\r\n"); 
    13. ch_code($a, $smtp_conn);
    14.  
    15.  
    16. fputs($smtp_conn,"AUTH LOGIN\r\n");
    17. ch_code($a, $smtp_conn);
    18.  
    19. и т.д., и т.д.
    20.  
     
  2. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.128
    Симпатии:
    1.248
    Адрес:
    там-сям
    Re: PHP и smtp. Скрипт (сокет).

    fgets полюбому будет ждать ответа. цикл не просто для ожидания ответа, а для ожидания ответа в нужном формате. будет читать, пока не будет получен нужный фрагмент текста (код результата). неправильные строки игнорируются.

    offtopic: вижу ты пытался выделить строку в коде. но внутри [ code ] никакие другие ббкоды не действуют :(
    советую отредактировать пост, заменив [code] на [code=php] чтобы была подсветка синтаксиса, а также сделать нормальные отступы внутри { } и возле места, которое надо выделить, поставить комментарий типа // вот это место, оно будет подсвечено другим цветом ;)

    удачи!
     
  3. dcc0

    dcc0 Активный пользователь

    С нами с:
    27 июн 2014
    Сообщения:
    217
    Симпатии:
    4
    Re: PHP и smtp. Скрипт (сокет).

    Добавлено спустя 4 минуты 21 секунду:
    artoodetoo , спасибо.
    Самое главное было понять с fgets.
    Кода много, захотелось разобраться.
    Формат в цикле определяется, как я понял, отсутствием символа после трехзначного кода. Только если почтовые протоколы достаточно жестко стандартизированы, зачем определять формат.
    Спасибо еще раз.
    P.S.
    В качестве шутки.
    Получается, можно использовать sleep(); для ответа сервера.
     
  4. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.128
    Симпатии:
    1.248
    Адрес:
    там-сям
    Re: PHP и smtp. Скрипт (сокет).

    можно, но зачем?

    Добавлено спустя 1 минуту 11 секунд:
    p.s. [b][/b] ты забыл убрать ))) оно там явно лишнее
     
  5. dcc0

    dcc0 Активный пользователь

    С нами с:
    27 июн 2014
    Сообщения:
    217
    Симпатии:
    4
    Re: PHP и smtp. Скрипт (сокет).

    Например, можно использовать для тестирования почтового сервера.
    В bash sleep часто упрощает некоторые задачи, обычно, когда что-то проверяешь.
    Я пару раз до написания программы для постоянного использования делал простую последовательность со sleep. Получается, своего рода прототип. Упрощает понимание порядка работы программы.