| Newsgroups |
php.bugs |
| Message-ID |
<[email protected]> |
Edit report at http://bugs.php.net/bug.php?id=51527&edit=1
ID: 51527
Comment by: [email protected]
Reported by: [email protected]
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] [email protected]
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] [email protected]
@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] [email protected]
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] [email protected]
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