2024年PHP日本大会

邮件函数

目录

添加注释

用户贡献的注释 6条注释

23
weethet dot nl 的 webmaster
17年前
如前所述,对于Windows用户,有一个伪造的sendmail选项。以下是更详细的操作说明:

如果您正在使用运行Windows和某种WAMP组合(XXAMP、WAMP Server等)的测试服务器,您会注意到PHP sendmail命令(mail())不起作用。Windows根本不提供sendmail语句……

不过,有一个简单的技巧可以解决这个问题:

1) 从http://glob.com.au/sendmail/下载(或使用附件文件)sendmail.zip

2) 将其解压缩到c盘上的某个文件夹中(最好使用简单的路径,例如c:\wamp\sendmail——长文件名可能会导致问题)

3) 编辑您的PHP.INI文件(注意:WAMP用户应从WAMP菜单访问其php.ini文件)。转到[mail function]部分并进行如下修改

[mail function]
; 仅适用于Win32。
;SMTP =

; 仅适用于Win32。
;sendmail_from =

; 仅适用于Unix。您也可以提供参数(默认值:“sendmail -t -i”)。
sendmail_path = "C:\wamp\sendmail\sendmail.exe -t"

; 强制添加指定参数作为额外参数传递
; 给sendmail二进制文件。即使在安全模式下,这些参数也将始终替换
; mail()的第五个参数的值。
;mail.force_extra_paramaters =

.. 并保存更改。

4) 打开sendmail.ini并修改设置:

[sendmail]

; 您必须将mail.mydomain.com更改为您的SMTP服务器,
; 或更改为IIS的“pickup”目录。(通常是C:\Inetpub\mailroot\Pickup)
; 通过IIS的pickup目录传送的电子邮件使sendmail
; 运行更快,但您不会收到错误消息返回到调用
; 应用程序。

smtp_server=mail.yourdomain.com

; SMTP端口(通常为25)

smtp_port=25

; 此服务器的默认域将从注册表中读取
; 当未提供电子邮件地址时,这将附加到电子邮件地址
; 如果要覆盖注册表中的值,请取消注释并修改

default_domain=yourdomain.com

; 将SMTP错误记录到error.log(默认为与sendmail.exe相同的目录)
; 取消注释以启用日志记录
; error_logfile=sendmail_error.log

; 创建调试日志为debug.log(默认为与sendmail.exe相同的目录)
; 取消注释以启用调试
; debug_logfile=sendmail_debug.log

; 如果您的SMTP服务器需要身份验证,请修改以下两行

;auth_username=
;auth_password=

; 如果您的SMTP服务器在SMTP身份验证之前使用POP3,请修改
; 以下三行

pop3_server=mail.yourdomain.com
[email protected]
pop3_password=mysecretpassword

; 要强制发件人始终为以下电子邮件地址,请取消注释并
; 使用有效的电子邮件地址填充。这只会影响“MAIL FROM”
; 命令,它不会修改邮件内容的“From: ”标题

[email protected]

; sendmail将在ehlo/helo中使用您的主机名和您的default_domain
; SMTP问候。如果需要,您可以手动设置ehlo/helo名称

hostname=

首次尝试时建议使用可选的错误和调试日志记录,以便在出现问题时知道问题所在。
Force_sender也是可选的,但建议避免服务器端混淆。
显然,mail.yourdomain.com、[email protected]和mysecretpassword应该是您SMTP服务器的相关信息。
现在重新启动WAMP服务(主要是Apache,以便PHP重新读取其配置)。

现在您可以像Unix用户一样使用PHP mail()语句了……
11
dicoe dot com 的 jcwebb
18年前
损坏的附件???
我花了几个小时处理损坏的附件(所有类型的文件)——答案是:$msg.=$file \r\n \r\n 后面需要一个空行[令人难以置信,但却是事实]。
这是一些用于发送附件的有用代码,并根据用户的电子邮件阅读器显示HTML或文本。

我使用许多不同的系统,所以……

<?php # 操作系统是Windows、Mac还是Linux
if (strtoupper(substr(PHP_OS,0,3)=='WIN')) {
$eol="\r\n";
} elseif (
strtoupper(substr(PHP_OS,0,3)=='MAC')) {
$eol="\r";
} else {
$eol="\n";
}
?>

<?php
# 附件文件
$f_name="../../letters/".$letter; // 使用相对路径,否则会遇到大麻烦。$letter 是我的附件文件。
$handle=fopen($f_name, 'rb');
$f_contents=fread($handle, filesize($f_name));
$f_contents=chunk_split(base64_encode($f_contents)); // 使用 base64_encode() 编码数据以便传输
$f_type=filetype($f_name);
fclose($handle);
# 收件人邮箱地址
$emailaddress="[email protected]";
# 邮件主题
$emailsubject="这是一封包含PDF文件的邮件".date("Y/m/d H:i:s");
# 邮件正文
ob_start();
require(
"emailbody.php"); // 我创建了一个简单美观的页面用于显示在邮件中
$body=ob_get_contents(); ob_end_clean();

# 通用邮件头
$headers .= 'From: Jonny <[email protected]>'.$eol;
$headers .= 'Reply-To: Jonny <[email protected]>'.$eol;
$headers .= 'Return-Path: Jonny <[email protected]>'.$eol; // 这两行设置回复地址
$headers .= "Message-ID:<".$now." TheSystem@".$_SERVER['SERVER_NAME'].">".$eol;
$headers .= "X-Mailer: PHP v".phpversion().$eol; // 这两行有助于避免垃圾邮件过滤器
# 用于标记分割和多类型邮件头的边界
$mime_boundary=md5(time());
$headers .= 'MIME-Version: 1.0'.$eol;
$headers .= "Content-Type: multipart/related; boundary=\"".$mime_boundary."\"".$eol;
$msg = "";

# 附件
$msg .= "--".$mime_boundary.$eol;
$msg .= "Content-Type: application/pdf; name=\"".$letter."\"".$eol; // 有时我需要发送 MS Word 文档,请使用 'msword' 代替 'pdf'
$msg .= "Content-Transfer-Encoding: base64".$eol;
$msg .= "Content-Disposition: attachment; filename=\"".$letter."\"".$eol.$eol; // !! 此行需要两个换行符 !! 非常重要 !!
$msg .= $f_contents.$eol.$eol;
# 文本或 HTML 设置
$msg .= "Content-Type: multipart/alternative".$eol;

# 文本版本
$msg .= "--".$mime_boundary.$eol;
$msg .= "Content-Type: text/plain; charset=iso-8859-1".$eol;
$msg .= "Content-Transfer-Encoding: 8bit".$eol;
$msg .= "这是一封 MIME 格式的多部分邮件。".$eol;
$msg .= "如果您正在阅读此邮件,请更新您的邮件阅读软件。".$eol;
$msg .= "+ + 来自天才 Jon 的纯文本邮件 + +".$eol.$eol;

# HTML 版本
$msg .= "--".$mime_boundary.$eol;
$msg .= "Content-Type: text/html; charset=iso-8859-1".$eol;
$msg .= "Content-Transfer-Encoding: 8bit".$eol;
$msg .= $body.$eol.$eol;

# 完成
$msg .= "--".$mime_boundary."--".$eol.$eol; // 使用两个换行符结尾以提高安全性,参见注入攻击。

# 发送邮件
ini_set(sendmail_from,'[email protected]'); // INI 行用于强制使用发件人地址!
mail($emailaddress, $emailsubject, $msg, $headers);
ini_restore(sendmail_from);
?>


希望这有帮助。
Jon Webb [马德里&伦敦]

[编辑 thiago 注:代码已由 o.straesser AT gmx DOT de 修复]
-1
anselm at netuxo dot co dot uk
18年前
如果您不想或无法为您的服务器配置 sendmail,一个不错的替代方案是 esmtp —— 它是一个配置简单的 SMTP 邮件发送器,可以用作 sendmail 的替代品: http://esmtp.sourceforge.net/
-1
aweather88 at gmail dot com
18年前
我花了几个小时搜索网络,试图找出为什么每次在我的服务器(Win2K3,IIS 6.0,PHP 4.4.1)上使用 mail() 函数时都会收到“警告:mail(): SMTP 服务器响应:501 5.5.4 无效地址”错误。我知道根据其他非 IIS 6.0 配置,SMTP 的所有设置都是正确的。

事实证明,IIS 6.0 SMTP 服务不喜欢 mail 头中“From”字段的格式。例如
<?PHP
// 此行无法正确发送邮件
$headers .= "From: \"".$fromname."\" <".$fromaddress.">\n";
?>
但是这个可以工作
<?PHP
// 此行可以正确发送邮件
$headers .= "From: \"".$fromaddress."\"\n";
?>

修复方法在 Microsoft 文章 ID 291828 中( http://support.microsoft.com/?id=291828 )。即使“错误”解决方法是针对 Exchange 2003 上与 UNIX 服务器通信的 IIS 6.0,但这解决了问题。只需跳到 Exchange 2003 的最后一部分,并按照说明使用 IIS 6 资源工具包中的 MetaBase Explorer 修改 IIS 6 MetaBase。
-2
lawcd at ntlworld dot com
18年前
对于使用exim的用户,如果它在使用-i选项时无法发送邮件,并且您无法轻松更改此设置,您可能需要查看imap_mail()函数,它的功能几乎完全相同,并且不使用exim,大多数虚拟主机都提供此函数。如果您使用自己的服务器,则需要使用imap库编译php。

参见 https://php.net/manual/en/function.imap-mail.php
-3
josh at sdfahrenheit dot com
20年前
对于任何遇到附件文件乱码问题的用户,请确保您的php.ini文件中magic_quotes_runtime设置为Off - 它会向您的附件数据添加奇怪的转义字符,从而导致附件乱码。

这让我非常头疼。
To Top