I finally have a fully working example with "pecl runkit" as I had trouble installing apd
on a fresh distrib (it's an old library).
You can install runkit
it with PECL:
pecl install runkit
and add the following lines in your php.ini:
extension=runkit.so
runkit.internal_override=1
I forgot to mention that error_reporting
can be defined in different way using error_reporting()
function or ini_set
. So we have to care about each function.
First we copy the old ini_set
using runkit_function_copy
and then we redefine it using runkit_function_redefine
I use debug_bactrace(1)
to get the calling file and line number.
And finally to catch both non-fatal and fatal error, we have to use set_error_handler
and register_shutdown_function
.
The following code will output, after an error, where ini_set
was called and the filename/line.
Error (type=2): Division by zero in file /var/www/html/test.php line 47
INI SET stack
- error_reporting was defined here (in order):
- /var/www/html/test.php, line 16, value: 0
- /var/www/html/test.php, line 17, value: 2
- /var/www/html/test.php, line 18, value: 1
- /var/www/html/test.php, line 19, value: 32767
Code:
<?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;
Previous post:
You can get the value of all local and global configuration options with the ini_get_all()
function.
To retrieve the values of both local and global value, you can set the $details
parameter to true:
ini_get_all(NULL, true);
You can get the value for individual options with the ini_get()
(for runtime value) and get_cfg_var()
(for global php.ini value) functions.
$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"
In order to see those results when an error occurs, you have to catch the errors.
For non fatal errors, you can use set_error_handler()
For fatal errors, you have to define a shutdown_function(), see How do I catch a PHP Fatal Error