### 如何用 PHP 发电子邮件(1)

一个发送 E-MAIL 的脚本也许是你能够在 Web 站点上找到的最普通的脚本之一了,虽然它很简单,一个邮件脚本有时会令程序员非常沮丧.PHP 中有一个叫做 mail()的函数,它只需要知道接收方的地址和信件主体就可以发送邮件,但是要让 mail()按你的意思运行你还需要解决一些棘手的问题.
要使 mail()能够运行,你必须有一个 SMTP 服务器以便 PHP 能够连接上去.不管这个服务器对邮件程序多么重要,大多数人对它如何运转没有一星半点的概念.在本教程中,我们将揭示 SMTP 的秘密并解决一些使用 PHP 发送邮件的常见问题.而本文中的另一些主题将包括循环遍历一个地址列表的方法以及同时以文本和 HTML 格式向接收者发送一个邮件的方法.
SMTP 是简单邮件传输协议(Simple Mail Transfer Protocol)的缩写,而一个 SMTP 服务器是一台运行这种协议并发出邮件的计算机.运行这种协议实际上指的是运行诸如 Sendmail 和 Qmail 的程序--如果你使用的是一台非 Windows 计算机的话.在 Windows 平台上,作为 Windows NT Service Pack 一部分或是内建于 Windows 2000 内部的 SMTP 服务程序就是典型的这种程序.
我并不是说 SMTP 软件包就只有那些,但是它们是最普通的.如果你的 Web 站点使用了互联网服务提供者的主机软件包(Internet Service Provider's virtual hosting package)的一部分,那么 SMTP 服务程序就应该已经在这台计算机上安装了.如果你是一台位于 ISP 或是室内的计算机的系统管理员,那么你很有可能已经在这台计算机上安装了某种 SMTP 软件,用来处理从 Web 服务器发送邮件的过程.
但是,如果你是一个个人用户并只有一个开发用的 Web 服务程序运行在你的个人电脑上,你可能没有在自己的机器上运行 SMTP 软件.下面是一个非常简单但是准确的拇指定律:如果你是一个 Windows 用户而从没有看见 SMTP 服务器这样的字眼,那么你就没有运行这个程序.如果你确实没有,那么你有两种选择:安装,配置,和维护一个 SMTP 服务程序(如果你不知道那是怎么一回事的话就不推荐你使用这种方法)或是使用一个现存的 SMTP 服务器.
"如果一个服务器现在没有运行的话,我又怎么使用它呢?"你可能要问.如果你的计算机是通过拨号连接(或是 DSL 或电缆)连到互联网的话,你可以使用你 ISP 的外发邮件服务器.例如,如果你开发用的 计算机是一个 Windows98 的系统并使用 56kbps modem 通过 EarthLink 连接到互联网,那么你就可以使用 mail.earthlink.net 作为你的 SMTP 服务器.不论你对你的外发邮件服务器使用什么样的邮件客户端(Eudora, Outlook, Netscape Mail 等等),它们都将和你的 PHP 代码使用你的 SMTP 服务器的过程一样.技巧就是使 PHP 知道一点点事实.
在 php.ini 管理配置文件里,有几个条目需要被设置以便 mail()函数能够正常运行.在改变它们以前,搞清楚它们都是做什么用的.你可以使用 phpinfo()函数通过创建一个文件来显示系统当前的配置情况,这个文件包括:
<? phpinfo() ?>
保存这个文件,将它放置到你的 Web 服务程序的文件根目录,然后通过你的浏览器访问它.你应该可以看到一个被优美的格式化了的信息,显示你的配置情况.你要查看的条目如下:
SMTP
sendmail_from
sendmail_path
如果你没有使用 windows,那么 sendmail_path 指令就是你唯一要担心的东西.如果你正在使用 Windows,你就需要看看最后两个指令.
如果你使用的是 Linux 或是一个 Unix 变种,sendmail_path 看起来应该象这样:
sendmail_path = /usr/sbin/sendmail
或者如果你使用 Qmail:
sendmail_path = /var/qmail/bin/sendmail
在这条指令里,你还可以设置配置参数来指明队列缓冲选项或是显示的设置 Return-Path 头,如下所示:
sendmail_path = /usr/sbin/sendmail -t -fyou@yourdomain.com
作为一个非 Windows 用户,这就是你要做的一切了.如果你使用的是 Windows,你有更多的事情要做.你还需要看一看 SMTP 和 sendmail_from 的值.不要被 sendmail_from 指令名字中的 sendmail 弄迷糊了.虽然你没有在 Windows 上使用名叫 Sendmail 的程序,但那只是指令的名字.不要被它吓到了.
在你的 phpinfo()显示的结果里,看看 SMTP 和 sendmail_from 的缺省值--它们要么是空白,要么包含了胡乱的值.你应该把它们改成有意义的值.
如果你决心在这台电脑上运行一个 SMTP 服务程序,你在 php.ini 文件中的条目就应该如下:
SMTP = localhost
但是,如果你要使用你 ISP(在这个例子中是 EarthLink)的外发邮件服务器,那么 php.ini 中的邮件看起来应该如下:
SMTP = mail.earthlink.net
你也可以使用 IP 地址而不是域名,因为计算机不区分这两种条目.
第二条配置指令是 sendmail_from,它应该被设置成 From 头中的电子邮件地址.它可以在脚本里被修改但是通常作为缺省值使用.下面就是这个配置指令的示例 youraddress@yourdomain.com 指的是你自己的邮件地址.
sendmail_from = youraddress@yourdomain.com
在做了这些配置上的改动以后,重启 Web 服务程序然后使用 phpinfo()函数来验证这些修改.在这些工作完成以后,你就可以用 PHP 来发送电子邮件了.
mail()函数是非常简单的:只有五个参数,而其中的两个是可选的.这些参数是:
接收方地址
主题
信件内容
其它文件信息头(可选)
SMTP 服务程序的其它配置选项(可选)
附加的头参数控制了诸如 CC, BCC, Reply-To 之类的邮件功能,或者其它遵循 SMTP 协议的功能.在这个例子中,我只使用 From 和 Reply-To 信息头.
如果你想给我发邮件但你使用的是一个非 Windows 系统, 程序代码就应该如下:
<?
$to = "julie@thickbook.com";
$subject = "ZDNet Developer article";
$msg = "I completely understand SMTP servers now!";
$headers = "From: me@mycompany.com\nReply-To: someoneelse@mycompany.com";
$config = "-fwebmaster@mycompany.com";
mail("$to", "$subject", "$msg", "$headers", "$config");
echo "finished!";
?>
如果你使用的是一个基于 Windows 的 SMTP 服务,那么你有可能不需要使用第五个参数,而且在附加的头信息参数中(也就是第四个参数),你需要将它们分开写--使用\r\n 而不是\n.所以,同样的一个邮件通过基于 Windows 的 SMTP 服务发送的代码如下:
<?
$to = "julie@thickbook.com";
$subject = "ZDNet Developer article";
$msg = "I completely understand SMTP servers now!";
$headers = "From: me@mycompany.com\r\nReply-To: someoneelse@mycompany.com";
mail("$to", "$subject", "$msg", "$headers");
echo "finished!";
?>
脚本中的 echo 语句使你的 Web 浏览器在脚本运行完成的时候向你显示一条信息.如果不写 echo 语句,你就会得到一个"空文件"的对话框,因为没有任何输出能够发送到浏览器端.
只要能够连接到指定的 SMTP 服务器 mail()函数就会返回真值.但是这并不意味着邮件成功的到达了接收方那里.mail()函数不会等待或报告 SMTP 服务器发来的成功/错误代码.
mail()函数有可能返回假值,然后给你警告"无法连接,在第 x 行"或是"未知的错误,在第 x 行."如果这两条信息中的任何一条出现了,你就应该检查 php.ini 中的 SMTP 值.引起这些消息有两种可能:SMTP 服务器瘫痪了,或者 PHP 无法连接到它.无论是这两种情况中的哪一种,你的邮件都无法被发送出去.
这个脚本对这些参数使用硬编码的值.使用一个简单的 HTML 表单,你就可以在这些参数中插入一些值并拥有一个良好的反馈表单.
一旦你知道了如何给一个人发送邮件,你可能按奈不住要把同一个邮件发送给许多接收者--就象新闻信件一样.所有这些牵涉到一个漂亮轻巧的循环来遍历一个接收者的列表并将邮件发送给他们.mail 函数的形式还是相同的: