|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2009-10-29 01:15 UTC] 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.
Patchescsxigxvg (last revision 2015-06-19 06:26 UTC by sample at email dot tst)Pull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Wed Oct 29 12:00:01 2025 UTC |
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();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"?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?