PHP Reflection - Получить метод Тип параметра As String
Я пытаюсь использовать отражение 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() требует определения класса - часть того, почему я делаю это, - это автозагрузка любых моделей, которые могут потребоваться для действия контроллера.
Есть ли способ получить имя типа параметра, не загружая сначала файл класса?
Ответы
Ответ 1
Я думаю, что единственный способ - 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;
Ответ 2
Я предполагал, что это то, что вы ищете:
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();
}
Ответ 3
Вы можете использовать Zend Framework 2.
$method_reflection = new \Zend\Code\Reflection\MethodReflection( 'class', 'method' );
foreach( $method_reflection->getParameters() as $reflection_parameter )
{
$type = $reflection_parameter->getType();
}
Ответ 4
У меня была аналогичная проблема при проверке getClass на параметре отражения, когда класс не был загружен. Я создал функцию-оболочку, чтобы получить имя класса из примера netcoder. Проблема заключалась в том, что код netcoder не работал, если он был массивом или не был функцией класса → ($ test) {} он возвращал метод 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;
}
Ответ 5
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()
);
Ответ 6
Это лучшее регулярное выражение, чем тот, который отвечает . Он будет работать, даже если параметр не является обязательным.
preg_match('~>\s+([a-z]+)\s+~', (string)$ReflectionParameter, $result);
$type = $result[1];