How does kint parse PHP functions prefixed by symbols (plus/minus sign, tilde, exclamation mark, at)?

268 Views Asked by At

The PHP debugging tool kint has a strange syntax where certain symbols can be prefixed to functions to alter their behavior, as shown in this guide.

The relevant information:

Modifiers are a way to change Kint output without having to use a different function. Simply prefix your call to kint with a modifier to apply it:

! Expand all data in this dump automatically  
+ Disable the depth limit in this dump  
- Attempt to clear any buffered output before this dump  
@ Return the output of this dump instead of echoing it  
~ Use the text renderer for this dump

Example:

+Kint::dump($data); // Disabled depth limit
!d($data); // Expanded automatically

How does this work?

By looking at the source code it seems that the symbols are being parsed into an array called $modifiers. But how can you do this with PHP? And what is the scope of this, could I do this with other unicode symbols as well, or are the five in question (+, -, ~, !, @) the only ones.

The '@' already has a use in PHP when prefixed, see: What is the use of the @ symbol in PHP?. How can this be overruled?


Edit: A follow-up question to the answers given is how exactly kint bends the (php) rules. For example why the ~ doesn't give a syntax error. Consider this example:

<?php
function d($args) {
  echo $args[0];
}
d([1,2,3]); // prints 1
~d([1,2,3]); // syntax error, unsupported operand types

vs

<?php
require 'kint.php';
~d([1,2,3]); // prints the array with the text renderer with no issues

Edit 2: removed unsubstantiated claim that kint uses eval()

2

There are 2 best solutions below

4
Max On

Sorry for the late reply. I was just reading the Kint documentation and had the same question. After finding your question I decided to investigate. You may have figured it out by now, but kind actually reads the source code of the file that invoked it to change its behavior based on whether any of these "modifiers" were present.

This behavior is absolutely unpredictable as far as I'm concerned and I can't believe anybody would use this kind of trick as anything but a proof of concept. Notably, because the file must be readable, kint modifiers fail on eval()'d code (which you shouldn't be using to begin with) and perhaps in other unusual cases as well.

4
raveren On

Original author of Kint here.

Sorry you found it confusing! The operands were added as a shorthand to switch some commonly used settings for common usecase scenarios.

Since Kint already parses the PHP code where it was called from to get and display the names (or expressions) of passed variables that are being dumped, adding the operands was a minor addition to that functionality.

variable name displayed

Note the variable name is displayed ^. As of time of writing Kint is still the only dumper that can do this!


And the actual explanation to the OP question comes from this in-depth answer:

PHP unary operators:

Thus, it is perfectly allowable to prefix function calls with these operators, as long as the function returns a type of value that the operator would normally work on:

function foo() {
    return 0;
}

// All of these work just fine, and generate no errors:
-foo();
+foo();
!foo();
~foo();