Background (Intro)
Kint is a PHP debugging tool that works as a more powerful replacement to PHP's var_dump()
, print_r()
, and debug_backtrace()
. One unusual -- for PHP at least -- feature of Kint is the ability to use real-time modifiers in the form of operands. Here is what the manual states about that feature:
There are a couple of real-time modifiers you can use:
- ~d($var) this call will output in plain text format.
- +d($var) will disregard depth level limits and output everything. Careful, this can hang your browser on large objects!
- !d($var) will expand the output automatically.
- -d($var) will attempt to ob_clean the previous output and flush after printing.
- You can combine modifiers too: ~+d($var)
There is an older exiting SO question that is similar to this question if you need more information.
Questions
- How does Kint add these operands without triggering a PHP error?
- How can I emulate/capture any calls that use these operands?
Without loading Kint if you attempt to use these operands or create your own functions to capture Kint operand calls you get Fatal error: Uncaught Error: Unsupported operand types
.
Important: I am using the kint.phar
file and I'm not using composer or any kind of CLI usage.
My Use Case (Please don't get distracted from the Questions)
I'm adding this information for those that are curious and to further clarify my questions. I sincerely want to learn and understand HOW they are doing this and would appreciate answers to that end. This question is not about defending / critiquing / disagreeing with my use case:
For security and optimization I am creating a fake (empty) Kint class that loads when my site is in production mode. This ensures that any Kint calls left in the code on accident do not trigger fatal errors, can never print anything out, and uses less resources compared to loading the real Kint class.
I know you can disable Kint with Kint::$enabled_mode = false;
but lets not focus on that. Here is the code I use to fake the Kint class. All that is missing is capturing calls that use these non-standard operands:
/**
* Fake class.
*/
class Kint {
const STATIC_BLACKHOLE = '';
public static $enabled_mode = false;
public function blackhole( $a ) {
return;
}
public function __call( $m, $a ) {
return call_user_func_array( array( $this, $this->blackhole ), $a );
}
public static function __callStatic( $m, $a ) {
return self::STATIC_BLACKHOLE;
}
}
$kint = new Kint();
// Alias of Kint::dump().
/**
* Fake function to catch d().
*
* @return void
*/
function d() {
return;
}
// Kint::dump basic mode.
/**
* Fake function to catch s().
*
* @return void
*/
function s() {
return;
}
\define( 'KINT_DIR', '/classes/Kint' );
\define( 'KINT_WIN', DIRECTORY_SEPARATOR !== '/' );
\define( 'KINT_PHP70', ( \version_compare( PHP_VERSION, '7.0' ) >= 0 ) );
\define( 'KINT_PHP71', ( \version_compare( PHP_VERSION, '7.1' ) >= 0 ) );
\define( 'KINT_PHP72', ( \version_compare( PHP_VERSION, '7.2' ) >= 0 ) );
\define( 'KINT_PHP73', ( \version_compare( PHP_VERSION, '7.3' ) >= 0 ) );
\define( 'KINT_PHP74', ( \version_compare( PHP_VERSION, '7.4' ) >= 0 ) );
\define( 'KINT_PHP80', ( \version_compare( PHP_VERSION, '8.0' ) >= 0 ) );