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 |
方法详细
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的魔术方法, 实现了这个行为功能。
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)===0 && 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;
参见
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)===0 && 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()检测组件属性是否已设置。
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)===0 && 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;
参见
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)===0 && 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。
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’。
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方法进行初始化。
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', )
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);这样设置使得这个处理程序被首先调用。
public boolean canGetProperty(string $name)
| ||
$name | string | 属性名 |
{return} | boolean | 属性是否可读 |
public function canGetProperty($name)
{
return method_exists($this,'get'.$name);
}
确定属性是否可读。 一个定义在类中了getter方法的属性。 注意,属性名是区分大小写的。
public boolean canSetProperty(string $name)
| ||
$name | string | 属性名 |
{return} | boolean | 属性是否可写 |
public function canSetProperty($name)
{
return method_exists($this,'set'.$name);
}
确定属性是否可写。 一个定义在类中了setter方法的属性。 注意,属性名是区分大小写的。
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方法将被调用。
public void detachBehaviors()
|
public function detachBehaviors()
{
if($this->_m!==null)
{
foreach($this->_m as $name=>$behavior)
$this->detachBehavior($name);
$this->_m=null;
}
}
从组件中分离所有行为。
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。
public void disableBehavior(string $name)
| ||
$name | string | 行为的名字。它是行为的唯一标识。 |
public function disableBehavior($name)
{
if(isset($this->_m[$name]))
$this->_m[$name]->setEnabled(false);
}
禁用一个附加行为。 一个行为仅当启用时才有效。
public void disableBehaviors()
|
public function disableBehaviors()
{
if($this->_m!==null)
{
foreach($this->_m as $behavior)
$behavior->setEnabled(false);
}
}
禁用组件附加的所有行为。
public void enableBehavior(string $name)
| ||
$name | string | 行为名称。它是行为的唯一标识。 |
public function enableBehavior($name)
{
if(isset($this->_m[$name]))
$this->_m[$name]->setEnabled(true);
}
启用一个附加行为。 一个行为仅当启用时有效。 一个行为在首次附加时启用。
public void enableBehaviors()
|
public function enableBehaviors()
{
if($this->_m!==null)
{
foreach($this->_m as $behavior)
$behavior->setEnabled(true);
}
}
启用组件附加的所有行为。
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访问。
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)));
}
返回一个事件的附加处理程序列表。
public boolean hasEvent(string $name)
| ||
$name | string | 事件名 |
{return} | boolean | whether 事件是否定义 |
public function hasEvent($name)
{
return !strncasecmp($name,'on',2) && method_exists($this,$name);
}
确定一个事件是否定义。 一个事件在定中的定义为类似‘onXXX’这样的方法。 注意,事件名是区分大小写的。
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;
}
检查事件是否有附加的处理程序。
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 方法的属性。 注意,属性名是区分大小写的。
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)));
}
发起一个事件。 这个方法表示发起一个事件。 它调用事件的所有附加处理程序。