属性(Properties)

    上述代码的缺点是只要修改 label 属性就必须再次调用 trim() 函数。
    若将来需要用其它方式处理 label 属性,比如首字母大写,
    就不得不修改所有给 label 属性赋值的代码。这种代码的重复会导致 bug,
    这种实践显然需要尽可能避免。

    为解决该问题,Yii 引入了一个名为 [[yii\base\Object]] 的基类,
    它支持基于类内的 gettersetter(读取器和设定器)方法来定义属性。
    如果某类需要支持这个特性,只需要继承 [[yii\base\Object]] 或其子类即可。

    getter 方法是名称以 get 开头的方法,而 setter 方法名以 set 开头。
    方法名中 get 或 后面的部分就定义了该属性的名字。如下面代码所示,
    getter 方法 getLabel() 和 setter 方法 setLabel() 操作的是 label 属性,:

    (详细解释:getter 和 setter 方法创建了一个名为 label 的属性,
    在这个例子里,它指向一个私有的内部属性 _label。)

    只定义了 getter 没有 setter 的属性是只读属性
    尝试赋值给这样的属性将导致 [[yii\base\InvalidCallException|InvalidCallException]] (无效调用)异常。
    类似的,只有 setter 方法而没有 getter 方法定义的属性是只写属性
    尝试读取这种属性也会触发异常。使用只写属性的情况几乎没有。

    通过 getter 和 setter 定义的属性也有一些特殊规则和限制:

    • 这类属性的名字是不区分大小写的。如,$object->label$object->Label 是同一个属性。
      因为 PHP 方法名是不区分大小写的。
    • 这类属性不支持可见性(访问限制)。定义属性的 getter 和 setter 方法是 public、protected 还是 private 对属性的可见性没有任何影响。
    • 对不确定有无魔术方法(getter 或 setter)的属性正常调用 property_exists() 将不会生效。你应该分别调用 [[yii\base\BaseObject::canGetProperty()|canGetProperty()]]
      或 [[yii\base\BaseObject::canSetProperty()|canSetProperty()]] 。