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