PHP リフレクション
Nette\Utils\Reflection は、PHP のリフレクションのための便利な関数を提供する静的クラスです。ネイティブのリフレクションクラスの弱点を補い、PHP のバージョンによる振る舞いの違いをそろえるのが目的です。
インストール:
composer require nette/utils
以下の例では、次のクラスの別名が定義されているものとします。
use Nette\Utils\Reflection;
areCommentsAvailable(): bool
リフレクションが PHPdoc のコメントにアクセスできるかを調べます。オペコードのキャッシュのせいでコメントが使えないことがあります。たとえば opcache.save-comments ディレクティブをご覧ください。
expandClassName (string $name, ReflectionClass $context): string
クラス $context の文脈で、その名前空間と定義された別名を考慮しながら、クラス名
$name を完全修飾名に展開します。要するに、$name が $context
クラスの本体の中に書かれていたら PHP のパーサーがどう解釈するかを決めます。
namespace Foo;
use Bar;
class DemoClass
{
// new Bar, new Baz
}
$context = new ReflectionClass(Foo\DemoClass::class);
Reflection::expandClassName('Bar', $context); // 'Bar'
Reflection::expandClassName('Baz', $context); // 'Foo\Baz'
getMethodDeclaringMethod (ReflectionMethod $method): ReflectionMethod
$method
の実際の宣言を含むメソッドのリフレクションを返します。ふつうメソッドは自分自身が宣言ですが、メソッドの本体がトレイトに由来し、しかも別の名前になっていることがあります。
PHP は真の宣言を確実に判定できるだけの情報を提供しないので、Nette は独自の推測を使います。これは確実であるはずです。
trait DemoTrait
{
function foo()
{
}
}
class DemoClass
{
use DemoTrait {
DemoTrait::foo as foo2;
}
}
$method = new ReflectionMethod('DemoClass::foo2');
Reflection::getMethodDeclaringMethod($method); // ReflectionMethod('DemoTrait::foo')
getParameterDefaultValue (\ReflectionParameter $param): mixed
関数やメソッドのパラメータの既定値を返します。ネイティブの
ReflectionParameter::getDefaultValue()
と違い、既定値として使われた定数やクラス定数も正しく解決します。定数を解決できない場合は
\ReflectionException を投げます。
class DemoClass
{
const DefaultValue = 123;
}
function demo($param = DemoClass::DefaultValue)
{
}
$param = new ReflectionParameter('demo', 'param');
echo Reflection::getParameterDefaultValue($param); // 123
getPropertyDeclaringClass (ReflectionProperty $prop): ReflectionClass
プロパティ $prop
の宣言を含むクラスやトレイトのリフレクションを返します。プロパティはトレイトの中で宣言されていることもあります。
PHP は真の宣言を確実に判定できるだけの情報を提供しないので、Nette は独自の推測を使います。これは完全に確実とはいえません。
trait DemoTrait
{
public $foo;
}
class DemoClass
{
use DemoTrait;
}
$prop = new ReflectionProperty(DemoClass::class, 'foo');
Reflection::getPropertyDeclaringClass($prop); // ReflectionClass('DemoTrait')
getUseStatements (ReflectionClass $class): array
クラス $class が定義されているファイルの use
文(別名)の配列を返します。キーが別名、値が完全修飾のクラス名です。PHP の
tokenizer 拡張が必要です。
namespace Foo;
use Nette\Utils\Strings;
use Nette\Utils\Arrays as Arr;
class DemoClass
{
}
$class = new ReflectionClass(Foo\DemoClass::class);
Reflection::getUseStatements($class);
// ['Strings' => 'Nette\Utils\Strings', 'Arr' => 'Nette\Utils\Arrays']
isBuiltinType (string $type): bool
$type が PHP
の組み込み型かどうかを調べます。そうでなければクラス名とみなされます。
Reflection::isBuiltinType('string'); // true
Reflection::isBuiltinType('Foo'); // false
Nette\Utils\Validators::isBuiltinType()を使ってください。
toString ($reflection): string
リフレクションのオブジェクトを人が読める文字列に変換します。
$func = new ReflectionFunction('func');
echo Reflection::toString($func); // 'func()'
$class = new ReflectionClass('DemoClass');
echo Reflection::toString($class); // 'DemoClass'
$method = new ReflectionMethod('DemoClass', 'foo');
echo Reflection::toString($method); // 'DemoClass::foo()'
$param = new ReflectionParameter(['DemoClass', 'foo'], 'param');
echo Reflection::toString($param); // '$param in DemoClass::foo()'
$prop = new ReflectionProperty('DemoClass', 'foo');
echo Reflection::toString($prop); // 'DemoClass::$foo'