Bug #51527 [Com]: is_callable() returning true for non-static callbacks
Edit report at http://bugs.php.net/bug.php?id=51527edit=1 ID: 51527 Comment by: hnzksq at gmail dot com Reported by: weierophin...@php.net Summary: is_callable() returning true for non-static callbacks Status: Open Type: Bug Package: Class/Object related Operating System: Linux PHP Version: 5.3.2 New Comment: ?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); } ? ææµè¯å¯ä»¥ç¨çã Previous Comments: [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? [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 ) 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 http://bugs.php.net/bug.php?id=51527 -- Edit this bug report at http://bugs.php.net/bug.php?id=51527edit=1
Bug #51527 [Com]: is_callable() returning true for non-static callbacks
Edit report at http://bugs.php.net/bug.php?id=51527edit=1 ID: 51527 Comment by: crrodriguez at opensuse dot org Reported by: weierophin...@php.net Summary: is_callable() returning true for non-static callbacks Status: Open Type: Bug Package: Class/Object related Operating System: Linux PHP Version: 5.3.2 New Comment: philduby at phriendly dot net : what you mention seems to be another bug/misfeature. Previous Comments: [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? [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. 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 http://bugs.php.net/bug.php?id=51527 -- Edit this bug report at http://bugs.php.net/bug.php?id=51527edit=1
Bug #51527 [Com]: is_callable() returning true for non-static callbacks
Edit report at http://bugs.php.net/bug.php?id=51527edit=1 ID: 51527 Comment by: philduby at phriendly dot net Reported by: weierophin...@php.net Summary: is_callable() returning true for non-static callbacks Status: Open Type: Bug Package: Class/Object related Operating System: Linux PHP Version: 5.3.2 New Comment: 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) Previous Comments: [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? [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. 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 http://bugs.php.net/bug.php?id=51527 -- Edit this bug report at http://bugs.php.net/bug.php?id=51527edit=1
Bug #51527 [Com]: is_callable() returning true for non-static callbacks
Edit report at http://bugs.php.net/bug.php?id=51527edit=1 ID: 51527 Comment by: weierophin...@php.net Reported by: weierophin...@php.net Summary: is_callable() returning true for non-static callbacks Status: Open Type: Bug Package: Class/Object related Operating System: Linux PHP Version: 5.3.2 New Comment: @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. Previous Comments: [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=51527edit=1
Bug #51527 [Com]: is_callable() returning true for non-static callbacks
Edit report at http://bugs.php.net/bug.php?id=51527edit=1 ID: 51527 Comment by: weierophin...@php.net Reported by: weierophin...@php.net Summary: is_callable() returning true for non-static callbacks Status: Bogus Type: Bug Package: Class/Object related Operating System: Linux PHP Version: 5.3.2 New Comment: @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? Previous Comments: [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=51527edit=1