4

我希望通过外部 SMTP 服务器在 Windows 上使用 PHP 发送电子邮件。为此,我必须使用SwiftMailer 。

我可以使用 PHP 的本机 mail() 函数和Fake Sendmail for Windows通过外部 SMTP 服务器发送电子邮件,但我无法让SwiftMailer正常工作。

使用 PHP 的 mail() 函数进行工作设置

这是我使用本机 mail() 函数成功发送邮件的 PHP 代码。

$returnValue = mail
(
   $params['to'     ],
   $params['subject'],
   $params['body'   ],
   "From: Sender McSender <{$params['from']}>"
);

echo "mail() returned "; var_dump($returnValue);

这是我的 php.ini 文件的相关部分。

[mail function]
sendmail_path = "C:\usr\lib\sendmail.exe"

Fake Sendmail for Windows有自己的 sendmail.ini 文件,我在其中指定了我的 smtp_server、smtp_port、auth_username 和 auth_password。

当我通过在 Web 浏览器中加载页面来运行 PHP 代码时,输​​出表明 mail() 函数返回 true,并且电子邮件按预期到达了预期的目的地。

尝试使用SwiftMailer 进行设置(不工作)

尝试使用SwiftMailer实现相同的结果,我按照SwiftMailer 文档中的说明将上面的 PHP 代码替换为以下代码。

$transport = Swift_SendmailTransport::newInstance('/usr/lib/sendmail -t');
$mailer    = Swift_Mailer::newInstance($transport);
$message   = Swift_Message::newInstance()
->setSubject($params['subject'])
->setFrom($params['from'])
->setTo($params['to'])
->setBody($params['body']);

$nSent = $mailer->send($message);

echo "Number of emails sent: $nSent\n";

当我尝试通过在我的网络浏览器中加载页面来运行上面的 PHP 代码时,该页面将永远加载。我已经尽可能地跟踪了 SwiftMailer 库中的 PHP 代码,发现在下面的“if ($err = stream_get_contents($pipes[2])) {”行之后我看不到 echo 语句的输出。如果我剪切并粘贴'echo "Okay so far." 和 'die;' 在'if'条件之后的行,无论是在'if'之后的花括号内部还是外部,页面都会永远加载。

/**
 * Opens a process for input/output.
 */
private function _establishProcessConnection()
{
echo "In StreamBuffer->_establishProcessConnection()\n";
    $command = $this->_params['command'];
    $descriptorSpec = array(
        0 => array('pipe', 'r'),
        1 => array('pipe', 'w'),
        2 => array('pipe', 'w')
        );
    $this->_stream = proc_open($command, $descriptorSpec, $pipes);
    stream_set_blocking($pipes[2], 0);
echo "Okay so far.\n";
die;
    if ($err = stream_get_contents($pipes[2])) {
        throw new Swift_TransportException(
            'Process could not be started [' . $err . ']'
            );
    }
    $this->_in =& $pipes[0];
    $this->_out =& $pipes[1];
}

我已经尝试过的事情

  • 我尝试在传递给 Swift_SendmailTransport::newInstance() 的 /usr/lib/sendmail 命令中使用 -bs 而不是 -t。我也尝试过不传递任何参数(即既不是-bs 也不是-t)。
  • 我尝试以与上面调用 PHP 的本机 mail() 函数相同的方式传递“from”参数。当我这样做时,SwiftMailer 抱怨我的“发件人”地址“不符合 RFC 2822”。
  • 我已经尝试过(感谢 Michael Sivolobov 在下面的建议),将 '/usr/lib/sendmail -t' 替换为 'C:\usr\lib\sendmail -t' 和 'C:/usr/lib/sendmail -t '。在这两种情况下,页面只会永远加载。
  • 我尝试不向 Swift_SendmailTransport::newInstance() 函数传递任何参数,希望 Swift 能够从我的 php.ini 文件中找出我的 sendmail.exe 的路径。这样做会导致以下错误“Uncaught exception 'Swift_TransportException' with message 'Process could not be started [The system cannot find the path specified.]” 上面复制的代码部分引发了异常。传递 '-t' 和 '-bs' 具有相同的效果。

我完全没主意了。任何人都可以就如何使 SwiftMailer 代码正常工作提供任何有用的建议,我们将不胜感激。

4

2 回答 2

3

您需要使用正确的交通工具:

$transport = Swift_SendmailTransport::newInstance('C:\usr\lib\sendmail.exe');

更新 使用这一行:

$transport = Swift_MailTransport::newInstance();
于 2013-07-05T08:41:22.080 回答
1

假设您已将伪造的 sendmail安装到本地目录中,例如:

C:\wamp64\bin\sendmail\sendmail.exe

像这样编辑您的php.ini文件:

sendmail_path = "C:\wamp64\bin\sendmail\sendmail.exe -t"

像这样编辑您的sendmail.ini文件:

smtp_server=localhost
smtp_port=25
smtp_ssl=none

然后像这样使用swiftmailer SMTP 传输:

$transport = new Swift_SmtpTransport('localhost', 25);
  • Swift_SendmailTransport仅适用于 (Linux/UNIX) 可执行文件。

对于 Laravel 用户

该过程是相同的,但您还需要.env像这样编辑您的文件:

MAIL_DRIVER=smtp
MAIL_HOST=localhost
MAIL_PORT=25
MAIL_USERNAME=
MAIL_PASSWORD=
MAIL_ENCRYPTION=
MAIL_FROM_ADDRESS=myemail@example.com
MAIL_FROM_NAME="My Name"
于 2017-11-15T18:17:11.807 回答