如何在PHP中强制使用From:标头(信封发件人)而不将其放入mail()?

前端之家收集整理的这篇文章主要介绍了如何在PHP中强制使用From:标头(信封发件人)而不将其放入mail()?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个开发Web服务器(CentOS LAMP堆栈),它使用postfix中的SMTP中继设置来发送电子邮件.我们使用 mailgun与多个用户,类似于 this的设置,但与特定用户而不是通配符电子邮件

/etc/postfix/main.cf中

smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_auth_enable = yes
sender_dependent_relayhost_maps = hash:/etc/postfix/relayhost_map
smtp_sender_dependent_authentication = yes
smtp_sasl_security_options = noanonymous
relayhost = [smtp.mailgun.org]:587

/等/后缀/ sasl_passwd

# our domains
no-reply@domain.com  postmaster@domain.com:password1
info@domain2.com     postmaster@domain2.com:password2
support@domain3.com  postmaster@domain3.com:password3

# in-case we don't have it setup,use a default
#[smtp.mailgun.org]:587      postmaster@domain2.com:password2

/等/后缀/ relayhost_map

no-reply@domain.com  [smtp.mailgun.org]:587
info@domain2.com     [smtp.mailgun.org]:587
support@domain3.com  [smtp.mailgun.org]:587

要设置电子邮件日志记录,我使用自己的SMTP凭据验证计算机上的每个开发人员.我想设置它,以便开发人员不需要添加additional_headers或additional_parameters来获得postfix中正确的smtp中继匹配 – 事实上,为不同的开发人员在代码中设置不同的邮件头需要做很多工作,尤其是使用版本化代码.我离题了.当我使用以下内容时,这在postfix的方面工作得很好:

mail('email@address.tld','subject','message here...','From: noreply@domain.com','-fnoreply@domain.com');

所以我然后将以下内容添加到vhost配置中:

PHP_admin_value sendmail_path "/usr/sbin/sendmail -t -i -fnoreply@domain.com"

这成功地让我摆脱了-f additional_parameter并仍然正确发送.然后我添加了以下内容

PHP_value sendmail_from "noreply@domain.com"

PHPinfo()转储中,我看到sendmail_from的本地值设置正确,但是现在当我发送电子邮件时,它出现为:

None@domain.com on behalf of Apache

似乎正确的发件人(MIME,而不是信封,因为postfix识别身份验证并获得250大成功).使用详细的postfix登录,我只看到来自sender输入属性的正确电子邮件的引用.

在mailgun中,我从日志中看到以下信息,但是,当不使用From:noreply@domain.com时,我会看到电子邮件

...
"envelope": {
    "transport": "smtp","sender": "noreply@domain.com","sending-ip": "x.x.x.x","targets": "email@address.tld"
},"message": {
    "headers": {
        "to": "email@address.tld","message-id": "2014061111016.ABC1D23456E@domain.com","from": "noreply@domain.com (Apache)","subject": "Debug Test"
    },"attachments": [],"recipients": [
        "email@address.tld"
    ],"size": 654
},...

有趣的是,当From:noreply@domain.com存在时,相同的日志,message-> headers-> from被正确地设置为noreply@domain.com而没有添加(Apache).当然这意味着它是PHP的错,并且PHP没有正确使用sendmail_from值?

所以考虑到所有这些,我得到的问题是如何在PHP中设置默认的MIME发送者(From头),而不是在mail()函数中?我上面的方法/配置错过了什么,或者它是否完全不可能?我很乐意在盒子外面思考一下,因为我们想要这个功能,这将有助于节省时间.

sendmail_from被忽略

http://www.php.net/manual/en/mail.configuration.php开始:

sendmail_from string
Which “From:” mail address should be used in mail sent from PHP under Windows.
This directive also sets the “Return-Path:” header.

因此,由于您使用的是CentOS LAMP堆栈,而不是Windows,因此会忽略此设置.

也:

sendmail_path string
If set,smtp,smtp_port and sendmail_from are ignored and the specified command is executed.

所以sendmail_from也会被忽略,因为你正在使用sendmail_path.

您还可以使用空值传递-F(大写字母F)以从标题删除“发件人全名”:

将-f noreply@domain.com -F“”传递给mail()函数的$additional_parameters参数.

其他说明

-f参数

当您看到发件人地址发生更改时,Postfix就是这样做的.这是因为(在您的情况下)Apache运行的系统用户正在调用sendmail二进制文件.此二进制文件将使用< system-user> @< hostname>作为发件人地址(除非-f或-r参数另有说明).

为防止这种情况,应使用-f< sender address>调用sendmail.将其传递给mail()函数的$additional_parameters参数,或者将其添加到sendmail_path ini-setting中.

但看起来你已经想到了这个:)

更好的解决方

我建议你根本不使用ini-settings.相反,在mail()函数周围编写一个小类:

class Mailer
{
    /**
     * @var string
     */
    private $fromEmail;

    /**
     * @var string
     */
    private $fromName;

    /**
     * @param string $fromEmail
     * @param string $fromName
     */
    public function __construct($fromEmail,$fromName)
    {
        $this->fromEmail = $fromEmail;
        $this->fromName  = $fromName;
    }

    /**
     * @param  string $to
     * @param  string $subject
     * @param  string $body
     * @param  array  $headers
     * @return bool
     */
    public function send($to,$subject,$body,array $headers = array())
    {
        $headers[]  = sprintf('From: "%s" <%s>',$this->fromName,$this->fromEmail);
        $parameters = sprintf('-f %s',$this->fromEmail);

        return mail($to,$headers,$parameters);
    }
}

并像这样使用它:

$mailer = new Mailer('noreply@domain.com','My Company');
$mailer->send('email@address.tld','Subject','Body');

这个类过于简化了,但它应该让你基本了解每次想要发送电子邮件时如何否定From:headers和-f参数的麻烦.

如果您使用的是依赖注入容器或注册表,则可以在应用程序的引导阶段配置/实例化此类,只需在发送电子邮件时从容器/注册表中获取它:

$container->get('mailer')->send($to,$message);

或者使用注册表:

Registry::get('mailer')->send($to,$message);

第三方图书馆

从长远来看,查看第三方库发送电子邮件是值得的.我个人更喜欢Swift Mailer.

猜你在找的PHP相关文章