- 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);