PHP实现参数的自定义顺序调用

  • A+
所属分类:PHP

首先我们以添加用户为例来看两个方法:

//方法①
public function addUser(string $userName, string $userPassword, string $telephone, string $userEmail = '')
{
    
}
//方法②
public function addUser(array $data)
{
    
}

方法①的优点: 通过方法的定义,就可以清楚的知道方法的参数个数以及数据类型,方便调用者使用。

              缺点: 如果参数过多,调用时会非常麻烦,而且如果默认参数有很多,在调用时, 非常容易出错。

方法②的优点: 调用者不需要按照参数的顺序调用,只需要将其拼接成数组即可。

             缺点:  调用者必须知道函数内部,究竟需要什么参数,才可以调用,增加了使用难度。

那么,可以通过什么样的方式来使方法②转化为方法①呢?

在之前,我们曾经使用过反射,来调用其他来的方法,那么可不可以通过反射的方式,得到函数的参数顺序和默认值,将方法②中的 $data 转化为 方法①中的参数。

具体实现:

//获取反射类
$className = $this->getReflectionClass($method);

$object = new \ReflectionClass($className);
//获取构造函数
$objectInstance = $object->newInstance();
$reflectionMethod = new \ReflectionMethod($className, $method);

//检测成员方法是否存在
if (empty($reflectionMethod)) {
    return '方法不存在';
}
//校验成员方法是否是public
if (!$reflectionMethod->isPublic()) {
    return '方法不可用';
}
$parameters = $reflectionMethod->getParameters();//获取所有的参数
if (empty($parameters)) {
    //无参数
    return $reflectionMethod->invoke($objectInstance);
}
$passParams = [];
foreach ($parameters as $parameter) {
    $paramName = $parameter->getName();
    if (isset($params[$paramName])) {
        //如果参数是数组,必须是数组
        if ($parameter->isArray() && !is_array($params[$paramName])) {
            return '参数格式错误';
        }
        $passParams[] = $params[$paramName];
    } else if ($parameter->isDefaultValueAvailable()) {
        //判断是否有默认值 取参数默认值
        $passParams[] = $parameter->getDefaultValue();
    } else {
        //必填参数 没有填 返回错误
        return '参数必填,没传';
    }
}

return $reflectionMethod->invoke($objectInstance, ...$passParams);

avatar

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: