Хотел реализовать свою функцию для отправки SMTP почты на PHP, без модулей вроде Mailer и т.д. Столкнулся с тем, что ничего не происходит в результате последовательности, она просто не работает:
$socket = fsockopen($this->smtp_host, $this->smtp_port, $errorNumber, $errorDescription, 30);
$server_name = filter_input(INPUT_SERVER, 'NAME');
fputs($socket, "EHLO $server_name\r\n");
fputs($socket, "AUTH LOGIN\r\n");
fputs($socket, base64_encode($this->smtp_username) . "\r\n");
fputs($socket, base64_encode($this->smtp_password) . "\r\n");
fputs($socket, "MAIL FROM: <" . $this->smtp_username . ">\r\n");
fputs($socket, "RCPT TO: <{$mailTo}>\r\n");
fputs($socket, "DATA\r\n");
fputs($socket, $contentMail . "\r\n.\r\n");
fputs($socket, "QUIT\r\n");
fclose($socket);
При этом код, который я нашел на просторах интернета в виде класса с проверкой через try - catch работает замечательно:
function send($mailTo, $subject, $message, $smtp_from) {
$contentMail = $this->getContentMail($subject, $message, $smtp_from);
try {
if (!$socket = @fsockopen($this->smtp_host, $this->smtp_port, $errorNumber, $errorDescription, 30)) {
throw new Exception($errorNumber . "." . $errorDescription);
}
if (!$this->_parseServer($socket, "220")) {
throw new Exception('Connection error');
}
$server_name = $_SERVER["SERVER_NAME"];
fputs($socket, "EHLO $server_name\r\n");
if (!$this->_parseServer($socket, "250")) {
// если сервер не ответил на EHLO, то отправляем HELO
fputs($socket, "HELO $server_name\r\n");
if (!$this->_parseServer($socket, "250")) {
fclose($socket);
throw new Exception('Error of command sending: HELO');
}
}
fputs($socket, "AUTH LOGIN\r\n");
if (!$this->_parseServer($socket, "334")) {
fclose($socket);
throw new Exception('Autorization error');
}
fputs($socket, base64_encode($this->smtp_username) . "\r\n");
if (!$this->_parseServer($socket, "334")) {
fclose($socket);
throw new Exception('Autorization error');
}
fputs($socket, base64_encode($this->smtp_password) . "\r\n");
if (!$this->_parseServer($socket, "235")) {
fclose($socket);
throw new Exception('Autorization error');
}
fputs($socket, "MAIL FROM: <" . $this->smtp_username . ">\r\n");
if (!$this->_parseServer($socket, "250")) {
fclose($socket);
throw new Exception('Error of command sending: MAIL FROM');
}
$mailTo = str_replace(" ", "", $mailTo);
$emails_to_array = explode(',', $mailTo);
foreach ($emails_to_array as $email) {
fputs($socket, "RCPT TO: <{$email}>\r\n");
if (!$this->_parseServer($socket, "250")) {
fclose($socket);
throw new Exception('Error of command sending: RCPT TO');
}
}
fputs($socket, "DATA\r\n");
if (!$this->_parseServer($socket, "354")) {
fclose($socket);
throw new Exception('Error of command sending: DATA');
}
fputs($socket, $contentMail . "\r\n.\r\n");
if (!$this->_parseServer($socket, "250")) {
fclose($socket);
throw new Exception("E-mail didn't sent");
}
fputs($socket, "QUIT\r\n");
fclose($socket);
} catch (Exception $e) {
return $e->getMessage();
}
return true;
}
private function _parseServer($socket, $response) {
while (@substr($responseServer, 3, 1) != ' ') {
if (!($responseServer = fgets($socket, 256))) {
return false;
}
}
if (!(substr($responseServer, 0, 3) == $response)) {
return false;
}
return true;
}
Как только я избавляю код от элементов дебага и функции _parseServer - почта перестает отправляться:
function send($mailTo, $subject, $message, $smtp_from) {
$contentMail = $this->getContentMail($subject, $message, $smtp_from);
$socket = fsockopen($this->smtp_host, $this->smtp_port, $errorNumber, $errorDescription, 30);
$server_name = $_SERVER["SERVER_NAME"];
fputs($socket, "EHLO $server_name\r\n");
fputs($socket, "AUTH LOGIN\r\n");
fputs($socket, base64_encode($this->smtp_username) . "\r\n");
fputs($socket, base64_encode($this->smtp_password) . "\r\n");
fputs($socket, "MAIL FROM: <" . $this->smtp_username . ">\r\n");
fputs($socket, "RCPT TO: <{$mailTo}>\r\n");
fputs($socket, "DATA\r\n");
fputs($socket, $contentMail . "\r\n.\r\n");
fputs($socket, "QUIT\r\n");
fclose($socket);
return true;
}
Я понимаю, что раз есть работающий вариант - можно не трогать его и работать с ним, но не могу делать это спокойно, не разобравшись в причинах проблемы при упрощении кода.