zendframework / zend-view

View component from Zend Framework
BSD 3-Clause "New" or "Revised" License
49 stars 61 forks source link

PHP 7.4: passing ArrayObject to $view->partial() no longer works #202

Closed zerocrates closed 5 years ago

zerocrates commented 5 years ago

Passing an ArrayObject as the $values parameter to the partial view helper no longer works in PHP 7.4 and zend-view 2.11.3.

The issue is that the Partial class internally uses get_object_vars to handle passed objects that don't have a toArray method:

        } elseif (is_object($values)) {
            if (null !== ($objectKey = $this->getObjectKey())) {
                $values = [$objectKey => $values];
            } elseif (method_exists($values, 'toArray')) {
                $values = $values->toArray();
            } else {
                $values = get_object_vars($values);
            }
        }

In PHP < 7.4, this gets you he wrapped array, but in PHP 7.4 get_object_vars now returns only the direct properties of an ArrayObject, not the contents of its wrapped array. Elsewhere in zend-view, like the variable-setting methods of PhpRenderer and ViewModel, objects implementing Traversable and/or ArrayAccess get specially checked for and handled, but not in the partial() helper.

Obviously, not using an ArrayObject eliminates the issue as well. The only reason I'm personally using an ArrayObject as values for the partial in my real-world use is that I'm using the event manager component to allow the values to be filtered, and prepareArgs results in the arguments being stored/retrieved as an ArrayObject. In previous versions I've been able to pass this directly to the partial() helper without issue.

It's possible to treat this as a 7.4 compatibility issue on the application side rather than the framework side, but as the get_object_vars call at issue lives in the framework, I think it's reasonable to consider this a framework issue.

Code to reproduce the issue

$args = new ArrayObject;
$args['key'] = 'value';
echo $this->partial('partial.phtml', $args);

// in partial.phtml

echo $key;

Expected results

Output:

value

Actual results

Notice: Undefined variable: key in partial.phtml

michalbundyra commented 5 years ago

Ref: https://www.php.net/manual/en/migration74.incompatible.php#migration74.incompatible.spl

michalbundyra commented 5 years ago

Thanks, @zerocrates! I am going to release 2.11.4 with the hotfix shortly!