<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/php-attributes-what-why-how-and-when-rtzv4erax" -->

---
title: PHP Attributes: What, Why, How and When | daily.dev
description: PHP attributes (introduced in PHP 8) are typed, structured metadata attached to classes, methods, properties, parameters, and more. They don't execute code...
canonical: https://daily.dev/posts/php-attributes-what-why-how-and-when-rtzv4erax
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: PHP Attributes: What, Why, How and When | daily.dev
og:description: PHP attributes (introduced in PHP 8) are typed, structured metadata attached to classes, methods, properties, parameters, and more. They don't execute code...
og:url: https://daily.dev/posts/php-attributes-what-why-how-and-when-rtzv4erax
og:image: https://api.daily.dev/og/posts/RtZv4eRAx.png
og:image:alt: PHP Attributes: What, Why, How and When
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# PHP Attributes: What, Why, How and When

**[W endell Adriel](https://daily.dev/sources/wendelladriel)** · [@wendell_adriel](https://daily.dev/wendell_adriel) · 19 min read · 20 upvotes · 2 comments

## Summary

PHP attributes (introduced in PHP 8) are typed, structured metadata attached to classes, methods, properties, parameters, and more. They don't execute code themselves — a consumer must read them via the Reflection API and turn them into behavior. The post covers how to define attributes with target restrictions and constructor arguments, how to build a practical webhook handler registry using reflection, performance best practices (reflect at boot, use plain data at runtime), Laravel examples like #[Scope] and #[Config], testing strategies, and a clear decision checklist for when attributes are appropriate versus when interfaces, configuration, or explicit code are better choices.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://wendelladriel.com/blog/php-attributes-what-why-how-and-when>

## Questions this post answers

### What is the difference between PHP attributes and PHPDoc annotations?

PHP attributes are native language constructs backed by a real class with a constructor, target restrictions, and a Reflection API, meant to be consumed by application or framework code at runtime. PHPDoc is documentation and static-analysis metadata read by tools like PHPStan or IDEs, but PHP itself never turns a docblock into a runtime object.

_Comparing metadata approaches gets easier when developers track PHP ecosystem patterns like these on daily.dev._

### How do I make a PHP attribute accept multiple values on the same declaration?

Mark the attribute with Attribute::IS_REPEATABLE combined with its target, for example Attribute::TARGET_CLASS | Attribute::IS_REPEATABLE. This lets the same attribute be applied more than once to a single declaration, such as stacking multiple #[UsesMiddleware(...)] entries on a controller class, though the consumer still decides how to interpret the collected values.

_Developers refining attribute-driven designs can follow more PHP metaprogramming coverage on daily.dev._

### How does Laravel's #[Scope] attribute work on Eloquent models?

The #[Scope] attribute, from Illuminate\Database\Eloquent\Attributes\Scope, marks a protected model method as a local query scope so Laravel can register it while preparing the model's query API, enabling calls like Post::published()->get(). The method itself still contains the query logic; the attribute only tells Eloquent that the method should be exposed as a scope.

_Teams adopting Laravel's newer attribute-based conventions can keep up with framework changes on daily.dev._

## Community discussion

Top comments from developers on daily.dev.

**@mrtbg22** · 0 upvotes

> Great article, very informative! Been wanting to get more familiar with attributes just never had time to dig into them but this summarized it really well. Great work!

**@devmandan** · 0 upvotes

> It is worth noting the handful of `attributes` that come predefined in PHP: [https://www.php.net/manual/en/reserved.attributes.php](https://www.php.net/manual/en/reserved.attributes.php)
>
> I've made it a force of habit to use the `#[Override]` attribute for interface and abstract implementations. The `#[SensitiveParameter]` attribute is also well worth knowing about.

## Similar posts on daily.dev

- [How PHP Attributes Changed the Way I Write Livewire](https://daily.dev/posts/how-php-attributes-changed-the-way-i-write-livewire-3sw5lnfbr) · FREEK.DEV · 43 upvotes · 1 comments
- [New in Symfony 7.4: Extending Validation and Serialization with PHP Attributes \(Symfony Blog\)](https://daily.dev/posts/new-in-symfony-7-4-extending-validation-and-serialization-with-php-attributes-symfony-blog--7xw05pews) · Symfony · 9 upvotes · 0 comments
- [New in Symfony 8.1: Dynamic Controller Attributes \(Symfony Blog\)](https://daily.dev/posts/new-in-symfony-8-1-dynamic-controller-attributes-symfony-blog--p1eaqpp8q) · Symfony · 4 upvotes · 0 comments
- [New in Symfony 8.2: Attribute-based Forms \(Symfony Blog\)](https://daily.dev/posts/new-in-symfony-8-2-attribute-based-forms-symfony-blog--xu6v5qpn6) · Symfony · 1 upvotes · 0 comments

---

Tags: [#php](https://daily.dev/tags/php), [#laravel](https://daily.dev/tags/laravel)

[View this post on daily.dev](https://daily.dev/posts/php-attributes-what-why-how-and-when-rtzv4erax)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"PHP Attributes: What, Why, How and When","url":"https://daily.dev/posts/php-attributes-what-why-how-and-when-rtzv4erax","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/php-attributes-what-why-how-and-when-rtzv4erax"},"datePublished":"2026-07-20T11:58:30.438Z","dateModified":"2026-09-14T09:00:44.154Z","description":"PHP attributes (introduced in PHP 8) are typed, structured metadata attached to classes, methods, properties, parameters, and more. They don't execute code...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/69ad228698f1ca1fc03c6bc1a1e3674a?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/69ad228698f1ca1fc03c6bc1a1e3674a?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"W endell Adriel","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Person","name":"Wendell Adriel","url":"https://daily.dev/wendell_adriel","image":"https://avatars1.githubusercontent.com/u/11641518?v=4","interactionStatistic":{"@type":"InteractionCounter","interactionType":{"@type":"EndorseAction"},"userInteractionCount":800}},"commentCount":2,"discussionUrl":"https://daily.dev/posts/php-attributes-what-why-how-and-when-rtzv4erax","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":20},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":2}],"keywords":"php,laravel","timeRequired":"PT19M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"W endell Adriel","item":"https://daily.dev/sources/wendelladriel"},{"@type":"ListItem","position":3,"name":"PHP Attributes: What, Why, How and When"}]}
{"@context":"https://schema.org","@type":"WebPage","@id":"https://daily.dev/posts/php-attributes-what-why-how-and-when-rtzv4erax","comment":[{"@type":"Comment","text":"Great article, very informative! Been wanting to get more familiar with attributes just never had time to dig into them but this summarized it really well. Great work!","datePublished":"2026-07-21T07:32:04.717Z","url":"https://daily.dev/posts/RtZv4eRAx#c-vc86I9c7h","author":{"@type":"Person","name":"mbg22","url":"https://daily.dev/mrtbg22","image":"https://avatars.githubusercontent.com/u/132388058?v=4"}},{"@type":"Comment","text":"It is worth noting the handful of attributes that come predefined in PHP: https://www.php.net/manual/en/reserved.attributes.php\nI’ve made it a force of habit to use the #[Override] attribute for interface and abstract implementations. The #[SensitiveParameter] attribute is also well worth knowing about.","datePublished":"2026-07-22T10:09:02.886Z","url":"https://daily.dev/posts/RtZv4eRAx#c-nNJzgmyhe","author":{"@type":"Person","name":"Daniel","url":"https://daily.dev/devmandan","image":"https://media.daily.dev/image/upload/s--ypn2TBF9--/f_auto/v1786619820/avatars/avatar_qDApMJOupymFKtjAmmtB4?_a=BAMAMicg0"}}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/php-attributes-what-why-how-and-when-rtzv4erax#faq","mainEntity":[{"@type":"Question","name":"What is the difference between PHP attributes and PHPDoc annotations?","acceptedAnswer":{"@type":"Answer","text":"PHP attributes are native language constructs backed by a real class with a constructor, target restrictions, and a Reflection API, meant to be consumed by application or framework code at runtime. PHPDoc is documentation and static-analysis metadata read by tools like PHPStan or IDEs, but PHP itself never turns a docblock into a runtime object. Comparing metadata approaches gets easier when developers track PHP ecosystem patterns like these on daily.dev."}},{"@type":"Question","name":"How do I make a PHP attribute accept multiple values on the same declaration?","acceptedAnswer":{"@type":"Answer","text":"Mark the attribute with Attribute::IS_REPEATABLE combined with its target, for example Attribute::TARGET_CLASS | Attribute::IS_REPEATABLE. This lets the same attribute be applied more than once to a single declaration, such as stacking multiple #[UsesMiddleware(...)] entries on a controller class, though the consumer still decides how to interpret the collected values. Developers refining attribute-driven designs can follow more PHP metaprogramming coverage on daily.dev."}},{"@type":"Question","name":"How does Laravel's #[Scope] attribute work on Eloquent models?","acceptedAnswer":{"@type":"Answer","text":"The #[Scope] attribute, from Illuminate\\Database\\Eloquent\\Attributes\\Scope, marks a protected model method as a local query scope so Laravel can register it while preparing the model's query API, enabling calls like Post::published()->get(). The method itself still contains the query logic; the attribute only tells Eloquent that the method should be exposed as a scope. Teams adopting Laravel's newer attribute-based conventions can keep up with framework changes on daily.dev."}}]}
```

