php 获取函数或方法的形参和实参

// 定义一个函数
funcrion my_fun($a,$b,$c,$d,$e,$n){
  my_fun2($args);
}
// 有时有需要将函数my_fun的多个参数合并传入另一个函数时,
// 特别麻烦需要一个手写合并为一个数组,当参数太多时,特别麻烦

解决方法一:func_num_args() 将参数合并

funcrion my_fun($a,$b,$c,$d,$e,$n){
  my_fun2(func_get_args());
}
var_dump(my_fun("asd1","asd2","asd3","asd4","asd5","asd6"));

输出

[
"asd1","asd2","asd3","asd4","asd5","asd6"
]

缺点

func_get_args 返回的是一个数字索引数组,如何返回key=>value 的关联数组呢

解决方法二:new ReflectionFunction 将参数合并

funcrion my_fun($a,$b,$c,$d,$e,$n){
  my_fun2(getFunctionArgs(__FUNCTION__));
}
/**
 * 获取函数的的形参名称
 * @param $functionName
 * @return false|array
 */
function getFunctionArgs($functionName){
    if (function_exists($functionName)) {
        try {
            $fun = new  ReflectionFunction($functionName);
        } catch (ReflectionException $e) {
            return false;
        }
        $paramsName = [];
        foreach ($fun->getParameters() as $parameter) {
            $paramsName[] = $parameter->name;
        }
        return $paramsName;
    }
}
var_dump(my_fun("asd1","asd2","asd3","asd4","asd5","asd6"));

输出

[
  "a"=>"asd1","b"=>"asd2",
  "c"=>"asd3","d"=>"asd4",
  "e"=>"asd5","n"=>"asd6"
]

缺点

ReflectionFunction 虽然返回了关联数组但是,只能用于函数,对象的方法不行

解决方法三:ReflectionMethod 对象方法的形参实参合并

funcrion my_fun($a,$b,$c,$d,$e,$n){
  my_fun2(getParams());
}
/**
 * 获取函数的的形参名称
 * @param $functionName
 * @return false|array
 */
function getFunctionArgs($functionName){
    if (function_exists($functionName)) {
        try {
            $fun = new  ReflectionFunction($functionName);
        } catch (ReflectionException $e) {
            return false;
        }
        $paramsName = [];
        foreach ($fun->getParameters() as $parameter) {
            $paramsName[] = $parameter->name;
        }
        return $paramsName;
    }
}

/**
 * 获取一个类的某个方法的形参名称
 * @param $className
 * @param $methodName
 * @return false|array
 */
function getMethodArgs($className, $methodName){
    try {
        $ref = new ReflectionMethod($className, $methodName);
    } catch (ReflectionException $e) {
        return false;
    }
    $paramsName = [];
    foreach ($ref->getParameters() as $param) {
        $paramsName[] = $param->name;
    }
    return $paramsName;
}

/**
 * 兼容对象和函数的写法
 * @return array|mixed
 */
function getParams(){
    $backtrace = debug_backtrace()[1];
    $functionName = $backtrace['function'];
    if (isset($backtrace["class"])) {
        $paramsNames = getMethodArgs($backtrace["class"], $functionName);
    } else {
        $paramsNames = getFunctionArgs($functionName);
    }
    return ($paramsNames and !empty($paramsNames))
        ? array_combine($paramsNames, $backtrace["args"])
        : $backtrace["args"];
}

var_dump(my_fun("asd1","asd2","asd3","asd4","asd5","asd6"));

输出

[
  "a"=>"asd1","b"=>"asd2",
  "c"=>"asd3","d"=>"asd4",
  "e"=>"asd5","n"=>"asd6"
]

最终

getParams() 函数通过兼容写法ReflectionMethod 类和 ReflectionFunction类,实现快速合并形参实参

This entry was posted in php. Bookmark the permalink.

发表回复