Bug #51527 [Com]: is_callable() returning true for non-static callbacks
| From: | philduby at phriendly dot net | Date: | Wed, 05 May 2010 05:03:51 +0000 |
| Subject: | Bug #51527 [Com]: is_callable() returning true for non-static callbacks | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-150184@lists.php.net to get a copy of this message | ||
Edit report at http://bugs.php.net/bug.php?id=51527&edit=1
ID: 51527
Comment by: philduby at phriendly dot net
Reported by: weierophinney@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] pajoye@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] weierophinney@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] johannes@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] weierophinney@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] pajoye@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=51527&edit=1