Edit report at https://bugs.php.net/bug.php?id=51527&edit=1
ID: 51527 Updated by: s...@php.net Reported by: weierophin...@php.net Summary: is_callable() returning true for non-static callbacks Status: Open -Type: Bug +Type: Feature/Change Request Package: Class/Object related Operating System: Linux PHP Version: 5.3.2 Block user comment: N Private report: N New Comment: Let's first make important note that it is not a bug - it is an intended functionality, is_callable is supposed to return true on this data and as far as I can see, has always done so at least since 5.2 (maybe earlier, just don't have binary to check). Secondly, Foo::Bar is not always a static call. Consider this code: class Foo { private $number = 42; public function bar() { var_dump($this->number); return __METHOD__; } } class Bar extends Foo { public function callme($callback) { echo call_user_func($callback); } } $callback = array('Foo', 'Bar'); var_dump(is_callable($callback)); $bar = new Bar(); $bar->callme($callback); This is a bit convoluted, but everything works just fine. Changing is_callable and the engine to prohibit this case would cause massive code breakage, and as a lot of code uses this pattern to call parent ctors, it's probably not feasible. There's a difference between "true static call" and "parent method call that looks like static call" and unfortunately, this difference exists only in runtime when the actual call is made, is_callable would not be able to predict it. Previous Comments: ------------------------------------------------------------------------ [2010-07-20 05:43:43] hnzksq at gmail dot com <?php /** * @author zhouw * @copyright 2010 */ class Foo { public function bar() { return 'foo bar'; } } $callback = array('Foo', 'bar'); if (is_callable($callback)) { echo call_user_func($callback); } ?> ææµè¯å¯ä»¥ç¨çã ------------------------------------------------------------------------ [2010-05-07 16:39:56] crrodriguez at opensuse dot org philduby at phriendly dot net : what you mention seems to be another bug/misfeature. ------------------------------------------------------------------------ [2010-05-05 07:03:50] philduby at phriendly dot net Another variation that actually (unexpectedly) works: Calling is_callable and call_user_func from inside an instance (non-static) method using any of: 'self::otherInstanceMethod', array('self','otherInstanceMethod'), array(self,'otherInstanceMethod') succeed. It appears that (the context for) '$this' is carried over from the original method, even though the calls are being done statically. Calling self::otherInstanceMethod() directly also succeeds. It appears that methods called from an instance method 'inherit' the context for $this. A bit unexpected, but *reasonable*. Win XP SP3 PHP 5.3.1 (xampp) ------------------------------------------------------------------------ [2010-04-12 11:50:33] paj...@php.net I don't like the optional flag idea. You can disable strictness using error_reporting already. However I would like to see this change in trunk, can you come up with a RFC pls? ------------------------------------------------------------------------ [2010-04-10 20:19:45] weierophin...@php.net @johannes Perhaps an optional "strict" flag to is_callable() would address this? That would keep BC, while allowing for better checking for >= PHP-5 apps. Usage would be: $callback = array('Foo', 'bar'); if (is_callable($callback, true)) { // Passed strict check } else { // failed strict check } Thoughts? ------------------------------------------------------------------------ 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=51527 -- Edit this bug report at https://bugs.php.net/bug.php?id=51527&edit=1