雲平台禁用 fsockopen,導致傳統 SMTP 郵件庫(如 PHPMailer)無法工作。利用 cURL 的 CURLOPT_CUSTOMREQUEST 發送原始 SMTP 命令序列,可繞過此限制。
$ telnet smtp.example.com 25
220 smtp.example.com ESMTP
EHLO localhost
250-PIPELINING ...
AUTH LOGIN
334 VXNlcm5hbWU6
dXNlcm5hbWU= # base64_encode(username)
334 UGFzc3dvcmQ6
cGFzc3dvcmQ= # base64_encode(password)
235 Authentication successful
MAIL FROM:<from@example.com>
250 OK
RCPT TO:<to@example.com>
250 OK
DATA
354 Start mail input
Subject: Test
From: <from@example.com>
To: <to@example.com>
Content-Type: text/html; charset=UTF-8
Hello World!
.
250 Queued
QUIT
221 Bye
<?php
$smtp = [
'url' => 'smtp.example.com',
'port' => 25,
'username' => 'user@example.com',
'password' => 'secret',
'from' => 'from@example.com',
'to' => 'to@example.com',
'subject' => '測試標題',
'body' => '測試內容'
];
$CRLF = "\r\n";
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $smtp['url']);
curl_setopt($curl, CURLOPT_PORT, $smtp['port']);
curl_setopt($curl, CURLOPT_TIMEOUT, 10);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
// 郵件頭構建(Base64 編碼主題與正文)
function inlineCode($str) {
$str = trim($str);
return $str ? '=?UTF-8?B?'.base64_encode($str).'?= ' : '';
}
$header = [
'Return-path' => '<'.$smtp['from'].'>',
'Date' => date('r'),
'From' => '<'.$smtp['from'].'>',
'MIME-Version'=> '1.0',
'Subject' => inlineCode($smtp['subject']),
'To' => $smtp['to'],
'Content-Type'=> 'text/html; charset=UTF-8; format=flowed',
'Content-Transfer-Encoding' => 'base64'
];
$data = implode("\n", array_map(fn($k,$v)=>"$k: $v", array_keys($header), $header))
. $CRLF . chunk_split(base64_encode($smtp['body']));
// SMTP 命令序列
$cmd = "EHLO {$smtp['url']}$CRLF";
$cmd .= "AUTH LOGIN$CRLF".base64_encode($smtp['username']).$CRLF.base64_encode($smtp['password']).$CRLF;
$cmd .= "MAIL FROM:{$smtp['from']}$CRLF";
$cmd .= "RCPT TO:{$smtp['to']}$CRLF";
$cmd .= "DATA$CRLF$data$CRLF.$CRLF";
$cmd .= "QUIT$CRLF";
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $cmd);
$response = curl_exec($curl);
var_dump($response);
curl_close($curl);
CURLOPT_CUSTOMREQUEST 直接發送拼裝好的 SMTP 命令字符串,而非 HTTP 請求。SmtpMailer 類,內部自動檢測 fsockopen 可用性,優先使用 socket,不可用時降級 cURL。摘自:bluefrog