PHP Attributes — metadata روی کد و کاربرد در Laravel
قبل از PHP 8 برای metadata روی کد از docblock annotation استفاده میشد — بدون type check. Attributes (PHP 8+) کلاس واقعی هستند که با #[...] روی class، method، property و parameter مینشینند و با Reflection خوانده میشوند.
تعریف Attribute
#[Attribute(Attribute::TARGET_METHOD | Attribute::TARGET_CLASS)]
class Cacheable
{
public function __construct(
public int $ttlSeconds = 3600,
public ?string $key = null,
) {}
}
استفاده
#[Cacheable(ttlSeconds: 600, key: 'posts.index')]
class ListPostsAction
{
public function handle(): Collection { /* ... */ }
}
خواندن با Reflection
$reflection = new ReflectionClass(ListPostsAction::class);
$attributes = $reflection->getAttributes(Cacheable::class);
if ($attributes !== []) {
/** @var Cacheable $cacheMeta */
$cacheMeta = $attributes[0]->newInstance();
$ttl = $cacheMeta->ttlSeconds;
}
frameworkها همین کار را در bootstrap انجام میدهند.
Laravel و Attributes
Laravel 11+ بخشی از routing و validation را با attribute پشتیبانی میکند:
use Illuminate\Routing\Attributes\Middleware;
#[Middleware('auth')]
class PostController extends Controller
{
//
}
قبل از route file پراکنده — co-location با controller.
Attribute تکرارشونده
#[Attribute(Attribute::TARGET_PROPERTY | Attribute::IS_REPEATABLE)]
class MapTo
{
public function __construct(public string $column) {}
}
مقایسه با Enum و Config
- Attribute — metadata compile-time روی symbol
- Config — runtime مرکزی
- Enum — finite value set
use case عملی
- cache TTL declarative روی Action
- permission marker روی متد
- mapper DTO field به column
- test group marker
محدودیتها
- فقط constant expression در constructor attribute
- overuse — logic پنهان در reflection magic
- IDE support بهتر از docblock اما نه همیشه کامل
جمعبندی
Attribute برای declarative metadata. Enum: پیشرفته. PSR: استانداردها.