<?php
class User {}
class Contact {}
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;
}
}
$my = new MyClass;
try {
echo "A\n";
$my->setHandler(function (User $user, Contact $contact) {});
echo "B\n";
$my->setHandler(function (User $user, $contact) {});
echo "C\n";
} catch (Exception $e) {
echo $e->getMessage();
}
PD9waHAKCmNsYXNzIFVzZXIge30KY2xhc3MgQ29udGFjdCB7fQoKY2xhc3MgTXlDbGFzcyB7CgogICAgcHJpdmF0ZSAkaGFuZGxlcjsKCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0SGFuZGxlcigkZnVuY3Rpb24pIHsKICAgICAgICB0cnkgewogICAgICAgICAgICAkciA9IG5ldyBSZWZsZWN0aW9uRnVuY3Rpb24oJGZ1bmN0aW9uKTsKICAgICAgICB9IGNhdGNoIChSZWZsZWN0aW9uRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ0ludmFsaWQgY2FsbGJhY2sgcGFzc2VkLicpOwogICAgICAgIH0KICAgICAgICBpZiAoJHItPmdldE51bWJlck9mUGFyYW1ldGVycygpICE9PSAyKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oJ1RoZSBjYWxsYmFjayBtdXN0IGhhdmUgZXhhY3RseSAyIGFyZ3VtZW50cy4nKTsKICAgICAgICB9CiAgICAgICAgc3RhdGljICRkID0gYXJyYXkoJ1VzZXInLCAnQ29udGFjdCcpOwogICAgICAgIGZvcmVhY2ggKCRyLT5nZXRQYXJhbWV0ZXJzKCkgYXMgJGkgPT4gJHApIHsKICAgICAgICAgICAgaWYgKCEkYyA9ICRwLT5nZXRDbGFzcygpIG9yIHN0cmNhc2VjbXAoJGMtPmdldE5hbWUoKSwgJGRbJGldKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbihzcHJpbnRmKAogICAgICAgICAgICAgICAgICAgICdUaGUgYXJndW1lbnQgIyVkIG11c3QgaGF2ZSB0eXBlIGhpbnRpbmc6ICVzJywKICAgICAgICAgICAgICAgICAgICAkaSArIDEsCiAgICAgICAgICAgICAgICAgICAgJGRbJGldCiAgICAgICAgICAgICAgICApKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAkdGhpcy0+aGFuZGxlciA9ICRmdW5jdGlvbjsKICAgIH0KCn0KCiRteSA9IG5ldyBNeUNsYXNzOwp0cnkgewogICAgZWNobyAiQVxuIjsKICAgICRteS0+c2V0SGFuZGxlcihmdW5jdGlvbiAoVXNlciAkdXNlciwgQ29udGFjdCAkY29udGFjdCkge30pOwogICAgZWNobyAiQlxuIjsKICAgICRteS0+c2V0SGFuZGxlcihmdW5jdGlvbiAoVXNlciAkdXNlciwgJGNvbnRhY3QpIHt9KTsKICAgIGVjaG8gIkNcbiI7Cn0gY2F0Y2ggKEV4Y2VwdGlvbiAkZSkgewogICAgZWNobyAkZS0+Z2V0TWVzc2FnZSgpOwp9