Currently, I have a logger which logs errors together with a backtrace.
The logger serializes the backtrace to JSON via json_encode().
Let's look at some hypothetical code...
<?php
error_reporting(-1); // show all errors
function test($b){
echo json_encode(debug_backtrace()); // take a backtrace snapshot
}
$c = imagecreate(50,50); // create a resource...
test($c); // ...and pass to function
?>
If you run the code above, we will see something like:
Warning: json_encode() [function.json-encode]: type is unsupported, encoded as null in /code/ch6gVw on line 5 [{"file":"/code/ch6gVw","line":8,"function":"test","args":[null]}]
We can notice two things going on here:
So, my proposed solution is something like:
foreach($trace as $i=>$v)
if(is_resource($v))
$trace[$i] = (string)$v.' ('.get_resource_type($v).')';
The result would look like Resource id #1 (gd)
This, however, may cause some grave issues.
$GLOBALS tend to cause this mess).clone() the object?I ended up with the following function:
function clean_trace($branch){
if(is_object($branch)){
// object
$props = array();
$branch = clone($branch); // doesn't clone cause some issues?
foreach($props as $k=>$v)
$branch->$k = clean_trace($v);
}elseif(is_array($branch)){
// array
foreach($branch as $k=>$v)
$branch[$k] = clean_trace($v);
}elseif(is_resource($branch)){
// resource
$branch = (string)$branch.' ('.get_resource_type($branch).')';
}elseif(is_string($branch)){
// string (ensure it is UTF-8, see: https://bugs.php.net/bug.php?id=47130)
$branch = utf8_encode($branch);
}
// other (hopefully serializable) stuff
return $branch;
}
You can see it in action here. However, I'm not convinced:
$a = array(); $a['ref'] = &$a; (PHP does this to some internal variables)__clone(), an invitation to wreck havoc).If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With