PHP邮件()函数返回false,但没有错误

8
我正在使用php的mail()函数来简单地将联系表格的内容通过E-Mail发送给相应的人员。奇怪的是,这个表格过去总是可以处理E-Mails,但有一天突然就停止了,现在函数返回false,但没有任何错误。

该网站是托管在共享主机上。当询问他们时,他们建议我使用smtp relay xx.xxx.x.xxx。

请纠正我,但是mail()函数没有提供相关支持,对吗?肯定是由HOST机器正确配置它的继电器?

我的问题是:这似乎是主机配置错误,还是我的代码?下面是我使用的邮件代码示例:

$to = "xxx@xxx.co.za"; //to who?
$subject = "Website Contact: $mysubject";
$headers .= "MIME-Version: 1.0\r\n";
$headers .= "From: $fname<$email1>\r\n";
$headers .= "Reply-To: $email1\r\n";
$headers .= "Return-Path:$email1\r\n";
$headers .= "Content-Type: text/html; charset=UTF-8\r\n";
$headers .= "Content-Transfer-Encoding: quoted-printable\r\n";
$msg2 = nl2br($msg);

$send = mail($to, $subject, $msg2, $headers); //process mail

if(!$send):
  //error stuff here
endif;

非常感谢,Simon。

@eisberg - 我使用自定义错误处理程序,代码如下:

//error handler function
function customError($errno, $errstr){
$err = "\n".date('Y-m-d H:m:s')." Error: [$errno] $errstr";
$fh = fopen("errlog.txt", 'a+');
fwrite($fh, $err);
fclose($fh);
}
set_error_handler("customError", E_ALL);

这是否意味着我需要将 set_error_handler("customError", E_ALL); 更改为 set_error_handler("customError", -1);

在你的代码前尝试使用 **error_reporting(-1);**。希望您能得到一个有用的消息。 来源:http://php.net/manual/en/function.error-reporting.php - eisberg
@eisberg - 我有一个自定义错误函数,将所有错误(E_ALL)记录到文件中,但仍然没有任何反应!它可以捕捉到最微小的错误,但与mail()相关的错误仍然没有被捕捉到。 - SimonDowdles
在所有的PHP版本中,E_ALL并不等于-1 :-) - eisberg
@eisberg - 请看我在上面关于错误处理的问题的回答,我需要格式化代码,因此将其添加到了问题中。 - SimonDowdles
我只是想说,使用“-1”将使您控制每个PHP版本中的每个错误。如果您在“-1”上没有收到错误,则很有可能您的配置存在问题。 - eisberg
7个回答

21

mail()函数返回false,但没有错误提示

欢迎使用PHP!

这似乎是主机配置的错误还是我的代码的问题?

谁知道呢?当mail()出现问题时,你无法从中获得有用的信息,因为它是一个黑盒子。

当我问到这个问题时,他们建议我使用smtp中继...

确实,你可能应该这样做。好好看看SwiftMailer,这是一个优秀、全面、现代化的PHP邮件库,可以直接与SMTP服务器通信。它擅长构建MIME消息,就像你似乎已经费力地准备好了那个消息一样。

其他流行的选项包括PEAR的MailZend Framework的Zend_Mail以及经典之作PHPMailer


1
推荐SwiftMailer,毫无疑问是最完整的PHP邮件库,并且正在积极开发中! - ChrisR
黑盒子的黑暗,哈哈。 - Adam Arold
1
我决定使用SwiftMailer,看了一下库和文档,它的使用方法就像php的mail()函数一样简单易懂! - SimonDowdles

7

看起来你的主机禁用了mail(),你应该考虑使用SMTP发送邮件,一个好的PHP邮件类,比如SwiftMailer,将允许你轻松地通过SMTP发送邮件。


感谢您提供的有用资源。这似乎是一个更好的方法。至少我可以依赖客户的SMTP帐户详细信息,而不是依赖于一个非常有问题的共享服务器。再次感谢。 - SimonDowdles

2
你应该查看邮件日志,它们保存着答案。不过你可能需要与托管公司联系以获取这些日志。

他们说“让我们甚至不要去那里”,这意味着他们可能在出售位于世界另一端的服务器上的托管空间,实际上他们并不知道自己在做什么。 邮件SMTP方法会是一个好选择。 - SimonDowdles
在这种情况下,SMTP就可以了 :) - vbence
1
在我的情况下,我在文件\mail\dovecot.index.cache中发现了错误“邮件发送失败-没有收件人地址”(地址来自数据库,但为空字符串)。 - Atara

1

很可能是主机配置的问题。我认为(但可能错了),mail()使用服务器邮件命令。因此,如果您在服务器上没有安装sendmail/postfix/ssmtp或其他MTA,则无法正常工作。
如果他们告诉您直接连接SMTP服务器,则应该使用另一个实现SMTP协议和Mail类来构建邮件并直接通过SMTP发送的库(在PEAR或Zend Framework PHP类中可以找到)


1
我遇到过类似的问题,我的网站是由共享托管服务提供的。我通过修复标题来解决了这个问题。问题是: $headers .= "From: $fname\r\n";
你在发件人字段中使用了用户电子邮件。我的托管只接受此字段中带有我的域名的电子邮件。因此,我将其替换为以下内容:
$headers = "From: webmaster@yourdomain.com" ."\r\n" ;

它解决了问题!在此之后,PHP mail()正常运行。


1

检查Web是否允许发送邮件,可以在终端中输入getsebool httpd_can_sendmail进行查询。如果输出为

httpd_can_sendmail --> off

通过发出setsebool httpd_can_sendmail 1命令,为https发送邮件授权。您必须具有根权限才能发出这些命令。


0

经过数月的苦思冥想,我最近终于弄清楚了这个问题。

Php mail() 函数每行限制为 70 个字符。在消息周围使用 wordwrap() 函数,可以防止它超出行并且每次都能正常工作(或者至少不会因为这个问题而失败)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接