Допустим у вас есть моделька
class Model { public int $id; public string $title; public function getValue(string $property): mixed { return $this->$property; } }
И вам очень сильно совсем надоело хардкодить проперти и ещё больше сильнее совсем надоело их рефакторить:
$model = new Model(); $model->id = 42; $model->title = 'my title'; $id = $model->getValue('id'); $title = $model->getValue('title'); var_dump($id, $title);
То есть преккрасное убогое решение которое поможет вам обманывать вашу IDE: автодополнение и рефакторинг работают. Но не всегда, конечно, а только в контексте исполнения.
trait PropertyNameTrait { public static function __property(): object { return new class { public function __get(string $property): string { return $property; } }; } } /** @method static Model __property() */ class Model { use PropertyNameTrait; public int $id; public string $title; public function getValue(string $property): mixed { return $this->$property; } } $model = new Model(); $model->id = 42; $model->title = 'my title'; $id = $model->getValue($model::__property()->id); $title = $model->getValue(Model::__property()->title); var_dump($id, $title);
Конечно, можно добавить ещё немного магии, но у вас не получится аккуратно чейнить __get()
в трейте и классе, так что это уже по желанию (мне не очень нравится, но пользоваться этим сильно более красивее). (ну и надо не забыть кидать фатал на 404, но мне лень писать эти проверки).
/** @property-read Model $__property */ class Model { public int $id; public string $title; public function getValue(string $property): mixed { return $this->$property; } public function __get(string $property): mixed { if ($property === '__property') { return new class { public function __get(string $property): string { return $property; } }; } throw new Error("404: {$property}"); } } $model = new Model(); $model->id = 42; $model->title = 'my title'; $id = $model->getValue($model->__property->id); $title = $model->getValue($model->__property->title); var_dump($id, $title);
2021.10.20 13:50