кусок документации на русском: smtp_rfc2821.pdf
smtp. Отправка письма без вложения. + копия
<?php
// Сервер исходящей почты smtp.majordomo.ru
// Протокол SMTP: порт 587, шифрование STARTTLS
function get_data($sock)
{
$rez = array();
$data = "";
while($str = fgets($sock,512))
{
$data .= $str;
if( (substr($str,3,1) == " ") or (substr($str,3, 2) == "\r\n") )
break;
}
if ($str !== false){
$rez[] = substr($str,0,1); // "2"
$rez[] = substr($str,1,1); // "5"
$rez[] = substr($str,2,1); // "0"
$rez[] = $data;
}
return $rez;
}
$header="Date: ".date("D, j M Y G:i:s")." +0300\r\n";
$header.="From: =?utf-8?B?". base64_encode('Почта сектетаря') ."?= <info@mirossa.ru>\r\n";
$header.="X-Mailer: Mail client. (ver 1.1.1) Professional\r\n";
$header.="Reply-To: =?utf-8?B?". base64_encode('Почта сектетаря') ."?= <info@mirossa.ru>\r\n";
$header.="X-Priority: 3 (Normal)\r\n";
$header.="Message-ID: <131415666.".date("YmjHis")."@mirossa.ru>\r\n";
//$header.="To: =?utf-8?B?". base64_encode('Почта сектетаря') ."?= <info@mirossa.ru>\r\n"; //представление + адрес
$header.="Cc: =?utf-8?B?". base64_encode('Почта сектетаря 2') ."?= <info2@mirossa.ru>\r\n"; //представление + адрес
$header.="Subject: =?utf-8?B?". base64_encode('Тестовое письмо') ."?=\r\n";
$header.="MIME-Version: 1.0\r\n";
$header.="Content-Type: text/html; charset=utf-8\r\n"; // text/plain
$header.="Content-Transfer-Encoding: 8bit\r\n";
$text="<html><body><p style=\"color: blue;\">Тестовое письмо.</p></body></html>";
$sock = fsockopen("smtp.majordomo.ru", 587,$errno, $errstr, 10);
if(!$sock) {print "соединение с серверов не прошло"; fclose($sock); exit;}
$rez = get_data($sock);
print $rez[3]; // del
fputs($sock,"EHLO ddd\r\n");
$rez = get_data($sock);
print $rez[3]; // del
if( $rez[0] != "2" ){ //250
print "ошибка приветсвия EHLO";
fclose($sock);
exit;
}
//STARTTLS
fputs($sock,"STARTTLS\r\n");
$rez = get_data($sock);
print $rez[3]; // del
if(false == stream_socket_enable_crypto($sock, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)){
// fclose($smtp); // unsure if you need to close as I haven't run into a security fail at this point
print "unable to start tls encryption";
exit;
}
fputs($sock,"EHLO ddd\r\n");
$rez = get_data($sock);
print $rez[3]; // del
if( $rez[0] != "2" ) { //250
print "ошибка приветсвия EHLO";
fclose($sock);
exit;
}
fputs($sock,"AUTH LOGIN\r\n");
$rez = get_data($sock);
print $rez[3]; // del
if($rez[0] != "3") { //334
print "сервер не разрешил начать авторизацию";
fclose($sock);
exit;
}
fputs($sock,base64_encode("info@mirossa.ru")."\r\n");
$rez = get_data($sock);
print $rez[3]; // del
if($rez[0] != "3") { //334
print "что-то с логином";
fclose($sock);
exit;
}
fputs($sock,base64_encode("password")."\r\n");
$rez = get_data($sock);
print $rez[3]; // del
if( $rez[0] != "2" ) { //235
print "не правильный пароль";
fclose($sock);
exit;
}
$size_msg = strlen($header."\r\n".$text);
fputs($sock,"MAIL FROM:<info@mirossa.ru> SIZE=".$size_msg."\r\n");
$rez = get_data($sock);
print $rez[3]; // del
if( $rez[0] != "2" ) { //250
print "сервер отказал в команде MAIL FROM";
fclose($sock);
exit;
}
// указываем получателя
fputs($sock,"RCPT TO:<info@mirossa.ru>\r\n");
$rez = get_data($sock);
print $rez[3]; // del
if($rez[0] != "2") { //250 //251
print "Сервер не принял команду RCPT TO";
fclose($sock);
exit;
}
// "копия"
fputs($sock,"RCPT TO:<info2@mirossa.ru>\r\n"); // в заголовке этот адрес указан в поле "Cc" (копия).
// если удалить поле "Cc", то каждый из двух получателей будет видеть, что как-будто только ему отправлено сообщение
$rez = get_data($sock);
print $rez[3]; // del
if($rez[0] != "2") { //250 //251
print "Сервер не принял команду RCPT TO";
fclose($sock);
exit;
}
//тело письма
fputs($sock,"DATA\r\n");
$rez = get_data($sock);
print $rez[3]; // del
if($rez[0] != "3") { //354
print "сервер не принял DATA";
fclose($sock);
exit;
}
fputs($sock,$header."\r\n".$text."\r\n.\r\n");
$rez = get_data($sock);
print $rez[3]; // del
if($rez[0] != "2") { //250
print "ошибка отправки письма";
fclose($sock);
exit;
}
fputs($sock,"QUIT\r\n");
$rez = get_data($sock);
print $rez[3]; // del
if($rez[0] != "2") { //221
print "ошибка завершения сеанса";
fclose($sock);
exit;
}
fclose($sock);
?>
ответы сервера
220 smtpout2.majordomo.ru ESMTP Exim 4.90_1 Ubuntu Sun, 14 Apr 2019 23:58:06 +0000
250-smtpout2.majordomo.ru Hello ddd [78.108.80.119]
250-SIZE 104857600
250-8BITMIME
250-AUTH LOGIN
250-CHUNKING
250-STARTTLS
250 HELP
220 TLS go ahead
250-smtpout2.majordomo.ru Hello ddd [78.108.80.119]
250-SIZE 104857600
250-8BITMIME
250-AUTH LOGIN
250-CHUNKING
250 HELP
334 VXNlcm5hbWU6
334 UGFzc3dvcmQ6
235 Authentication succeeded
250 OK
250 Accepted
250 Accepted
354 Enter message, ending with "." on a line by itself
250 OK id=1hFp0g-0000Az-9I
221 smtpout2.majordomo.ru closing connection
сделав небольшие изменения, получим следующий файл
smtp. Отправка письма с вложением.
<?php
// Сервер исходящей почты smtp.majordomo.ru
// Протокол SMTP: порт 587, шифрование STARTTLS
function get_data($sock)
{
$rez = array();
$data = "";
while($str = fgets($sock,512))
{
$data .= $str;
if( (substr($str,3,1) == " ") or (substr($str,3, 2) == "\r\n") )
break;
}
if ($str !== false){
$rez[] = substr($str,0,1); // "2"
$rez[] = substr($str,1,1); // "5"
$rez[] = substr($str,2,1); // "0"
$rez[] = $data;
}
return $rez;
}
// для варианта с quoted-printable
// строка "From: =?utf-8?Q?". "Почта секретаря" ."?= <info@mirossa.ru>" должна быть закодирована так
// "From: =?utf-8?Q?". "=D0=9F=D0=BE=D1=87=D1=82=D0=B0 =D1=81=D0=B5=D0=BA=D1=80=D0=B5=D1=82=D0=B0=D1=80=D1=8F" ."?= <info@mirossa.ru>"
//
// функция quoted_printable_encode('Почта сектетаря') разбивает закодированные длинные строки по(до) 76 символов со знаком "=" в конце :
//=D0=9F=D0=BE=D1=87=D1=82=D0=B0 =D1=81=D0=B5=D0=BA=D1=80=D0=B5=D1=82=D0=
//=B0=D1=80=D1=8F
// которые без дополнительной обработки в =?utf-8?Q?...?= не засунуть (лишние "=" в конце и переносы строк).
//
// вызов quoted_printable_encode('Почта сектетаря') можно заменить на конструкцию :
// str_replace("+"," ",str_replace("%","=",urlencode('Почта сектетаря')));
//
// поле "From:" можно разбить на несколько строк :
//From: =?UTF-8?Q?=D0=9F=D0=BE=D1=87=D1=82=D0=B0 =D1=81=D0=B5=D0=BA=D1=80?=
// =?UTF-8?Q?=D0=B5=D1=82=D0=B0=D1=80=D1=8F?= <info@mirossa.ru>
$header = "Date: ".date("D, j M Y G:i:s")." +0300\r\n";
$header .= "From: =?utf-8?B?". base64_encode('Почта сектетаря') ."?= <info@mirossa.ru>\r\n";
$header .= "X-Mailer: Mail client. (ver 1.1.1) Professional\r\n";
$header .= "Reply-To: =?utf-8?B?". base64_encode('Почта сектетаря') ."?= <info@mirossa.ru>\r\n";
$header .= "X-Priority: 3 (Normal)\r\n";
$header.= "Message-ID: <131415666.".date("YmjHis")."@mirossa.ru>\r\n";
$header .= "To: =?utf-8?B?". base64_encode('Почта сектетаря') ."?= <info@mirossa.ru>\r\n"; //представление + адрес
$header .= "Subject: =?utf-8?B?". base64_encode(Важный вопрос') ."?=\r\n";
$header .= "MIME-Version: 1.0\r\n";
$header .= "Content-Type: multipart/mixed; boundary=\"b1d4ce5d-2857-4679-948c-cfa72fa94f86\"\r\n";
$text = "--b1d4ce5d-2857-4679-948c-cfa72fa94f86
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: 8bit
<html><body><p style=\"color: blue;\">Может тебе ещё ключ от квартиры, где деньги лежат?</p></body></html>";
$text = $text . "
--b1d4ce5d-2857-4679-948c-cfa72fa94f86
Content-transfer-encoding: base64
Content-Type: application/octet-stream; name=\"question.txt\"
Content-Disposition: attachment; filename=\"question.txt\"
" . chunk_split(base64_encode("Может тебе ещё ключ от квартиры, где деньги лежат?"));
//второй файл
$fname = "Остап.jpg";
$f = fopen($fname, "rb");
$fdata = chunk_split(base64_encode(fread($f, filesize($fname))));
fclose($f);
$text = $text . "
--b1d4ce5d-2857-4679-948c-cfa72fa94f86
Content-transfer-encoding: base64
Content-Type: image/jpeg; name=\"=?UTF-8?B?". base64_encode($fname) ."?=\"
Content-Disposition: attachment; filename=\"=?UTF-8?B?". base64_encode($fname) ."?=\"
".$fdata;
$text = $text . "
--b1d4ce5d-2857-4679-948c-cfa72fa94f86--";
$sock = fsockopen("smtp.majordomo.ru", 587,$errno, $errstr, 10);
if(!$sock) {print "соединение с серверов не прошло"; fclose($sock); exit;}
$rez = get_data($sock);
print $rez[3]; // del
fputs($sock,"EHLO ddd\r\n");
$rez = get_data($sock);
print $rez[3]; // del
if( $rez[0] != "2" ){ //250
print "ошибка приветсвия EHLO";
fclose($sock);
exit;
}
//STARTTLS
fputs($sock,"STARTTLS\r\n");
$rez = get_data($sock);
print $rez[3]; // del
if(false == stream_socket_enable_crypto($sock, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)){
// fclose($smtp); // unsure if you need to close as I haven't run into a security fail at this point
print "unable to start tls encryption";
exit;
}
fputs($sock,"EHLO ddd\r\n");
$rez = get_data($sock);
print $rez[3]; // del
if( $rez[0] != "2" ) { //250
print "ошибка приветсвия EHLO";
fclose($sock);
exit;
}
fputs($sock,"AUTH LOGIN\r\n");
$rez = get_data($sock);
print $rez[3]; // del
if($rez[0] != "3") { //334
print "сервер не разрешил начать авторизацию";
fclose($sock);
exit;
}
fputs($sock,base64_encode("info@mirossa.ru")."\r\n");
$rez = get_data($sock);
print $rez[3]; // del
if($rez[0] != "3") { //334
print "что-то с логином";
fclose($sock);
exit;
}
fputs($sock,base64_encode("password")."\r\n");
$rez = get_data($sock);
print $rez[3]; // del
if( $rez[0] != "2" ) { //235
print "не правильный пароль";
fclose($sock);
exit;
}
$size_msg = strlen($header."\r\n".$text);
fputs($sock,"MAIL FROM:<info@mirossa.ru> SIZE=".$size_msg."\r\n");
$rez = get_data($sock);
print $rez[3]; // del
if( $rez[0] != "2" ) { //250
print "сервер отказал в команде MAIL FROM";
fclose($sock);
exit;
}
// указываем получателя
fputs($sock,"RCPT TO:<info@mirossa.ru>\r\n");
$rez = get_data($sock);
print $rez[3]; // del
if($rez[0] != "2") { //250 //251
print "Сервер не принял команду RCPT TO";
fclose($sock);
exit;
}
//тело письма
fputs($sock,"DATA\r\n");
$rez = get_data($sock);
print $rez[3]; // del
if($rez[0] != "3") { //354
print "сервер не принял DATA";
fclose($sock);
exit;
}
fputs($sock,$header."\r\n".$text."\r\n.\r\n");
$rez = get_data($sock);
print $rez[3]; // del
if($rez[0] != "2") { //250
print "ошибка отправки письма";
fclose($sock);
exit;
}
fputs($sock,"QUIT\r\n");
$rez = get_data($sock);
print $rez[3]; // del
if($rez[0] != "2") { //221
print "ошибка завершения сеанса";
fclose($sock);
exit;
}
fclose($sock);
?>
результат работы скрипта