php 魔术方法 深度理解

来源:互联网 发布:百万公众网络答题活动 编辑:程序博客网 时间:2024/05/22 04:24

  摘要:在trace yii框架源码的时候,遇到__set()魔术方法的使用,有些疑惑,所以写了demo来测试,果然发现了玄机,整理如下。

1. 先来看看书本上讲魔术方法__set()是怎么用的

  使用__set()魔术方法的目的是:在对象外部 为私有属性赋值,不能获取私有属性的值。
  函数原型:

void __set(string name,mixed value)

  写个demo:

class CModule {    private $_components = '';    public function __set($name,$value){        $this->$name = $value;    }    public function echoPrivate(){        echo $this->_components;    }}$module = new CModule();$module->_components = 'request';$module->echoPrivate();//打印结果是//request

  解释:要给对象的私有属性赋值的时候,本来是不行的(书里面讲类的封装性的时候,提出的概念),但是我们声明了魔术方法__set(),所以当给私有属性赋值的时候,就会调用这个方法。因为这个方法在对象内部,所以可以对私有属性赋值。要读取这个对象的私有属性的值,也不能直接读取,要通过该公有方法间接读取。
  这就是魔术方法最普通的用法。
  那么再来看看这种情况,如果对私有属性的赋值在构造函数里面,会发生什么。

2. 也看起来挺正常的用法,但有些小疑虑

  写个demo:

class CModule {    private $_components = '';    public function __construct($config=null){        foreach($config as $key=>$value)            $this->$key=$value;    }    public function __set($name,$value){        $this->$name = $value . "__set";    }    public function echoPrivate(){        echo $this->_components;    }}$config = array(    '_components'=>'request');$module = new CModule($config);$module->echoPrivate();//打印结果是//request

  解释:这次是在new出对象的时候,顺便调用构造函数对私有属性赋值的,打印结果是’request’,没有调用魔术方法__set(),这也是很合乎情理的,因为构造函数里面对私有属性赋值本身就是合法的。
  这样对私有属性赋值的时候,是没有调用魔术方法__set()的。

3. yii框架里面的用法,比较不走寻常路

class CModule {    public function __construct($config=null){        foreach($config as $key=>$value)            $this->$key=$value;    }    public function __set($name,$value){        $this->$name = $value . "__set";    }}$config = array(    '_components'=>'request');$module = new CModule($config);echo $module->_components;//打印结果是//request__set

  yii框架初始化的时候,将配置数组里面的配置项复制进CWepAppliaction的属性的时候就是这样做的。
  他里面并没有声明私有变量,然后在构造函数里面执行赋值,这时候就会调用魔术方法。是不是感觉优点绕。
  暂时没有找到一个标准的定律,先记下来。


<完>

1 0
原创粉丝点击