blackcube/magic-compose
最新稳定版本:1.0.0
Composer 安装命令:
composer require blackcube/magic-compose
包简介
Simple solution for magic methods and method composition using attributes
关键字:
README 文档
README
⚠️ Blackcube Warning
PHP says one
__getper class. Blackcube says no.Multiple traits, each with their own magic handlers, dispatched by priority via attributes. It's not a hack — it's composition where PHP forgot to provide it.
Simple solution for magic methods and method composition using attributes.
Installation
composer require blackcube/magic-compose
Problem
PHP traits can't compose magic methods. When multiple traits define __get, only one wins:
class MyClass { use TraitA, TraitB; // TraitB::__get shadows TraitA::__get }
Solution
Mark handlers with attributes, let MagicComposeTrait dispatch:
class MyClass { use MagicComposeTrait, TraitA, TraitB; } trait TraitA { #[MagicGetter] protected function getFromA(string $name): mixed { if ($name === 'foo') return 'from A'; throw new MagicNotHandledException(); } } trait TraitB { #[MagicGetter(priority: Priority::HIGH)] protected function getFromB(string $name): mixed { if ($name === 'bar') return 'from B'; throw new MagicNotHandledException(); } } $obj = new MyClass(); $obj->foo; // 'from A' $obj->bar; // 'from B'
Attributes
| Attribute | Magic method | Handler signature |
|---|---|---|
#[MagicGetter] |
__get |
(string $name): mixed |
#[MagicSetter] |
__set |
(string $name, mixed $value): void |
#[MagicIsset] |
__isset |
(string $name): bool |
#[MagicUnset] |
__unset |
(string $name): void |
#[MagicCall] |
__call |
(string $name, array $arguments): mixed |
Priority
Handlers are sorted by priority (highest first):
use Blackcube\MagicCompose\Attributes\Priority; #[MagicGetter(priority: Priority::HIGH)] // 90 - runs first #[MagicGetter(priority: Priority::NORMAL)] // 50 - default #[MagicGetter(priority: Priority::LOW)] // 10 - runs last
Constants: CRITICAL (100), HIGH (90), NORMAL (50), LOW (10).
MagicExtend
Intercept parent class methods with chainable $this->next():
trait AuditTrait { use MagicComposeMethodsBaseTrait; #[MagicExtend(method: 'save')] protected function auditSave(): bool { $this->log('before save'); $result = $this->next(); // call parent::save() or next handler $this->log('after save'); return $result; } }
ActiveRecord Integration
For Yii ActiveRecord, use MagicComposeActiveRecordTrait:
use Yiisoft\ActiveRecord\ActiveRecord; use Blackcube\MagicCompose\MagicComposeActiveRecordTrait; class User extends ActiveRecord { use MagicComposeActiveRecordTrait; use SomeCustomTrait; }
Pre-wired methods: propertyValuesInternal, refreshInternal, populateProperty, deleteInternal, populateRecord.
Handler Flow
- Handlers discovered via reflection (cached)
- Sorted by priority DESC
- First handler that doesn't throw
MagicNotHandledExceptionwins - If all throw → fallback to parent or PHP error
License
BSD-3-Clause. See LICENSE.md.
Author
Philippe Gaultier philippe@blackcube.io
统计信息
- 总下载量: 30
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 5
- 依赖项目数: 1
- 推荐数: 1
其他信息
- 授权协议: BSD-3-Clause
- 更新时间: 2026-02-26