PHP Reflection - Get Method Parameter Type As String

后端 未结 6 1847
無奈伤痛
無奈伤痛 2020-12-01 18:44

I\'m trying to use PHP reflection to dynamically load the class files of models automatically based upon the type of parameter that is in the controller method. Here\'s an e

相关标签:
6条回答
  • 2020-12-01 19:10

    You could use Zend Framework 2.

    $method_reflection = new \Zend\Code\Reflection\MethodReflection( 'class', 'method' );
    
    foreach( $method_reflection->getParameters() as $reflection_parameter )
    {
      $type = $reflection_parameter->getType();
    }
    
    0 讨论(0)
  • 2020-12-01 19:15

    getType method can be used since PHP 7.0.

    class Foo {}
    class Bar {}
    
    class MyClass
    {
        public function baz(Foo $foo, Bar $bar) {}
    }
    
    $class = new ReflectionClass('MyClass');
    $method = $class->getMethod('baz');
    $params = $method->getParameters();
    
    var_dump(
        'Foo' === (string) $params[0]->getType()
    );
    
    0 讨论(0)
  • 2020-12-01 19:24

    I supposed this is what you are looking for:

    class MyClass {
    
        function __construct(AnotherClass $requiredParameter, YetAnotherClass $optionalParameter = null) {
        }
    
    }
    
    $reflector = new ReflectionClass("MyClass");
    
    foreach ($reflector->getConstructor()->getParameters() as $param) {
        // param name
        $param->name;
    
        // param type hint (or null, if not specified).
        $param->getClass()->name;
    
        // finds out if the param is required or optional
        $param->isOptional();
    }
    
    0 讨论(0)
  • 2020-12-01 19:29

    This is a better regular expression than the one from that answer. It will work even when the parameter is optional.

    preg_match('~>\s+([a-z]+)\s+~', (string)$ReflectionParameter, $result);
    $type = $result[1];
    
    0 讨论(0)
  • 2020-12-01 19:32

    I think the only way is to export and manipulate the result string:

    $refParam = new ReflectionParameter(array('Foo', 'Bar'), 0);
    
    $export = ReflectionParameter::export(
       array(
          $refParam->getDeclaringClass()->name, 
          $refParam->getDeclaringFunction()->name
       ), 
       $refParam->name, 
       true
    );
    
    $type = preg_replace('/.*?(\w+)\s+\$'.$refParam->name.'.*/', '\\1', $export);
    echo $type;
    
    0 讨论(0)
  • 2020-12-01 19:35

    I had similar problem, when checking getClass on reflection parameter when a class was not loaded. I made a wrapper function to get the class name from example netcoder made. Problem was that netcoder code didnt work if it was an array or not an class -> function($test) {} it would return the to string method for the reflection parameter.

    Below the way how i solved it, im using try catch because my code requires at some point the class. So if i request it the next time, get class works and doesnt throw an exception.

    /**
     * Because it could be that reflection parameter ->getClass() will try to load an class that isnt included yet
     * It could thrown an Exception, the way to find out what the class name is by parsing the reflection parameter
     * God knows why they didn't add getClassName() on reflection parameter.
     * @param ReflectionParameter $reflectionParameter
     * @return string Class Name
     */
    public function ResolveParameterClassName(ReflectionParameter $reflectionParameter)
    {
        $className = null;
    
        try
        {
                     // first try it on the normal way if the class is loaded then everything should go ok
            $className = $reflectionParameter->getClass()->name;
    
        }
        // if the class isnt loaded it throws an exception and try to resolve it the ugly way
        catch (Exception $exception)
        {
            if ($reflectionParameter->isArray())
            {
                return null;
            }
    
            $reflectionString = $reflectionParameter->__toString();
            $searchPattern = '/^Parameter \#' . $reflectionParameter->getPosition() . ' \[ \<required\> ([A-Za-z]+) \$' . $reflectionParameter->getName() . ' \]$/';
    
            $matchResult = preg_match($searchPattern, $reflectionString, $matches);
    
            if (!$matchResult)
            {
                return null;
            }
    
            $className = array_pop($matches);
        }
    
        return $className;
    }
    
    0 讨论(0)
提交回复
热议问题