gpt4 book ai didi

php - 如何获取运行时确定的可调用参数的数量?

转载 作者:IT王子 更新时间:2023-10-29 00:06:07 25 4
gpt4 key购买 nike

注意:通过写这个问题,我已经发现我对使用新的语言功能过于热心了。更简洁的解决方案是改用策略模式……不过,我还是很好奇是否有解决此问题的正确方法。

TL;DR:您能否反射(reflection) PHP 中的泛型 Callable,而无需手动对所有类型的 Callable 进行类型检查?

在 PHP 5.4 中,我们有一个新的类型提示:可调用。这看起来很有趣。我想我会通过以下方式利用它:

<?php
public function setCredentialTreatment(callable $credentialTreatment) {
// Verify $credentialTreatment can be used (ie: accepts 2 params)
... magic here ...
}
?>

到目前为止,我的想法是对可调用对象进行一系列类型检查,并从中推断出要使用哪个 Reflection* 类:

<?php
if(is_array($callable)) {
$reflector = new ReflectionMethod($callable[0], $callable[1]);
} elseif(is_string($callable)) {
$reflector = new ReflectionFunction($callable);
} elseif(is_a($callable, 'Closure') || is_callable($callable, '__invoke')) {
$objReflector = new ReflectionObject($callable);
$reflector = $objReflector->getMethod('__invoke');
}

// Array of ReflectionParameters. Yay!
$parameters = $reflector->getParameters();
// Inspect parameters. Throw invalidArgumentException if not valid.
?>

现在,对我来说,这感觉太复杂了。我是否缺少某种捷径来实现我在这里想要做的事情?欢迎任何见解:)

最佳答案

我创建了一个更短的版本,它的工作方式与 call_user_func() 非常相似,并在 PHP 手册中针对回调/可调用对象的所有不同类型对其进行了测试。这样您几乎可以在任何地方使用它。 call_user_func() 不只接受对象,而且我认为这个函数也没有意义,因为它只处理回调。

下面包含有关如何使用它的测试和建议,希望对您有所帮助:

function getNrOfParams($callable)
{
$CReflection = is_array($callable) ?
new ReflectionMethod($callable[0], $callable[1]) :
new ReflectionFunction($callable);
return $CReflection->getNumberOfParameters();
}

整个测试及其结果:

<?php   
class Smart
{
public function __invoke($name)
{

}

public function my_callable($one, $two, $three)
{

}

public static function myCallableMethod($one, $two)
{

}

public static function who()
{
echo "smart the parent class";
}
}

class Smarter extends Smart
{
public static function who()
{
echo "smarter";
}
}

function my_ca($one)
{

}

function getNrOfParams($callable)
{
$CReflection = is_array($callable) ? new ReflectionMethod($callable[0], $callable[1]) : new ReflectionFunction($callable);
return $CReflection->getNumberOfParameters();
}
// Test 1 Callable Function
echo "Test 1 - Callable function:" . getNrOfParams('my_ca');

// Test 2 Static method
echo " Test 2 - Static class method:" . getNrOfParams(array('Smart', 'myCallableMethod'));

// Test 3 Object method
$smart = new Smart();
echo " Test 3 - Object method:" . getNrOfParams(array($smart, 'my_callable'));

// Test 4 Static method call (As of PHP 5.2.3)
//echo " Test 4 - Static class method call:" . getNrOfParams('Smart::myCallableMethod');
// Calling a static method this way does not work in ReflectionFunction.
// However, Test 2 provides a solution.

// Test 5 Relative static method (As of PHP 5.3.0)
//echo " Test 5 - Relative static class method:" . getNrOfParams(array('Smarter', 'parent::who'));
// Calling a relative static method doesn't work either. ReflectionMethod lacks support.
// All other tests work.

// Tesy 6 __invoke
echo " Test 6 - __invoke:" . getNrOfParams(array($smart, '__invoke'));

// Test 7 Closure
$closure = function($one, $two, $three)
{
// Magic
};
echo " Test 7 - Closure:" . getNrOfParams($closure);

关于php - 如何获取运行时确定的可调用参数的数量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13071186/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com