【问题标题】:How do I get the type of constructor parameter via reflection?如何通过反射获取构造函数参数的类型?
【发布时间】:2018-12-13 01:47:23
【问题描述】:

我在构造函数参数列表中使用类型提示,如下所示:

public function __construct(FooRepository $repository)

有没有办法使用 PHP 反射 API 来获取提示类型?换句话说,我想要一个可以调用的反射函数以某种方式取回字符串“FooRepository”。我尝试通过反射获取构造函数,然后获取构造函数的参数,但我没有看到任何可以给我提示类型的字符串的东西。

【问题讨论】:

  • 最终,这被写入了 Laravel 的 IoC 容器 - bravo @taylorotwell!

标签: php reflection


【解决方案1】:

试试这个。

class Foo {
    public function __construct(Bar $test) {
    }
}

class Bar {
    public function __construct() {
    }
}

$reflection = new ReflectionClass('Foo');
$params = $reflection->getConstructor()->getParameters();
foreach ($params AS $param) {
    echo $param->getClass()->name . '<br>';
}

【讨论】:

  • +1 太棒了。而且我以前很长一段时间都在这样做。他们真的应该有朝一日记录反思。
  • 这仅适用于类,任何其他提示都会失败,并出现“类 *** 不存在”异常。
  • @AlixAxel 实际上只允许类和数组进行类型提示。你应该先检查ReflectionParameter::isArray()
  • @hek2mgl 甚至更好 $param-&gt;getType()-&gt;getName() 用于获取类型。这不需要检索类,也允许标量类型。
【解决方案2】:

查看 PHP 5.4

他们计划在今年推出 PHP 5.4,它将具有 parameter->getHint()

的反射方法(当前在开发版本中)

但是,在 5.4 正式发布之前,我使用的是 ReflectionClass::getDocComment()

例如,您可以在@param 中指定它。

// Adapted from meager's example
class Bar {}

class Foo {
    /**
    * @param MyType $value
    * @param array $value2
    */
    function __construct(Bar $value, array $value2) {
    }
}

// Regex
function getHint( $docComment, $varName ) {
    $matches = array();
    $count = preg_match_all('/@param[\t\s]*(?P<type>[^\t\s]*)[\t\s]*\$(?P<name>[^\t\s]*)/sim', $docComment, $matches);
    if( $count>0 ) {
        foreach( $matches['name'] as $n=>$name ) {
            if( $name == $varName ) {
                return $matches['type'][$n];
            }
        }
    }
    return null;
}

$reflection = new ReflectionClass('Foo');
$constructor= $reflection->getConstructor();
$docComment = $constructor->getDocComment();
$params = $constructor->getParameters();
foreach ($params AS $param) {
    $name = $param->getName();
    echo $name ." is ";
    //echo $param->getHint()."\n"; // in PHP 5.4
    echo getHint($docComment, $name)."\n"; // work around
}

输出:

value is MyType
value2 is array

【讨论】:

  • +1,但是 PHP 5.4.7 并且仍然没有 ReflectionParameter::getHint() 的迹象 :(.
  • @AlixAxel,遗憾的是,由于语言开发人员完全缺乏远见/专注,过去几年我已经离开 PHP。 :(
  • 哦,好的。只是出于好奇,您选择什么来代替它?
  • @AlixAxel Java 主要是。比 C# 更喜欢它。语言有一个很好的时间表。如果 PHP 6 会出现,那就太不理想了。
【解决方案3】:

你是想得到暗示的类型,还是实际的类型?我不明白您为什么要获取提示类型,因为您知道它是“FooRepository”,否则 PHP 会引发错误。

您可以通过get_class 获取实际类型,还可以通过ReflectionClass::isSubclassOf 确定对象是否继承自给定类。

【讨论】:

  • 我可以看到这将在 MVC 框架中派上用场,用于动态加载模型类的文件并将 post/get 数据动态映射到对象。
  • @Twisted typehinted type 是有区别的。重新阅读我的回答,你完全没有抓住重点。
  • @meager 请允许我重新措辞。我断言在很多情况下您都想知道暗示的类型。例如,您可以轻松地在 ORM 对象类中创建一些 setPropX(myType $value) 方法。然后,您的 ORM 实现可以反映以获取提示,以便您知道要转换为哪种类型。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-13
  • 2021-10-05
  • 1970-01-01
  • 2017-09-14
  • 1970-01-01
  • 2019-11-23
相关资源
最近更新 更多