【问题标题】:Get use statement from class从类中获取使用语句
【发布时间】:2015-07-30 05:58:27
【问题描述】:

不太确定最好的标题,但我会尽我所能解释我的要求。假设我有以下文件:

MyCustomClass.php

<?php    

namespace MyNamespace;

use FooNamespace\FooClass;
use BarNamespace\BarClass as Bar;
use BazNamespace\BazClass as BazSpecial;

class MyCustomClass {

    protected $someDependencies = [];

    public function __construct(FooClass $foo, Bar $bar) {

        $someDependencies[] = $foo;
        $someDependencies[] = $bar;
    }
}

现在,如果我要使用反射,我可以从构造中的类型提示中获取完全限定的类名。

但是,我会收到 FooNamespace\FooClassBarNamespace\BarClass。不是,FooNamespace\FooClassBarNamespace\Bar。我也不会提到BazNamespace\BazClass

基本上,我的问题是:如何在只知道FooClassBarBazSpecial 的情况下从MyCustomClass.php 获得完全限定名称?

我不想使用文件解析器,因为这会影响性能。我希望能够做类似的事情:

$class = new ReflectionClass('MyCustomClass');
...
$class->getUsedClass('FooClass'); // FooNamespace\FooClass
$class->getUsedClass('Bar'); // BarNamespace\BarClass
$class->getUsedClass('BazSpecial'); // BazNamespace\BazClass

我该怎么做呢?

【问题讨论】:

    标签: php reflection namespaces fully-qualified-naming


    【解决方案1】:

    鉴于没有人回答,我认为没有一种简单的方法可以实现这一点。因此,我创建了自己的名为 ExtendedReflectionClass 的类,它可以满足我的需要。

    我用类文件和自述文件创建了一个要点,它位于底部,所以请滚动!

    ExtendedReflectionClass

    使用示例

    require 'ExtendedReflectionClass.php';
    require 'MyCustomClass.php';
    
    $class = new ExtendedReflectionClass('MyNamespace\Test\MyCustomClass');
    
    $class->getUseStatements();    
    // [
    //     [
    //         'class' => 'FooNamespace\FooClass',
    //         'as' => 'FooClass'
    //     ],
    //     [
    //         'class' => 'BarNamespace\BarClass',
    //         'as' => 'Bar'
    //     ],
    //     [
    //         'class' => 'BazNamespace\BazClass',
    //         'as' => 'BazSpecial'
    //     ]
    // ]
    
    $class->hasUseStatement('FooClass'); // true
    $class->hasUseStatement('BarNamespace\BarClass'); // true
    $class->hasUseStatement('BazSpecial'); // true
    
    $class->hasUseStatement('SomeNamespace\SomeClass'); // false
    

    【讨论】:

    • @TheodoreR.Smith 1. 我想我没有看到需要创建一个包.. 我什至不记得我需要它是为了什么,是 4 年前 2. 是的,但是我有再次,我没有看到有必要在两个 require 语句中使用 composer 来证明概念。 UAF 是什么意思? 3. 谢谢。我希望我能记住我需要它的目的。
    【解决方案2】:

    我为此使用TokenFinderTool

    基本上,它使用标记来提取使用语句。

    据我所知,php 中的 \Reflection 对象很遗憾还没有这样的方法。

    下面的代码使用 TokenFinder 工具从文件中提取 use import 语句。

    $tokens = token_get_all(file_get_contents("/path/to/MyCompany/MyClass.php"));
    a(TokenFinderTool::getUseDependencies($tokens));
    

    将输出:

    array (size=9)
      0 => string 'Bat\CaseTool' (length=12)
      1 => string 'Bat\FileSystemTool' (length=18)
      2 => string 'Bat\StringTool' (length=14)
      3 => string 'Bat\ValidationTool' (length=18)
      4 => string 'CopyDir\AuthorCopyDirUtil' (length=25)
      5 => string 'PhpBeast\AuthorTestAggregator' (length=29)
      6 => string 'PhpBeast\PrettyTestInterpreter' (length=30)
      7 => string 'PhpBeast\Tool\ComparisonErrorTableTool' (length=38)
      8 => string 'Tiphaine\TiphaineTool' (length=21)
    

    注意:如果你只有一个类名,你可以用这个 sn-p 代替:

    $o = new \ReflectionClass($className);
    $tokens = token_get_all(file_get_contents($$o->getFileName()));
    $useStatements = TokenFinderTool::getUseDependencies($tokens);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-05
      • 1970-01-01
      • 2018-12-24
      • 2016-09-16
      • 2011-01-19
      相关资源
      最近更新 更多