Error messages from PHP 7

Error messages from PHP 6

Prepare for PHP 7 error messages (part 3)

This is the third party of our presentation of PHP error messages. In the first article, we covered the evolution of error messages in the PHP binary, and in the second, we reviewed eight new messages. We’ll finish with sever other messages and three that were dropped since PHP 5.6.

« Redefinition of parameter $%s »

It took me probably fourteen years before I tried this in a PHP script :

<?php
function x ($a, $a, $a) {}
?>

Yes, multiple identical parameters. That works. If you want to have fun with it, go try it. About 2% of every PHP projects uses this, so you’re unlikely to be one of them but it do happen.

In PHP 5.6, the incoming arguments will be assigned to the same variables in the incoming order. x(1,2,3) will have $a = 3 and 1 and 2 are now lost. This looks like a quite impossible error, but it was found in some Open Source project and may live quite long there until it is changed.

« Bit shift by negative number »

This is a change in behavior for the bitshift operators, << and >> . Negative values are not accepted anymore : they now throw a warning and return false ; Positive shifts that are beyond the scope of the bitfield are now 0, and won’t emit an error. If you’re using bitshift, you’ll have to check them before PHP 7.

« Methods with the same name as their class will not be constructors in a future version of PHP; %s has a deprecated constructor »

This is the error message you’ll get if you’re still using PHP 4 constructors. PHP 4 constructors are still working if the class is not in a namespace, if the class or its parents has no __construct method : that should be a concern to a very little number of classes.

Note that this error is linked to strict standards, and that the PHP 4 constructor will not disappear until PHP 8. It is still a good idea to check that PHP 4 code that you plan to use in your PHP 7 plate-form : for the constructor and for the rest of it.

« get_resources(): Unknown resource type ‘%s’ »

First piece of news with this error message : there is a new PHP native function called get_resources. It is not in the manual yet : as stated in the source, it lists all the created resources (files, database connexions, xml parser, etc) available at the time of call. This is similar to get_declared_classes or get_defined_constants.

The error itself indicates that PHP couldn’t find the type of resource that it is going to return. That is hopefully a rare bug, since PHP doesn’t drop resource definitions while executing some code. It may happen when code is compiled into opcode, then reused later by another version of PHP.

« strict_types declaration must be »

« strict_types declaration must not »

« strict_types declaration must have 0 or 1 as its value »

All three messages refer to the declare syntax and the new strict_types directive.

Declare itself has been around for a long time already, dating back to PHP 4. It is a mechanism to provide dynamic configuration to PHP, in a different way than ini_set() or .htaccess. The other directive are ticks (which runs a callback every ; or {} ) and encoding (which provides a local encoding for the script). Generally speaking, they are rarely used.

With PHP 7, declare gets a new directive: strict_types. This configure the behavior of scalar type hint. Scalar type hint are type hint with scalar types, such as int, float, boolean or string. They are not supported in PHP 5, and will be in PHP 7. To ensure that everyone can still use PHP the way he likes, strict_type directive may be strict (where the passed arguments must conform the requested typehint) or weak (where the passed argument may undergo some type casting).

PHP 5.6 dropped error messages

We’ll finish this review with some of the error messages that were dropped since PHP 5.6. There aren’t too many, and some are really cryptic.

« A trait (%s) cannot extend a class. Traits can only be composed from other traits with the ‘use’ keyword. »

This PHP 5.6 message use to warn developers that trait doesn’t follow the extends/implements that class do. This is now abandoned, probably as a side effect of the AST : trait x extends just doesn’t compile at all and ends with a fatal error. That makes it easy to lint, and since it is not difficult to understand, it should be easy to remove.

« Cannot call __clone() method on objects – use ‘clone $obj’ instead »

PHP 5.6 did emit error when the __clone() magic method was called directly. This message is now abandoned in PHP 7, and it is possible to call the __clone method directly. Since __clone doesn’t return anything (see the first error messages), it will apply itself to the calling object. This allows the transformation of an original object into a cloned one.

Other magic methods may be called directly, though it is recommended to call them with their intended syntax ( for example, don’t call __toString() but use the (string) operator or let print/echo to the job).

« You seem to be trying to use a different language… »

This was indeed an error message. It is linked to ‘use strict’ and only in this case. This is an instruction for HHVM, which will configure a strict mode. It is not used in PHP at all, but code that may run on both PHP or HHVM will have this displayed. This message was intended to be an easter egg, and was removed (https://github.com/facebook/hhvm/issues/4556)

Conclusion

This will conclude the panorama of new PHP errors. There are still some extra messages that we didn’t cover, but you may read the whole list [download id=”652″] and clone the PHP source https://github.com/php/php-src/. The archives includes some messages that I couldn’t generate myself : I tried hard to create buggy PHP code, but it appears that I bad at buggy code.

The good news it that even if PHP gets stricter with version 7, there are only a fistful of new situations. Preparing the code for PHP 5.6 should make an excellent first step for current code back, and from there, PHP 7 will be an easy upgrade.