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

Reply via email to