关于php:SMTP配置在生产环境中不起作用

SMTP configuration not working in production

我正在尝试在提交表单时发送电子邮件。我正在使用PHPMailer通过以下配置发送邮件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$mail = new PHPMailer;
$mail->isSMTP();
$mail->Host = 'mail.example.in';
$mail->Port = 25;
$mail->SMTPAuth = true;
$mail->Username = 'user@example.in';
$mail->Password = 'password';

$mail->setFrom("user@example.in" ,"User");
$mail->addAddress('receiver@example.in', 'Receiver');
$mail->addBCC('anotheruser@somedomain.com', 'Another user');
$mail->AddReplyTo('user@example.in', 'User');

$mail->isHTML(true);

$mail->Subject = $subject;
$mail->Body    = $message;
if($mail->send())
    echo"Your request has been received. We will soon contact you.";
else echo"Unable to send your request. Please try again";

这在localhost中可以正常工作。但是,当我将其部署到服务器(example.in)时,出现以下异常。

1
2
SMTP ERROR: Failed to connect to server: Connection timed out (110)
SMTP connect() failed. https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting

-编辑-

我尝试使用telnet命令连接到SMTP服务器,但是我无法添加收件人。我收到以下错误?

1
2
3
4
5
6
7
8
9
10
11
12
Last login: Fri Sep 16 11:08:06 on ttys000
admin:~ admin$ telnet mail.example.in 25
Trying 111.91.153.112...
Connected to mail.example.in.
Escape character is '^]'.
220 fbs-ho-mailserver.example.in ESMTP Service (Lotus Domino Release 8.5.3FP3) ready at Fri, 16 Sep 2016 11:36:01 +0530
HELO example.in
250 fbs-ho-mailserver.example.in Hello example.in ([111.91.127.222]), pleased to meet you
MAIL from: marketing@example.in
250 marketing@example.in... Sender OK
RCPT to: john.hh@gmail.com
554 Relay rejected for policy reasons.

-编辑-

我能够在Outlook中设置此帐户。我真的很困惑。

enter


您的错误提示:

1
2
SMTP ERROR: Failed to connect to server: Connection timed out (110)
SMTP connect() failed. https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting

所以让我们看一下https://github.com/PHPMailer/PHPMailer/wiki/故障排除:

"SMTP Error: Could not connect to SMTP host."

This may also appear as SMTP connect() failed or Called Mail() without
being connected in debug output. This is often reported as a PHPMailer
problem, but it's almost always down to local DNS failure, firewall
blocking (for example as GoDaddy does) or other issue on your local
network. It means that PHPMailer is unable to contact the SMTP server
you have specified in the Host property, but doesn't say exactly why.
It can also be caused by not having the openssl extension loaded (See
encryption notes below).

Some techniques to diagnose the source of this error are discussed
below.

GoDaddy

Popular US hosting provider GoDaddy imposes very strict (to the point
of becoming almost useless) constraints on sending email. They block
outbound SMTP to ports 25, 465 and 587 to all servers except their
own. This problem is the subject of many frustrating questions on
Stack Overflow. If you find your script works on your local machine,
but not when you upload it to GoDaddy, this will be what's happening
to you. The solution is extremely poorly documented by GoDaddy: you
must send through their servers, and also disable all security
features, username and password (great, huh?!), giving you this config
for PHPMailer:

1
2
3
4
5
$mail->isSMTP();
$mail->Host = 'relay-hosting.secureserver.net';
$mail->Port = 25;
$mail->SMTPAuth = false;
$mail->SMTPSecure = false;

GoDaddy also refuses to send with a From address belonging to any aol,
gmail, yahoo, hotmail, live, aim, or msn domain (see their docs). This
is because all those domains deploy SPF and DKIM anti-forgery
measures, and faking your from address is forgery.

You may find it easier to switch to a more enlightened hosting
provider.


您遇到的问题-而不是两个不相关的问题非常简单:

SMTP ERROR: Failed to connect to server: Connection timed out (110)
SMTP connect() failed.

,并且您已验证服务器确实在接受连接:

I tried connecting to the SMTP server using telnet command

1
2
3
4
Last login: Fri Sep 16 11:08:06 on ttys000
admin:~ admin$ telnet mail.example.in 25
Trying 111.91.153.112...
Connected to mail.example.in.

您的脚本从生产服务器运行时无法连接到SMTP服务器。

可能的原因是生产服务器具有防火墙,为了避免滥用该防火墙,可以防止与外部的任何连接。该服务器可以处理Web请求,但不能再提供其他服务。

如果测试已验证端口25没有响应,则(在检查主机地址正确之后)您可以尝试在587中尝试telnet mail.example.。如果可行,则可能意味着服务器不接受不安全的连接(端口25),但接受安全的连接。然后,使用PHPMailer,您可以尝试激活安全连接:

1
$mail->SMTPSecure = 'tls';

1
$mail->SMTPSecure = 'ssl';

如果这不起作用,则可能仍然存在防火墙问题;否则您可能需要查看phpinfo()并确认您确实在PHP中具有OpenSSL支持。

你需要做什么

  • 要求维护生产服务器的IT人员打开防火墙;
  • 更有希望的是,问他们如何从该服务器发送电子邮件。您可能需要使用mail()函数,或者将localhost127.0.0.1用作SMTP服务器。然后,电子邮件将通过您的生产服务器的服务网络发送出去。

他们可能会告诉您不允许使用端口25,但可以使用端口465或567(例如)。您将必须更新配置和/或相应地添加TLS / SSL(请参见上文)。

  • 否则可能会允许您连接到第三方SMTP服务器,您必须为其提供IP地址,以允许IT人员打开合适的防火墙窗口。然后,电子邮件将通过第三方服务器发送出去。

第二个问题(可能不是问题)

250 marketing@example.in... Sender OK
RCPT to: john.hh@gmail.com
554 Relay rejected for policy reasons

为避免滥用,SMTP服务器不会让每个人都可以连接和发送电子邮件,而只能让他们自己的客户连接和发送电子邮件。我看到在PHPMailer配置中,您指定了一个用户和一个密码。在telnet会话中,您没有。因此,很可能PHPmailer可以发送但不能连接,而您的telnet可以连接但不能发送。

解决连接问题后,身份验证问题将解决或消失(因为您将使用IT专家提供给您的另一台服务器,例如localhost)。 >

第三个问题(可能永远不会出现)

滥用服务的第三种方法是过度使用-向太多人发送太多电子邮件。与IT人员确认发送电子邮件的可接受策略是什么。

问题,问题

要考虑的其他事项包括源的信誉(您可能希望代表未将您选择的SMTP服务器指定为允许的发件人的某个域发送电子邮件)和数据的机密性(即使使用TLS) / SSL连接,如果为您提供localhost作为SMTP服务器,则您的IT人员将对您发送的任何电子邮件都具有完全,不受限制,无法检测的访问权限。您可能会也可能不知道)。


我遇到了类似的超时问题,原因是我的托管服务提供商(Linode)。
TLDR;默认情况下,对于在2019年11月5日之后创建的帐户,Linode设置了SMTP限制。您需要为实例配置rDNS并打开支持票证以确认CAN-SPAM符合性,并且支持应迅速取消限制。我猜很多人由于smtp限制而面临这个问题


我认为,只需几个步骤,我们就可以使它正常工作。

  • 在您的Godaddy / Hostgator面板中>选择MX记录>选择有问题的域>选择"远程邮件交换器"

    您现在可以测试邮件传递,问题可能会解决。

  • 我确定设置正确,但是当谈到好ole Cpanel,PhpMailer和Godaddy / Hostgator时,请相信我。这是一个没有常识的地方。

  • 替换:

    1
    $mail->Host = 'mail.example.in';

    具有:

    1
    $mail->Host = 'localhost';

    我认为,只要登录凭据之类的东西有效,这就能解决所有问题。


    因此,您有一台GoDaddy服务器,并且您想通过新收购的SMTP中继发送电子邮件。如果您在Google上做些戳戳,可能会发现"您无法找到"。

    如果您多花一点钱,您可能会发现GoDaddy的官方解决方案是使用其内部邮件中继。这是不理想的,因为它们设置了任意障碍,例如:

    Our dedicated servers have an outbound email limit of 1000 per day. If
    you need to send more than 1000 emails per day, please call Customer
    Support or open a support ticket to request a higher limit.

    快速有效的解决方案:获取支持使用HTTP API发送电子邮件的SMTP中继。

    我的建议:(一个简单有效的工作解决方案,我个人正在使用)

    注册Sendgrid中的帐户。 Sendgrid每月提供免费的12k电子邮件,我认为这足以满足任何基本需求。

    第一步:Sendgrid将要求您添加一些DNS记录以验证您的身份,以便代表该主机发送电子邮件。这样做。

    第二步:配置白色标签https://sendgrid.com/docs/User_Guide/Settings/Whitelabel/index.html(这并不重要,但是它将使您发送的电子邮件具有专业的外观)

    第三步:生成API密钥

    您可以从SendGrid客户门户管理API密钥。此外,您可以通过API本身来管理API密钥。

    第四步:继续编写我们的代码。

    使用github上提供的该库在sendgrid上使用PHP发送邮件很容易:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // using SendGrid's PHP Library
    // https://github.com/sendgrid/sendgrid-php
    require 'vendor/autoload.php';
    $sendgrid = new SendGrid("SENDGRID_APIKEY");
    $email    = new SendGrid\\Email();

    $email->addTo("test@sendgrid.com")
          ->setFrom("you@youremail.com")
          ->setSubject("Sending with SendGrid is Fun")
          ->setHtml("and easy to do anywhere, even with PHP");

    $sendgrid->send($email);

    这是如何工作的

    GoDaddy阻止端口25、2525、587和485,这是SMTP的理想端口。因此,我们使用端口80/443,并请求sengrid \\的API使用端口80代表我们发送电子邮件,是的,我们欺骗了GoDaddy。


    什么是phpmailer版本?

    您可能会忘记添加此行

    1
      $mail->IsSMTP(); //  use SMTP

    启动$ mail后。

    尝试一下。


    如果未在该服务器上启用smtp,请咨询您的托管服务提供商。我之前对于smtp和curl都有相同的问题。请与托管服务提供商联系。


    使用您自己的SMTP是个坏主意。
    根据您的处理方式,您很有可能会将电子邮件以某种方式阻止或标记为垃圾邮件。而且您将不得不花费一些时间来使服务器保持最新。

    使用对每个提供商都列入白名单的在线服务,这些服务公开API以发送您的交易邮件:
    https://www.mailjet.com/
    http://mailchimp.com/
    ...

    他们通常会建议一个小批量的免费帐户(每天少于2000封电子邮件)。
    使用该API非常简单,可以在几分钟内就位(例如:https://dev.mailjet.com/)


    第一个报价单(来自ibm社区):

    john.hh@gmail.com was a member of a group (Reject) that was listed in
    gmail.com's"Deny messages intended for the following internet
    addresses" field (in the destination server's Domino Configuration
    document's Router/SMTP, Restrictions and Controls, SMTP Inbound
    Controls tab's"Inbound Intended Recipient's Controls" section).

    Removing Mary's hierarchical name (Mary Jones/ABC) from the members
    list in the Reject (group) document allows Mary to receive messages
    from the Internet.

    第二个引号:

    Most mail servers, to prevent them being used as anonymous spam
    relays, are configured only to relay mail from certain hosts.


    我明白你的意思了。我也发生了同样的问题,我只添加了一行并且对我有用。请使用,

    1
    $mail->SMTPSecure = 'ssl';

    并根据ssl配置您的设置。另外,请正确检查服务端的邮件配置。


    您需要在php.ini中更改一些设置:

    1
    2
    3
    4
    5
    upload_max_filesize = 2M
    ;or whatever size you want

    max_execution_time = 60
    ; also, higher if you must - sets the maximum time in seconds.

    您的PHP.ini是否取决于您的环境,更多信息:
    参考

    将其放在您的PHP脚本的顶部,并放宽您的脚本

    1
    ini_set('max_execution_time', 600); //600 seconds = 10 minutes or set your time


    超时错误是丢包的典型现象,因此也可能是Web服务器和SMTP服务器之间的防火墙问题。
    如果您拥有对服务器的ssh访问权限,则可以尝试使用以下命令连接到smtp:

    1
    telnet <smtp server> 25

    即使使用telnet发生超时错误,您也可以肯定问题出在网络/防火墙方面。