We said before that most classes in Yii2 inherit from yiibaseObject, let us take a look at this today kind.
Object is a basic class that implements the function of attributes. Its basic content is as follows:
<?<span>php namespace yii\base; </span><span>use</span><span> Yii; </span><span>/*</span><span>* * Object 是一个基础类,实现了属性的功能 * Yii最基础的类,大多数类都继承了该类 </span><span>*/</span> <span>class</span> <span>Object</span> <span>implements</span><span> Configurable { </span><span>/*</span><span>* * 获取静态方法调用的类名。返回类的名称,如果不是在类中调用则返回 FALSE。 </span><span>*/</span> <span>public</span> <span>static</span> <span>function</span><span> className() { </span>...<span> } </span><span>/*</span><span>* * Constructor. </span><span>*/</span> <span>public</span> <span>function</span> __construct(<span>$config</span> =<span> []) { </span>...<span> } </span><span>/*</span><span>* * 初始化对象 </span><span>*/</span> <span>public</span> <span>function</span><span> init() { } </span><span>/*</span><span>* * 魔术方法,实现 getter </span><span>*/</span> <span>public</span> <span>function</span> __get(<span>$name</span><span>) { </span>...<span> } </span><span>/*</span><span>* * 魔术方法,实现 setter </span><span>*/</span> <span>public</span> <span>function</span> __set(<span>$name</span>, <span>$value</span><span>) { </span>...<span> } </span><span>/*</span><span>* * 魔术方法,实现 isset,基于 getter 实现,有 getter 方法的属性才算存在 </span><span>*/</span> <span>public</span> <span>function</span> __isset(<span>$name</span><span>) { </span>...<span> } </span><span>/*</span><span>* * 魔术方法,实现 unset,基于 setter 实现,有 setter 方法的属性才能 unset 掉 </span><span>*/</span> <span>public</span> <span>function</span> __unset(<span>$name</span><span>) { </span>...<span> } </span><span>/*</span><span>* * Calls the named method which is not a class method. </span><span>*/</span> <span>public</span> <span>function</span> __call(<span>$name</span>, <span>$params</span><span>) { </span>...<span> } </span><span>/*</span><span>* * 检查对象或类是否具有 $name 属性,如果 $checkVars 为 true,则不局限于是否有 getter/setter </span><span>*/</span> <span>public</span> <span>function</span> hasProperty(<span>$name</span>, <span>$checkVars</span> = <span>true</span><span>) { </span>...<span> } </span><span>/*</span><span>* * 检查对象或类是否能够获取 $name 属性,如果 $checkVars 为 true,则不局限于是否有 getter </span><span>*/</span> <span>public</span> <span>function</span> canGetProperty(<span>$name</span>, <span>$checkVars</span> = <span>true</span><span>) { </span>...<span> } </span><span>/*</span><span>* * 检查对象或类是否能够设置 $name 属性,如果 $checkVars 为 true,则不局限于是否有 setter </span><span>*/</span> <span>public</span> <span>function</span> canSetProperty(<span>$name</span>, <span>$checkVars</span> = <span>true</span><span>) { </span>...<span> } </span><span>/*</span><span>* * 检查对象或类是否具有 $name 方法 </span><span>*/</span> <span>public</span> <span>function</span> hasMethod(<span>$name</span><span>) { </span>...<span> } }</span>
If you want to see detailed annotations, you can visit https://github.com/ReadCode/yii2-2.0.3-annotated/blob/master/framework/base/Object.php
From the above content, we can see that the Object class overrides the __get and __set methods. Let’s take a closer look at these two methods:
<span>/*</span><span>* * Returns the value of an object property. * * Do not call this method directly as it is a PHP magic method that * will be implicitly called when executing `$value = $object->property;`. * * 魔术方法,实现 getter * * @param string $name the property name * @return mixed the property value * @throws UnknownPropertyException if the property is not defined * @throws InvalidCallException if the property is write-only * @see __set() </span><span>*/</span> <span>public</span> <span>function</span> __get(<span>$name</span><span>) { </span><span>$getter</span> = 'get' . <span>$name</span><span>; </span><span>if</span> (<span>method_exists</span>(<span>$this</span>, <span>$getter</span><span>)) { </span><span>//</span><span> 对象存在 $getter 方法,就直接调用</span> <span>return</span> <span>$this</span>-><span>$getter</span><span>(); } </span><span>elseif</span> (<span>method_exists</span>(<span>$this</span>, 'set' . <span>$name</span><span>)) { </span><span>//</span><span> 如果存在 'set' . $name 方法,就认为该属性是只写的</span> <span>throw</span> <span>new</span> InvalidCallException('Getting write-only property: ' . <span>get_class</span>(<span>$this</span>) . '::' . <span>$name</span><span>); } </span><span>else</span><span> { </span><span>//</span><span> 否则认为该属性不存在</span> <span>throw</span> <span>new</span> UnknownPropertyException('Getting unknown property: ' . <span>get_class</span>(<span>$this</span>) . '::' . <span>$name</span><span>); } } </span><span>/*</span><span>* * Sets value of an object property. * * Do not call this method directly as it is a PHP magic method that * will be implicitly called when executing `$object->property = $value;`. * * 魔术方法,实现 setter * * @param string $name the property name or the event name * @param mixed $value the property value * @throws UnknownPropertyException if the property is not defined * @throws InvalidCallException if the property is read-only * @see __get() </span><span>*/</span> <span>public</span> <span>function</span> __set(<span>$name</span>, <span>$value</span><span>) { </span><span>$setter</span> = 'set' . <span>$name</span><span>; </span><span>if</span> (<span>method_exists</span>(<span>$this</span>, <span>$setter</span><span>)) { </span><span>//</span><span> 对象存在 $setter 方法,就直接调用</span> <span>$this</span>-><span>$setter</span>(<span>$value</span><span>); } </span><span>elseif</span> (<span>method_exists</span>(<span>$this</span>, 'get' . <span>$name</span><span>)) { </span><span>//</span><span> 如果存在 'get' . $name 方法,就认为该属性是只读的</span> <span>throw</span> <span>new</span> InvalidCallException('Setting read-only property: ' . <span>get_class</span>(<span>$this</span>) . '::' . <span>$name</span><span>); } </span><span>else</span><span> { </span><span>//</span><span> 否则认为该属性不存在</span> <span>throw</span> <span>new</span> UnknownPropertyException('Setting unknown property: ' . <span>get_class</span>(<span>$this</span>) . '::' . <span>$name</span><span>); } }</span>
Based on the above code, we can see that if you access a certain property of an Object object, Yii will call a function named get property name() . For example, SomeObject->Foo will automatically call SomeObject->getFoo(). If a property is modified, the corresponding setter function will be called. For example, SomeObject->Foo = $someValue will automatically call SomeObject->setFoo( $someValue) .
Take SomeObject's Foo as an example. If only the getFoo() method exists, then it is read-only. If only the setFoo() method exists, then it is write-only. Only when both methods exist Both readable and writable.
One thing to note is that only when reading and writing a non-existent member variable of an object, __get() __set() will be called automatically. If Foo is a public property, it will not go through the __get() and __set() methods.
So usually attributes are private, for example:
<span>class</span> User <span>extends</span> yii\base\<span>Object</span><span> { </span><span>private</span> <span>$_name</span><span>; </span><span>public</span> <span>function</span><span> getName() { </span><span>return</span> <span>$this</span>-><span>_name; } </span><span>public</span> <span>function</span> setName(<span>$name</span><span>) { </span><span>$this</span>->_name = <span>trim</span>(<span>$name</span><span>); } }</span>
We can also do some special processing in the get and set methods.
In addition to __get() __set(), yiibaseObject The following methods are also provided to facilitate the use of attributes:
Students who are interested in the Yii2 source code can pay attention to the project yii2-2.0.3-annotated. A lot of comments about the Yii2 source code have been added to it, and they will continue to be added in the future~
Interested students can also participate and submit comments on the Yii2 source code.