On Thu, Feb 23, 2012 at 9:03 PM, Stas Malyshev <smalys...@sugarcrm.com>wrote:

> Hi!
>
>
>  If I create a callback with either of these values:
>>
>>     * $callback = 'Foo::bar';
>>     * $callback = array('Foo', 'Bar');
>>
>> is_callable() now returns true. In PHP 5.2 and 5.3, it returned false,
>> which is what I'd expect.
>>
>
> I tried the code from the bug and it returned true for me in 5.3:
>
>  class Foo
>    {
>        public function bar()
>        {
>           return __METHOD__;
>        }
>    }
> $callback = array('Foo', 'Bar');
> var_dump(is_callable($**callback));
>
> prints true in 5.3.9. Same happens for me with 5.2.
>
> I think if it returned false, it was a bug - this method is certainly
> callable, which one can check by calling it and succeeding.
>
>
>  you can call it; it just raises an E_STRICT." That's true. Unless the
>> method actually utilizes $this, in which case you get a fatal: "Using
>> $this when not in object context." And I can think of precisely zero
>> situations where I'd want to call a non-static method statically and
>> expect it to work.
>>
>
> This is a different thing - yes, the method may fail, however is_callable
> is not meant to answer the question "will method work as expected" - it is
> not possible - but only the question "if I called this method as a callback
> - would the engine be able to proceed with the call?". We could of course
> make the engine to disallow static calls to non-static functions - it would
> be quite complex as Foo::Bar not always means static call - but that is not
> within the responsibilities of is_callable. is_callable is supposed to
> dry-run the call code and see if it would fail to resolve, nothing more.
>
> As for situations where static and non-static method would be expected to
> work - unfortunately, I've seen code that calls functions both statically
> and non-statically, and expects it to work. I'm not saying it's a good
> thing but that's what people use. Changing it means changing the engine
> rules and probably will break some code.
>
>
>  The point is: if I call is_callable() and it returns true, I should have
>> a reasonable expectation that calling the callback will now work. In
>>
>
> We have different definitions of what "work" means here. The call will
> work. The method itself may not work, but is_callable is certainly never
> would be able to guarantee that certain method will never fail. I
> understand I'm being a bit formalistic here, but that's because I'm trying
> to explain what is_callable is actually does. The problem is not in
> is_callable but in the fact that the engine allows you to call Foo::Bar.
> This call may mean a number of things - static call, parent method call,
> etc.
>
>
>  I propose that when a string callback referencing a static method call
>> OR an array callback referencing a static method call refers to a method
>> that is not marked static, is_callable() should return false.
>>
>
> I don't see this happening in 5.4, but in more general way, I don't see
> is_callable departing from what the engine does. To make it worse, there
> are more cases where is_callable returns true but you can not actually call
> it - try making bar abstract method. The problem is that even the success
> of the call is actually runtime-dependent, so what is_callable is
> *actually* saying is "I can see how it could work, given the right
> circumstances", but nobody can guarantee there won't be wrong circumstances
> when it is actually called. I don't think it can be really fixed without
> doing pretty serious changes to the engine and breaking some code.
> --
> Stanislav Malyshev, Software Architect
> SugarCRM: http://www.sugarcrm.com/
> (408)454-6900 ext. 227
>
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>
Well, I'm +1 with Stas (and his explanation) ; but I'm also +1 to break the
compatibility about that behavior in our next major (PHP6? PHP7?)

We need to patch the engine, as patching is_callable() to handle just some
cases wouldn't be a good solution. As Stas said, is_callable() has to
reflect what the engine thinks (zend_is_callable_ex()).
But to patch it, we need approval from the community, and to wait for the
next major release as our release process prevents us from breaking BC in
minors :)

Cheers,

Julien.P

Reply via email to