Skip to content

[14.x] Adds PHP Attribute helper [WIP]#60254

Draft
DarkGhostHunter wants to merge 1 commit into
laravel:masterfrom
DarkGhostHunter:feat/master/attr-helper
Draft

[14.x] Adds PHP Attribute helper [WIP]#60254
DarkGhostHunter wants to merge 1 commit into
laravel:masterfrom
DarkGhostHunter:feat/master/attr-helper

Conversation

@DarkGhostHunter

@DarkGhostHunter DarkGhostHunter commented May 24, 2026

Copy link
Copy Markdown
Contributor

What?

This PR introduces the Attr helper to retrieve attributes instances from any target (Classes/Objects, Methods or Properties) in one line.

There are three intentions behind this PR:

  • Remove verbosy attribute retrieval (Reflection → getAttributes() → → check → newInstance() → check).
  • Avoid do-while loops in recursive attribute retrieval.
  • Allow third-party packages to do the same.
use App\Models\Article;
use ReflectionClass;
use Illuminate\Database\Eloquent\Attributes\Table;
use Illuminate\Support\Attr;

// Before
$attributes = (new ReflectionClass(Article::class))->getAttributes(Table::class);

if (isset($attributes[0])) {
    return $attributes[0]->newInstance()->name;
}

// After
return Attr::onClass(Article::class)->instance(Table::class)->name;

...and that was just the simplest offender.

Usages

There are three main usages that I've found across the framework:

  1. Attribute presence: Simple Does this class has this attribute?.
  2. Retrieving an Attribute value: Because the getAttributes() return an array, additional checks must be done to check is not empty, and then instance the first attribute to retrieve the value correctly.
  3. Retrieving all Attributes recursively: Using a do-while loop to get all the attributes including ancestors.

In light of that, I made the helper with the intention of simplify these tasks, and centralise the attribute retrieval.

Conveniences

This helper may look like over-engineering attribute retrieval, but in reality is just simply offering an expressive way to retrieve an Attribute instance or value, without bringing the kitchen sink. Of course, this only works on the sections of the framework that require illuminate/support.

Here are some examples.

  • Check if a class has the given attribute
use App\Models\Article;
use Illuminate\Database\Eloquent\Attributes\Table;
use Illuminate\Support\Attr;

Attr::onClass(Article::class)->has(Table::class);
  • Get the first instance
use App\Models\Article;
use App\Attributes\StrTransform;
use Illuminate\Support\Attr;

Attr::onMethod(Article::class, 'title')->instance(StrTransform::class)?->call;
  • Return ALL the attributes until the last parent as a Collection
use App\Models\Article;
use Illuminate\Auth\Attributes\Authorize;
use Illuminate\Support\Attr;

$article = Article::find(251);

Attr::onMethod($article, 'publish')->recursive(true)->collect(Authorize::class);

Integration

I took the liberty to use Attr on all framework parts that require illuminate/support (almost all of them). I left some places of the framework as-is because adding the helper would add little to an overall verbosy code block.

@github-actions

Copy link
Copy Markdown

Thanks for submitting a PR!

Note that draft PRs are not reviewed. If you would like a review, please mark your pull request as ready for review in the GitHub user interface.

Pull requests that are abandoned in draft may be closed due to inactivity.

@DarkGhostHunter DarkGhostHunter force-pushed the feat/master/attr-helper branch 3 times, most recently from cc06fbd to 22452d3 Compare May 24, 2026 07:15
@DarkGhostHunter DarkGhostHunter force-pushed the feat/master/attr-helper branch from 22452d3 to 1dfcf89 Compare May 24, 2026 07:17
@jnoordsij

Copy link
Copy Markdown
Contributor

https://github.com/spatie/php-attribute-reader already does a lot of this; maybe it would make sense to see if efforts there could be leveraged there, and otherwise improve there?

@DarkGhostHunter

Copy link
Copy Markdown
Contributor Author

https://github.com/spatie/php-attribute-reader already does a lot of this; maybe it would make sense to see if efforts there could be leveraged there, and otherwise improve there?

Didn't saw that. Guess I'll have to simplify this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants