PHP的mail
函数似乎在一个干净的系统上传递邮件,管理员或网站管理员没有进行明显的配置(php.ini
中没有SMTP配置等)。mail
函数如何将邮件传递到远程服务器?
在*nix上,它调用sendmail
二进制文件,然后使用邮件配置来路由电子邮件。在Windows上,它发送到SMTP服务器。在这两种情况下,系统管理员都会设置邮件系统。
您可以检测它的工作方式,如下所示。
第一种方法
$ ltrace php -r "mail('tester@127.0.0.1', '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
从以上命令的结果可以看出,popen()
函数打开了/usr/sbin/sendmail -t -i
的进程。
$ ls -l /usr/sbin/sendmail
... /usr/sbin/sendmail -> exim4
因此sendmail
是到exim4
的符号链接,因此sendmail -t -i
调用exim4 -t -i
。
在exim4
的手册页面中,您可以阅读这些选项-t -i
:
$ man exim4 | grep ' -t -i'
-ti This option is exactly equivalent to -t -i. It is provided for compatibility with Sendmail.
第二种方法
安装snoopy并运行:
# grep snoopy /var/log/auth.log | tail
... php -r mail('tester@127.0.0.1', '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
上述命令的结果显示了执行的命令的顺序。
mail()使用sendmail,它使用DNS查找目标域的MX记录并直接发送到那里。就是这样。
由于目标服务器可能不知道您的ip地址,特别是如果它是NAT,它可能会被标记为垃圾邮件。
您可以修改您的配置,使用不同的(合法的)smtp服务器作为中介。
实际上,除非正确配置了底层sendmail
或其他东西,否则它真的不那么可靠。
亚马逊SES的服务器比你使用的任何服务器都要好,而且在那里收到邮件的次数比mail()
多。
你不应该使用mail()
的真正原因是,你的服务器的IP地址可能对GMail、Yahoo等邮件服务完全未知,而且它被标记为垃圾邮件的可能性更大。为什么它被标记为垃圾邮件?因为mail()
很容易被用于垃圾邮件目的。