3

I'm using msmtp as a relay and trying to send an email with the mail() function. It works perfectly in CLI, but does nothing in Apache. My PHP configs for cli and apache are identical, there are no errors in any of the logs and I'm really out of ideas.

Any idea what this could be caused by?

Jake S.
  • 161
  • 1
  • 5
  • If you're using RHEL or CentOS SELinux might actively restrict and prevent apache from establishing outgoing mail/network connections. – HBruijn Apr 03 '17 at 12:06
  • 1
    Sorry, I forgot to mention I'm using debian. No SELinux there. – Jake S. Apr 03 '17 at 12:06

3 Answers3

3

I've found the solution to this problem. I'm using msmtp, which is an SMTP proxy and works similar to sendmail, thus, when trying to send a mail, the msmtp command is called from php with similar syntax to sendmail.

Now, the msmtp command will be run by the same user apache2 is running under. In my case www-data.

There is a configuration file for msmtp (/etc/.msmtp_php in my case) that needs to be readable by the www-data user.

The reason CLI was working and Apache PHP was not is, that I was running the CLI under root, which had the correct permissions for the file, but apache2 is runnuing under www-data, which didn't have those permissions.

So the solution is: chown the /etc/.msmtp_php file to www-data:www-data and chmod the same file to 0600, otherwise, msmtp will complain about loose permissions.

Jake S.
  • 161
  • 1
  • 5
1

One way you can send mail by using it in exec() function.

exec('usr/bin/mail <parameter>', $output); //$output for debugging

Check output for response, but still you have to resolve your settings for using php mail() function.

1

First of all: Check whether you are actually using the php.ini file you believe.

Apache can for example use different php.ini location for every user, if mod_suphp is enabled. With suPHP, the location is set with suPHP_ConfigPath directive in mods-enabled/suphp.conf and it defaults to PHP's compiled default path even when different PHPIniDir is set for global configuration. (PHP: The configuration file gives more information about the order where php.ini gets searched.)

  1. You can get the php.ini location by using <?php phpinfo(); ?> within same directory.
  2. You can directly get the current SMTP server used by mail() function with ini_get():

    <?php echo ini_get('SMTP') . ":" . ini_get('smtp_port'); ?>

If the SMTP server is the one it should be, the mail() function should return TRUE if the mail was successfully accepted for delivery and otherwise FALSE. In both cases, if the function was able to connect the SMTP server, more information on the connection can be found in SMTP server log file.

If mail() returns FALSE without connecting to the SMTP, check whether you have safe_mode on and mail() additional_parameters set. From changelog (PHP version 4.2.3):

The additional_parameters parameter is disabled in safe_mode and the mail() function will expose a warning message and return FALSE when used.

Esa Jokinen
  • 43,252
  • 2
  • 75
  • 122
  • This answer needs improvement in regards to suggestions about mail() returning TRUE/FALSE. It needs an example. – Elijah Lynn Dec 18 '19 at 00:21