Home » Php » email – How does PHP's `mail` work?

email – How does PHP's `mail` work?

Posted by: admin April 23, 2020 Leave a comment


PHP’s mail function seems to deliver mail on a clean system, with no apparent configuration done by the administrator or webmaster (no SMTP configuration in php.ini, etc.). How does the mail function deliver mail to a remote server?

How to&Answers:

On *nix it invokes the sendmail binary, which then uses the mail configuration to route the email. On Windows, it sends to a SMTP server. In both cases the sysadmin sets up the mail system.


You can detect how it works as below.

First method

$ ltrace php -r "mail('[email protected]', 'Test', 'Hello world');" 2>&1 | grep sendmail
memcpy(0x095ea168, "sendmail_from", 14)          = 0x095ea168
memcpy(0x095ea1e0, "sendmail_path", 14)          = 0x095ea1e0
popen("/usr/sbin/sendmail -t -i ", "w")          = 0x0977c7c0

From the results of the above command can be seen that the popen() function opens the process of /usr/sbin/sendmail -t -i.

$ ls -l /usr/sbin/sendmail
... /usr/sbin/sendmail -> exim4

So sendmail is the symbolic link to exim4 and hence sendmail -t -i invokes exim4 -t -i.

And in the manual page of exim4 you can read about these options -t -i:

$ man exim4 | grep ' -t -i'
-ti       This option is exactly equivalent to -t -i. It is provided for compatibility with Sendmail.

Second method

Install snoopy and run:

# grep snoopy /var/log/auth.log | tail
... php -r mail('[email protected]', 'Test', 'Hello world');
... /usr/sbin/sendmail -t -i
... /usr/sbin/exim4 -Mc 1YxxYn-0006a7-Nw
... /usr/sbin/exim4 -t -oem -oi -f <> -E1YxxYn-0006a7-Nw
... /usr/sbin/exim4 -Mc 1YxxYn-0006aB-Oj

The results of the above command show the sequence of the commands which were performed.


mail() uses sendmail, that uses DNS to find MX record of target domain and delivers there directly. thats it.

and since destination server probably does not know your ip address, especially if it is NATed it may be marked as spam.

you can modify your config to use different (legit ad known) smtp server to act as intermediary.


It’s really not that reliable, actually, unless the underlying sendmail or something is properly configured.

Amazon SES has better servers than whatever server you’re using and gets mail there more times than with mail().

The real reason you shouldn’t use mail() is because your server’s IP address is probably completely unknown to mail services such as GMail, Yahoo, etc, and there is a higher chance it will get marked as spam. Why does it get marked as spam? Because mail() is very easy and simple to exploit for spam purposes.