zendframework / zend-stdlib

Stdlib component from Zend Framework
BSD 3-Clause "New" or "Revised" License
384 stars 76 forks source link

Strange behaviour in Parameters object with PHP 7.1.4 #77

Closed jonathangreco closed 6 years ago

jonathangreco commented 7 years ago

My co-workers and I, tested it today, it seems there is a bug with Parameters in PHP 7.1.4 : This is the full example : https://3v4l.org/l56rd

We think this strange behaviour is related to this fix : https://bugs.php.net/bug.php?id=74058

This behaviour is also in our version of Zend/Stlib 2.7.7.

weierophinney commented 6 years ago

I'm not quite sure what to do about this, to be honest.

ArrayObject::offsetGet is not defined in such a way as to return by reference. If we were to alter our own implementation to return by reference (e.g., &offsetGet($name)), we get errors under PHP 7.1 and 7.2:

The way to solve this at the user level is to use the provided get() method instead of direct array-style access. However, that doesn't help when you want to iteratively work on an array you're storing within the parameters. To solve that: pass in an ArrayObject instance, as that will be passed by reference, and any changes you make to it will then reflect in the Parameters instance:

$data = new Parameters();
$data->set('param', new \ArrayObject([]));
$data->param['toto'] = 'tutu';
$data->param['type'] = 1;

I've tried a number of different approaches in PHP 7.1 and 7.2, and essentially there's no way to mimic the behavior prior to 7.1.4. The php.net bug indicates it is fixed, but if it is, it's not in any released versions.

jonathangreco commented 6 years ago

@weierophinney Thanks for your answer, your code is working of course and it should be solved my issue for sure even if when i'll migrate to ZF3 + PHP7.1.4 I'll have to refactor some parts due to BC break.

This issue is, from your perspective, a PHP's bug ? Means this package should ignore it until a php realease ?

weierophinney commented 6 years ago

It's both a PHP bug and feature at this point.

Prior versions of PHP allowed for variance in signatures with regards to changing whether or not arguments were passed by reference and/or the signature returned by reference. However, they made a change to that behavior, as it is a problem with regards to inheritance. The issue with that change is that it happened in a minor release, not a major one, which led us to this situation. If we want our package to support PHP 7.1 and 7.2, we have to operate under those constraints, unfortunately. As such, your only option is the above workaround.