• yii框架CComponent源码分析


    简介:这是yii框架CComponent源码分析的详细页面,介绍了和php,有关的知识、技巧、经验,和一些php源码等。

    class='pingjiaF' frameborder='0' src='http://biancheng.dnbcw.info/pingjia.php?id=339159' scrolling='no'>
    CComponent源码分析

    //所有部件的基类
    class CComponent
    {
    private $_e;
    private $_m;

    //获取部件属性、事件和行为的magic method
    public function __get($name)
    {
    $getter='get'.$name;
    //是否存在属性的get方法
    if(method_exists($this,$getter))
    return $this->$getter();
    //以on开头,获取事件处理句柄
    else if(strncasecmp($name,'on',2)===0 && method_exists($this,$name))
    {
    // 事件名小写
    $name=strtolower($name);
    // 如果_e[$name] 不存在,返回一个空的CList事件句柄队列对象
    if(!isset($this->_e[$name]))
    $this->_e[$name]=new CList;
    // 返回_e[$name]里存放的句柄队列对象
    return $this->_e[$name];
    }
    // _m[$name] 里存放着行为对象则返回
    else if(isset($this->_m[$name]))
    return $this->_m[$name];
    else
    throw new CException(Yii::t('yii','Property "{class}.{property}" is not defined.',
    array('{class}'=>get_class($this), '{property}'=>$name)));
    }

    /**
    * PHP magic method
    * 设置组件的属性和事件
    */
    public function __set($name,$value)
    {
    $setter='set'.$name;
    //是否存在属性的set方法
    if(method_exists($this,$setter))
    $this->$setter($value);
    //name以on开头,这是事件处理句柄
    else if(strncasecmp($name,'on',2)===0 && method_exists($this,$name))
    {
    // 事件名小写
    $name=strtolower($name);
    // _e[$name] 不存在则创建一个CList对象
    if(!isset($this->_e[$name]))
    $this->_e[$name]=new CList;
    // 添加事件处理句柄
    $this->_e[$name]->add($value);
    }
    // 属性没有set方法,只有get方法,为只读属性,抛出异常
    else if(method_exists($this,'get'.$name))
    throw new CException(Yii::t('yii','Property "{class}.{property}" is read only.',
    array('{class}'=>get_class($this), '{property}'=>$name)));
    else
    throw new CException(Yii::t('yii','Property "{class}.{property}" is not defined.',
    array('{class}'=>get_class($this), '{property}'=>$name)));
    }

    /**
    * PHP magic method
    * 为isset()函数提供是否存在属性和事件处理句柄的判断
    */
    public function __isset($name)
    {
    $getter='get'.$name;
    if(method_exists($this,$getter))
    return $this->$getter()!==null;
    else if(strncasecmp($name,'on',2)===0 && method_exists($this,$name))
    {
    $name=strtolower($name);
    return isset($this->_e[$name]) && $this->_e[$name]->getCount();
    }
    else
    return false;
    }

    /**
    * PHP magic method
    * 设置属性值为空或删除事件名字对应的处理句柄
    */
    public function __unset($name)
    {
    $setter='set'.$name;
    if(method_exists($this,$setter))
    $this->$setter(null);
    else if(strncasecmp($name,'on',2)===0 && method_exists($this,$name))
    unset($this->_e[strtolower($name)]);
    else if(method_exists($this,'get'.$name))
    throw new CException(Yii::t('yii','Property "{class}.{property}" is read only.',
    array('{class}'=>get_class($this), '{property}'=>$name)));
    }

    /**
    * PHP magic method
    * CComponent未定义的类方法,寻 找行为类里的同名方法, 实现行为方法的调用
    */
    public function __call($name,$parameters)
    {
    // 行为类存放的$_m数组不空
    if($this->_m!==null)
    {
    // 循环取出$_m数组里存放的行为类
    foreach($this->_m as $object)
    {
    // 行为类对象有效,并且方法存在,调用之
    if($object->enabled && method_exists($object,$name))
    return call_user_func_array(array($object,$name),$parameters);
    }
    }
    throw new CException(Yii::t('yii','{class} does not have a method named "{name}".',
    array('{class}'=>get_class($this), '{name}'=>$name)));
    }

    /**
    * 根据行为名返回行为类对象
    */
    public function asa($behavior)
    {
    return isset($this->_m[$behavior]) ? $this->_m[$behavior] : null;
    }

    /**
    * Attaches a list of behaviors to the component.
    * Each behavior is indexed by its name and should be an instance of
    * {@link IBehavior}, a string specifying the behavior class, or an
    * array of the following structure:
    * <pre>
    * array(
    * 'class'=>'path.to.BehaviorClass',
    * 'property1'=>'value1',
    * 'property2'=>'value2',
    * )
    * </pre>
    * @param array list of behaviors to be attached to the component
    * @since 1.0.2
    */
    public function attachBehaviors($behaviors)
    {
    // $behaviors为数组 $name=>$behavior
    foreach($behaviors as $name=>$behavior)
    $this->attachBehavior($name,$behavior);
    }


    /**
    * 添加一个行为到组件
    */
    public function attachBehavior($name,$behavior)
    {
    /* $behavior不是IBehavior接口的实例,则为
    * array(
    * 'class'=>'path.to.BehaviorClass',
    * 'property1'=>'value1',
    * 'property2'=>'value2',
    * )
    * 传递给Yii::createComponent创建行为了并初始化对象属性
    */
    if(!($behavior instanceof IBehavior))
    $behavior=Yii::createComponent($behavior);
    $behavior->setEnabled(true);
    $behavior->attach($this);
    return $this->_m[$name]=$behavior;
    }

    /**
    * Raises an event.
    * This method represents the happening of an event. It invokes
    * all attached handlers for the event.
    * @param string the event name
    * @param CEvent the event parameter
    * @throws CException if the event is undefined or an event handler is invalid.
    */
    public function raiseEvent($name,$event)
    {
    $name=strtolower($name);
    // _e[$name] 事件处理句柄队列存在
    if(isset($this->_e[$name]))
    {
    // 循环取出事件处理句柄
    foreach($this->_e[$name] as $handler)
    {
    // 事件处理句柄为全局函数
    if(is_string($handler))
    call_user_func($handler,$event);
    else if(is_callable($handler,true))
    {
    // an array: 0 - object, 1 - method name
    list($object,$method)=$handler;
    if(is_string($object)) // 静态类方法
    call_user_func($handler,$event);
    else if(method_exists($object,$method))
    $object->$method($event);
    else
    throw new CException(Yii::t('yii','Event "{class}.{event}" is attached with an invalid handler "{handler}".',
    array('{class}'=>get_class($this), '{event}'=>$name, '{handler}'=>$handler[1])));
    }
    else
    throw new CException(Yii::t('yii','Event "{class}.{event}" is attached with an invalid handler "{handler}".',
    array('{class}'=>get_class($this), '{event}'=>$name, '{handler}'=>gettype($handler))));
    // $event 的handled 设置为true后停止队列里剩余句柄的调用
    if(($event instanceof CEvent) && $event->handled)
    return;
    }
    }
    else if(YII_DEBUG && !$this->hasEvent($name))
    throw new CException(Yii::t('yii','Event "{class}.{event}" is not defined.',
    array('{class}'=>get_class($this), '{event}'=>$name)));
    }
    }
    转自:http://blog.163.com/zyf_win/blog/static/1220628922010544612617/

    爱J2EE关注Java迈克尔杰克逊视频站JSON在线工具

    http://biancheng.dnbcw.info/php/339159.html pageNo:8
  • 相关阅读:
    Ubuntu18.04+windows10双系统时间同步教程
    Ubuntu官方源
    Ubuntu 16.04下OLSR协议安装教程
    Ubuntu 18.04中的Vim编辑器的高级配置
    关于vue-cli的安装
    var与let、const的区别
    jq点击相册弹出弹窗并可以轮播相册效果
    css三角形上下左右实心空心尖角箭头
    leetcode-44. Wildcard Matching
    c++转换构造函数和类型转换函数
  • 原文地址:https://www.cnblogs.com/ooooo/p/2246181.html
Copyright © 2020-2023  润新知