Bug #72084 [Nab]: is_callable returns true for array with class and non static method
| From: | requinix@php.net | Date: | Sat, 23 Apr 2016 05:50:58 +0000 |
| Subject: | Bug #72084 [Nab]: is_callable returns true for array with class and non static method | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-200709@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=72084&edit=1
ID: 72084
Updated by: requinix@php.net
Reported by: heah at heahprod dot com
Summary: is_callable returns true for array with class and
non static method
Status: Not a bug
Type: Bug
Package: Scripting Engine problem
Operating System: os X 10.11.4
PHP Version: 5.6.20
Block user comment: N
Private report: N
New Comment:
> My expectation reading the docs was that a callable array syntax would use a
> class for static calls and an object for non static methods, and that the test
> of "is_callable" would prevent a broken call to "call_user_func".
That's precisely true: it tells you that the method is callable, as in PHP will begin executing
it. What it does not do is look at the code inside the method, see the "$this", realize
that using $this won't work from a static call, and return false instead.
The method can be called. What happens when the method executes is another matter entirely.
Previous Comments:
------------------------------------------------------------------------
[2016-04-23 05:38:22] heah at heahprod dot com
Thank you for your response.
Yes it makes sense, and I'm happy to learn about that deprecation in 7.0 (can't wait to
deal with a global upgrade :)
In fact, my only concern is about that fatal error, even if I understand the cause, I don't
understand why "is_callable" returns true in that case.
My expectation reading the docs was that a callable array syntax would use a class for static calls
and an object for non static methods, and that the test of "is_callable" would prevent a
broken call to "call_user_func".
If there is no bug or feature request in that, I guess I'll just use a try block instead and we
can close here.
But I'm actually facing this issue in a development, I need to know how to deal with it though.
Thank you again for your time.
------------------------------------------------------------------------
[2016-04-23 05:19:53] requinix@php.net
To be honest I'm a little confused by your description. So I'll start from the beginning.
https://3v4l.org/2P3dd
The four class/object + instance/static method combinations are callable in the sense that you can
successfully use call_user_func() on them. For the two odd cases,
1. For now, calling an instance method from a static context is allowed for compatibility with old
PHP scripts and methods that were written without the "static" keyword. Perhaps PHP 4-era
code and practices. However doing so could easily be the source of problems so PHP will raise a
strict/deprecated notice when that happens.
2. Calling a static method from an instance context is a bit odd but there isn't really any
technical reason why that should not be allowed. So PHP allows it silently.
And that fatal error? Even though PHP allowed the instance-method-from-static-context call, the
method did something PHP couldn't recover from: try to use $this. Since it's a static call
there is no instance to bind to $this and PHP has no choice but to fatal.
Does that make sense?
------------------------------------------------------------------------
[2016-04-23 03:53:18] heah at heahprod dot com
Description:
------------
Hi,
documentation says that valid callables might be string name of functions, closure, or:
"A method of an instantiated object is passed as an array containing an object at index 0 and
the method name at index 1. Accessing protected and private methods from within a class is allowed.
Static class methods can also be passed without instantiating an object of that class by passing the
class name instead of an object at index 0. As of PHP 5.2.3, it is also possible to pass
'ClassName::methodName'."
ref http://php.net/manual/en/language.types.callable.php
However "is_callable" does not behave as I would expect when passing an array with a class
and a non static method, true is returned instead of false.
Is this an expected behavior? Shouldn't we rely on "is_callable" before calling
"call_user_func"?
If not please update or let me know if I should open another issue for:
http://php.net/manual/en/function.is-callable.php
since it currently says:
"Verify that the contents of a variable can be called as a function. This can check that a
simple variable contains the name of a valid function, or that an array contains a properly encoded
object and function name."
If we change the test script I provide to "echo" a regular string like "object
call" instead of using an object property, the string is printed after the warning triggered by
"is_callable", so "call_user_func" is actually called.
Since I'm just a php beginner and don't know anything about the internal, I don't
know if the error comes with "is_callable" because "call_user_func" is actually
callable or if it comes from "call_user_func" because "is_callable" returns
true.
But my guess is that "call_user_func" should test internally if the array is callable
(second case), and throw an invalid argument exception instead.
The a user like me should be able to use "is_callable" before using it and getting the
invalid argument exception.
However the current fatal error got from the provided test script looks really wrong to me.
Note that it happens in my local environment but not on my server holding the script online.
Thank you for your time reading this and for working on PHP, it is an awesome open-source project!
(sorry for any mistake, this is my first issue report and I'm not a native speaker).
Test script:
---------------
http://heahprod.com/php/bug-is_callable.php
Expected result:
----------------
static call static call object call object message
Actual result:
--------------
static call
Strict Standards: call_user_func() expects parameter 1 to be a valid callback, non-static method
SomeClass::someObjectMethod() should not be called statically in /test.php on line 39
object call
Strict Standards: call_user_func() expects parameter 1 to be a valid callback, non-static method
SomeClass::getMessage() should not be called statically in /test.php on line 45
Fatal error: Using $this when not in object context in /test.php on line 19
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=72084&edit=1