检查callable是否可以在php中接收类作为参数 [英] Check if callable can receive class as parameter in php
问题描述
我有一个可调用的 $f
,我想知道它是否可以接收某个类 Foo
的实例作为输入.
I have a callable $f
and I would like to know if it can receive an instance of a certain class Foo
as input.
目前我正在做类似的事情
At the moment I'm doing something like
try {
$f($foo);
} catch (\TypeError $e) {
throw new \InvalidArgumentException('The provided function can not evaluate inputs of this type');
}
有没有办法在不实际调用可调用对象的情况下进行检查?也许是反射或其他一些黑魔法?
Is there a way to check this WITHOUT actually invoking the callable? Maybe with reflection or some other dark magic?
推荐答案
如果您希望能够反映任何类型的可调用对象,您需要将逻辑封装在一个小函数中.根据您是否有数组、函数名或匿名函数,您需要创建一个 ReflectionFunction
或 反射方法
.幸运的是,这些都扩展了 ReflectionFunctionAbstract
,所以我们可以对返回值进行类型提示.
If you want to be able to reflect any kind of callable, you'll need to wrap up the logic in a small function. Depending on whether you've got an array, a function name or an anonymous function, you need to create either a ReflectionFunction
or ReflectionMethod
. Fortunately, these both extend ReflectionFunctionAbstract
, so we can type-hint the return value.
function reflectCallable($arg): ReflectionFunctionAbstract {
if (is_array($arg)) {
$ref = new ReflectionMethod(...$arg);
} elseif (is_callable($arg)) {
$ref = new ReflectionFunction($arg);
}
return $ref;
}
这将为您的可调用值返回适当的对象,然后您可以使用它来获取参数并采取相应的行动:
This will return you the appropriate object for your callable value, which you can then use to fetch the parameters and act accordingly:
function definedFunc(Foo $foo) {}
$callable = function(Foo $foo) {};
class Bar { public function baz(Foo $foo) {} }
foreach (['definedFunc', $callable, ['Bar', 'baz']] as $callable) {
$reflected = reflectCallable($callable);
if ((string) $reflected->getParameters()[0]->getType() === 'Foo') {
echo 'Callable takes Foo', PHP_EOL;
}
}
请注意,这不会进行任何错误处理 - 如果可调用对象不带任何参数或第一个参数没有类型,您可能会收到警告/通知.它还需要 PHP 7+,但希望这不是问题.
Note that this doesn't do any error handling - you'll probably get warnings/notices if the callable doesn't take any parameters or the first parameter doesn't have a type. It also requires PHP 7+, but hopefully that's not an issue.
目前不支持实现 我刚刚在 Twig 的源代码中发现了一些非常相似的东西,它做得更彻底:https://github.com/twigphp/Twig/blob/v2.8.0/src/Node/Expression/CallExpression.php#L280__invoke
的对象或定义为 "Foo::bar"
的静态调用,但它们不会太难必要时添加.
It doesn't currently support objects that implement I've just found something very similar in the source of Twig, which does a more thorough job: https://github.com/twigphp/Twig/blob/v2.8.0/src/Node/Expression/CallExpression.php#L280__invoke
or static calls defined as "Foo::bar"
, but they wouldn't be too hard to add if necessary.
这篇关于检查callable是否可以在php中接收类作为参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!