承接 ock/reflector-aware-attributes 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

ock/reflector-aware-attributes

最新稳定版本:1.0.0-alpha1

Composer 安装命令:

composer require ock/reflector-aware-attributes

包简介

README 文档

README

Provides mechanisms for attribute objects to know about the symbol they are attached to.

Motivation

An attribute may want to know about the symbol it describes, to:

  • Perform validation, and throw an exception if it is attached to the wrong symbol.
  • Populate default values based on the symbol. E.g., an attribute attached to a parameter may populate a property value based on the parameter type.

Usage

Using AttributeConstructor::getReflector().

Create an attribute class that calls AttributeConstructor::getReflector() in the constructor.

use Ock\ReflectorAwareAttributes\AttributeConstructor;
use Ock\ReflectorAwareAttributes\ReflectorAwareAttributeInterface;

#[\Attribute(\Attribute::TARGET_ALL)]
class MyAttribute {

  public readonly \Reflector $reflector;

  public function __construct(): void {
    $this->reflector = AttributeConstructor::getReflector();
  }

}

Attach the attribute to a class or other symbol.

#[MyAttribute]
class MyClass {}

Call get_attributes() to extract attributes instances from the class.

use function Ock\ReflectorAwareAttributes\get_attributes;

$reflection_class = new \ReflectionClass(MyClass::class);
$attribute_instances = get_attributes($reflection_class, MyAttribute::class);

assert($attribute_instances[0] instanceof MyAttribute);
assert($attribute_instances[0]->reflector === $reflection_class);

Using the interface with ->setReflector().

Create an attribute class that implements ReflectorAwareAttributeInterface.

use Ock\ReflectorAwareAttributes\ReflectorAwareAttributeInterface;

#[\Attribute(\Attribute::TARGET_ALL)]
class MyReflectorAwareAttribute implements ReflectorAwareAttributeInterface {

  public readonly \Reflector $reflector;

  public function setReflector(\Reflector $reflector): void {
    $this->reflector = $reflector;
  }

}

Attach the attribute to a class or other symbol.

#[MyReflectorAwareAttribute]
function foo() {}

Call get_attributes() to extract attributes instances from the function.

use function Ock\ReflectorAwareAttributes\get_attributes;

$reflection_function = new \ReflectionFunction('foo');
$attribute_instances = get_attributes($reflection_function, MyReflectorAwareAttribute::class);
assert($attribute_instances[0] instanceof MyReflectorAwareAttribute);
assert($attribute_instances[0]->reflector === $reflection_function);

Using AttributeReader.

The AttributeReader class allows to support attribute types that do not use the mechanisms from this package.

Assume you have an attribute class like this, coming from a 3rd party package:

#[\Attribute(\Attribute::TARGET_CLASS)]
class ThirdPartyAttribute {
  public readonly \Reflector $reflector;
}

You can create a custom instantiator that will populate the property.

Ideally this should use the decorator pattern, so that multiple operations can be applied.

use Ock\ReflectorAwareAttributes\Instantiator\AttributeInstantiatorInterface;
use Ock\ReflectorAwareAttributes\Reader\AttributeReader;

class MyInstantiator implements AttributeInstantiatorInterface {

  public function __construct(
    private readonly AttributeInstantiatorInterface $decorated,
  ) {}

  public function newInstance(
    \ReflectionAttribute $attribute,
    \ReflectionClassConstant|\ReflectionParameter|\ReflectionClass|\ReflectionProperty|\ReflectionFunctionAbstract $reflector,
  ): object {
    $instance = $this->decorated->newInstance($attribute, $reflector);
    if ($instance instanceof ThirdPartyAttribute) {
      $instance->reflector = $reflector;
    }
    return $instance;
  }

}

Now we can use a reader with this instantiator decorator to get the attribute instances.

#[ThirdPartyAttribute]
class C {}

$reader = AttributeReader::basic()
  ->withDecoratingInstantiator(
    fn (AttributeInstantiatorInterface $decorated) => new MyInstantiator($decorated),
  );

$reflection_class = new \ReflectionClass(C::class);
$instances = $reader->getInstances($reflection_class, ThirdPartyAttribute::class);

assert($instances[0] instanceof ThirdPartyAttribute);
assert($instances[0]->reflector === $reflection_class);

统计信息

  • 总下载量: 16
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 1
  • 点击次数: 0
  • 依赖项目数: 4
  • 推荐数: 0

GitHub 信息

  • Stars: 1
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2025-05-23