Nette Documentation Preview

syntax
PHP リフレクション
***********

.[perex]
[api:Nette\Utils\Reflection] は、PHP のリフレクションのための便利な関数を提供する静的クラスです。ネイティブのリフレクションクラスの弱点を補い、PHP のバージョンによる振る舞いの違いをそろえるのが目的です。


インストール:

```shell
composer require nette/utils
```

以下の例では、次のクラスの別名が定義されているものとします。

```php
use Nette\Utils\Reflection;
```


areCommentsAvailable(): bool .[method]
--------------------------------------

リフレクションが PHPdoc のコメントにアクセスできるかを調べます。オペコードのキャッシュのせいでコメントが使えないことがあります。たとえば [opcache.save-comments|https://www.php.net/manual/en/opcache.configuration.php#ini.opcache.save-comments] ディレクティブをご覧ください。


expandClassName(string $name, ReflectionClass $context): string .[method]
-------------------------------------------------------------------------

クラス `$context` の文脈で、その名前空間と定義された別名を考慮しながら、クラス名 `$name` を完全修飾名に展開します。要するに、`$name` が `$context` クラスの本体の中に書かれていたら PHP のパーサーがどう解釈するかを決めます。

```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]
------------------------------------------------------------------------------

`$method` の実際の宣言を含むメソッドのリフレクションを返します。ふつうメソッドは自分自身が宣言ですが、メソッドの本体がトレイトに由来し、しかも別の名前になっていることがあります。

PHP は真の宣言を確実に判定できるだけの情報を提供しないので、Nette は独自の推測を使います。これは**確実であるはず**です。

```php
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 .[method]
----------------------------------------------------------------------

関数やメソッドのパラメータの既定値を返します。ネイティブの `ReflectionParameter::getDefaultValue()` と違い、既定値として使われた定数やクラス定数も正しく解決します。定数を解決できない場合は `\ReflectionException` を投げます。

```php
class DemoClass
{
	const DefaultValue = 123;
}

function demo($param = DemoClass::DefaultValue)
{
}

$param = new ReflectionParameter('demo', 'param');
echo Reflection::getParameterDefaultValue($param); // 123
```


getPropertyDeclaringClass(ReflectionProperty $prop): ReflectionClass .[method]
------------------------------------------------------------------------------

プロパティ `$prop` の宣言を含むクラスやトレイトのリフレクションを返します。プロパティはトレイトの中で宣言されていることもあります。

PHP は真の宣言を確実に判定できるだけの情報を提供しないので、Nette は独自の推測を使います。これは完全に確実とは**いえません**。

```php
trait DemoTrait
{
	public $foo;
}


class DemoClass
{
	use DemoTrait;
}

$prop = new ReflectionProperty(DemoClass::class, 'foo');
Reflection::getPropertyDeclaringClass($prop); // ReflectionClass('DemoTrait')
```


getUseStatements(ReflectionClass $class): array .[method]
---------------------------------------------------------

クラス `$class` が定義されているファイルの use 文(別名)の配列を返します。キーが別名、値が完全修飾のクラス名です。PHP の `tokenizer` 拡張が必要です。

```php
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 .[method deprecated]
------------------------------------------------------

`$type` が PHP の組み込み型かどうかを調べます。そうでなければクラス名とみなされます。

```php
Reflection::isBuiltinType('string'); // true
Reflection::isBuiltinType('Foo');    // false
```

.[note]
[Nette\Utils\Validators::isBuiltinType() |validators#isBuiltinType()]を使ってください。


toString($reflection): string .[method]
---------------------------------------

リフレクションのオブジェクトを人が読める文字列に変換します。

```php
$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'
```

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'