You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHPMailer在浏览器正常运行但Cron任务无法发送邮件问题求助

Cron执行PHPMailer脚本失败&无法写入文件:目录名称的隐性问题

问题场景

我有一个使用PHPMailer发送邮件的PHP脚本,通过浏览器访问时完全正常:邮件能成功发送,生成phpinfo信息文件的操作也能顺利完成;但当通过Cron任务执行时,不仅邮件发不出去,连简单的文件写入操作都无法完成。我已经把require语句的路径改成了绝对路径,且相关目录的权限设置完全一致,最终排查发现是目录名称导致的问题,想了解具体原因。

相关代码

邮件发送脚本

<?php 
/* Namespace alias. */ 
// Import PHPMailer classes into the global namespace 
// These must be at the top of your script, not inside a function 
use PHPMailer\PHPMailer\PHPMailer; 
use PHPMailer\PHPMailer\Exception; 
use PHPMailer\PHPMailer\SMTP; 

/* If you installed PHPMailer without Composer do this instead: */ 
require '/hermes/bosnaweb21a/b1837/ipw.whitmerd/public_html/test03/include/PHPMailer/PHPMailer.php'; 
require '/hermes/bosnaweb21a/b1837/ipw.whitmerd/public_html/test03/include/PHPMailer/Exception.php'; 
require '/hermes/bosnaweb21a/b1837/ipw.whitmerd/public_html/test03/include/PHPMailer/SMTP.php'; 

//SMTP needs accurate times, and the PHP time zone MUST be set 
date_default_timezone_set('America/New_York'); 

echo phpinfo(); 
echo __DIR__; 

// Email the results 
$mailSubject = "Email Subject"; 

// Create the body of the mail 
$mailBody = "Body of email"; 

/* Create a new PHPMailer object. Passing TRUE to the constructor enables exceptions. */ 
$mail = new PHPMailer(TRUE); 

// Configure the mail object for iPower email account 
$mail->IsSMTP(); 
$mail->SMTPDebug = 2; 
$mail->SMTPAuth = true; 
$mail->Host = "smtp.ipower.com"; 
$mail->Port = 25; 
$mail->SMTPSecure = 'tls'; 
$mail->isHtml(true); 
$mail->CharSet = 'UTF-8'; 
$mail->Encoding = 'base64'; 
$mail->Username = "validuser"; 
$mail->Password = "password"; 
$mail->setFrom('Example@gmail.com', 'Example Name'); 
$mail->Subject = $mailSubject; 
$mail->addAddress('Example@gmail.com', 'Example Name'); 
$mail->Body = $mailBody; 

$mailSendSuccess = $mail->send(); 
$mail = null; 

// Success or failure message 
if ($mailSendSuccess) { 
    echo "<br>Email was sent sucessfully."; 
} else { 
    echo "<br>There was a problem sending the email."; 
}

文件生成脚本

<?php 
$tempDir = '/hermes/bosnaweb21a/b1837/ipw.whitmerd/public_html/test03/misc/'; 
$tempFile = 'phpini_fromcron.html'; 

$fileContents = dirname(__DIR__); 
$fileContents .= '<br>'; 
$fileContents .= 'Test file contents.'; 

// ob_start(); 
// phpinfo(); 
// $phpini = ob_get_contents(); 
// ob_end_clean(); 
// $fileContents .= $phpini; 

$createFile = fopen($tempDir . $tempFile, 'w'); 
if (fwrite($createFile, $fileContents)) { 
    echo "File created."; 
} else { 
    echo "There were problems."; 
} 
fclose($createFile);

问题原因分析

这种情况几乎可以确定是Cron执行环境的文件系统大小写敏感性导致的!

大多数Linux服务器的文件系统是严格区分大小写的,但Web服务器(比如Apache、Nginx)通常会配置不区分大小写的URL解析(比如Apache的mod_speling模块会自动匹配大小写不同的路径)。这就导致了:

  • 浏览器访问时,哪怕你脚本里写的目录名大小写和实际服务器上的不一致,Web服务器也能自动找到正确的路径;
  • 但Cron是通过CLI(命令行界面)执行PHP脚本,完全遵循Linux文件系统的大小写规则,一旦脚本里的路径大小写和实际目录名不匹配,就会出现"找不到目录/文件"的错误——无法写入文件,也无法加载PHPMailer的依赖文件,最终导致邮件发送失败。

举个实际例子:如果服务器上的实际目录是Misc(首字母大写),但你脚本里写的是misc(全小写),浏览器访问时能正常工作,但CLI执行时就会认为/hermes/.../misc/不存在,直接触发fopen失败。

验证与解决方法

  1. 验证路径大小写:登录服务器,用ls -l /hermes/bosnaweb21a/b1837/ipw.whitmerd/public_html/test03/命令查看目录的实际大小写名称,和你脚本里的路径逐一对比。
  2. 修正路径大小写:把脚本中所有路径的大小写改成和服务器实际目录完全一致,确保CLI环境能正确定位到文件和目录。
  3. 额外排查技巧:
    • 在Cron命令中指定PHP的绝对路径,比如* * * * * /usr/bin/php /hermes/.../your_script.php(避免Cron环境找不到PHP执行文件);
    • 给Cron任务添加日志输出,方便排查错误:* * * * * /usr/bin/php /hermes/.../your_script.php >> /tmp/cron_script.log 2>&1;
    • 在脚本中加入echo get_current_user();,对比Web环境的执行用户,确保权限范围一致。

内容的提问来源于stack exchange,提问作者Bishop

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 21:27:38