Requirements
We have production PHP code running on a webserver. In some sitations we want to enrich debug output (going e.g. to error.log) with context information. The context can have arbitrary fields and structure.
Our goal is to find a general purpose debug producing function which does not generate warnings in any of the corner cases. It is acceptable if the output is only partial.
TL;DR
All three PHP standard functions cause warnings with certain contexts:
- print_r & var_dump fail to handle mysqli objects with closed connections
- var_export fails to handle recursion
Question
Is there a way to return the context of arbitrary objects as human readable string?
Test Cases
// Dealing with recursion:
$recObj = new stdClass();
$recObj->recursion = $recObj;
print_r ($recObj); // works
var_export($recObj); // throws: "Warning: var_export does not handle circular references"
var_dump ($recObj); // works
// dealing with mysqli
$mysqli = mysqli_connect('mysql', 'root', 'myPass', 'mysql');
print_r ($mysqli); // works
var_export($mysqli); // works as in "does not throw warnings" but all values are null
var_dump ($mysqli); // works
// Try again with closed connection
mysqli_close($mysqli);
print_r ($mysqli); // throws: "Warning: print_r(): Couldn't fetch mysqli"
var_export($mysqli); // works (again all values are null)
var_dump ($mysqli); // throws: Warning: var_dump(): Couldn't fetch mysqli
As per the relevance of a closed mysqli connection: If you do your context printing in an error handler or registered shutdown function (which is a good location to do so), the mysqli object will already have auto-closed the connection once you reach that handler.
As you can see, none of the build-in output methods gives the desired result of just being able to return whatever context you throw at it.
Options considered
- It might be possible to suppress the warnings using the @notation. However, the registered error handlers and shutdown functions still get called with the error and would require custom logic to ignore that particular error. This might hide real errors and also gets quite annoying if dealing with 3rd party error tracking systems like sentry.io
- The
serialize()
function does not produce warnings in any of the cases but it lacks in human-readability. - The
json_encode()
function can be much more readable than serialize but it does not return anything in the recursion test case....