Yii2 framework backup
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

7.3 KiB

Свойства

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

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

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

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

Информация: Почти все внутренние классы Yii наследуются от yii\base\Object или его потомков. Это значит, что всякий раз, когда вы встречаете геттер или сеттер в классах фреймворка, вы можете обращаться к нему, как к свойству.

Геттер - это метод, чье название начинается со слова get; имя сеттера начинается со слова set. А часть названия после префикса get или set определяет имя свойства. Например, геттер getLabel() и/или сеттер setLabel() определяют свойство label, как показано в коде ниже:

namespace app\components;

use yii\base\Object;

class Foo extend Object
{
    private $_label;

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

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

(Для наглядности, здесь геттер и сеттер реализуют свойство label, но значение хранят в закрытом свойстве _label).

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

// Идентично вызову $label = $object->getLabel();
$label = $object->label;

// Идентично вызову $object->setLabel('abc');
$object->label = 'abc';

Свойство для которого объявлен только геттер без сеттера может использоваться только для чтения. Попытка присвоить ему значение вызовет yii\base\InvalidCallException. Точно так же, свойство для которого объявлен только сеттер без геттера может использоваться только для записи. Попытка получить его значение так же вызовет исключение. Свойства предназначенные только для чтения встречаются не часто.

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

  • Имена таких свойств регистронезависимы. Таким образом, $object->label и $object->Label - одно и то же. Это обусловлено тем, что имена методов в PHP регистронезависимы.
  • Если имя такого свойства уже используется переменной-членом класса, то последнее будет иметь более высокий приоритет. Например, если в классе Foo объявлено свойство label, то при вызове $object->label = 'abc' будет напрямую изменено значение свойства label. А метод setLabel() не будет вызван.
  • Свойства, объявленные таким образом, не поддерживают идентификаторы видимости. Это значит, что объявление геттера или сеттера как открытого, защищенного или закрытого никак не скажется на области видимости свойства.
  • Свойства могут быть объявлены только с помощью нестатичных геттеров и/или сеттеров. Статичные методы не будут обрабатываться подобным образом.

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