Req #50029 [Com]: Weird invoke issue on class as property
| From: | karsten at typo3 dot org | Date: | Tue, 06 Dec 2011 16:34:31 +0000 |
| Subject: | Req #50029 [Com]: Weird invoke issue on class as property | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-165702@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=50029&edit=1
ID: 50029
Comment by: karsten at typo3 dot org
Reported by: marc dot gray at gmail dot com
Summary: Weird invoke issue on class as property
Status: Analyzed
Type: Feature/Change Request
Package: Class/Object related
Operating System: Ubuntu 9.04
PHP Version: 5.3.0
Block user comment: N
Private report: N
New Comment:
I would go for simple rules to solve this. When having a class and calling
$this->prop() PHP should
* use __invoke on $this->prop if there is no method prop() in the class
* if there is an actual method, the method takes precedence
In the latter one can still use $this->prop->__invoke(), but should probably
rather clean up the code. :)
Previous Comments:
------------------------------------------------------------------------
[2011-08-24 18:49:06] marc dot gray at gmail dot com
I've been thinking about this since the same issue appears to exist with assigning a closure to
a static
variable too (tested in 5.3.5, 5.3.8 & 5.4alpha3.
//----------------------------------
// Create a very basic static class
class closureProperty {
static public $myClosure;
}
// Assign a closure to a class property
closureProperty::$myClosure = function() { echo('Hi'); };
// Fatal error: Function name must be a string
closureProperty::$myClosure();
// Works as expected
$safeCopy = closureProperty::$myClosure;
$safeCopy();
//----------------------------------
I can understand why it happens with dynamic properties, apparently you can have a variable and
function named
identically? I admit I've never tried.
I would propose making identically named variables and functions as deprecated (does anyone
who's any good
actually do that? Talk about poor readability...) and implement a collision warning in the mean
time. I would
also suggest this makes less sense in a static case (due to $ variable prefix) than it did in a
dynamic case,
and should be changed.
If nothing else, some discussion on the matter would be lovely.
Thoughts?
------------------------------------------------------------------------
[2011-02-07 22:36:54] dhaarbrink at gmail dot com
@bkarwin: The control would be passed to __call(), since there is no way to disambiguate. __call()
would then be responsible for deciding what to do.
I have to agree with Matthew, it's a huge WTF. It just doesn't work as it should
(that's beyond what is expected).
------------------------------------------------------------------------
[2010-04-07 20:22:38] bkarwin@php.net
How would Matthew's suggestion work if a magic __call() method is present?
class b {
private $x;
public function __call($method, $args) { echo "Called\n"; }
function __construct() {
$this->x = new a();
$this->x();
}
}
Should this execute $this->__call("x") and output "Called" or should it
execute $this->x->__invoke() and output "Invoked"?
------------------------------------------------------------------------
[2010-04-07 14:52:19] ballouc at gmail dot com
I'm in agreement with the Matt's last suggestion. I believe that errors should only be
raised in the event of a collision. The current implementation of the __invoke method, IMO, would
not perform as a third party developer would have anticipated. My personal choice would be to throw
an E_WARNING for collisions as I have seen ~E_NOTICE far too often.
Personally, I believe that an __invoke collision occurring would be more indicative of a developer
error than intentional. If this is not the case, and you find many people readily anticipate having
both foo() and __invoke called in succession, this would need to be discussed further as that is
also a viable option.
------------------------------------------------------------------------
[2010-04-07 13:41:14] weierophinney@php.net
I can understand wanting to ensure that collisions between existing methods and
invokable properties don't occur, but when there aren't any collisions, it
doesn't make sense.
I'd argue that the following behavior should be implemented:
* If no matching method exists, simply allow invoking.
* If a matching method exists, call the method, and raise either an E_NOTICE or
E_WARNING indicating the collision.
Right now, it's a fairly big WTF moment -- you expect it to work, and instead
get an E_FATAL. Copying to a temporary variable is code clutter, particularly
when you know the object is invokable.
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
https://bugs.php.net/bug.php?id=50029
--
Edit this bug report at https://bugs.php.net/bug.php?id=50029&edit=1