How can I make the From: header (envelope sender) in PHP not put it in mail ()?

I have a development web server (CentOS LAMP stack) that uses the postfix SMTP relay setting to send email. We use mailgun with several users, the setting is similar to this , but with specific users, and not just wildcards:

/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 

/ etc / postfix / 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 

/ etc / postfix / relayhost_map

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

To set up email logging, I confirm that each developer on the computer has their own SMTP credentials. I want to configure it so that developers do not need to add additional_headers or additional_parameters to get the smtp relay matching in postfixes - and indeed, it will take a lot of work to configure different mail headers in the code for different developers, especially with the version of the code. I got distracted. This worked differently from the postfix side of things when I use the following:

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

So, I added the following to the vhost configuration:

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

which successfully allowed me to get rid of -f additional_parameter and still send correctly. Then I added the following:

 php_value sendmail_from " noreply@domain.com " 

In the phpinfo() dump, I see that the local value for sendmail_from set correctly, however now when I send an email, it appears as:

None@domain.com on behalf of Apache

It seems that the correct sender is (MIME, not an envelope, as postfix recognizes authentication and gives 250 big successes). When postfix registers with verbose, I only see links to the correct email address from the sender input attribute.

In the mail, I see the following information from the journal, however, for email when From: noreply@domain.com used From: noreply@domain.com :

 ... "envelope": { "transport": "smtp", "sender": " noreply@domain.com ", "sending-ip": "xxxx", "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 }, ... 

Interesting is the same log when From: noreply@domain.com present , message->headers->from set according to noreply@domain.com without adding (Apache) . Surely this means that this is a PHP error and that PHP is not using the sendmail_from value correctly?

So, considering all this, my resulting question is: how can I set the default MIME sender (From header) in PHP, except for the mail() function? Am I missing something using my / config method above, or is it just not possible? I am glad to think a little that this will save time for the reason that we want this feature.

+7
php email apache postfix-mta
source share
2 answers

sendmail_from is ignored

From http://www.php.net/manual/en/mail.configuration.php :

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

Since you are using the CentOS LAMP stack, not Windows , this parameter is ignored.

also:

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

So sendmail_from also ignored because you are using sendmail_path .

Decision

You can also pass -F (capital F) with a null value to remove the sender’s full name from the header:

Pass -f noreply@domain.com -F "" the $additional_parameters argument to the mail() function.

Other notes

-f option

When you see that your sender address has changed, Postfix does this. This is because (in your case) the system user Apache runs under calls the sendmail binary. And this binary will use <system-user>@<hostname> as the sender address (unless specified otherwise with the -F or -r option).

To prevent this, sendmail should be called with -f <sender address> . Either by passing it to the $additional_parameters argument to the mail() function, or by adding it to sendmail_path ini-setting.

But it looks like you already understood it :)

The best solution

I suggest you not use ini-settings at all. Instead, write a small class around the mail() function:

 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, $subject, $body, $headers, $parameters); } } 

And use it like this:

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

This class is overly simplistic, but it should give you a general idea of ​​how to reset problems with From: and -F headers every time you want to send an email.

And if you use a dependency injection container or registry, you can configure / create an instance of this class at the bootstrap stage of your application and simply extract it from the container / registry whenever you want to send an email

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

Or using the registry:

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

third party library

In the long run, you may need to study third-party libraries to send email. I personally prefer Swift Mailer .

+3
source share

Be sure to configure the postfix using the appropriate smtp sasl card. Usually located in /etc/postfix/main.cf

Find or add:

 # SASL smtp_sasl_password_maps = static: noreply@domain.com :xxxxx 

If the email is the configured SMTP email address and xxxxx is the SMTP password that you configured in mailgun.

Provide your services (including postfix) reboot, and you should be in business.

0
source share

All Articles