Lan*_*nce 11 php apache logging
有没有办法通过增强的错误日志消息或输出变量确定运行时使用的CORE PHP DIRECTIVES值的值?这与每个错误的phpinfo()输出相同.
一个基本的例子是error_reporting变量.如果/etc/php.ini值设置为x,并且phpinfo()声明该php.ini文件实际上是ini变量的预期来源.但是如果用户在代码中对该变量实现运行时调整,我们是否能够在抛出错误时输出error_reporting变量.
例如当php.ini文件有E_ALL&〜E_STRICT但日志文件中报告了E_STRICT错误时,有一种方法可以增强输出到日志文件,显示所有系统变量的"堆栈跟踪"可能通过添加到httpd日志的错误ID来激活或至少修改它们的源,以及报告的每个错误的源,该错误ID对应于在错误发生时显示那些运行时设置的可选文件.
我确实认识到可以使用try/catch,但我不相信可以在实际中实现混合第三方代码的大型部署.
这样的机制是否存在于PHP中,或者是否有人开发过(google说不太可能)?通过将变量设置的相关性与错误消息相关联来加速代码库的合并,这对于许多其他错误情况可能是有价值的.
我希望我只是看着这个错误,并且有一个简单的解决方法,我很想念.
谢谢!
我终于有了一个完整的"pecl runkit"示例,因为我apd在新的分发版上安装时遇到了麻烦 (这是一个旧的库).
您可以runkit使用PECL 安装它:
pecl install runkit
Run Code Online (Sandbox Code Playgroud)
并在php.ini中添加以下行:
extension=runkit.so
runkit.internal_override=1
Run Code Online (Sandbox Code Playgroud)
我忘了提到 error_reporting可以使用error_reporting()函数或不同的方式定义ini_set.所以我们必须关心每个功能.首先我们复制旧的ini_set使用runkit_function_copy,然后我们使用重新定义它runkit_function_redefine
我debug_bactrace(1)用来获取调用文件和行号.
最后要抓住非致命和致命的错误,我们必须使用set_error_handler和register_shutdown_function.
发生错误后,以下代码将输出ini_set调用的位置和文件名/行.
错误(类型= 2):在文件/var/www/html/test.php第47行中除以零
INI SET堆栈
- 这里定义了error_reporting(按顺序):
- /var/www/html/test.php,第16行,值:0
- /var/www/html/test.php,第17行,值:2
- /var/www/html/test.php,第18行,值:1
- /var/www/html/test.php,第19行,价值:32767
码:
<?php
runkit_function_copy("ini_set", "old_ini_set");
runkit_function_redefine("ini_set", '$key,$value', '
global $iniset;
$trace=debug_backtrace(1);
$iniset[$key][]=$trace[0];
old_ini_set($key, $value);');
runkit_function_redefine("error_reporting", '$value', '
global $iniset;
$trace=debug_backtrace(1);
$iniset["error_reporting"][]=$trace[0];
old_ini_set($key, $value);');
// let test now
ini_set("error_reporting", 0);
ini_set("error_reporting", E_WARNING);
error_reporting(E_ERROR);
ini_set("error_reporting", E_ALL);
set_error_handler("custom_error_handler");
register_shutdown_function("custom_error_handler");
function custom_error_handler($errno=NULL, $errstr=NULL) {
global $iniset;
if (!($error=func_get_args())) {
$error=error_get_last();
if ($error!=E_ERROR) $error=NULL;
}
if ($error) {
echo "Error (type=$error[0]): $error[1]\n
in file $error[2] line $error[3]<br />\n";
echo "INI SET stack<br />\n";
echo "<ul>";
foreach ($iniset as $key=>$val) {
echo "<li>$key was defined here (in order):<ul>";
foreach ($val as $def) {
echo "<li>{$def['file']}, line {$def['line']},
value: ".array_pop($def['args'])."</li>";
}
echo "</li></ul>";
}
echo "</table>";
}
}
// division by 0
12/0;
Run Code Online (Sandbox Code Playgroud)
上一篇文章:
您可以使用该ini_get_all()函数获取所有本地和全局配置选项的值.
要检索本地值和全局值的值,可以将$details参数设置为true:
ini_get_all(NULL, true);
Run Code Online (Sandbox Code Playgroud)
您可以使用ini_get()(对于运行时值)和get_cfg_var()(对于全局php.ini值)函数获取各个选项的值.
$global_value=get_cfg_var("error_reporting");
$local_value=ini_get("error_reporting");
echo "Error reporting (Local value: $local_value, global value: $global_value)\n"
Run Code Online (Sandbox Code Playgroud)
为了在发生错误时查看这些结果,您必须捕获错误.
对于非致命错误,您可以使用set_error_handler()
对于致命错误,您必须定义shutdown_function(),请参阅如何捕获PHP致命错误