Not quite sure of the best title but I will explain what I am asking as best I can. Assume I have the following file:
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;
}
}
Now if I were to use reflection, I could get the fully qualified class names from the type hints in the construct.
However, I would recieve FooNamespace\FooClass
and BarNamespace\BarClass
. Not, FooNamespace\FooClass
and BarNamespace\Bar
. I would also get no reference to BazNamespace\BazClass
.
Basically, my question is: How can I get the fully qualified names from MyCustomClass.php
while only knowing FooClass
, Bar
, and, BazSpecial
?
I do not want to use a file parser as this will eat performance. I want to be able to do something like:
$class = new ReflectionClass('MyCustomClass');
...
$class->getUsedClass('FooClass'); // FooNamespace\FooClass
$class->getUsedClass('Bar'); // BarNamespace\BarClass
$class->getUsedClass('BazSpecial'); // BazNamespace\BazClass
How would I go about doing this?
Seeing as no one has answered, I assume there is not an easy way to achieve this. I have therefore created my own class called ExtendedReflectionClass
which achieves what I need.
I have created a gist with the class file and a readme, which is at the bottom so get scrolling!.
ExtendedReflectionClass
Usage example:
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
I use the TokenFinderTool for that.
Basically, it uses tokens to extract the use statements.
As far as I know, \Reflection objects in php unfortunately don't have such a method yet.
The code below extracts the use import statements from a file, using the TokenFinder tool.
$tokens = token_get_all(file_get_contents("/path/to/MyCompany/MyClass.php"));
a(TokenFinderTool::getUseDependencies($tokens));
Will output:
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)
Note: if you have a class name only, you can use this snippet instead:
$o = new \ReflectionClass($className);
$tokens = token_get_all(file_get_contents($$o->getFileName()));
$useStatements = TokenFinderTool::getUseDependencies($tokens);