当自动加载的文件有 "compile-time" 错误时,如何使 PHP 自动加载器抛出错误(没关系,它已经这样做了)
How to make a PHP autoloader throw an error when the autoloaded file has "compile-time" errors (never mind, it already does)
编辑:原来我在这个问题中所说的是完全错误的。该代码实际上在自动加载之前明确关闭了错误报告,在我没有找到它的地方。
所以这个问题基本没用。接受的答案是正确的。
在我当前的配置中,每当某些 PHP 文件出现语法错误或调用不存在的函数等致命错误时,我通常会收到如下错误消息:
Parse error: syntax error, unexpected <whatever> in /path/to/file.php on line XXX
或
Fatal error: Call to undefined function whatever() in /path/to/file.php on line YYY
或类似的输出。
但是,我使用的是使用第三方自动加载器的第三方库。每当在任何自动加载的 类 中出现致命错误(包括解析错误或调用不存在的函数 - 实际上不完全确定后者但肯定是解析错误情况),我只会得到一个 空白page,不仅如此:Apache 的 error_log 文件甚至没有记录任何错误,而通常 PHP 致命错误会被记录。所以调试变得不可能。
我怎么强调都不为过:这 仅当致命错误是 在某些自动加载的文件 中时才会发生 。在所有其他情况下(当然包括通过 require()
、include()
等包含的文件中的错误),相同的错误确实会出现在输出和 error_log.[=17 中=]
autoloader的代码我没有写,但基本上是这样的:
// no idea why this line, but I don't think it's relevant:
ini_set('unserialize_callback_func', 'spl_autoload_call');
spl_autoload_register(array('My_Autoloader', 'autoload'), true);
class My_Autoloader {
static function autoload($classname) {
$filename = //.... computes $filename from $classname
require_once($filename);
}
}
如果错误不在自动加载的文件中,必须有一种方法可以让自动加载器以与抛出(和处理)相同的方式抛出错误,对吗?
我如何获得它?
仅在命令行检查语法错误
与 php -l somefile.php
来自 PHP
shell_exec('php -l /fullpath/to/somefile.php')
但您必须分析响应字符串是否有错误。
正常反应No syntax errors detected in somefile.php
在 PHP <= 5.0.4 中有 php.net/manual/en/function.php-check-syntax.php
这是一个有效的致命错误捕捉:
register_shutdown_function(function(){
$err=error_get_last();
if($err['type']===1){
/*you got an fatal error do something, write it to an file*/
#file_put_contents(var_export($err,true),'myfatalerror.log');
}
});
希望对您有所帮助:)
使用 php 例外,这样您就可以将文件调用到
function inverse($x) {
if (!$x) {
throw new Exception('Division par zéro.');
}
return 1/$x;
}
try {
echo inverse(5) . "\n";
echo inverse(0) . "\n";
} catch (Exception $e) {
echo 'Exception reçue : ', $e->getMessage(), "\n";
}
代码按照您的建议运行的唯一方法是第三方代码覆盖错误报告。 (OP 编辑:是的,事实证明确实如此。) 这通常被认为是生产系统的良好做法,但它应该是 记录错误.
您的第三方代码导致此类错误让我停下来想知道它的质量,但我们暂时忽略它。
PHP 的内置机制将处理报告(到浏览器)和日志记录(到文件)。非致命错误可以在调用 set_error_handler() 后由您自己的代码管理,但是致命错误不会通过此路由传递。可以在您自己的代码中捕获和处理致命错误 using register_shutdown_function()。但首先要检查您的日志文件。
如果如您所说,错误记录和错误报告都被禁用,请停止使用此第三方代码 - 它有毒。
编辑:原来我在这个问题中所说的是完全错误的。该代码实际上在自动加载之前明确关闭了错误报告,在我没有找到它的地方。
所以这个问题基本没用。接受的答案是正确的。
在我当前的配置中,每当某些 PHP 文件出现语法错误或调用不存在的函数等致命错误时,我通常会收到如下错误消息:
Parse error: syntax error, unexpected <whatever> in /path/to/file.php on line XXX
或
Fatal error: Call to undefined function whatever() in /path/to/file.php on line YYY
或类似的输出。
但是,我使用的是使用第三方自动加载器的第三方库。每当在任何自动加载的 类 中出现致命错误(包括解析错误或调用不存在的函数 - 实际上不完全确定后者但肯定是解析错误情况),我只会得到一个 空白page,不仅如此:Apache 的 error_log 文件甚至没有记录任何错误,而通常 PHP 致命错误会被记录。所以调试变得不可能。
我怎么强调都不为过:这 仅当致命错误是 在某些自动加载的文件 中时才会发生 。在所有其他情况下(当然包括通过 require()
、include()
等包含的文件中的错误),相同的错误确实会出现在输出和 error_log.[=17 中=]
autoloader的代码我没有写,但基本上是这样的:
// no idea why this line, but I don't think it's relevant:
ini_set('unserialize_callback_func', 'spl_autoload_call');
spl_autoload_register(array('My_Autoloader', 'autoload'), true);
class My_Autoloader {
static function autoload($classname) {
$filename = //.... computes $filename from $classname
require_once($filename);
}
}
如果错误不在自动加载的文件中,必须有一种方法可以让自动加载器以与抛出(和处理)相同的方式抛出错误,对吗?
我如何获得它?
仅在命令行检查语法错误
与 php -l somefile.php
来自 PHP
shell_exec('php -l /fullpath/to/somefile.php')
但您必须分析响应字符串是否有错误。
正常反应No syntax errors detected in somefile.php
在 PHP <= 5.0.4 中有 php.net/manual/en/function.php-check-syntax.php
这是一个有效的致命错误捕捉:
register_shutdown_function(function(){
$err=error_get_last();
if($err['type']===1){
/*you got an fatal error do something, write it to an file*/
#file_put_contents(var_export($err,true),'myfatalerror.log');
}
});
希望对您有所帮助:)
使用 php 例外,这样您就可以将文件调用到
function inverse($x) {
if (!$x) {
throw new Exception('Division par zéro.');
}
return 1/$x;
}
try {
echo inverse(5) . "\n";
echo inverse(0) . "\n";
} catch (Exception $e) {
echo 'Exception reçue : ', $e->getMessage(), "\n";
}
代码按照您的建议运行的唯一方法是第三方代码覆盖错误报告。 (OP 编辑:是的,事实证明确实如此。) 这通常被认为是生产系统的良好做法,但它应该是 记录错误.
您的第三方代码导致此类错误让我停下来想知道它的质量,但我们暂时忽略它。
PHP 的内置机制将处理报告(到浏览器)和日志记录(到文件)。非致命错误可以在调用 set_error_handler() 后由您自己的代码管理,但是致命错误不会通过此路由传递。可以在您自己的代码中捕获和处理致命错误 using register_shutdown_function()。但首先要检查您的日志文件。
如果如您所说,错误记录和错误报告都被禁用,请停止使用此第三方代码 - 它有毒。