PHPackages                             amondar-libs/class-attributes - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. amondar-libs/class-attributes

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

amondar-libs/class-attributes
=============================

PHP class attributes workflow for package development.

3.1.0(1mo ago)1532MITPHPPHP ^8.2

Since Oct 27Pushed 1mo agoCompare

[ Source](https://github.com/amondar-libs/class-attributes)[ Packagist](https://packagist.org/packages/amondar-libs/class-attributes)[ RSS](/packages/amondar-libs-class-attributes/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (12)Versions (19)Used By (2)

PHP Attributes helpers
======================

[](#php-attributes-helpers)

This package provides a small, framework-friendly toolkit to work with native PHP 8 attributes on your classes and methods. It leverages [spatie/php-structure-discoverer](https://github.com/spatie/php-structure-discoverer) for fast and efficient attribute discovery.

What you get:

- Simple fluent API to read class, method, property, constant, and parameter attributes
- Support for repeatable attributes and inheritance lookups
- Filtering helpers: `onClass()`, `onMethods()`, `onProperties()`, `onConstants()`, `onParameters()`
- Optional caching support for performance in production

Installation:

```
composer require amondar-libs/class-attributes
```

Contents:

- [Attributes usage](#attributes-usage)
- [Attribute class usage](#attribute-class-usage)
- [Batch Discovery](#batch-discovery)
- [Caching](#caching)
- [License](#license)

---

Attributes usage
----------------

[](#attributes-usage)

Below are quick, copy-pasteable examples showing how to declare attributes and how to read them using this package.

The package works with native PHP attributes (PHP &gt;= 8.3). It provides a fluent `Amondar\ClassAttributes\Parse` helper.

### 1) Define your attributes

[](#1-define-your-attributes)

Create attribute classes using native PHP Attribute metadata.

```
use Attribute;

#[Attribute(Attribute::TARGET_CLASS)]
class ClassAttribute
{
    public function __construct(public array $someData) {}
}

#[Attribute(Attribute::TARGET_METHOD)]
class MethodAttribute
{
    public function __construct(public string $description) {}
}

#[Attribute(Attribute::TARGET_ALL)]
class TagAttribute
{
    public function __construct(public string $description) {}
}
```

### 2) Annotate your classes/methods

[](#2-annotate-your-classesmethods)

```
#[ClassAttribute(['someData' => 'someValue'])]
class Example
{
    #[TagAttribute('MyConst')]
    public const MY_CONST = 'my-const';

    #[TagAttribute('isOk')]
    public bool $isOk = true;

    #[MethodAttribute('First method description')]
    public function firstMethod() {}

    #[MethodAttribute('Second method description')]
    public function secondMethod() {}
}
```

### 3) Read attributes: Parse helper

[](#3-read-attributes-parse-helper)

The `get()` method returns a `Collection` of `Discovered` objects. Each `Discovered` instance contains:

- `name` — the name of the target (class name, method name, property name, etc.)
- `parent` — the parent/declaring class name (FCQN)
- `attribute` — the attribute instance
- `target` — a `Target` enum case (`onClass`, `method`, `property`, `constant`, `parameter`)

```
use Amondar\ClassAttributes\Parse;

// Get all discovered attributes on a class (class-level, methods, properties, constants)
$results = Parse::attribute(TagAttribute::class)
    ->on(Example::class)
    ->get();

// $results is a Collection of Discovered instances
foreach ($results as $discovered) {
    echo $discovered->name;              // e.g. 'MY_CONST', 'isOk', 'firstMethod'
    echo $discovered->target->value;     // e.g. 'constant', 'property', 'method'
    echo $discovered->attribute->description; // e.g. 'MyConst'
}
```

### 4) Filter by target

[](#4-filter-by-target)

Use dedicated filter methods to narrow results to a specific target type:

```
// Only class-level attributes
$classAttrs = Parse::attribute(ClassAttribute::class)
    ->on(Example::class)
    ->onClass();

// Only method attributes
$methodAttrs = Parse::attribute(MethodAttribute::class)
    ->on(Example::class)
    ->onMethods();

// Only property attributes
$propAttrs = Parse::attribute(TagAttribute::class)
    ->on(Example::class)
    ->onProperties();

// Only constant attributes
$constAttrs = Parse::attribute(TagAttribute::class)
    ->on(Example::class)
    ->onConstants();

// Only parameter attributes
$paramAttrs = Parse::attribute(RequestAttribute::class)
    ->on(Example::class)
    ->onParameters();
```

### 5) Inheritance lookup

[](#5-inheritance-lookup)

Include parent class attributes in the search using `ascend()`:

```
$results = Parse::attribute(TagAttribute::class)
    ->on(ChildOfExample::class)
    ->ascend()
    ->get();
```

> That will include attributes from `Example` class and all its parents. Can be useful for resolving repeatable attributes, for example, when a child can add some new functionality.

---

Attribute class usage
---------------------

[](#attribute-class-usage)

Under the hood, the `Parse` facade delegates to `Amondar\ClassAttributes\Support\Attribute` — a lower-level, reflection-based class you can use directly for fine-grained control.

### Creating an instance

[](#creating-an-instance)

Use the static `for()` factory, passing either a class-string or a `DiscoveredAttribute` instance:

```
use Amondar\ClassAttributes\Support\Attribute;

$attr = Attribute::for(TagAttribute::class);
```

### Checking if an attribute exists

[](#checking-if-an-attribute-exists)

The `existsOn()` method returns `true` if the attribute is present anywhere on the class (class-level, methods, properties, constants, or parameters):

```
$attr->existsOn(Example::class); // true / false
```

### Finding all attribute usages on a class

[](#finding-all-attribute-usages-on-a-class)

`findOn()` returns an array of `Discovered` objects for every occurrence of the attribute on the given class:

```
$results = $attr->findOn(Example::class);
// array
```

### Targeted lookups

[](#targeted-lookups)

Each method accepts a class-string, an object, or a `ReflectionClass` instance. They return an array of `Discovered` objects (or `bool` when the `$exist` flag is `true`):

```
// Class-level attributes only
$attr->on(Example::class);

// Method attributes only (optionally include parameter attributes)
$attr->onMethods(Example::class, includeParameters: true);

// Property attributes only
$attr->onProperties(Example::class);

// Constant attributes only
$attr->onConstants(Example::class);

// Parameter attributes only
$attr->onParameters(Example::class);
```

You can also pass a visibility filter using PHP's `ReflectionMethod`/`ReflectionProperty` filter constants:

```
$attr->onMethods(Example::class, filter: ReflectionMethod::IS_PUBLIC);
$attr->onProperties(Example::class, filter: ReflectionProperty::IS_PUBLIC);
$attr->onConstants(Example::class, filter: ReflectionClassConstant::IS_PUBLIC);
```

### Inheritance lookup

[](#inheritance-lookup)

Just like the `Parse` helper, you can include parent class attributes with `ascend()`:

```
$attr = Attribute::for(TagAttribute::class)->ascend();

$results = $attr->findOn(ChildOfExample::class);
// Includes attributes from ChildOfExample and all its parents
```

---

Batch Discovery
---------------

[](#batch-discovery)

You can discover all classes using a specific attribute within given directories.

```
use Amondar\ClassAttributes\Parse;

$parser = Parse::attribute(ClassAttribute::class);

// Find all classes that use this attribute
$usages = $parser->findUsages(__DIR__ . '/src');
// Returns Collection of \Spatie\StructureDiscoverer\Data\DiscoveredClass

// Discover and parse all attributes for classes in directories
$all = $parser->in(__DIR__ . '/src', __DIR__ . '/tests');
// Returns Collection
```

---

Caching
-------

[](#caching)

For production environments, you can enable caching to avoid repeated reflection and file scanning.

The package uses `spatie/php-structure-discoverer` caching mechanism. You can use any driver that implements `Spatie\StructureDiscoverer\Cache\DiscoverCacheDriver`.

```
use Amondar\ClassAttributes\Parse;
use Spatie\StructureDiscoverer\Cache\LaravelDiscoverCacheDriver;

$parser = Parse::attribute(ClassAttribute::class)
    ->withCache(new LaravelDiscoverCacheDriver('my-cache-key'));

// Subsequent calls will be cached
$result = $parser->on(Example::class)->get();
```

> **Note:** `LaravelDiscoverCacheDriver` is just one example. You can use any driver supported by [spatie/php-structure-discoverer official docs](https://github.com/spatie/php-structure-discoverer#caching). Current package ships with `Amondar\\ClassAttributes\\Laravel\\AttributeCacheDriver` out of the box.

---

License
-------

[](#license)

This library is open-sourced software licensed under the MIT license. See [LICENSE.md](LICENSE.md).

###  Health Score

46

—

FairBetter than 93% of packages

Maintenance96

Actively maintained with recent releases

Popularity12

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity56

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~8 days

Recently: every ~17 days

Total

18

Last Release

50d ago

Major Versions

1.2.2 → 2.0.02026-01-01

2.4.0 → 3.0.02026-03-20

PHP version history (2 changes)1.0.0PHP ^8.3

3.0.0PHP ^8.2

### Community

Maintainers

![](https://www.gravatar.com/avatar/00b2e99bd1ba72674cf4370c0ef6e8efabebdd257036e5ed14020b5b487772b5?d=identicon)[amondar-libs](/maintainers/amondar-libs)

---

Top Contributors

[![amondar-libs](https://avatars.githubusercontent.com/u/3830450?v=4)](https://github.com/amondar-libs "amondar-libs (32 commits)")

###  Code Quality

TestsPest

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/amondar-libs-class-attributes/health.svg)

```
[![Health](https://phpackages.com/badges/amondar-libs-class-attributes/health.svg)](https://phpackages.com/packages/amondar-libs-class-attributes)
```

###  Alternatives

[spatie/laravel-data

Create unified resources and data transfer objects

1.7k28.9M626](/packages/spatie-laravel-data)[illuminate/support

The Illuminate Support package.

583107.1M34.3k](/packages/illuminate-support)[pragmarx/countries

PHP Countries and Currencies

1.9k3.3M18](/packages/pragmarx-countries)[illuminate/events

The Illuminate Events package.

13454.3M1.7k](/packages/illuminate-events)[illuminate/config

The Illuminate Config package.

10842.7M2.2k](/packages/illuminate-config)[illuminate/pagination

The Illuminate Pagination package.

10532.5M856](/packages/illuminate-pagination)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
