运行 CRON 时,'require' 静默失败
Posted
技术标签:
【中文标题】运行 CRON 时,\'require\' 静默失败【英文标题】:When running CRON, 'require' fails silently运行 CRON 时,'require' 静默失败 【发布时间】:2017-03-26 04:20:22 【问题描述】:我有一个从浏览器运行的备份脚本没有问题。它从数据库中提取数据并将其写入一个小于 2MB 的 ZIP 文件。
它大部分从服务器运行,但在遇到特定行时会失败(静默):
require ('/absolute-path/filename'); // pseudo filespec
这是几个这样的陈述之一。这些是库文件,除了“将东西放入内存”之外什么都不做。 我已经完全消除了路径问题的任何可能性。我正在使用条件is_readable()
测试文件,输出它,然后给自己发送电子邮件。
$fs = '/absolute-path/filename'; // pseudo filespec
if (is_readable ($fs) )
mail('myaddress','cron','before require'); // this works reliably
require ($fs); // can be an empty file ie. <?php ?>
mail('myaddress','cron','after require'); // this never works.
当我注释掉 require($fs)
时,脚本会继续(大部分情况见下文)。
我检查了行尾(不可见的字符)。不是在每个include
-ed 文件上,但肯定正在运行的文件具有换行符 (NL) 结尾(Linux 风格),而不是换行符 + 回车符 (NL CR)(Windows 风格)。
我尝试要求一个空文件(只是<?php ?>
)来查看脚本是否会超过那个点。它没有。
我已经尝试调用mail();
从包含的脚本。我收到邮件。再说一次,我知道这条路是对的。它正在执行,但它永远不会返回,而且我没有收到任何错误,至少在 PHP 日志中没有。 CRON 作业终止...
这是一个新服务器。我刚刚将应用程序从 PHP 5.3.10 迁移到 PHP7。其他一切都有效。
我不认为我的内存不足。在脚本的这一点上,我什至还没有从数据库中获取数据,但这似乎是某种累积错误,因为当我注释掉有问题的行时,错误会转移到另一个同样令人费解的沉默在代码中进一步失败。
我还应该查看其他有用的测试、日志或环境条件吗?有什么可以问网络主机的吗?
【问题讨论】:
【参考方案1】:这通常意味着在包含的文件中触发了一些致命错误。如果您没有打开所有错误,PHP 可能会在包含具有某些致命错误的文件时静默失败。
PHP 7 会在 PHP 5.3 没有的某些事情上抛出致命错误,例如Division by Zero。
如果您无权访问服务器配置以打开所有错误,则调用未定义的函数将静默失败。您可以尝试通过放置
die('test');
__halt_compiler();
在一行的开头,从顶部开始,在第一个 <?php
标记之后的行上,看看它是否加载。如果它确实缓慢地逐行替换(尽管不要削减控制结构!)并在每次之后重新测试,当它死亡时,你知道错误就在上面的那一行。
【讨论】:
【参考方案2】:我相信问题可能是 PHP 7 的错误。该代码仅在被 CRON 调用时中断,并且“fix”是删除结束 PHP 标记 ?>。虽然很难相信这可能是一个问题,但我做了很多单元测试,删除了之前的代码等。我正在运行 PHP 7.0.33。其他十几个(备份)脚本在由 CRON 运行时都没有损坏。
【讨论】:
【参考方案3】:作为 nzn indicated,这很可能是由包含文件触发的错误引起的。从外面很难诊断。一个可能的情况是该文件中的相对 include
/require
。一种验证方法是从不同位置在控制台上运行脚本。 f 可能是在启动 PHP 之前从 cron 调用 cd
,或者在执行进一步包含之前在主文件中执行 chdir(__DIR__)
。
【讨论】:
这是有道理的,但正如我所说,我做了很多单元测试。我一直隔离代码,直到我尽可能确信唯一的变量是删除 PHP 关闭标记?>以上是关于运行 CRON 时,'require' 静默失败的主要内容,如果未能解决你的问题,请参考以下文章