Edit report at http://bugs.php.net/bug.php?id=50029&edit=1
ID: 50029
Comment by: dhaarbrink at gmail dot com
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:
@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).
Previous Comments:
[2010-04-07 20:22:38] bkar...@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] weierophin...@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.
[2009-11-02 15:58:23] ka...@php.net
There was lots of discussion about this, because it could override class
methods like:
class Test {
private $closure;
public function __construct() {
$this->closure = function() {
echo 'Hello World';
};
}
public function closure() {
echo 'Hello PHP';
}
public function call() {
$this->closure();
}
}
$test = new Test;
// Call Test::$closure or Test::closure() now?
$test->call();
What you need to do is to copy the instance into a variable like:
$closoure = $this->closure;
$closure();
[2009-10-29 01:15:36] marc dot gray at gmail dot com
Description:
Placing a class with an __invoke method as a property inside another
class seems to nullify the invokeability of the original class.
Tested on:
Ubuntu 9.04, PHP 5.3.0
CentOS 5.3, PHP 5.2.11 ionCube / Suhosin
Reproduce code:
---
class a {
function __construct() { }
function __invoke() { echo("Invoked\n"); }
}
$a = new a();
$a();
// Prints: Invoked
class b {
private $x;
function __construct() {
$this->x = new a();
$this->x();
}
}
$b = new b();
// Issues error: undefined method b::x
Expected result:
I expect "new b()" construct to call the class a invoke
Actual result:
--
Undefined method - it doesn't seem to recognise the invokeable class
property as actually invokeable.
--
Edit this bug report at http://bugs.php.net/bug.php?id=50029&edit=1