In PHP, the member variables of a class are also called attributes (properties). They are part of a class definition that represents the state of an instance (that is, different instances of the domain classification). In practice, you will often want to use a slightly more specific method to achieve the property of reading and writing. For example, if you have a requirement to trim the label property each time, you can do so with the following code:
$object->label = Trim ($label);
The disadvantage of the above code is that the trim () function must be called again as soon as the Label property is modified. In the future, you will have to modify all the code that assigns the label property to a label property, such as a first letter capitalization. The repetition of this code can lead to bugs, and this practice obviously needs to be avoided as much as possible.
To resolve this problem, Yii introduces a base class called Yii\base\object that supports defining attributes based on the getter and setter (reader and Setup) methods within the class. If a class needs to support this feature, simply inherit Yii\base\object or its subclasses.
Add: Almost every core class in the YII framework inherits from Yii\base\object or its subclasses. This means that as long as the getter or setter method is seen in the core class, it can be called like an attribute.
The Getter method is a method whose name begins with Get, and the setter method name begins with a set. The name of the property is defined by the part behind the get or set in the method name. As shown in the following code, the Getter Method Getlabel () and setter Method SetLabel () manipulate the Label property:
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);
}
(explained in detail: The Getter and setter methods create a property named label, in this case, it points to a private internal property _label.) )
Getter/setter defines the same property usage as a class member variable. The main difference is that when this property is read, the corresponding Getter method is invoked, and when the property is assigned, the corresponding setter method is invoked. Such as:
Equivalent to $label = $object->getlabel ();
$label = $object->label;
Equivalent to $object->setlabel (' abc ');
$object->label = ' abc ';
A property that only defines a getter without a setter is a read-only property. Attempting to assign to such a property will result in an yii\base\invalidcallexception (invalid call) exception. Similarly, an attempt to read a property that has a setter method and no Getter method definition is a write-only property can also trigger an exception. There are few cases where write-only properties are used.
There are special rules and restrictions for attributes defined by getter and setter:
The names of such properties are case-insensitive. For example, $object->label and $object->label are the same property. Because the PHP method name is case-insensitive.
If this class property name and class member variable are the same, the following will prevail. For example, suppose that the Foo class has a label member variable and then assigns $object->label = ' abc ' to assign to the member variable instead of the setter SetLabel () method.
This type of property does not support visibility (access restrictions). The getter and setter methods that define a property have no effect on the visibility of the property, whether public, protected, or private.
The getter and setter methods for such attributes can only be defined as non-static and are not treated in the same way if defined as static methods (static).
Back to the problem mentioned at the beginning, instead of calling the trim () function everywhere, now we just need to call it once in the setter SetLabel () method. If the new requirement for the label first letter becomes uppercase, we only need to modify the SetLabel () method without touching any other code.
Steps to implement a property
We know that __get () __set () is invoked automatically when reading and writing a nonexistent member variable for an object. Yii is leveraging this to provide support for attributes. As you can see from the code above, Yii invokes a function called a Get property name () if one of the properties of an object is accessed. For example, Someobject->foo will automatically call Someobject->getfoo (). If you modify a property, the corresponding setter function is invoked. For example, Someobject->foo = $someValue, the Someobject->setfoo ($someValue) is automatically invoked.
Therefore, to implement a property, there are usually three steps:
- Inherited from Yii\base\object.
- Declares a private member variable that is used to hold the property.
- Provides getter or setter functions, or both, for accessing and modifying the private member variables mentioned above. If only the getter is provided, then the property is read-only, only the setter is provided, and write-only.
The following Post class, which implements a readable writable property title:
Class Post extends Yii\base\object //First step: Inherit from Yii\base\object
{
private $_title; Step two: Declare a private member variable public
function GetTitle () //Step three: Provide getter and setter
{return
$this->_title;
} Public
function Settitle ($value)
{
$this->_title = Trim ($value);
}
}
Theoretically speaking, the private $_title is written as public $title, and can be realized to the $post->title reading and writing. But this is not a good habit, for the following reasons:
Lost the encapsulation of the class. Generally speaking, the member variable is not visible externally is a better programming habit. You may not see it from here, but if one day you don't want the user to change the title, how do you change it? How do I make sure that the title is not directly modified in the code? If a setter is provided, as long as the setter is deleted, an exception is thrown when there is no clean write to the caption. Using the public $title method, you change to private $title You can troubleshoot written exceptions, but the read is also prohibited.
For the title write, you want to remove the space. Using the setter method, you just need to call trim () in this place like the code snippet above. However, if you use the method of public $title, there is no doubt that the trim () is invoked for each write statement. Can you guarantee that there is no one missing?
Therefore, the use of public $title is only temporary and seems simple, but future revisions are a hassle. It's a nightmare, you can say. This is the meaning of software engineering, through a certain method, make the code easy to maintain, easy to modify. It seems unnecessary to look at the moment, but in fact the loss of a friend or a client boss forced to modify the code written by a programmer, greeting his loved ones, will feel that this is very necessary.
But there is no absolute. Because __get () and __set () are iterating through all the member variables, they are invoked only if they cannot find a matching member variable. Therefore, its efficiency is inherently lower than the use of member variables in the form. In some simple cases, such as data structure, dataset and so on, and do not need to read and write control, you can consider using member variables as attributes, which can improve the efficiency.
Another trick to improve efficiency is to use the $pro = $object->getpro () instead of the $pro = $object->pro, substituting $objcect->setpro ($value) for $object->p Ro = $value. This is functionally the same effect, but avoids the use of __get () and __set (), which is equivalent to bypassing the traversal process.
It is estimated that someone should scold me, Yii finally implemented the mechanism of the attribute, is to facilitate the developer, the result I am here to teach you how to use the original way, to improve the so-called efficiency. Well, indeed, there is a certain contradiction between the convenience of development and the efficiency of implementation. My personal point of view is more inclined to facilitate the first, with good, with the full use of yii to create the convenient conditions for us. As for the efficiency of things, more is the framework itself need to pay attention to, we just don't write exceptionally 2 code on the OK.
But you can rest assured that in the framework of yii, there is very little $app->request code, but the use of $app->getrequest (). In other words, the framework itself is particularly focused on efficiency, and as for convenience, it is left to the developer. In short, here just point out there is such a knowledge point, as for the use, how to use, it is entirely up to you.
It is noteworthy that:
The opportunity to automatically invoke the __get () __set () occurs only when accessing a member variable that does not exist. Therefore, if you define a member variable public $title then they will not be invoked even if GetTitle () Settitle () is defined. __get () __set () is not invoked because $post->title directly points to the Pulic $title. It was cut off from the root.
Because PHP is case-insensitive for class methods, which are case insensitive, $post->gettitle () and $post->gettitle () are called the same function. Therefore, $post->title and $post->title are the same property. That is, the property name is also case-insensitive.
Since __get () __set () are public, it is meaningless to declare getTitle () Settitle () as public, private, or protected, and the outside is equally accessible. So, all the attributes are public.
Because __get () __set () are not static, there is no way to use static properties.
Other properties-related methods of object
In addition to the __get () __set (), Yii\base\object provides the following methods for making the properties easier to use:
- __isset () is used to test whether a property value is not null and is invoked automatically when Isset ($object->property). Note that the property must have a corresponding getter.
- __unset () is used to set the property value to null and is invoked automatically when unset ($object->property). Note that the property must have a corresponding setter.
- Hasproperty () is used to test whether there is an attribute. That is, the getter or setter is defined. If the parameter of Hasproperty () is $checkVars = True (the default is true), a member variable of the same name is considered to have this property, as the public $title mentioned earlier.
- Cangetproperty () tests whether a property is readable, and the meaning of the parameter $checkVars ditto. As long as the getter is defined, the property is readable. Also, if $checkVars is true. So long as the class defines a member variable, whether public, private, or protected, it is considered readable.
- Cansetproperty () tests whether a property is writable, and the meaning of the parameter $checkVars ditto. As long as the setter is defined, the property can be written. At the same time, the $checkVars for ture. So long as the class defines a member variable, whether public, private, or protected, it is considered writable.
- Object and Component
Yii\base\component inherits from Yii\base\object, so he also has basic functions such as attributes.
However, since Componet also introduces events and behaviors, it does not simply inherit the property implementation of object, but rather overloads functions such as __get () __set () based on the same mechanism. But from the realization mechanism, it is the same. This does not affect understanding.
As I said before, the authorities are positioning yii in a component-based framework. The concept of visible components is the foundation of Yii. If you are interested in reading Yii's source code or API documentation, you will find that almost all of Yii's core classes are born (inherited from) yii\base\component.
In the Yii1.1, there is already component, then is ccomponent. Yii2 splits the ccomponent in Yii1.1 into two classes: Yii\base\object and yii\base\component.
Where object is lighter, the properties of the class are defined by getter and setter. Component is derived from object and supports events (event) and behavior (behavior). Therefore, the component class has three important features:
- Properties (property)
- Events (Event)
- Behavior (behavior)
I believe you have more or less learned that these three features are an important entry point for enriching and expanding class functions and changing behavior. Therefore, component's position in Yii is extremely high.
At the same time as providing more functions and more convenience, component has also sacrificed certain efficiency because of the addition of event and behavior, which is convenient for development. If you do not need to use both the event and behavior features in development, such as classes that represent some data. Then, you can inherit from object instead of from component. A typical scenario is to use object if it represents a set of data entered by a user. And if you need to deal with the behavior of the object and the events that respond to it, there is no doubt that component should be used. In terms of efficiency, object is closer to the native PHP class, so you should use object precedence, where possible.