Допустим у вас есть моделька
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