xp-framework / reflection
反射
Requires
- php: >=7.4.0
- xp-framework/ast: ^11.0 | ^10.0 | ^9.0 | ^8.0 | ^7.6
- xp-framework/core: ^12.0 | ^11.0 | ^10.13
Requires (Dev)
- xp-framework/test: ^2.0 | ^1.0
- dev-main
- v3.2.0
- v3.1.0
- v3.0.0
- v2.15.0
- v2.14.1
- v2.14.0
- v2.13.6
- v2.13.5
- v2.13.4
- v2.13.3
- v2.13.2
- v2.13.1
- v2.13.0
- v2.12.0
- v2.11.0
- v2.10.1
- v2.10.0
- v2.9.1
- v2.9.0
- v2.8.1
- v2.8.0
- v2.7.0
- v2.6.0
- v2.5.0
- v2.4.1
- v2.4.0
- v2.3.0
- v2.2.0
- v2.1.0
- v2.0.1
- v2.0.0
- v1.9.1
- v1.9.0
- v1.8.1
- v1.8.0
- v1.7.0
- v1.6.0
- v1.5.0
- v1.4.0
- v1.3.0
- v1.2.0
- v1.1.0
- v1.0.1
- v1.0.0
- v0.9.0
- v0.8.0
- v0.7.0
- v0.6.0
- v0.5.0
- v0.4.0
- v0.3.1
- v0.3.0
- v0.2.0
- v0.1.1
- v0.1.0
- dev-two
- dev-feature/asymmetric-visibility
- dev-feature/property-hooks-support
- dev-feature/source
- dev-refactor/always-use-attributes-in-php8
This package is auto-updated.
Last update: 2024-08-27 18:20:27 UTC
README
此库提供了XP框架反射API的替代品。
特性
简洁:此库旨在通过其访问器方法简单地返回NULL来减少类似if (hasX(...)) { getX() }
的代码噪声。随着PHP 7中引入null合并运算符??
和PHP 8中引入的null安全调用运算符?->
(以及在XP编译器中),null处理得到了改进。
PHP 7 & 8:此库在PHP 7(使用编译器的AST库)和PHP 8(使用其本机反射API)中处理PHP 8属性。
子命令:此库提供RFC #0303集成,并为新的XP运行器提供“reflect”子命令。有关如何使用它,请参阅xp help reflect
。
API
入口点是lang.Reflection
类。可以通过传递对象、类型字面量(例如Date::class
)、完全限定的类名(例如util.Date
)、lang.XPClass
或PHP的ReflectionClass
实例来构造它。
use lang\Reflection; use org\example\{Base, Inject, Fixture}; $type= Reflection::type(Fixture::class); $type->name(); // org.example.Fixture $type->declaredName(); // Fixture $type->literal(); // Fixture::class $type->modifiers(); // Modifiers<public> $type->comment(); // (api doc comment) $type->class(); // lang.XPClass instance $type->classLoader(); // lang.ClassLoader instance $type->package(); // Package or NULL $type->parent(); // Type or NULL $type->interfaces(); // Type[] $type->traits(); // Type[] $type->kind(); // Kind::$INTERFACE, Kind::$TRAIT, Kind::$CLASS, Kind::$ENUM $type->is(Base::class); // true if ($type->instantiable()) { $instance= $type->newInstance('Testing'); } $type->isInstance($instance); // true
可以通过迭代annotations()
或使用简写方法annotation()
来访问注解。
foreach ($type->annotations() as $annotation) { $annotation->type(); // Author::class $annotation->name(); // 'author' $annotation->arguments(); // ['Test', test => true] $annotation->argument(0); // 'Test' $annotation->argument('test'); // true $annotation->newInstance(); // Author class instance } $type->annotation(Inject::class); // Annotation or NULL
可以通过constructor()
访问构造函数。与成员一样,它提供了对修饰符、注解及其声明类型的访问器。
$type->constructor(); // Constructor or NULL if ($constructor= $type->constructor()) { $constructor->name(); // '__construct' $constructor->compoundName(); // 'org.example.Fixture::__construct()' $constructor->modifiers(); // Modifiers<public> $constructor->comment(); // (api doc comment) $constructor->annotations(); // Annotations $constructor->annotation(Inject::class); // Annotation or NULL $constructor->declaredIn(); // Type $constructor->parameters(); // Parameters $constructor->parameter(0); // Parameter or NULL $constructor->newInstance([]); // (instance of the type) }
可以使用initializer()
控制类型实例化。它接受闭包或实例方法的命名引用。
// Instantiates type without invoking a constructor // Any passed arguments are discarded silently $instance= $type->initializer(null)->newInstance(); // Instantiates type by providing a constructor, regardless of whether one exists or not // Arguments are passed on to the initializer function, which has access to $this $instance= $type->initializer(function($name) { $this->name= $name; })->newInstance(['Test']); // Instantiates type by selecting an instance method as an initializer // The unserialize callback is invoked with ['name' => 'Test'] if ($unserialize= $type->initializer('__unserialize')) { $instance= $unserialize->newInstance([['name' => 'Test']]); }
可以通过迭代或通过按名称的简写查找来访问所有成员(常量、属性和方法)。成员提供了对修饰符、注解及其声明类型的访问器。
$type->constant('POWER'); // Constant or NULL $type->property('value'); // Property or NULL $type->method('fixture'); // Method or NULL foreach ($type->constants() as $name => $constant) { $constant->name(); // 'POWER' $constant->compoundName(); // 'org.example.Fixture::POWER' $constant->value(); // 6100 $constant->modifiers(); // Modifiers<public> $constant->comment(); // (api doc comment) $constant->annotations(); // Annotations $constant->annotation(Inject::class); // Annotation or NULL $constant->declaredIn(); // Type } foreach ($type->properties() as $name => $property) { $property->name(); // 'value' $property->compoundName(); // 'org.example.Fixture::$value' $property->modifiers(); // Modifiers<public> $property->comment(); // (api doc comment) $property->annotations(); // Annotations $property->annotation(Inject::class); // Annotation or NULL $property->declaredIn(); // Type $property->constraint(); // Constraint $property->get($instance); // (property value) $property->set($instance, $value); // (value) } foreach ($type->methods() as $name => $method) { $method->name(); // 'fixture' $method->compoundName(); // 'org.example.Fixture::fixture()' $method->comment(); // (api doc comment) $method->modifiers(); // Modifiers<public> $method->annotations(); // Annotations $method->annotation(Inject::class); // Annotation or NULL $method->declaredIn(); // Type $method->returns(); // Constraint $method->parameters(); // Parameters $method->parameter(0); // Parameter or NULL $method->closure($instance); // Closure instance $method->invoke($instance, []); // (method return value) }
可以通过迭代parameters()
、通过偏移量parameter($position)
或通过名称parameter($name)
来检索方法和构造函数参数。
$method->parameter(0); // Parameter or NULL $method->parameter('arg'); // Parameter or NULL $parameters= $method->parameters(); // Parameters instance $parameters->at(0); // Parameter or NULL $parameters->named('arg'); // Parameter or NULL $args= ['test']; if ($parameters->accept($args)) { $method->invoke(null, $args); } foreach ($parameters as $name => $parameter) { $parameter->position(); // 0 $parameter->name(); // 'arg' $parameter->variadic(); // false $parameter->optional(); // true $parameter->default(); // (parameter default value) $parameter->constraint(); // Constraint $parameter->annotations(); // Annotations $parameter->annotation(Inject::class) // Annotation or NULL }
可以通过将命名空间名称传递给Reflection::of()
来对包进行反射。
use lang\Reflection; $package= Reflection::of('org.example'); $package->name(); // org.example $package->literal(); // 'org\example' $package->type('Fixture'); // Type instance $package->types(); // iterable with Type instances $package->parent() // Package or NULL $package->children(); // iterable with Package instances $package->classLoaders(); // iterable with lang.ClassLoader instances