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 $ |
源码 | framework/base/CComponent.php |
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); }其中
$event
是CEvent或它的子类的一个实例。 你可直接调用一个方法来代替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 | 方法返回值 |
publicfunction__call($name,$parameters)
{
if($this->_m!==null)
{
foreach($this->_mas$object)
{
if($object->getEnabled()&&method_exists($object,$name))
returncall_user_func_array(array($object,$name),$parameters);
}
}
if(class_exists('Closure',false)&&$this->canGetProperty($name)&&$this->$nameinstanceofClosure)
returncall_user_func_array($this->$name,$parameters);
thrownewCException(Yii::t('yii','{class}anditsbehaviorsdonothaveamethodorclosurenamed"{name}".',
array('{class}'=>get_class($this),'{name}'=>$name)));
}
如果类中没有调的方法名,则调用这个方法。 不能直接调用此方法。这是重载了PHP的魔术方法, 实现了这个行为功能。
__get() 方法public mixed __get(string $name) | ||
$name | string | 属性名或事件名 |
{return} | mixed | 属性值,附加的事件处理程序或一个行名称 |
publicfunction__get($name)
{
$getter='get'.$name;
if(method_exists($this,$getter))
return$this->$getter();
elseif(strncasecmp($name,'on',2)===0&&method_exists($this,$name))
{
//duplicatinggetEventHandlers()hereforperformance
$name=strtolower($name);
if(!isset($this->_e[$name]))
$this->_e[$name]=newCList;
return$this->_e[$name];
}
elseif(isset($this->_m[$name]))
return$this->_m[$name];
elseif(is_array($this->_m))
{
foreach($this->_mas$object)
{
if($object->getEnabled()&&(property_exists($object,$name)||$object->canGetProperty($name)))
return$object->$name;
}
}
thrownewCException(Yii::t('yii','Property"{class}.{property}"isnotdefined.',
array('{class}'=>get_class($this),'{property}'=>$name)));
}
返回一个属性值、一个事件处理程序列表或一个行为名称。 不能直接调用此方法。这是重载了PHP的魔术方法, 允许使用以下语法读取一个属性或获得一个事件处理程序:
$value=$component->propertyName; $handlers=$component->eventName;
参见
- __set
public boolean __isset(string $name) | ||
$name | string | 属性名或事件名 |
{return} | boolean |
publicfunction__isset($name)
{
$getter='get'.$name;
if(method_exists($this,$getter))
return$this->$getter()!==null;
elseif(strncasecmp($name,'on',2)===0&&method_exists($this,$name))
{
$name=strtolower($name);
returnisset($this->_e[$name])&&$this->_e[$name]->getCount();
}
elseif(is_array($this->_m))
{
if(isset($this->_m[$name]))
returntrue;
foreach($this->_mas$object)
{
if($object->getEnabled()&&(property_exists($object,$name)||$object->canGetProperty($name)))
return$object->$name!==null;
}
}
returnfalse;
}
检查一个属性是否为null。 不能直接调用此方法。这是重载了PHP的魔术方法, 允许使用isset()检测组件属性是否已设置。
__set() 方法public mixed __set(string $name, mixed $value) | ||
$name | string | 属性名或者事件名 |
$value | mixed | 属性值或回调 |
{return} | mixed |
publicfunction__set($name,$value)
{
$setter='set'.$name;
if(method_exists($this,$setter))
return$this->$setter($value);
elseif(strncasecmp($name,'on',2)===0&&method_exists($this,$name))
{
//duplicatinggetEventHandlers()hereforperformance
$name=strtolower($name);
if(!isset($this->_e[$name]))
$this->_e[$name]=newCList;
return$this->_e[$name]->add($value);
}
elseif(is_array($this->_m))
{
foreach($this->_mas$object)
{
if($object->getEnabled()&&(property_exists($object,$name)||$object->canSetProperty($name)))
return$object->$name=$value;
}
}
if(method_exists($this,'get'.$name))
thrownewCException(Yii::t('yii','Property"{class}.{property}"isreadonly.',
array('{class}'=>get_class($this),'{property}'=>$name)));
else
thrownewCException(Yii::t('yii','Property"{class}.{property}"isnotdefined.',
array('{class}'=>get_class($this),'{property}'=>$name)));
}
设置一个组件的属性值。 不能直接调用此方法。这是重载了PHP的魔术方法, 允许使用以下语法设置一个属性或获得一个事件处理程序:
$this->propertyName=$value; $this->eventName=$callback;
参见
- __get
public mixed __unset(string $name) | ||
$name | string | 属性名或事件名 |
{return} | mixed |
publicfunction__unset($name)
{
$setter='set'.$name;
if(method_exists($this,$setter))
$this->$setter(null);
elseif(strncasecmp($name,'on',2)===0&&method_exists($this,$name))
unset($this->_e[strtolower($name)]);
elseif(is_array($this->_m))
{
if(isset($this->_m[$name]))
$this->detachBehavior($name);
else
{
foreach($this->_mas$object)
{
if($object->getEnabled())
{
if(property_exists($object,$name))
return$object->$name=null;
elseif($object->canSetProperty($name))
return$object->$setter(null);
}
}
}
}
elseif(method_exists($this,'get'.$name))
thrownewCException(Yii::t('yii','Property"{class}.{property}"isreadonly.',
array('{class}'=>get_class($this),'{property}'=>$name)));
}
设置一个组件的属性为null。 不能直接调用此方法。这是重载了PHP的魔术方法, 可以使用unset()设置一个组件属性为null。
asa() 方法public IBehavior asa(string $behavior) | ||
$behavior | string | 行为名 |
{return} | IBehavior | 返回行为对象,如果行为对象不存在,则返回null。 |
publicfunctionasa($behavior)
{
returnisset($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 | 行为对象 |
publicfunctionattachBehavior($name,$behavior)
{
if(!($behaviorinstanceofIBehavior))
$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 | 附加到组件的一个行为列表 |
publicfunctionattachBehaviors($behaviors)
{
foreach($behaviorsas$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 | 事件处理程序 |
publicfunctionattachEventHandler($name,$handler)
{
$this->getEventHandlers($name)->add($handler);
}
为事件附加一个事件处理程序。
一个事件处理程序必须是一个有效的PHP回调。 如,一个指字全局函数名的字符串或一个数组,该数组包含两个元素, 第一个元素是一个对象, 第二个元素是这个对象的方法。
一个事件处理程序必须定义为以下方式,
function handlerName($event) {}其中$event包含了事件相关的参数。
这是一个附加事件处理程序的简便方法。 它等价于以下代码:
$component->getEventHandlers($eventName)->add($eventHandler);
使用getEventHandlers,也能够指定同个事件的多个附加事件处理程序的顺序, 例如:
$component->getEventHandlers($eventName)->insertAt(0,$eventHandler);这样设置使得这个处理程序被首先调用。
参见
- detachEventHandler
public boolean canGetProperty(string $name) | ||
$name | string | 属性名 |
{return} | boolean | 属性是否可读 |
publicfunctioncanGetProperty($name)
{
returnmethod_exists($this,'get'.$name);
}
确定属性是否可读。 一个定义在类中了getter方法的属性。 注意,属性名是区分大小写的。
参见
- canSetProperty
public boolean canSetProperty(string $name) | ||
$name | string | 属性名 |
{return} | boolean | 属性是否可写 |
publicfunctioncanSetProperty($name)
{
returnmethod_exists($this,'set'.$name);
}
确定属性是否可写。 一个定义在类中了setter方法的属性。 注意,属性名是区分大小写的。
参见
- canGetProperty
public IBehavior detachBehavior(string $name) | ||
$name | string | 这个行为的名字,它是行为的唯一标识。 |
{return} | IBehavior | 分离后的行为,如果行为不存在返回null。 |
publicfunctiondetachBehavior($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() |
publicfunctiondetachBehaviors()
{
if($this->_m!==null)
{
foreach($this->_mas$name=>$behavior)
$this->detachBehavior($name);
$this->_m=null;
}
}
从组件中分离所有行为。
detachEventHandler() 方法public boolean detachEventHandler(string $name, callback $handler) | ||
$name | string | 事件名 |
$handler | callback | 需要被移除的事件处理程序 |
{return} | boolean | 是否移除成功 |
publicfunctiondetachEventHandler($name,$handler)
{
if($this->hasEventHandler($name))
return$this->getEventHandlers($name)->remove($handler)!==false;
else
returnfalse;
}
分离一个存在的事件处理程序。 这个方法相对于attachEventHandler。
参见
- attachEventHandler
public void disableBehavior(string $name) | ||
$name | string | 行为的名字。它是行为的唯一标识。 |
publicfunctiondisableBehavior($name)
{
if(isset($this->_m[$name]))
$this->_m[$name]->setEnabled(false);
}
禁用一个附加行为。 一个行为仅当启用时才有效。
disableBehaviors() 方法public void disableBehaviors() |
publicfunctiondisableBehaviors()
{
if($this->_m!==null)
{
foreach($this->_mas$behavior)
$behavior->setEnabled(false);
}
}
禁用组件附加的所有行为。
enableBehavior() 方法public void enableBehavior(string $name) | ||
$name | string | 行为名称。它是行为的唯一标识。 |
publicfunctionenableBehavior($name)
{
if(isset($this->_m[$name]))
$this->_m[$name]->setEnabled(true);
}
启用一个附加行为。 一个行为仅当启用时有效。 一个行为在首次附加时启用。
enableBehaviors() 方法public void enableBehaviors() |
publicfunctionenableBehaviors()
{
if($this->_m!==null)
{
foreach($this->_mas$behavior)
$behavior->setEnabled(true);
}
}
启用组件附加的所有行为。
evaluateExpression() 方法 (可用自 v1.1.0)public mixed evaluateExpression(mixed $_expression_, array $_data_=array ( )) | ||
$_expression_ | mixed | 一个PHP表达式或PHP回调。 |
$_data_ | array | 传递给表达式或回调的附加参数 |
{return} | mixed | 表达式结果 |
publicfunctionevaluateExpression($_expression_,$_data_=array())
{
if(is_string($_expression_))
{
extract($_data_);
returneval('return'.$_expression_.';');
}
else
{
$_data_[]=$this;
returncall_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 | 一个事件的附加处理程序列表 |
publicfunctiongetEventHandlers($name)
{
if($this->hasEvent($name))
{
$name=strtolower($name);
if(!isset($this->_e[$name]))
$this->_e[$name]=newCList;
return$this->_e[$name];
}
else
thrownewCException(Yii::t('yii','Event"{class}.{event}"isnotdefined.',
array('{class}'=>get_class($this),'{event}'=>$name)));
}
返回一个事件的附加处理程序列表。
hasEvent() 方法public boolean hasEvent(string $name) | ||
$name | string | 事件名 |
{return} | boolean | whether 事件是否定义 |
publicfunctionhasEvent($name)
{
return!strncasecmp($name,'on',2)&&method_exists($this,$name);
}
确定一个事件是否定义。 一个事件在定中的定义为类似‘onXXX’这样的方法。 注意,事件名是区分大小写的。
hasEventHandler() 方法public boolean hasEventHandler(string $name) | ||
$name | string | 事件名 |
{return} | boolean | 事件是否附加了一个或多个处理程序 |
publicfunctionhasEventHandler($name)
{
$name=strtolower($name);
returnisset($this->_e[$name])&&$this->_e[$name]->getCount()>0;
}
检查事件是否有附加的处理程序。
hasProperty() 方法public boolean hasProperty(string $name) | ||
$name | string | 属性名 |
{return} | boolean | 属性是否定义 |
publicfunctionhasProperty($name)
{
returnmethod_exists($this,'get'.$name)||method_exists($this,'set'.$name);
}
确定属性是否被定义。 一个定义在类中了getter 或 setter 方法的属性。 注意,属性名是区分大小写的。
参见
- canGetProperty
- canSetProperty
public void raiseEvent(string $name, CEvent $event) | ||
$name | string | 事件名 |
$event | CEvent | 事件参数 |
publicfunctionraiseEvent($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);
elseif(is_callable($handler,true))
{
if(is_array($handler))
{
//anarray:0-object,1-methodname
list($object,$method)=$handler;
if(is_string($object))//staticmethodcall
call_user_func($handler,$event);
elseif(method_exists($object,$method))
$object->$method($event);
else
thrownewCException(Yii::t('yii','Event"{class}.{event}"isattachedwithaninvalidhandler"{handler}".',
array('{class}'=>get_class($this),'{event}'=>$name,'{handler}'=>$handler[1])));
}
else//PHP5.3:anonymousfunction
call_user_func($handler,$event);
}
else
thrownewCException(Yii::t('yii','Event"{class}.{event}"isattachedwithaninvalidhandler"{handler}".',
array('{class}'=>get_class($this),'{event}'=>$name,'{handler}'=>gettype($handler))));
//stopfurtherhandlingifparam.handledissettrue
if(($eventinstanceofCEvent)&&$event->handled)
return;
}
}
elseif(YII_DEBUG&&!$this->hasEvent($name))
thrownewCException(Yii::t('yii','Event"{class}.{event}"isnotdefined.',
array('{class}'=>get_class($this),'{event}'=>$name)));
}
发起一个事件。 这个方法表示发起一个事件。 它调用事件的所有附加处理程序。