PHP の型
Nette\Utils\Type は PHP のデータ型を表します。文字列から得たものであれリフレクションから得たものであれ、型を解析・比較・操作するために使います。
現在の PHP
はとても豊かな型システムを持っています。スカラー型(int、string)から、オブジェクトやインターフェース、さらに複合的な型(合併型
A|B、交差型 A&B、選言標準形 (A&B)|D)まで。加えて
void、never、mixed のような特別な型や、相対的な型
self、static もあります。
これらの型をそのまま、とくに ReflectionType
を通して扱うのは、ReflectionNamedType、ReflectionUnionType
などのオブジェクトを再帰的に区別しなければならないため、しばしば面倒です。Nette\Utils\Type
クラスはこれらをすべて包み込み、PHP が対応するあらゆる型を扱うための統一された直感的な
API を提供します。
たとえば、ある型が別の型を受け入れるか(互換性)を簡単に調べたり、型を広げたり、リフレクションを読みやすい表記に変換したりできます。
インストール:
composer require nette/utils
以下の例では、次のクラスの別名が定義されているものとします。
use Nette\Utils\Type;
fromReflection ($reflection): ?Type
この静的メソッドは、リフレクションをもとに Type
オブジェクトを作ります。パラメータには ReflectionMethod や ReflectionFunction
のオブジェクト(戻り値の型を返します)、あるいは ReflectionParameter や
ReflectionProperty
のオブジェクトを渡せます。self、static、parent
は実際のクラス名に解決されます。対象に型がなければ null を返します。
class DemoClass
{
public self $foo;
}
$prop = new ReflectionProperty(DemoClass::class, 'foo');
echo Type::fromReflection($prop); // 'DemoClass'
fromString (string $type): Type
この静的メソッドは、文字列表現から Type オブジェクトを作ります。
$type = Type::fromString('Foo|Bar');
echo $type; // 'Foo|Bar'
fromValue (mixed $value): Type
渡された値の型をもとに Type オブジェクトを作る静的メソッドです。
$type = Type::fromValue('hello'); // 'string'
$type = Type::fromValue(123); // 'int'
$type = Type::fromValue(new stdClass); // 'stdClass'
リソースに対しては mixed を返します。PHP には resource
型がないからです。無名クラスに対しては、最も近い祖先の名前か
object を返します。
$obj = new class extends Foo { };
$type = Type::fromValue($obj); // 'Foo'
getNames (): (string|array)[]
複合型を構成する部分型を表す文字列の配列を返します。交差型の場合は配列の配列を返します。
$type = Type::fromString('string|null'); // または '?string'
$type->getNames(); // ['string', 'null']
$type = Type::fromString('(Foo&Bar)|string');
$type->getNames(); // [['Foo', 'Bar'], 'string']
getTypes(): Type[]
複合型を構成する部分型を表す Type オブジェクトの配列を返します。
$type = Type::fromString('string|null'); // または '?string'
$type->getTypes(); // [Type::fromString('string'), Type::fromString('null')]
$type = Type::fromString('(Foo&Bar)|string');
$type->getTypes(); // [Type::fromString('Foo&Bar'), Type::fromString('string')]
$type = Type::fromString('Foo&Bar');
$type->getTypes(); // [Type::fromString('Foo'), Type::fromString('Bar')]
getSingleName(): ?string
単純な型(?string のような単純な nullable
型を含みます)については型名を返します。そうでなければ null を返します。
$type = Type::fromString('string|null');
echo $type; // '?string'
echo $type->getSingleName(); // 'string'
$type = Type::fromString('?Foo');
echo $type; // '?Foo'
echo $type->getSingleName(); // 'Foo'
$type = Type::fromString('Foo|Bar');
echo $type; // 'Foo|Bar'
echo $type->getSingleName(); // null(合併型なので)
isSimple(): bool
単純な型かどうかを返します。単純な nullable 型(?string、?Foo
など)も単純な型に含まれます。
$type = Type::fromString('string');
$type->isSimple(); // true
$type->isUnion(); // false
$type = Type::fromString('?Foo'); // または 'Foo|null'
$type->isSimple(); // true
$type->isUnion(); // true(null を含むので)
isUnion(): bool
合併型(| を含む)かどうかを返します。
$type = Type::fromString('Foo&Bar');
$type->isUnion(); // true
isIntersection(): bool
交差型(& を含む)かどうかを返します。
$type = Type::fromString('Foo&Bar');
$type->isIntersection(); // true
isBuiltin(): bool
その型が単純で、かつ PHP
の組み込み型(string、int、array、callable
など)かどうかを返します。
$type = Type::fromString('string');
$type->isBuiltin(); // true
$type = Type::fromString('string|int');
$type->isBuiltin(); // false
$type = Type::fromString('Foo');
$type->isBuiltin(); // false
isClass(): bool
その型が単純で、かつクラス名(string や int
のような組み込み型ではない)かどうかを返します。
$type = Type::fromString('string');
$type->isClass(); // false
$type = Type::fromString('Foo|null');
$type->isClass(); // true
$type = Type::fromString('Foo|Bar');
$type->isClass(); // false
isClassKeyword(): bool
その型が内部のキーワード self、parent、static
のいずれかかどうかを返します。
$type = Type::fromString('self');
$type->isClassKeyword(); // true
$type = Type::fromString('Foo');
$type->isClassKeyword(); // false
allows (string|Type $type): bool
allows()
メソッドは型の互換性を調べます。たとえば、ある型の値をこの型を期待する関数のパラメータとして渡せるかどうかを判定できます。
$type = Type::fromString('string|null');
$type->allows('string'); // true
$type->allows('null'); // true
$type->allows('Foo'); // false
$type = Type::fromString('mixed');
$type->allows('null'); // true
with (string|Type $type): Type
もとの型と、追加する型の両方を受け入れる Type オブジェクトを返します。いわゆる合併型を作ります。
このメソッドは賢く、型を無駄に重複させません。すでにある型や、現在の型を包含する型(たとえば
string に mixed を足す場合)を追加すると、結果は単純化されます。
$type = Type::fromString('string');
// nullable な string に広げる
echo $type->with('null'); // '?string'
// 合併型を作る
echo $type->with('int'); // 'string|int'
// すべてを包含する型を足す
echo $type->with('mixed'); // 'mixed'