ID:               45925
 Updated by:       [EMAIL PROTECTED]
 Reported By:      david at grudl dot com
 Status:           Wont fix
 Bug Type:         Feature/Change Request
 Operating System: -
 PHP Version:      5.3.0alpha1
 New Comment:

You want to be able to type hint the fact that an object can be
invoked.

You may want __invoke on a class without having anything related to
closures, so the other solutions don't sound reasonable as well. But if
you really feel they are, write an RFC and post it on the internals ML.




Previous Comments:
------------------------------------------------------------------------

[2008-08-26 20:17:00] david at grudl dot com

Thats right (this is mentioned in text). But interface Callable can
exists without any method (so-called "marker interface"). 

What about two others solutions?

------------------------------------------------------------------------

[2008-08-26 20:08:12] [EMAIL PROTECTED]

__invoke takes arbitrary arguments, which means you can't have an
interface that covers it.

------------------------------------------------------------------------

[2008-08-26 16:33:13] david at grudl dot com

Description:
------------
It should be useful to encapsulate PHP pseudotype callback using new
magic method __invoke(). But this type of "callable" objects are not
distinguishable by any interface or class name (compare it with
ArrayAccess or Countable interfaces).

// this is simple callback encapsulation
class Callback 
{
        private $callback;

        public function __construct($callback)
        {
                $this->callback = $callback;
        }

        public function __invoke()
        {
                $args = func_get_args();
                return call_user_func_array($this->callback, $args);
        }
}


// a Callback object:
$callback = new Callback(array('MyClass', 'anyMethod'));

// a Closure object:
$closure = function() { ... };


The problem: there is nothing common between Callback and Closure
object, what can be used (for example) as type hinting. 

First solution using interface:

interface Callable { 
    function __invoke()
}

class Callback implements Callable { ... }

function event(Callable $obj)
{
        $obj($sender, $param);
}

event($callback);
event($closure); // do not work

The class Closure is not Callable implementor thus it do not work.
Problematic is __invoke method's parameters too.

The other way:

class Callback extends Closure { ... } // do not work

function event(Closure $obj)
{
        $obj($sender, $param);
}

event($callback);
event($closure);

This is not possible, because Closure is final. Solution is make
Closure non-final.

The third way - create static factory to encapsulate PHP callback as
Closure:

function event(Closure $obj)
{
        $obj($sender, $param);
}

$callback = Closure::factory(array('MyClass', 'anyMethod'));
event($callback);
event($closure);

Maybe the most easy way.



------------------------------------------------------------------------


-- 
Edit this bug report at http://bugs.php.net/?id=45925&edit=1

Reply via email to