020-29133788
    资 讯
    您的位置:首页 >> 资 讯 >> 软件应用 >> 编程开发 >> 正文
    用php发送E-MAIL

    点击:   发布日期:2013-01-18

    本文来自 www.020fix.com

    用来传送 e-mail 的描述语言程式(Script)可说是网站上最常见的程式之一。虽然它很单纯,但是在某些时候,它却往往对程式设计师们造成极大的困扰。在 PHP 中有一个函式叫做 mail(),只要有收信者名称以及讯息内容,就可以拿来传送讯息。但是你还是需要针对 mail()做某些调整,才能让mail()为你完成你想做的事。

    首先,要让 mail()能够运作,你必须先有一个 SMTP 伺服器,好让你的 PHP 连上去。虽然这个伺服器在电子邮件程式中佔有极其重要的地位,大部分的人还是对它一知半解。在这篇教学指南里,我们会为你揭开 SMTP 的神秘面纱,并且同时解说关于使用 PHP 传送电子邮件的某些常见问题。其中精采的内容还包括了:如何以迴圈的程式叙述,读取电子邮件住址名单,同时针对其中的收件者一一传送邮件,包括纯文字格式以及 HTML 格式的邮件等等。

    了解你的 SMTP 伺服器
    SMTP 是 Simple Mail Transfer Protocol 的缩写,而 SMTP 伺服器则是透过执行该通讯协定而传送电子邮件的电脑。基本上,执行通讯协定指的是:如果你使用的是非 Windows 作业平台,执行的是 Sendmail 或 Qmail这类的电子邮件软体。而如果这部机器使用的是 Windows 作业平台,那么 SMTP 服务已经包括在 Windows NT Service Pack 中,或者内建在 Windows 2000 里面,而且,这项服务通常就是正在执行中的电子邮件服务。

    这并不是说,SMTP 软体就只有那几种,只是它们是最被广为使用的。如果你的网站是 ISP 的虚拟主机(Vitual hosting)套件的一部分,SMTP 服务应该就已经安装在主机上面了。如果你是位系统管理者,负责管理某台放在 ISP 或公司机房的专属主机(Dedicated machine)的话,那么你很可能会需要在那部机器安装某种 SMTP daemon,特别用来处理网站伺服器的电子邮件传递。

    然而,如果你只是一个单独的使用者,只有一套网站伺服器开发平台在你的个人电脑上面,你可能没有在你的机器上安装 SMTP。这里有个非常简单但是精确的准则: 如果你是个 Windows 使用者,而你从来未曾听过 SMTP 伺服器,那么你就没有安装 SMTP。若果真如此,你有两个选择:安装, 设定,并维护一个 SMTP 伺服器(如果你不知道那是什么,我并不鼓励你这样做)或者直接使用已经在你手边的东西。

    「我没有安装,怎么会说在我手边呢?」你可能会这样问。嗯,如果你的电脑是透过拨接上网的(或 DSL 或者 cable),你可以直接使用你的 ISP 的外寄邮件伺服器(outgoing mail server)。例如,如果你的开发平台是 Windows 98,以及一台 56Kbps 的数据机,并透过 EarthLink 上网, 那么你可以用 mail.earthlink.net 当作你的 SMTP 伺服器。不管你使用的是哪一种电子邮件客户端软体 (Eudora,Outlook,Netscape Mail 等等),你的外寄邮件伺服器都可以在 PHP 程式码中,指定为 SMTP 伺服器。要诀在于,你要告知 PHP 这件事情。

    在 PHP 的主要设定档,php.ini 中,有一些 directive 是你必须去设定,这样一来 mail() 函式才能够使用。在更改那些设定以前,你先看看它们是什么。使用 phpinfo() 函式,可以显示你的系统目前的设定, 做法是,建一个档案,包括下列文字:

    <? phpinfo() ?>

    将档案存起来,放在你的网站伺服器的文件根目录中。然后用你的浏览器去看这个档案。你应该会看到一个编排良好的现有设定列表。在这里,你要注意的设定选项为:

    SMTP
    sendmail_from
    sendmail_path
    如果你用的不是 Windows,你只须担心 sendmail_path directive。如果你用的是 Windows,你就要注意先前两个 directive。

    如果你用的是 Linux 或其他 Unix 变种系统,sendmail_path 应该差不多是这样子设定的:

    sendmail_path = /usr/sbin/sendmail

    或者,如果你用的是 Qmail:

    sendmail_path = /var/qmail/bin/sendmail

    在这个 directive 里面,你也可以设定某些 flag 来指明你的 queuing 做法,或者是用来明确的写出你的 Return-Path 标题,就像这样:

    sendmail_path = /usr/sbin/sendmail -t -fyou@yourdomain.com

    如果你不是 Windows 使用者,你所需要做的就那么多了。如果你使用的是 Windows,你还有一些事情要处理。你必须看看 SMTP 以及 sendmail_from 的值。不要被 sendmail_from 的 directive 名字中的 sendmail 给搞煳涂了。虽然你在 Windows 上面并没有用一个叫做 Sendmail 的程式,这个只是 directive 的名字而已。不要紧张。

    在phpinfo() 所显示的结果中,注意一下 SMTP 以及 sendmail_from 原先的设定值 -- 它们应该是空白的,或者只是虚值(dummy)。你必须将它们改为对你系统有意义的值。

    如果你真的在你的机器上安装并启动 SMTP 伺服器,你的 php.ini 应该要有这样的设定:

    SMTP = localhost

    然而,如果你要用你的 ISP 的外寄邮件伺服器(在这里,我们用 EarthLink 做例子),那么你的 php.ini 就要有这样的设定:

    SMTP = mail.earthlink.net

    你也可以直接用 IP address 而非名字,因为电脑并不会区别这两者的差异。

    第二个我们要设定的 directive 是 sendmail_from,这个是设定在 From 标题(header)里面所使用的 e-mail 位址。这个设定值可以用 mail 程式更改,但是通常这里的设定值都被拿来当作内定值。以下是,如果你的电子邮件地址是 youraddress@yourdomain.com, 所应该做的设定值。

    sendmail_from = youraddress@yourdomain.com

    在更改以上设定值之后,重新启动你的网站伺服器,再用 phpinfo() 函式来确定这些设定已经被更改了。当你完成这些事情后, 你就已经准备好用 PHP 来传送 e-mail 了。


    传送一个简单的 e-mail
    mail() 函式相当简单:只有五个参数,而且其中两个是选择性的(optional)。这些参数是:
    收件者地址
    主旨
    讯息
    其他邮件标题(选择性)
    其他 SMTP 伺服器的设定选项(选择性)
    额外的邮件标题参数,是用来控制某些电子邮件功能,像是 CC,BCC,Reply-To fields,或其他 SMTP 通讯协定所规定的功能。 在这个例子里,我只用 From 以及 Reply-To 电子邮件标题。

    如果你要送 mail 给我,而你用的不是 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 叙述,是让你的网页浏览器在执行完这个程式后,回传给你一个讯息。如果没有这项叙述,你会收到一个「Document contains no data」对话方块,因为没有东西传送到你的网页浏览器上。

    mail() 函式只要连到指定的 SMTP 伺服器,就会回传 true。这并不意味着邮件已经成功抵达收件者了。mail() 函式并不会等 SMTP 伺服器告诉它传送成功或失败。

    mail() 函式会回传 false,并且送给你一个警告,像是「Couldn't connect in line x」 或者是「Unknown error in line x」。如果你没看到前面两个讯息,检查一下 php.ini 的 SMTP 设定值。有两种可能性会导致这个讯息的产生:SMTP 伺服器当掉了,或者是 PHP 没连到 SMTP 伺服器。当然,这两种情况下, 你的电子邮件都不会被传送出去。

    这个程式用的参数都是写死在程式中的。你可以透过一个简单的 HTML 表格,将这些值送出去,然后再回传给你一个回馈表格(feedback form)。

    以迴圈读取传送名单
    一旦你知道要怎样传送电子邮件给一个人,你或许会感到非常兴奋而且想传送同样的讯息给很多收件者 --就像电子报一样。你只要做一个简单的迴圈叙述, 一一阅读你名单上的名字,然后传送电子邮件给他们。

    mail 函式的格式是一样的:

    mail([recipient], [subject], [message], [any headers]);

    你必须将 [recipient] 换成迴圈中你的名单的下一个名字。假设你有一个 e-mail 地址的阵列:

    $addresses = array("me@mycompany.com", "you@yourcompany.com", "someone@otherplace.com");

    你只要以迴圈读取这个 array, 取得新的电子邮件地址,然后传送邮件。

    如果你的电子邮件地址名单是存在资料库里面,你还是可以用同样的方式:以迴圈一一读取它们。

    就是这么简单。显然的,同样的观念可以运用到你特定的资料库种类以及表格(table)架构, 虽然程式码必须做一点修改。

    这里还有一个小小的诀窍,在以迴圈叙述读取一串电子邮件名单的时候,似乎每一个人都忽略了它:如果你有多于五十个邮件地址,你的程式或许在还没完成读取名单的时候,就逾时(time out)了,因为 PHP 对每个程式的内建时间限制是三十秒。你可以修改这个时间限制, 但是要小心。试着将这个修改的效果限制在某些特定的程式中, 例如迴圈读取电子邮件名单并且传送邮件。否则的话,你可能会有一些伺服器程序 (server process) 一直在你的伺服器上,你的主机会几乎停滞,整个世界就会停止。

    要在程式里面设定时间限制,使用 set_time_limit() 函式。你可以指定这个限制,例如六十秒(set_time_limit(60)),或者你可以让它一直等下去,(set_time_limit(0))。

    将这个放在你的程式中,你传送电子邮件的迴圈叙述就会一直持续下去直到名单中所有的地址都传送出去为止。

    传递 HTML 格式的电子邮件
    传送 HTML 格式的 e-mail 是另一个看起来困难但是做起来简单的事情。一旦你知道怎么做,你或许会为了以前把它想得太困难而想打你自己一顿!

    我们需要对先前用过的基本电子邮件叙述程式做两个修改:

    你的邮件讯息应该是 HTML 格式的。
    你必须增加内容种类邮件标题(content-type header)。
    这样就可以了。使用者如果拥有可以读取 HTML 格式邮件的电子邮件客户端软体的话,他所看到的邮件讯息会是大型的粗体字形。如果你传送的 HTML 格式的电子邮件有影像的 tag 在里面,你必须记得在 src 属性中使用完整的 URL。例如:<img src="http://www.yourdomain.com/images/image.gif">。

    记得,不是所有人都可以读取 HTML 格式的电子邮件,如果使用的软体不能读取 HTML 格式的电子邮件,那么收件者就只能看到 HTML 程式码。这会让人有点受不了,所以小心使用这项功能。

    结论
    你可以用几乎你所能想像得到的所有各种不同的方式,使用 PHP 传送电子邮件。这篇文章只有接触到基本面而已:设定你的伺服器,并且传送一些简单的电子邮件。你也可以用 mail() 产生的电子邮件来传送附件,修改很多不同的邮件标题。大致上说来,你也可以用 PHP 做任何现实生活中, 电子邮件客户端软体或邮件名单程式可以做到的事情。