【问题标题】:PHP Command-line script exits on falsePHP 命令行脚本以 false 退出
【发布时间】:2023-04-10 04:40:01
【问题描述】:

我正在 PHP 命令行中运行一个循环脚本,它使用 PHPMailer 向客户发送电子邮件。我收到的问题是当 PHPMailer 返回 false 时命令行脚本退出。

这是脚本伪代码:

while(the loop is valid){
    if(mail ID exists){
        set_time_limit(30);
        ..compose mail..
        if($mail->Send()){
            ..Mark as success in database..
            usleep(10000);
        } else {
            ..Mark as failure in database..
            usleep(10000);
        }
    }
    ..continue loop..
}

如果 $mail->Send() 返回 false,则脚本停止并退出。这是命令行中 PHP 的预期行为吗?如果是这样的话,有没有办法告诉 PHP 在收到 false 时不要停止?

感谢您的帮助。

【问题讨论】:

  • 你确定 send() 是退出的原因吗?也可能是脚本超时或 while 循环条件错误。
  • 我的测试表明脚本只有在遇到循环的失败部分时才会退出。
  • 您是否使用 error_reporting=E_ALL 和 display_errors=true 运行脚本(或密切关注 error.log)?
  • 是的,我正在跟踪 error.log,但那里没有任何重要信息。所以我的问题是命令行脚本是否会在遇到错误时退出。这有点奇怪,因为我们几乎在所有地方都使用布尔结果,对吧?
  • 不,php-cli 不会因为某些任意函数/方法返回 false 而退出。

标签: php command-line phpmailer


【解决方案1】:

我猜$mail->Send() 函数(或完全是其他的东西)正在抛出一个错误,导致脚本的执行停止。

我认为数据库中的值也没有更新?如果是这样,情况就会如此。运行带有错误报告的脚本以确定这一点。

error_reporting(E_ALL);
ini_set('display_errors', true);

【讨论】:

  • 是的!数据库中的值未更新。我在打开错误报告的情况下运行,但没有提示返回。
  • PHPMailer 的手册说:Send() 创建消息并分配 Mailer。如果消息未成功发送,则返回 false。使用 ErrorInfo 变量查看错误的描述。成功返回真,失败返回假。
  • PHPMailer 可能会尝试使用 @ 抑制器来消除故障,但如果这是一个致命错误,它无论如何都会退出。
  • 我使用 PHP 5.3 并在论坛中阅读:PHPMailer makes use of features that are deprecated in PHP version 5.3. This results in E_DEPRECATED messages (a new type of warning) if those are enabled in the php.ini configuration file. 这会触发退出吗?不推荐使用的消息是否会停止脚本?感谢您的帮助。
  • 正如@VolkerK 所说,E_DEPRECATED 消息是警告,不会停止脚本的执行。其他地方会出现错误,甚至可能在 PHPMailer 中都没有,即停止执行。
【解决方案2】:

最有可能的错误处理例程(在 else 分支中)调用 exit 或导致导致 php 退出的致命错误。
添加两行调试输出,检查脚本是否进入和离开else分支(成功)。

while(the loop is valid){
     [...]
        } else {
          error_log('Debug: Send() failed. Start error handling');
          ..Mark as failure in database..
          usleep(10000);
          error_log('Debug: Send() failed. End error handling');
        }
     [...]

【讨论】:

  • 不。该脚本甚至不进入故障例程。它只是退出。我尝试从浏览器运行相同的脚本,它成功了!如果为 false,它会处理故障例程并继续循环。我在浏览器中调用页面的问题是 IIS 在指定的超时后停止任何快速 CGI,无论我们在 php.ini 中指定什么。因此,不可能发送完整的电子邮件列表。
  • 你可以使用像 xdebug 和 netbeans 这样的调试器作为前端来单步调试代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-03-04
  • 2021-07-10
  • 2017-10-31
  • 1970-01-01
  • 1970-01-01
  • 2013-03-01
  • 2016-10-06
相关资源
最近更新 更多