MartyIX
MartyIX

Reputation: 28648

How to "validate" callback functions?

I put my question in the following code since it seems the easier way how to explain my question:

class MyClass 
{

       public function setHandler($function) {
             // at this point I would like to validate
             // that the function $function can be called
             // with certain parameters.
             //
             // For example: $function has to be a function
             // with the synopsis: function (User $user, Contact $contact) {}

             // The point of the check is to know about an error soon.
       }
}

Reflection seems so impractical for daily use. How would you solve the problem?

Upvotes: 0

Views: 333

Answers (2)

mpyw
mpyw

Reputation: 5744

Do you really think this snippet has heavy weight...? I don't think so.

class MyClass {

    private $handler;

    public function setHandler($function) {
        try {
            $r = new ReflectionFunction($function);
        } catch (ReflectionException $e) {
            throw new InvalidArgumentException('Invalid callback passed.');
        }
        if ($r->getNumberOfParameters() !== 2) {
            throw new InvalidArgumentException('The callback must have exactly 2 arguments.');
        }
        static $d = array('User', 'Contact');
        foreach ($r->getParameters() as $i => $p) {
            if (!$c = $p->getClass() or strcasecmp($c->getName(), $d[$i])) {
                throw new InvalidArgumentException(sprintf(
                    'The argument #%d must have type hinting: %s',
                    $i + 1,
                    $d[$i]
                ));
            }
        }
        $this->handler = $function;
    }

}

Example: http://ideone.com/kt7jk7
Benchmark: http://ideone.com/OmF010

Upvotes: 0

Sven
Sven

Reputation: 70853

It seems like you want to confirm that a given callback function does have a certain interface.

Functions cannot implement interfaces, but classes can. Why don't you pass an object implementing a certain interface instead of a function?

Upvotes: 1

Related Questions