В PHP переменные класса также называются свойствами. Эти переменные являются частью определения класса и используются для представления состояния экземпляра класса (т.е. Для выделения одного экземпляра класса из другого). На практике вы часто можете обрабатывать чтение или запись свойств специальными способами. Например, вы можете всегда обрезать строку, когда она назначается свойству label. Для достижения этой цели вы можете использовать следующий код:

$object->label = trim($label);

Недостатком приведенного выше кода является то, что вам придется вызывать trim() везде в коде, где вы можете установить свойство label. Если в будущем свойство label получит новое требование, например, первая буква должна быть заглавной, вам снова придется модифицировать каждый бит кода, который присваивает значение метке. Повторение кода приводит к ошибкам, и это практика, которую вы хотите избежать в максимально возможной степени.

Чтобы решить эту проблему, Yii вводит базовый класс с именем yii\base\Object, который поддерживает определение свойств на основе методов класса getter и setter. Если класс нуждается в этой функциональности, он должен распространяться от yii\base\Object или из дочернего класса.

Метод getter - это метод, имя которого начинается со слова get; Метод setter начинается с set. Имя после префикса get или set определяет имя свойства. Например, getter getLabel() или сеттер setLabel() определяют свойство с именем label, как показано в следующем коде:

namespace app\components;

use yii\base\Object;

class Foo extends Object
{
    private $_label;

    public function getLabel()
    {
        return $this->_label;
    }

    public function setLabel($value)
    {
        $this->_label = trim($value);
    }
}

Чтобы быть ясным, методы геттера и сеттера создают свойство label, которая в этом случае внутренне ссылается на частное свойство с именем _label.

Свойства, определенные геттерами и сеттерами, могут использоваться как переменные-члены класса. Основное отличие состоит в том, что при считывании такого свойства будет вызван соответствующий метод получения; Когда этому свойству присваивается значение, будет вызван соответствующий метод setter. Например:

// equivalent to $label = $object->getLabel();
$label = $object->label;

// equivalent to $object->setLabel('abc');
$object->label = 'abc';

Свойство, определяемое геттером без установщика, доступно только для чтения. Попытка присвоить значение этому свойству вызовет InvalidCallException. Аналогично, свойство, определенное установщиком без геттера, является только записью, и попытка прочитать такое свойство также вызовет исключение. Не является обычным иметь свойства только для записи.

Существует несколько специальных правил и ограничений для свойств, определяемых с помощью геттеров и сеттеров:

  • Имена таких свойств не зависят от регистра. Например, $object->label и $object->Label одинаковы. Это связано с тем, что имена методов в PHP не чувствительны к регистру.
  • Если имя такого свойства совпадает с именем переменной класса, последний будет иметь приоритет. Например, если в указанном выше классе Foo есть label переменная, то присвоение $object->label = 'abc' повлияет на переменную label. Эта строка не будет вызывать метод setLabel() setter.
  • Эти свойства не поддерживают видимость. Это не имеет никакого отношения к определяющему методу getter или setter, если свойство public, protected или private.
  • Свойства могут быть определены только нестатическими геттерами и/или сеттерами. Статические методы не будут обрабатываться одинаково.
  • Нормальный вызов property_exists() не работает для определения магических свойств. Вы должны вызвать canGetProperty() или canSetProperty() соответственно.

Вместо вызова trim() везде присваивается значение label, теперь функция trim() должна быть вызвана только в setter setLabel(). И если новое требование делает необходимым, чтобы метка была первоначально заглавной, метод setLabel() можно быстро изменить, не затрагивая какой-либо другой код. Одно изменение будет повсеместно влиять на каждое присваивание label.