yii2 源码分析 object类分析 (一)

 转载请注明链接http://www.cnblogs.com/liuwanqiu/p/6737327.html 

yii2基本上所有的类都是继承的object类,下面就来分析一下object类吧

object类实现了一个接口Configurable,既然接口里什么都没有,就不介绍这个接口了。。。

最上面的注释被我删了,大致说了一下几点:
*1.一个属性通过get和set方法会被定义
*2.类的属性不区分大小写
*3.当创建一个对象后既可以通过对象的get和set方法来访问类的属性,也可以访问类的属性
*4.类的构造方法先被调用,然后类的属性被初始化,然后init方法会被调用
*5.英文注释还说了,为了保证声明周期,当有子类重写父类的__construct构造方法时,让你在这个构造方法里传个配置数组

 

class Object implements Configurable{
    /**
     *返回类的完全合格名,get_called_class()和get_class()是不同的,想详细了解,参考这个http://www.cnblogs.com/liuwanqiu/p/6736863.html
     */
    public static function className()
    {
    //哪个类调用,返回哪个类
        return get_called_class();
    }

    /**
     * 此方法做了两件事情:
     *1.对象的属性初始化
     *2.调用init()方法
     *传入的数组是键值对,键是对象的属性名,值是对象的属性值
     * @param array $config name-value pairs that will be used to initialize the object properties
     */
    public function __construct($config = [])
    {
        if (!empty($config)) {
            Yii::configure($this, $config);//去BaseYii.php进行对象的属性赋值操作
        }
        $this->init();
    }

    /**
     * 可以根据属性进行一系列操作
     */
    public function init()
    {
    }

    /**
     *重写了php的魔术方法__get方法,此方法被隐式调用,当获取不存在的属性时被调用,通过查找get和set方法,人性化的提示,此属性是找不到还是只能写
     */
    public function __get($name)
    {
        $getter = 'get' . $name;
        if (method_exists($this, $getter)) {
            return $this->$getter();
        } elseif (method_exists($this, 'set' . $name)) {
            throw new InvalidCallException('Getting write-only property: ' . get_class($this) . '::' . $name);
        } else {
            throw new UnknownPropertyException('Getting unknown property: ' . get_class($this) . '::' . $name);
        }
    }

    /**
     * 和__get方法差不多,提示属性不存在或者只能读
     *
     */
    public function __set($name, $value)
    {
        $setter = 'set' . $name;
        if (method_exists($this, $setter)) {
            $this->$setter($value);
        } elseif (method_exists($this, 'get' . $name)) {
            throw new InvalidCallException('Setting read-only property: ' . get_class($this) . '::' . $name);
        } else {
            throw new UnknownPropertyException('Setting unknown property: ' . get_class($this) . '::' . $name);
        }
    }

    /**
     *判断属性是否被定义或者不为空
     */
    public function __isset($name)
    {
        $getter = 'get' . $name;
        if (method_exists($this, $getter)) {
            return $this->$getter() !== null;
        } else {
            return false;
        }
    }

    /**
     * 把一个对象的属性设置为空
     *如果此方法只能读,就会抛出异常
     */
    public function __unset($name)
    {
        $setter = 'set' . $name;
        if (method_exists($this, $setter)) {
            $this->$setter(null);
        } elseif (method_exists($this, 'get' . $name)) {
            throw new InvalidCallException('Unsetting read-only property: ' . get_class($this) . '::' . $name);
        }
    }

    /**
     * 调用不存在的方法时,隐式调用,人性化的抛出异常
     */
    public function __call($name, $params)
    {
        throw new UnknownMethodException('Calling unknown method: ' . get_class($this) . "::$name()");
    }

    /**
     * 判断一个类的属性是否被定义,即对象是否有get或set方法,属性名不区分大小写
     * 第二个参数表示是否将成员变量作为属性
     */
    public function hasProperty($name, $checkVars = true)
    {
        return $this->canGetProperty($name, $checkVars) || $this->canSetProperty($name, false);
    }

    /**
     *判断get方法或set方法是否存在
     */
    public function canGetProperty($name, $checkVars = true)
    {
        return method_exists($this, 'get' . $name) || $checkVars && property_exists($this, $name);
    }

    /**
     *这个和上面一样,不介绍了。。
     */
    public function canSetProperty($name, $checkVars = true)
    {
        return method_exists($this, 'set' . $name) || $checkVars && property_exists($this, $name);
    }

    /**
     * 判断方法是否存在
     */
    public function hasMethod($name)
    {
        return method_exists($this, $name);
    }
}

  

  

  

posted @ 2017-04-20 10:17  岁月无言成追忆  阅读(417)  评论(0)    收藏  举报