php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #70790 Nested __get calls in some cases.
Submitted: 2015-10-26 13:10 UTC Modified: 2015-11-08 04:22 UTC
From: phplists at stanvassilev dot com Assigned:
Status: No Feedback Package: Scripting Engine problem
PHP Version: 7.0.0RC5 OS: OSX
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: phplists at stanvassilev dot com
New email:
PHP Version: OS:

 

 [2015-10-26 13:10 UTC] phplists at stanvassilev dot com
Description:
------------
A "magic property" call into __get shouldn't trigger nested __get, but in some cases it does - namely, when you do isset on an array key of a non-existing property.

This is not a new behavior for PHP 7, PHP 5.6 also does this. But it's undesirable in general.



Test script:
---------------
class Abc {
	function __get($name) {
		echo $name . ", ";
		if (isset($this->shallow)); // Doesn't trigger __get.
		if (isset($this->deep['foo'])); // Triggers __get with name "deep".
		return 'value';
	}
}

$abc = new Abc();
echo $abc->trigger; // Produces output: trigger, deep, value.

Expected result:
----------------
It's expected isset() checks in __get won't produce nested __get calls in the same object (the "deep" part of the output shouldn't exist).

Actual result:
--------------
Nested calls of __get occur.

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-10-26 14:12 UTC] phplists at stanvassilev dot com
I was also surprised that the "recursive call" circuit-breaker flag is name-specific, which doesn't allow me to do this:

class Foo {
	function __set($name, $value) {
		$this->{$name . '_was_set'} = $value;
	}
}

$f = new Foo;
$f->x = 123; // Out of memory error...

I feel that simply disallowing magic methods inside a magic methods without tracking *what name* they're handling would be simpler, and faster in the runtime, right? Why can't it be implemented this way.
 [2015-10-30 17:32 UTC] kalle@php.net
-Status: Open +Status: Feedback
 [2015-10-30 17:32 UTC] kalle@php.net
Hi,

Is this also the case for PHP5, as in the 5.6 branch?
 [2015-10-31 14:01 UTC] phplists at stanvassilev dot com
As I noted in the bug report, this behavior is not new, PHP 5 behaves that way as well.

However, I think it's reasonable to say the behavior is a bug. It doesn't make sense from userland perspective to differentiate isset($this->foo) from isset($this->foo['bar']) in terms of one not triggering __get and the other triggering it.

If the behavior has to change towards more correct, I think a major release is a good point to change it. I do understand also PHP is at RC6 and it might be a bad idea to start making changes like that in the last moment.

But I ask that we at least keep the bug open for discussion.
 [2015-10-31 17:45 UTC] kalle@php.net
Personally I would like this changed as well to be more predictable and consistent, but for PHP 7.0, this is a no go but it could be an idea for 7.1 if you write an RFC, as its more likely to get the attention that this actually needs to get it implemented in PHP.
 [2015-11-08 04:22 UTC] php-bugs at lists dot php dot net
No feedback was provided. The bug is being suspended because
we assume that you are no longer experiencing the problem.
If this is not the case and you are able to provide the
information that was requested earlier, please do so and
change the status of the bug back to "Re-Opened". Thank you.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Apr 18 05:01:28 2024 UTC