How can I use fake sendmail with SwiftMailer on Wi

2019-05-07 19:20发布

I wish to send emails using PHP on Windows via an external SMTP server. I must use SwiftMailer for this purpose.

I can send emails via the external SMTP server using PHP's native mail() function and Fake Sendmail for Windows, but I cannot get SwiftMailer working.

Working Setup Using PHP's mail() Function

Here is the PHP code I use to send mail successfully using the native mail() function.

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

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

Here is the relevant portion of my php.ini file.

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

Fake Sendmail for Windows has its own sendmail.ini file, in which I have specified my smtp_server, smtp_port, auth_username, and auth_password.

When I run above PHP code by loading a page in my web browser, the output indicates that the mail() function returns true, and the email arrives at its intended destination as expected.

Attempted Setup Using SwiftMailer (Not Working)

Attempting to achieve the same result using SwiftMailer, I replace my PHP code above with the following, as instructed to in the SwiftMailer documentation.

$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";

When I attempt to run the PHP code above by loading a page in my web browser, the page just loads forever. I have traced the PHP code in the SwiftMailer library as far as I can, and found that I could not see output from echo statements after the "if ($err = stream_get_contents($pipes[2])) {" line below. If I cut and paste the 'echo "Okay so far."' and 'die;' lines to after the 'if' condition, either inside or outside the curly braces following the 'if', the page just keeps loading forever.

/**
 * 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];
}

Things I have Tried Already

  • I have tried using -bs instead of -t in the /usr/lib/sendmail command passed to Swift_SendmailTransport::newInstance(). I have tried passing no parameter (ie. neither -bs nor -t) also.
  • I have tried passing the 'from' parameter the same way as I do in the call to PHP's native mail() function above. When I did that, SwiftMailer complained that my 'from' address 'does not comply with RFC 2822'.
  • I have tried (thanks to Michael Sivolobov's suggestion below), replacing '/usr/lib/sendmail -t' with 'C:\usr\lib\sendmail -t', and with 'C:/usr/lib/sendmail -t'. In both cases, the page just keeps loading forever.
  • I've tried passing no arguments to the Swift_SendmailTransport::newInstance() function in the hope that Swift would figure out the path to my sendmail.exe from my php.ini file. Doing that resulted in the following error "Uncaught exception 'Swift_TransportException' with message 'Process could not be started [The system cannot find the path specified.]" The exception was thrown from the code section reproduced above. Passing '-t' and '-bs' had the same effect.

I'm all out of ideas. Any helpful suggestions anyone can offer on how to get the SwiftMailer code working would be greatly appreciated.

2条回答
Deceive 欺骗
2楼-- · 2019-05-07 20:02

Assuming you have installed the fake sendmail into a local directory like:

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

Edit your php.ini file like this:

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

Edit your sendmail.ini file like this:

smtp_server=localhost
smtp_port=25
smtp_ssl=none

then use swiftmailer SMTP transport like this:

$transport = new Swift_SmtpTransport('localhost', 25);
  • Swift_SendmailTransport is designed only for (Linux/UNIX) executable.

For Laravel Users

the process is the same but you also need to edit your .env file like this:

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"
查看更多
看我几分像从前
3楼-- · 2019-05-07 20:10

You need to use right transport:

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

UPDATE Use this line:

$transport = Swift_MailTransport::newInstance();
查看更多
登录 后发表回答