问题描述
$mail = new PHPMailer(true);
$mail->IsSMTP();
$mail->SMTPDebug = 3;
$mail->SMTPAuth = false;
$mail->Port = 25;
$mail->Host = "localhost";
$mail->Username = 'username';
$mail->Password = 'password';
$mail->isSendmail();
$mail->From = $email;
$mail->FromName = "Website";
$mail->AddAddress("jn@website.com");
$mail->Subject = "Inquiry - " . $name;
$mail->WordWrap = 80;
$mail->MsgHTML($message);
$mail->IsHTML(true);return $mail->send();
我得到的输出如下:
使用 sendmail 发送:
Sendmail path: /usr/sbin/sendmail -t -i
Sendmail command: /usr/sbin/sendmail -t -i -oi -ft@t.com -t
Envelope sender: t@t.com
Headers: Date: Wed,21 Apr 2021 22:43:52 +0000To: jn@website.comFrom: Website <t@t.com>Subject: Inquiry - testMessage-ID: <Km4AQw3yoiFLxzzxLhULZdgQjrgPSBSTT66rxurg4@website.com>X-Mailer: PHPMailer 6.3.0 (https://github.com/PHPMailer/PHPMailer)MIME-Version: 1.0Content-Type: multipart/alternative; boundary="b1_Km4AQw3yoiFLxzzxLhULZdgQjrgPSBSTT66rxurg4"Content-transfer-encoding: 8bit
Result: true
问题是我没有收到这些电子邮件。
预先感谢您的任何回复。
解决方法
PHP 电子邮件很容易欺骗 From 标头并且经常被拒绝。这很可能是您的接收方邮件服务器以潜在不安全为由拒绝了它。
请注意,仅仅因为电子邮件离开了您的服务器,并不意味着收件人的邮件服务器很乐意接收它。邮件服务器通常会以 Status: OK
响应,即使它无意将其传递到收件人邮箱。
您可以尝试以下几点:
- 确保您的
From
是有效的电子邮件地址。 - DKIM 可以极大地帮助验证电子邮件是否来自有效位置
- SPF 可以帮助验证电子邮件是否来自它所说的位置。
- 修改 X-Mailer 标头,一些 MX 服务器将 PHPMailer 视为不可信。请参阅此处:https://phpmailer.github.io/PHPMailer/classes/PHPMailer.PHPMailer.PHPMailer.html#property_XMailer
DKIM
DKIM 要求您使用自己生成的公钥/私钥在要发送的域上拥有 TXT DNS 记录:
请注意,DNS 记录应使用公钥
v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4lox7LckG2/QtT/IY677O2JTgzh3z/FKKqGSVjAk6Gh+7Tyu8jjFUmPdLj/G5u9cFGkQvqa[..]QJZOGgxBeFv2V/Evk9GZtF+3yiHm5tZvi0Z4xhT17dt8ZxcFZ3QIDAQAB
TXT DNS 记录的名称应为:whoeveryouare._domainkey.mydomain.com
然后,您可以像这样使用 PHPMailer 签署您的电子邮件:
// must match the domain in the "From"
$this->DKIM_domain = "mydomain.com"
// private key path
$this->DKIM_private = "/path/to/dkim/private.key";
// dns selector (this matches with TXT record with hostname: whoeveryouare._domainkey.mydomain.com)
$this->DKIM_selector = 'whoeveryouare';
// private key passphrase (has none)
$this->DKIM_passphrase = '';
//Suppress listing signed header fields in signature,defaults to true for debugging purpose
$this->DKIM_copyHeaderFields = true; // SHOULD BE FALSE IN PRODUCTION
// who is signing this email
$this->DKIM_identity = $this->From;
使用 DKIM 可以抑制说它们是“代表”发送的电子邮件,并提高收件人邮件服务器接受您的电子邮件的机会。
SPF
SPF 代表发件人政策框架。
发件人策略框架 (SPF) 是一种电子邮件身份验证方法,旨在检测电子邮件发送过程中的伪造发件人地址
SPF 有助于确保发件人(发件人地址)实际上来自它所说的地方。 SPF 记录如下所示
v=spf1 +ip4:192.168.3.4 -all
其中 192.168.3.4 是发送电子邮件的服务器的 IP 地址。
我个人扩展 PHPMailer 并即时完成所有这些:
/**
* Class Mailer
*
* A wrapper class for the PHPMailer package
*/
class Mailer extends \PHPMailer\PHPMailer\PHPMailer
{
/**
* PHPMailer constructor.
*
* Automatically configure SMTP credentials and adjust X-Mailer header
*
* @param null $exceptions
*/
public function __construct($exceptions = null)
{
parent::__construct($exceptions);
$this->XMailer = "My Super Cool Platform";
}
/**
* Automatically signs emails with a DKIM signature if enabled
*
* @return bool
* @throws \PHPMailer\PHPMailer\Exception
*/
public function send()
{
// must match the domain in the "From"
$this->DKIM_domain = "mydomain.com"
// private key path
$this->DKIM_private = "/path/to/dkim/private.key";
// dns selector (this matches with TXT record with hostname: whoeveryouare._domainkey.mydomain.com)
$this->DKIM_selector = 'whoeveryouare';
// private key passphrase (has none)
$this->DKIM_passphrase = '';
//Suppress listing signed header fields in signature,defaults to true for debugging purpose
$this->DKIM_copyHeaderFields = true; // SHOULD BE FALSE IN PRODUCTION
// who is signing this email
$this->DKIM_identity = $this->From;
return parent::send();
}
}
处理电子邮件一直是一件乏味的事情,您可以通过使用 SMTP 服务器发送带有 DKIM/SPF 的电子邮件来解决您可能面临的许多问题。
,@zanderwar 的回答大部分是正确的,但不幸的是没有那么重要。您可以使用任何语言同样好地欺骗电子邮件来源,但这就是我们提供 SPF 和 DKIM 的原因。
这里的主要问题是使用 GoDaddy。他们阻止出站 SMTP,并要求您仅通过他们自己的 secureserver.net
服务器发送,无需加密或身份验证。这足以防止在除 GoDaddy 拥有的域之外的几乎所有情况下进行有用的发送。您可以通过 include
机制将它们添加到您的 SPF 记录中,但这不太可能对接收者产生太大影响。
您还有其他一些问题。
您正在调用 isSMTP()
,然后是 isSendmail()
– 最后调用后者,实际使用的也是如此,这意味着您的所有 SMTP 设置都将被忽略。选择一种发送机制。
接下来,您实际上不太可能想要使用 isSendmail()
;这适用于那些自定义安装了自己的邮件服务器软件,需要特殊处理的用户,mail()
(例如 qmail)或 SMTP to localhost(少数情况)不支持。你在 GoDaddy 上,这意味着你无论如何都做不到。要么使用默认的 isMail()
,要么最好使用 SMTP 到 localhost
(最快和最安全的方法,也提供最好的反馈)。
你很难知道发生了什么,因为你没有错误处理。您没有检查任何返回值,没有异常处理(您也需要在 PHPMailer 中启用),没有显示错误消息,并且没有启用调试输出(尽管这仅对 SMTP 发送非常有用)。我建议您将代码基于 the examples provided with PHPMailer,它展示了如何做这些事情。
是的,您也应该与 DKIM 签约,但同样,GoDaddy 在这里将无济于事。
最后,发帖前先搜索一下;此处有许多与 using PHPMailer with GoDaddy 相关的问题和答案,其中大部分与使用 GoDaddy 所固有的问题完全相同。如果可能的话,我建议改用不会让电子邮件变得如此混乱的主机。