PHP Reflection - Получить тип параметра метода в виде строки - PullRequest
11 голосов
/ 23 декабря 2010

Я пытаюсь использовать PHP-отражение для динамической загрузки файлов классов моделей автоматически в зависимости от типа параметра в методе контроллера.Вот пример метода контроллера.

<?php

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

Вот то, что у меня пока есть.

//Target the first parameter, as an example
$param = new ReflectionParameter(array('ExampleController', 'PostMaterial'), 0);

//Echo the type of the parameter
echo $param->getClass()->name;

Это работает, и на выходе будет «SteelSlugModel», как и ожидалось.Тем не менее, существует вероятность того, что файл класса модели еще не может быть загружен, и использование getClass () требует, чтобы класс был определен - часть того, почему я делаю это, - автозагрузка любых моделей, которые могут потребоваться для действия контроллера.

Есть ли способ получить имя типа параметра без предварительной загрузки файла класса?

Ответы [ 6 ]

10 голосов
/ 28 октября 2013

Я предположил, что это то, что вы ищете:

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();
}
9 голосов
/ 23 декабря 2010

Я думаю, что единственный способ - export и манипулирование строкой результата:

$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;
4 голосов
/ 30 октября 2012

Вы можете использовать Zend Framework 2.

$method_reflection = new \Zend\Code\Reflection\MethodReflection( 'class', 'method' );

foreach( $method_reflection->getParameters() as $reflection_parameter )
{
  $type = $reflection_parameter->getType();
}
2 голосов
/ 30 августа 2015

getType метод может быть использован начиная с 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()
);
1 голос
/ 29 февраля 2012

У меня была похожая проблема при проверке getClass для параметра отражения, когда класс не был загружен.Я сделал функцию-обертку, чтобы получить имя класса из примера netcoder.Проблема заключалась в том, что код сетевого кодера не работал, если он был массивом или не классом -> function ($ test) {}, он возвращал бы метод to string для параметра отражения., я использую try catch, потому что мой код требует в какой-то момент класса.Так что, если я запрошу это в следующий раз, класс получится и не выдаст исключение.

/**
 * 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 голосов
/ 03 марта 2017

Это лучшее регулярное выражение, чем из , которое отвечает . Он будет работать, даже если этот параметр является необязательным.

preg_match('~>\s+([a-z]+)\s+~', (string)$ReflectionParameter, $result);
$type = $result[1];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...