PHP 8で導入されたPHP属性は、クラス、方法、関数、パラメーター、およびプロパティにメタデータを追加する宣言的な方法を提供します。これらは、以前はメタデータを提供する標準的な方法でした。これらを使用する方法は次のとおりです。
カスタム属性を定義するには、 #[Attribute]
属性を使用してクラスを作成し、適用できる場所( TARGET_CLASS
、 TARGET_METHOD
など)を指定します。
<code class="php">#[Attribute(Attribute::TARGET_CLASS)] class MyAttribute { public function __construct(public string $value) {} } #[MyAttribute('example')] class MyClass { // Class implementation }</code>
リフレクションを使用して、実行時に属性を取得できます。
<code class="php">$reflectionClass = new ReflectionClass(MyClass::class); $attributes = $reflectionClass->getAttributes(MyAttribute::class); foreach ($attributes as $attribute) { $instance = $attribute->newInstance(); echo $instance->value; // Outputs: example }</code>
PHP属性は、いくつかの方法でコードの読みやすさと保守性を向上させます。
属性は、PHPDOCのコメントと比較して、より構造化されて読みやすい構文を提供します。これらはPHP言語自体の一部であり、開発者がコメントを解析することなくクラスまたは方法に適用されるメタデータを理解しやすくすることができます。
<code class="php">// Less readable PHPDoc comment /** * @Route("/example") */ class MyClass {} // More readable attribute #[Route('/example')] class MyClass {}</code>
属性はクラスであるため、現代のIDEのタイプチェックとオートコンプリートの恩恵を受けます。これにより、エラーが減少し、開発効率が向上します。
属性により、メタデータを1つの場所(クラス定義)で定義することで、維持と変更が容易になります。この集中化により、矛盾の可能性が減り、コードベースがより保守可能になります。
多くの最新のPHPフレームワークとライブラリは、ルーティング、検証、シリアル化などの属性を活用して、アプリケーションの開発と構成を合理化できます。
PHP属性は、さまざまな実用的なシナリオで使用できます。
LaravelやSymfonyなどのフレームワークでは、属性を使用して、コントローラーメソッドのルートを直接定義し、ルーティング構成の明確さと保守性を向上させることができます。
<code class="php">use Symfony\Component\Routing\Annotation\Route; class BlogController { #[Route('/blog/{slug}', name: 'blog_show')] public function show(string $slug): Response { // Implementation } }</code>
属性は、プロパティで検証ルールを直接定義し、データの整合性を確保するプロセスを簡素化できます。
<code class="php">use Symfony\Component\Validator\Constraints as Assert; class User { #[Assert\NotBlank] #[Assert\Email] public $email; }</code>
APIでは、属性はオブジェクトがJSONまたは他の形式にシリアル化される方法を制御できます。
<code class="php">use JMS\Serializer\Annotation as Serializer; class Product { #[Serializer\SerializedName('product_id')] public $id; #[Serializer\Exclude] public $internalData; }</code>
属性を使用して、どの方法を記録するか、どのレベルでログするかなど、伐採動作を定義できます。
<code class="php">use App\Logging\Annotation\Loggable; class UserService { #[Loggable(level: 'info')] public function createUser(User $user): void { // Implementation } }</code>
はい、PHP属性を使用して、特に属性ベースの構成をサポートする最新のフレームワークで依存関係注入を実装できます。これがどのように行われるかは次のとおりです。
まず、注入のパラメーターをマークするために使用される属性クラスを定義します。
<code class="php">#[Attribute(Attribute::TARGET_PARAMETER)] class Inject { public function __construct(public string $service) {} }</code>
次に、コンストラクターパラメーターまたはメソッドパラメーターの属性を使用して、どのサービスを注入するかを示します。
<code class="php">class UserService { private $logger; public function __construct( #[Inject('LoggerInterface')] LoggerInterface $logger ) { $this->logger = $logger; } public function createUser(User $user): void { $this->logger->info('Creating user'); // Implementation } }</code>
最後に、これらの属性を処理し、正しいサービスを挿入できる依存関係噴射コンテナが必要です。これは、コンテナがどのように機能するかの簡略化された例です。
<code class="php">class Container { public function get($className) { $reflectionClass = new ReflectionClass($className); $constructor = $reflectionClass->getConstructor(); if (!$constructor) { return new $className; } $parameters = $constructor->getParameters(); $dependencies = []; foreach ($parameters as $parameter) { $attribute = $parameter->getAttributes(Inject::class)[0] ?? null; if ($attribute) { $injectAttribute = $attribute->newInstance(); $dependencies[] = $this->get($injectAttribute->service); } else { $dependencies[] = $this->get($parameter->getType()->getName()); } } return $reflectionClass->newInstanceArgs($dependencies); } }</code>
この例では、 Container
クラスは反射を使用して、コンストラクターパラメーターとその属性を検査します。 Inject
属性が見つかった場合、指定されたサービスを解決し、新しいインスタンスに注入します。
依存関係の注入に属性を使用することにより、コンテナが依存関係の配線を処理できるようにしながら、コードを清潔に保ち、ビジネスロジックに焦点を合わせます。このアプローチは、アプリケーションの読みやすさと保守性の両方を向上させます。
以上がPHP属性(注釈):使用法と例。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。