Как наиболее правильно реализовать в Yii2 аналог аксессоров из Laravel?

В Yii2 нет явного аналога аксессоров из Laravel, но есть несколько способов реализации схожего функционала.

Первый способ - использование методов-геттеров (getter) и методов-сеттеров (setter). Метод-геттер позволяет получить значение определенного свойства модели, а метод-сеттер - установить его значение. Например, предположим, у нас есть модель "User" с свойством "name":

class User extends yiidbActiveRecord
{
    // ...
    public function getName()
    {
        return $this->first_name . ' ' . $this->last_name;
    }

    public function setName($name)
    {
        $parts = explode(' ', $name);
        $this->first_name = $parts[0];
        $this->last_name = $parts[1] ?? '';
    }
    // ...
}

Теперь мы можем получить и установить значение свойства "name" следующим образом:

$user = User::findOne(1);
$name = $user->name; // Получение значения свойства
$user->name = 'John Doe'; // Установка значения свойства

Второй способ - использование виртуальных свойств (virtual properties). Это позволяет определить геттеры и сеттеры для свойств, которых на самом деле нет в базе данных, но которые должны быть доступны в коде. Для этого необходимо переопределить методы __get() и __set() в модели:

class User extends yiidbActiveRecord
{
    // ...
    private $_name;

    public function __get($name)
    {
        switch ($name) {
            case 'name':
                return $this->first_name . ' ' . $this->last_name;
            default:
                return parent::__get($name);
        }
    }

    public function __set($name, $value)
    {
        switch ($name) {
            case 'name':
                $parts = explode(' ', $value);
                $this->first_name = $parts[0];
                $this->last_name = $parts[1] ?? '';
                break;
            default:
                parent::__set($name, $value);
                break;
        }
    }
    // ...
}

Теперь мы можем использовать виртуальное свойство "name" так же, как и ранее:

$user = User::findOne(1);
$name = $user->name; // Получение значения свойства
$user->name = 'John Doe'; // Установка значения свойства

Третий способ - использование валидаторов (validators). Валидаторы позволяют определить функции обратного вызова, которые будут вызываться при попытке чтения или записи определенного свойства модели. Для этого нужно добавить соответствующие правила в метод rules() модели:

class User extends yiidbActiveRecord
{
    // ...
    public function rules()
    {
        return [
            // ...
            [['name'], 'string'],
            [['name'], 'validateName'],
        ];
    }

    public function validateName($attribute, $params)
    {
        switch ($attribute) {
            case 'name':
                // Валидация значения свойства
                break;
        }
    }
    // ...
}

Теперь мы можем использовать валидаторы для свойства "name" следующим образом:

$user = User::findOne(1);
$name = $user->name; // Получение значения свойства
$user->name = 'John Doe'; // Установка значения свойства

Однако, в отличие от аксессоров в Laravel, при таком подходе используется явное обращение к методам или свойствам модели, что может быть несколько более громоздким.