CComponent


system.base
继承 class CComponent
子类 CAccessRule, CAction, CActiveFinder, CApplicationComponent, CAuthAssignment, CAuthItem, CBaseActiveRelation, CBaseController, CBaseUrlRule, CBaseUserIdentity, CBehavior, CCacheDependency, CChainedCacheDependency, CCodeFile, CConsoleCommand, CConsoleCommandRunner, CDataProvider, CDateFormatter, CDbColumnSchema, CDbCommand, CDbCommandBuilder, CDbCriteria, CDbDataReader, CDbExpression, CDbMigration, CDbSchema, CDbTableSchema, CDbTransaction, CEvent, CFilter, CFormElement, CGettextFile, CGridColumn, CHttpCookie, CList, CLocale, CLogFilter, CLogRoute, CLogger, CMap, CMemCacheServerConfiguration, CModel, CModule, CNumberFormatter, CPagination, CQueue, CSort, CStack, CTheme, CUploadedFile, CValidator, CWebService, CWsdlGenerator
源自 1.0
版本 $Id: CComponent.php 3521 2011-12-29 22:10:57Z mdomba $
源码
CComponent 是所有组件类的基类。

CComponent 实现了定义、使用属性和事件的协议。

属性是通过getter方法或/和setter方法定义。 访问属性就像访问普通的对象变量。 读取或写入属性将调用应相的getter或setter方法, 例如:
$a=$component->text;     // equivalent to $a=$component->getText();
$component->text='abc';  // equivalent to $component->setText('abc');
getter和setter方法的格式如下,
// getter, defines a readable property 'text'
public function getText() { ... }
// setter, defines a writable property 'text' with $value to be set to the property
public function setText($value) { ... }


事件是定义为以‘on’开头的方法。 这个方法名就是事件名。 当发起一个事件,附加到事件上的函数(回调,或事件处理程序)将被自动调用。

一个事件的发起是通过raiseEvent方法, 附加在此事件上的事件处理程序将按顺序自动被调用。 事件处理程序必须按以下格式定义,
function eventHandler($event) { ... }
其中的$event包含了与事件相关的参数。

要附加一个事件处理程序,参见attachEventHandler。 你也可以使用如下语法:
$component->onClick=$callback;    // or $component->onClick->add($callback);
其中的$callback指的是一个有效的PHP回调函数。下面我们展示一个回调函数的例子:
'handleOnClick'                   // handleOnClick() is a global function
array($object,'handleOnClick')    // using $object->handleOnClick()
array('Page','handleOnClick')     // using Page::handleOnClick()


发起一个事件可以通过使用raiseEvent。 这个方法通常定义为如下形式:
public function onClick($event)
{
    $this->raiseEvent('onClick',$event);
}
其中$eventCEvent或它的子类的一个实例。 你可直接调用一个方法来代替raiseEvent

属性名和事件名都是大小写敏感的,需要区分大写。

CComponent支持行为。 一个行为是附加在组件上的IBehavior类的实例。 组件可以调用行为中的方法,这个方法就好像是组件的一部份。 多个行为可以附加到同一个组件。

附加行为可以通过调用attachBehavior方法; 从组件分离行为可以调用detachBehavior方法。

行为可以通过调用enableBehavior 方法或disableBehavior方法的临时启用或禁用。 当禁用时,组件将不能调用行为中的方法。

从1.1.0版本开始, 一个行为的属性(或它的公共变量或通过getters/setters方法定义的属性), 能够通过这个组件进行访问。

公共方法

方法 描述 定义在
__call() 如果类中没有调的方法名,则调用这个方法。 CComponent
__get() 返回一个属性值、一个事件处理程序列表或一个行为名称。 CComponent
__isset() 检查一个属性是否为null。 CComponent
__set() 设置一个组件的属性值。 CComponent
__unset() 设置一个组件的属性为null。 CComponent
asa() 返回这个名字的行为对象。 CComponent
attachBehavior() 附加一个行为到组件。 CComponent
attachBehaviors() 附加一个行为列表到组件。 CComponent
attachEventHandler() 为事件附加一个事件处理程序。 CComponent
canGetProperty() 确定属性是否可读。 CComponent
canSetProperty() 确定属性是否可写。 CComponent
detachBehavior() 从组件中分离一个行为。 CComponent
detachBehaviors() 从组件中分离所有行为。 CComponent
detachEventHandler() 分离一个存在的事件处理程序。 CComponent
disableBehavior() 禁用一个附加行为。 CComponent
disableBehaviors() 禁用组件附加的所有行为。 CComponent
enableBehavior() 启用一个附加行为。 CComponent
enableBehaviors() 启用组件附加的所有行为。 CComponent
evaluateExpression() 计算一个PHP表达式,或根据组件上下文执行回调。 CComponent
getEventHandlers() 返回一个事件的附加处理程序列表。 CComponent
hasEvent() 确定一个事件是否定义。 CComponent
hasEventHandler() 检查事件是否有附加的处理程序。 CComponent
hasProperty() 确定属性是否被定义。 CComponent
raiseEvent() 发起一个事件。 CComponent

方法详细

__call() 方法
public mixed __call(string $name, array $parameters)
$name string 方法名
$parameters array 方法参数
{return} mixed 方法返回值
public function __call($name,$parameters)
{
    if(
$this->_m!==null)
    {
        foreach(
$this->_m as $object)
        {
            if(
$object->getEnabled() && method_exists($object,$name))
                return 
call_user_func_array(array($object,$name),$parameters);
        }
    }
    if(
class_exists('Closure'false) && $this->canGetProperty($name) && $this->$name instanceof Closure)
        return 
call_user_func_array($this->$name$parameters);
    throw new 
CException(Yii::t('yii','{class} and its behaviors do not have a method or closure named "{name}".',
        array(
'{class}'=>get_class($this), '{name}'=>$name)));
}

如果类中没有调的方法名,则调用这个方法。 不能直接调用此方法。这是重载了PHP的魔术方法, 实现了这个行为功能。

__get() 方法
public mixed __get(string $name)
$name string 属性名或事件名
{return} mixed 属性值,附加的事件处理程序或一个行名称
public function __get($name)
{
    
$getter='get'.$name;
    if(
method_exists($this,$getter))
        return 
$this->$getter();
    else if(
strncasecmp($name,'on',2)===&& method_exists($this,$name))
    {
        
// duplicating getEventHandlers() here for performance
        
$name=strtolower($name);
        if(!isset(
$this->_e[$name]))
            
$this->_e[$name]=new CList;
        return 
$this->_e[$name];
    }
    else if(isset(
$this->_m[$name]))
        return 
$this->_m[$name];
    else if(
is_array($this->_m))
    {
        foreach(
$this->_m as $object)
        {
            if(
$object->getEnabled() && (property_exists($object,$name) || $object->canGetProperty($name)))
                return 
$object->$name;
        }
    }
    throw new 
CException(Yii::t('yii','Property "{class}.{property}" is not defined.',
        array(
'{class}'=>get_class($this), '{property}'=>$name)));
}

返回一个属性值、一个事件处理程序列表或一个行为名称。 不能直接调用此方法。这是重载了PHP的魔术方法, 允许使用以下语法读取一个属性或获得一个事件处理程序:

$value=$component->propertyName;
$handlers=$component->eventName;

参见

__isset() 方法
public boolean __isset(string $name)
$name string 属性名或事件名
{return} boolean
public function __isset($name)
{
    
$getter='get'.$name;
    if(
method_exists($this,$getter))
        return 
$this->$getter()!==null;
    else if(
strncasecmp($name,'on',2)===&& method_exists($this,$name))
    {
        
$name=strtolower($name);
        return isset(
$this->_e[$name]) && $this->_e[$name]->getCount();
    }
    else if(
is_array($this->_m))
    {
         if(isset(
$this->_m[$name]))
             return 
true;
        foreach(
$this->_m as $object)
        {
            if(
$object->getEnabled() && (property_exists($object,$name) || $object->canGetProperty($name)))
                return 
$object->$name!==null;
        }
    }
    return 
false;
}

检查一个属性是否为null。 不能直接调用此方法。这是重载了PHP的魔术方法, 允许使用isset()检测组件属性是否已设置。

__set() 方法
public mixed __set(string $name, mixed $value)
$name string 属性名或者事件名
$value mixed 属性值或回调
{return} mixed
public function __set($name,$value)
{
    
$setter='set'.$name;
    if(
method_exists($this,$setter))
        return 
$this->$setter($value);
    else if(
strncasecmp($name,'on',2)===&& method_exists($this,$name))
    {
        
// duplicating getEventHandlers() here for performance
        
$name=strtolower($name);
        if(!isset(
$this->_e[$name]))
            
$this->_e[$name]=new CList;
        return 
$this->_e[$name]->add($value);
    }
    else if(
is_array($this->_m))
    {
        foreach(
$this->_m as $object)
        {
            if(
$object->getEnabled() && (property_exists($object,$name) || $object->canSetProperty($name)))
                return 
$object->$name=$value;
        }
    }
    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的魔术方法, 允许使用以下语法设置一个属性或获得一个事件处理程序:

$this->propertyName=$value;
$this->eventName=$callback;

参见

__unset() 方法
public mixed __unset(string $name)
$name string 属性名或事件名
{return} mixed
public function __unset($name)
{
    
$setter='set'.$name;
    if(
method_exists($this,$setter))
        
$this->$setter(null);
    else if(
strncasecmp($name,'on',2)===&& method_exists($this,$name))
        unset(
$this->_e[strtolower($name)]);
    else if(
is_array($this->_m))
    {
        if(isset(
$this->_m[$name]))
            
$this->detachBehavior($name);
        else
        {
            foreach(
$this->_m as $object)
            {
                if(
$object->getEnabled())
                {
                    if(
property_exists($object,$name))
                        return 
$object->$name=null;
                    else if(
$object->canSetProperty($name))
                        return 
$object->$setter(null);
                }
            }
        }
    }
    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)));
}

设置一个组件的属性为null。 不能直接调用此方法。这是重载了PHP的魔术方法, 可以使用unset()设置一个组件属性为null。

asa() 方法
public IBehavior asa(string $behavior)
$behavior string 行为名
{return} IBehavior 返回行为对象,如果行为对象不存在,则返回null。
public function asa($behavior)
{
    return isset(
$this->_m[$behavior]) ? $this->_m[$behavior] : null;
}

返回这个名字的行为对象。 ‘asa’代表‘as a’。

attachBehavior() 方法
public IBehavior attachBehavior(string $name, mixed $behavior)
$name string 行为的名字,它应该是唯一行为标识。
$behavior mixed 这个行为的配置,它首先通过这个参数, 调用YiiBase::createComponent创建行为对象。
{return} IBehavior 行为对象
public function attachBehavior($name,$behavior)
{
    if(!(
$behavior instanceof IBehavior))
        
$behavior=Yii::createComponent($behavior);
    
$behavior->setEnabled(true);
    
$behavior->attach($this);
    return 
$this->_m[$name]=$behavior;
}

附加一个行为到组件。 这个方法将基于给定的配置创建行为对象。 在此后, 这个行为对像将调用它的IBehavior::attach方法进行初始化。

attachBehaviors() 方法
public void attachBehaviors(array $behaviors)
$behaviors array 附加到组件的一个行为列表
public function attachBehaviors($behaviors)
{
    foreach(
$behaviors as $name=>$behavior)
        
$this->attachBehavior($name,$behavior);
}

附加一个行为列表到组件。 每一个行为是一个 IBehavior实例,使用字符串指定一个行为类, 或使用一个如下结构的数组来指定:

array(
    'class'=>'path.to.BehaviorClass',
    'property1'=>'value1',
    'property2'=>'value2',
)
attachEventHandler() 方法
public void attachEventHandler(string $name, callback $handler)
$name string 事件名
$handler callback 事件处理程序
public function attachEventHandler($name,$handler)
{
    
$this->getEventHandlers($name)->add($handler);
}

为事件附加一个事件处理程序。

一个事件处理程序必须是一个有效的PHP回调。 如,一个指字全局函数名的字符串或一个数组,该数组包含两个元素, 第一个元素是一个对象, 第二个元素是这个对象的方法。

一个事件处理程序必须定义为以下方式,

function handlerName($event) {}
其中$event包含了事件相关的参数。

这是一个附加事件处理程序的简便方法。 它等价于以下代码:
$component->getEventHandlers($eventName)->add($eventHandler);


使用getEventHandlers,也能够指定同个事件的多个附加事件处理程序的顺序, 例如:
$component->getEventHandlers($eventName)->insertAt(0,$eventHandler);
这样设置使得这个处理程序被首先调用。
canGetProperty() 方法
public boolean canGetProperty(string $name)
$name string 属性名
{return} boolean 属性是否可读
public function canGetProperty($name)
{
    return 
method_exists($this,'get'.$name);
}

确定属性是否可读。 一个定义在类中了getter方法的属性。 注意,属性名是区分大小写的。

canSetProperty() 方法
public boolean canSetProperty(string $name)
$name string 属性名
{return} boolean 属性是否可写
public function canSetProperty($name)
{
    return 
method_exists($this,'set'.$name);
}

确定属性是否可写。 一个定义在类中了setter方法的属性。 注意,属性名是区分大小写的。

detachBehavior() 方法
public IBehavior detachBehavior(string $name)
$name string 这个行为的名字,它是行为的唯一标识。
{return} IBehavior 分离后的行为,如果行为不存在返回null。
public function detachBehavior($name)
{
    if(isset(
$this->_m[$name]))
    {
        
$this->_m[$name]->detach($this);
        
$behavior=$this->_m[$name];
        unset(
$this->_m[$name]);
        return 
$behavior;
    }
}

从组件中分离一个行为。 这个行为的IBehavior::detach方法将被调用。

detachBehaviors() 方法
public void detachBehaviors()
public function detachBehaviors()
{
    if(
$this->_m!==null)
    {
        foreach(
$this->_m as $name=>$behavior)
            
$this->detachBehavior($name);
        
$this->_m=null;
    }
}

从组件中分离所有行为。

detachEventHandler() 方法
public boolean detachEventHandler(string $name, callback $handler)
$name string 事件名
$handler callback 需要被移除的事件处理程序
{return} boolean 是否移除成功
public function detachEventHandler($name,$handler)
{
    if(
$this->hasEventHandler($name))
        return 
$this->getEventHandlers($name)->remove($handler)!==false;
    else
        return 
false;
}

分离一个存在的事件处理程序。 这个方法相对于attachEventHandler

disableBehavior() 方法
public void disableBehavior(string $name)
$name string 行为的名字。它是行为的唯一标识。
public function disableBehavior($name)
{
    if(isset(
$this->_m[$name]))
        
$this->_m[$name]->setEnabled(false);
}

禁用一个附加行为。 一个行为仅当启用时才有效。

disableBehaviors() 方法
public void disableBehaviors()
public function disableBehaviors()
{
    if(
$this->_m!==null)
    {
        foreach(
$this->_m as $behavior)
            
$behavior->setEnabled(false);
    }
}

禁用组件附加的所有行为。

enableBehavior() 方法
public void enableBehavior(string $name)
$name string 行为名称。它是行为的唯一标识。
public function enableBehavior($name)
{
    if(isset(
$this->_m[$name]))
        
$this->_m[$name]->setEnabled(true);
}

启用一个附加行为。 一个行为仅当启用时有效。 一个行为在首次附加时启用。

enableBehaviors() 方法
public void enableBehaviors()
public function enableBehaviors()
{
    if(
$this->_m!==null)
    {
        foreach(
$this->_m as $behavior)
            
$behavior->setEnabled(true);
    }
}

启用组件附加的所有行为。

evaluateExpression() 方法 (可用自 v1.1.0)
public mixed evaluateExpression(mixed $_expression_, array $_data_=array ( ))
$_expression_ mixed 一个PHP表达式或PHP回调。
$_data_ array 传递给表达式或回调的附加参数
{return} mixed 表达式结果
public function evaluateExpression($_expression_,$_data_=array())
{
    if(
is_string($_expression_))
    {
        
extract($_data_);
        return eval(
'return '.$_expression_.';');
    }
    else
    {
        
$_data_[]=$this;
        return 
call_user_func_array($_expression_$_data_);
    }
}

计算一个PHP表达式,或根据组件上下文执行回调。

有效的PHP回调是一个类的方法, 格式为array(ClassName/Object, MethodName)或匿名函数(需要PHP 5.3.0 或以上版本支持)。

如果使用一个PHP回调,对应的函数或方法应该为如下格式

function foo($param1, $param2, ..., $component) { ... }
这个方法的第二个参数是一个数组元素, 将传递给回调的方式为$param1,$param2,...;最后一个参数将是组件的自身。

如果使用一个PHP表达式, 第二个参数将执行“extracted”插入PHP变量可以在表达式中直接使用。参见PHP extract 了解更详细信息。在表达式中组件对象可以使用$this访问。
getEventHandlers() 方法
public CList getEventHandlers(string $name)
$name string 事件名
{return} CList 一个事件的附加处理程序列表
public function getEventHandlers($name)
{
    if(
$this->hasEvent($name))
    {
        
$name=strtolower($name);
        if(!isset(
$this->_e[$name]))
            
$this->_e[$name]=new CList;
        return 
$this->_e[$name];
    }
    else
        throw new 
CException(Yii::t('yii','Event "{class}.{event}" is not defined.',
            array(
'{class}'=>get_class($this), '{event}'=>$name)));
}

返回一个事件的附加处理程序列表。

hasEvent() 方法
public boolean hasEvent(string $name)
$name string 事件名
{return} boolean whether 事件是否定义
public function hasEvent($name)
{
    return !
strncasecmp($name,'on',2) && method_exists($this,$name);
}

确定一个事件是否定义。 一个事件在定中的定义为类似‘onXXX’这样的方法。 注意,事件名是区分大小写的。

hasEventHandler() 方法
public boolean hasEventHandler(string $name)
$name string 事件名
{return} boolean 事件是否附加了一个或多个处理程序
public function hasEventHandler($name)
{
    
$name=strtolower($name);
    return isset(
$this->_e[$name]) && $this->_e[$name]->getCount()>0;
}

检查事件是否有附加的处理程序。

hasProperty() 方法
public boolean hasProperty(string $name)
$name string 属性名
{return} boolean 属性是否定义
public function hasProperty($name)
{
    return 
method_exists($this,'get'.$name) || method_exists($this,'set'.$name);
}

确定属性是否被定义。 一个定义在类中了getter 或 setter 方法的属性。 注意,属性名是区分大小写的。

raiseEvent() 方法
public void raiseEvent(string $name, CEvent $event)
$name string 事件名
$event CEvent 事件参数
public function raiseEvent($name,$event)
{
    
$name=strtolower($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))
            {
                if(
is_array($handler))
                {
                    
// an array: 0 - object, 1 - method name
                    
list($object,$method)=$handler;
                    if(
is_string($object))    // static method call
                        
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 
// PHP 5.3: anonymous function
                    
call_user_func($handler,$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}'=>gettype($handler))));
            
// stop further handling if param.handled is set 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)));
}

发起一个事件。 这个方法表示发起一个事件。 它调用事件的所有附加处理程序。