2010-12-22 65 views
11

我想使用PHP反射動態加載基於控制器方法中的參數類型的模型類文件。這是一個示例控制器方法。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()要求定義該類 - 我爲什麼要這樣做的一部分是自動加載控制器操作可能需要的任何模型。

有沒有辦法獲得參數類型的名稱,而無需首先加載類文件?

+0

'$ p`是什麼?你的意思是`$ param`? – 2010-12-22 21:33:56

+0

除非Reflection類在其文檔中缺少重要的信息,否則我不認爲如果不加載類就可以獲得暗示類型。 – simshaun 2010-12-22 21:41:06

+0

@simshaun:否。該類需要加載,否則`getClass`將拋出`ReflectionException`。 – netcoder 2010-12-22 21:45:08

回答

8

我認爲,唯一的辦法就是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; 
1

我有類似的問題,在反射參數檢查時的getClass時未加載的類。我做了一個包裝函數來從例子netcoder中取得類名。問題是netcoder代碼不工作,如果它是一個數組或不是類 - >函數($ test){}它將返回字符串方法的反射參數。

下面的方式我如何解決它,即時通訊使用嘗試抓住,因爲我的代碼需要在某個階段的類。所以,如果我下次要求它,得到類的作品,並沒有拋出異常。

/** 
* 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; 
} 
4

你可以使用Zend框架2.

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

foreach($method_reflection->getParameters() as $reflection_parameter) 
{ 
    $type = $reflection_parameter->getType(); 
} 
7

我認爲這是你在找什麼:

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

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

這是一個比that answer更好的正則表達式。即使參數是可選的,它也可以工作。

preg_match('~>\s+([a-z]+)\s+~', (string)$ReflectionParameter, $result); 
$type = $result[1]; 
相關問題