In PHP, class member variables are also called *properties*. They are part of a class definition and are used
In PHP, class member variables are also called *properties*. These variables are part of the class definition, and are used
to represent the state of a class instance. In practice, you may often want to do some special handling when
to represent the state of a class instance (i.e., to differentiate one instance of the class from another). In practice, you may often want to handle the reading or writing of properties in special ways. For example, you may want to trim a string when it is being assigned
a property is being read or modified. For example, you may want to trim a string when it is being assigned
to a `label` property. You could use the following code to achieve this task:
to a `label` property. You could use the following code to achieve this task:
```php
```php
$object->label=trim($label);
$object->label=trim($label);
```
```
The drawback of the above code is that you have to call `trim()` everywhere whenever you modify the `label`
The drawback of the above code is that you have to call `trim()` everywhere in your code where you met set the `label`
property. And if in future, the `label` property has a new requirement, such as the first letter must be turned
property. If in the future, the `label` property gets a new requirement, such as the first letter must be captialized, you would again have to modify every bit of code that assigns a value to `label`. The repetition of code leads to bugs and is a practice you want to avoid as much as possible.
into upper case, you would have to modify all those places - a practice you want to avoid as much as possible.
To solve this problem, Yii introduces a base class called [[yii\base\Object]] to support defining properties
To solve this problem, Yii introduces a base class called [[yii\base\Object]] that supports defining properties
based on *getter* and *setter* class methods. If a class needs such a support, it should extend from
based on *getter* and *setter* class methods. If a class needs such support, it should extend from
[[yii\base\Object]] or its child class.
[[yii\base\Object]] or a child class.
> Info: Nearly every core class in the Yii framework extends from [[yii\base\Object]] or its child class.
> Info: Nearly every core class in the Yii framework extends from [[yii\base\Object]] or a child class.
This means whenever you see a getter or setter in a core class, you can use it like a property.
This means that whenever you see a getter or setter in a core class, you can use it like a property.
A getter method is a method whose name starts with the word `get`, while a setter method starts with `set`.
A getter method is a method whose name starts with the word `get`; a setter method starts with `set`.
The name after the `get` or `set` prefix defines the name of a property. For example, a getter `getLabel()` and/or
The name after the `get` or `set` prefix defines the name of a property. For example, a getter `getLabel()` and/or
a setter `setLabel()` defines a property named `label`, as shown in the following code:
a setter `setLabel()` defines a property named `label`, as shown in the following code:
...
@@ -46,9 +44,11 @@ class Foo extend Object
...
@@ -46,9 +44,11 @@ class Foo extend Object
}
}
```
```
Properties defined by getters/setters can be used like class member variables. The main difference is that
(To be clear, the getter and setter methods create the property `label`, which in this case internally refer to a private attributed named `_label`.)
when such a property is being read, the corresponding getter method will be called; and when the property is
being assigned, the corresponding setter method will be called. For example,
Properties defined by getters and setters can be used like class member variables. The main difference is that
when such a property is being read, the corresponding getter method will be called; when the property is
being assigned a value, the corresponding setter method will be called. For example:
```php
```php
// equivalent to $label = $object->getLabel();
// equivalent to $label = $object->getLabel();
...
@@ -63,17 +63,15 @@ an [[yii\base\InvalidCallException|InvalidCallException]]. Similarly, a property
...
@@ -63,17 +63,15 @@ an [[yii\base\InvalidCallException|InvalidCallException]]. Similarly, a property
is *write only*, and trying to read such a property will also cause an exception. It is not common to have write-only
is *write only*, and trying to read such a property will also cause an exception. It is not common to have write-only
properties.
properties.
There are several special rules or limitations of the properties defined based on getters and setters.
There are several special rules for, and limitations on, the properties defined via getters and setters:
* The names of such properties are *case-insensitive*. For example, `$object->label` and `$object->Label` are the same.
* The names of such properties are *case-insensitive*. For example, `$object->label` and `$object->Label` are the same.
This is because PHP method names are case-insensitive.
This is because method names in PHP are case-insensitive.
* If the name of such a property is the same as a class member variable, the latter will take precedence.
* If the name of such a property is the same as a class member variable, the latter will take precedence.
For example, if the above `Foo` class has a member variable `label`, then the assignment `$object->label = 'abc'`
For example, if the above `Foo` class has a member variable `label`, then the assignment `$object->label = 'abc'`
will happen to the member variable instead of the setter `setLabel()`.
will affect the member variable 'label', that line would not call the `setLabel()` setter method.
* The properties do not support visibility. It makes no difference for the visibility of a property
* These properties do not support visibility. It makes no difference for the visibility of a property
if the defining getter or setter method is public, protected or private.
if the defining getter or setter method is public, protected or private.
* The properties can only be defined by *non-static* getters and/or setters. Static methods do not count.
* The properties can only be defined by *non-static* getters and/or setters. Static methods will not be treated in this same manner.
Back to the problem we described at the very beginning, instead of calling `trim()` everywhere, we are calling it
Returning back to the problem described at the beginning of this guide, instead of calling `trim()` everywhere a `label` value is assigned, `trim()` only needs to be invoked within the setter `setLabel()`. And if a new requirement comes that requires the label be initially capitalized, the `setLabel()` method can quickly be modified without touching any other code. The one change will universally affect every assignment to `label`.
only within the setter `setLabel()`. And if a new requirement comes that the first letter of the label should
be turned into upper case, we just need to modify the `setLabel()` method without touching any other code.