PHP Reflection - Get Method Parameter Type As String

11,053

Solution 1

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;

Solution 2

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

Solution 3

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

Solution 4

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

Solution 5

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;
}
Share:
11,053

Related videos on Youtube

Jarrod Nettles
Author by

Jarrod Nettles

Engineering Manager with Apple Maps.

Updated on May 13, 2022

Comments

  • Jarrod Nettles
    Jarrod Nettles almost 2 years

    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 example controller method.

    <?php
    
    class ExampleController
    {
        public function PostMaterial(SteelSlugModel $model)
        {
            //etc...
        }
    }
    

    Here's what I have so far.

    //Target the first parameter, as an example
    $param = new ReflectionParameter(array('ExampleController', 'PostMaterial'), 0);
    
    //Echo the type of the parameter
    echo $param->getClass()->name;
    

    This works, and the output would be 'SteelSlugModel', as expected. However, there is the possibility that the class file of the model may not be loaded yet, and using getClass() requires that the class be defined - part of why I'm doing this is to autoload any models that a controller action may require.

    Is there a way to get the name of the parameter type without having to load the class file first?

  • Jarrod Nettles
    Jarrod Nettles over 13 years
    This works, although I truly wish I could avoid having to parse a string to do it. Good work.
  • dellsala
    dellsala over 11 years
    Is this still the only way to do this? Having to rely on the export method's non-standard output format is sketchy!
  • Matthias Tylkowski
    Matthias Tylkowski over 11 years
    The function getTypeis not existing enymore, it's now called getClass.
  • Xeoncross
    Xeoncross about 11 years
    This function doesn't need to waste time using preg_match. (It also fails of the parameter doesn't have a class hint). See my updated example: gist.github.com/Xeoncross/4723819
  • Maciej Sz
    Maciej Sz about 9 years
    Using current reflection API this is the best solution and should be the accepted answer.
  • emmanuel honore
    emmanuel honore over 7 years
    getClass() leads to error when a method signature contains type hinting like "string" or "array". And type "string" can't be detected on PHP < 7.