Edit report at http://bugs.php.net/bug.php?id=51527&edit=1
ID: 51527 Updated by: paj...@php.net Reported by: weierophin...@php.net Summary: is_callable() returning true for non-static callbacks -Status: Bogus +Status: Open Type: Bug Package: Class/Object related Operating System: Linux PHP Version: 5.3.2 New Comment: 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? Previous Comments: ------------------------------------------------------------------------ [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? ------------------------------------------------------------------------ [2010-04-10 17:55:25] johan...@php.net The method can always be called statically. The access to $this might be forbidden but the method itself can be called. is_callable() doesn't mean it will execute properly. (the $this error is basically the same as a call to an undefined funciton in there or such) To change this the only way would be to forbid calling non-static methods statically. Maybe this can be done nowadays (we needed the behavior for PHP 4 compatibility) but that's no bug but requires a RFC and discussion on internals as this might break quite a few applications (many PEAR-based things, many legacy applications not fully "converted" to PHP 5 ....) ------------------------------------------------------------------------ [2010-04-10 16:43:31] weierophin...@php.net @pajoye: Yes, this particular example was callable. However, if the method is actually an instance method, and has references to $this, is_callable() still returns true -- making it an invalid test to use to determine whether or not it's safe to then call call_user_func(). Instead, to really determine if the callback is valid, you have to start doing a bunch of reflection -- checking to see if the method is defined and static, or if there is a __callStatic defined that would intercept the call. That's the more serious implication of the behavior, and why it needs to be fixed. ------------------------------------------------------------------------ [2010-04-10 16:29:12] paj...@php.net It is actually callable. But calling it statically breaks the strict standards, but the strict standards will break BC in many situations. I would suggest to make this change in trunk only. ------------------------------------------------------------------------ [2010-04-10 16:07:17] weierophin...@php.net Description: ------------ is_callable() is returning a false-positive for callbacks that reference non- static methods. As an example, if I have defined a class 'Foo' with an instance (i.e., non-static) method 'bar', and define the callback "array('Foo', 'bar')", is_callable() will falsely return true. Additionally, if you then pass this callback to call_user_func(), this latter function will actually try to call the method statically -- and raise an E_STRICT about the callback being invalid. If the method has any references to $this, it then fails with an E_FATAL, but otherwise it will run the method as if it were static. This behavior is unexpected, and unintuitive. Calling non-static methods as if they were static, even when they do not reference $this, violates visibility. I would expect is_callable() to return false in these instances, and for call_user_func() to immediately raise an E_FATAL if the method is not defined as static. Test script: --------------- class Foo { public function bar() { return 'foo bar'; } } $callback = array('Foo', 'bar'); if (is_callable($callback)) { echo call_user_func($callback); } Expected result: ---------------- No output. Actual result: -------------- PHP Strict Standards: call_user_func() expects parameter 1 to be a valid callback, non-static method Foo::bar() should not be called statically Strict Standards: call_user_func() expects parameter 1 to be a valid callback, non-static method Test\Foo::bar() should not be called statically foo bar ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/bug.php?id=51527&edit=1