Debug, error, and exception messages in PHP often contain type information about variables that did not satisfy a defined validation constraint. The idiomatic way to add this type information is currently via the gettype()
function, however, the information that can be retrieved via that function is very sparse and developers need to repeat certain patterns over and over again to enrich it. This RFC proposes a new function called var_info()
that addresses this issue and helps developers to create better debug, error, and exception messages in their software.
Research of big and successful PHP userland projects (e.g. a search with is_object\([^\)]+\)\s*\?\s*get_class\([^\)]+\)\s*:\s*gettype
shows 44 results in a fresh Drupal 8.2.x checkout with all composer dependencies installed) has shown that the gettype()
function is often used as follows:
$type = is_object($var) ? get_class($var) : gettype($var);
The result of such a check is then mostly used as part of an error message. It is trivial to write the above line of code, and the performance hit of an additional function call is negligible (due to the fact that it is usually only executed in error branches of software). Nevertheless, it is an unnecessary hurdle, and the so retrieved information on the type is not very extensive. Hence, the proposal for a new function that is called var_info()
that works as follows:
echo var_info([]); // array echo var_info([SomeClass::class, 'someMethod']); // callable array echo var_info([new SomeClass, 'someMethod']); // callable array echo var_info(false); // false echo var_info(-1.0); // negative float echo var_info(0.0); // zero float echo var_info(1.0); // positive float echo var_info(INF); // infinite float echo var_info(NAN); // invalid float echo var_info(-1); // negative int echo var_info(0); // zero int echo var_info(1); // positive int echo var_info(new stdClass); // object of class stdClass echo var_info(new Some\Namespaced\UserClass); // object of class Some\Namespaced\UserClass echo var_info(unserialize('O:1:"A":0:{}')); // object of class __PHP_Incomplete_Class echo var_info(function () {}); // object of class Closure echo var_info(STDIN); // resource of type stream $fh = tmpfile(); fclose($fh); echo var_info($fh); // closed resource echo var_info('string'); // string echo var_info('strlen'); // callable string echo var_info('SomeClass::someMethod'); // callable string echo var_info('10'); // numeric string echo var_info('1.0'); // numeric string echo var_info(true); // true
The following table summarizes the possible return values in a more readable form:
Return Value | Comment |
---|---|
array | |
callable array | is_callable() |
false | bool(false) |
negative float | $var < 0.0 |
zero float | $var === 0.0 || $var === -0.0 |
positive float | $var > 0.0 |
infinite float | is_infinite() |
invalid float | is_nan() |
negative int | $var < 0 |
zero int | $var === 0 || $var === -0 |
positive int | $var > 0 |
object of class %s | %s will contain the result of get_class() . |
resource of type %s | %s will contain the result of get_resource_type() . |
closed resource | If no type is available anymore or is invalid/unknown. |
string | |
callable string | is_callable() |
numeric string | is_numeric() |
true | bool(true) |
The return values do not contain any kind of special characters like brackets in order to not interfere with the formatting a developer might choose to format her message (e.g. ( and ) are not appropriate within ( and ) in English language). This should be taken into account in possible future extensions of this function.
Developers should however not rely on the returned values for anything other than outputting them. This is because the returned values might change in any major PHP release, the PHP team will of course take careful care not to alter the output during non-major releases, but it is still highly discouraged.
The function prefix var_
was chosen on purpose because another possibly more suitable prefix like val_
or value_
would introduce a new prefix to the PHP ecosystem. It is true that this function can be used with the return value of functions too as well as with literal values, however, exactly the same argument is true for var_dump()
and var_export()
. Naming consistency is very important and this tiny blemish is on purpose in this case.
Writing a function that does exactly the same as the proposed var_info()
function in userland is trivial. However, the inclusion of tiny dependencies for every day tasks is not something library developers want since every dependency results in an maintainability increase. Another solution would be to copy the few lines of code that provide the functionality from project to project, it should be obvious that this is never an appropriate solution for any kind of problem. Hence, such a tiny but portable functionality is best provided by the platform itself. The inclusion in core should support developers while creating useful error messages, in tiny scripts as well as fully fledged applications and replace calls to gettype()
for that purpose or even var_dump()
/var_export()
.
None
This RFC targets the next feature release, currently 7.1.0.
None
None
None
None
None
negative zero float
for -0.0
values or not.invalid object
instead of object of class __PHP_Incomplete_Class
.Everything
None
This RFC will have a single poll that requires a 50%+1 majority.
The GitHub Pull Request #1957 contains the implementation as well as tests for the new function. The changes in the PR are considered final, however, a thorough code review would be much appreciated and might result in minor changes.
typeof()
.None