— — — —Yii的CComponent是Yii的组件基础类。组件机制,是Yii整个体系的思想精髓,在使用Yii之前,最应该先了解其组件机制,如果不了解这个机制,那么阅读Yii源代码会非常吃力。组件机制给Yii框架赋予了无穷的灵活性和可扩展性,可以毫不夸张地说,Yii框架的基础结构就是组件。大到CApplication对象、控制器、路由管理器(urlManager),小到一些其它插件,均是以组件形式存在的。
—什么是Yii组件?
Yii中几乎所有可实例化并继承自CComponent的类,均可称为组件。
—组件的特点是什么?
继承自CComponent类(直接继承或间接继承),拥有事件及行为机制,可在配置文件中定义其各个属性。
—如何创建一个组件?
编写自定义类,并继承自CComponent/Component类即可。路径(\protected\components\***)。
————————CComponent getters和setters 的使用————————————————————————————————————————————————————————————————————
PHP属性的读和写
class MyClass
{
// 隐藏属性
private $property;
// getter
public function getProperty()
{
return $this->property;
}
// setter
public function setProperty($value)
{
$this->property = $value;
}
}
$object = new MyClass();
// 设置值
$object->setProperty('value');
// 获取值
echo $object->getProperty();
Yii 组件属性的读和写
class MyClass extends CComponent
{
private $read = 'read only property';
private $write = 'write only property';
public function getRead()
{
return $this->read;
}
public function setWrite($value)
{
$this->write = $value;
}
}
$object = new MyClass();
// 这里会报错,因为我们正试图写入只读属性。
$object->read = 'value';
// 显示 'read only property'
echo $object->read;
// 这里会报错,因为我们正试图读取只写属性。
echo $object->write;
// 将 'value' 写入私有变量 $write中去
$object->write = 'value';
为了允许像上面那种 属性风格 使用 getters 和 setters ,CComponent 使用PHP 魔术方法:__get,__set,__isset,和__unset
Yii深入地使用了这项技术。例如:当你调用Yii::app()->user->id 来获取当前登录用户id,实际上调用的是Yii::app()->getUser()->getId()。
__________________CComponent _事件的使用___________________________________________________________________________________________________
1. 定义事件名称,其实就是级组件定义一个on开头的方法,其中的代码是固定的,
public function onBeginRequest($event){
//public void raiseEvent(string $name, CEvent $event)
$this->raiseEvent('onBeginRequest',$event);
}
即函数名与事件名是一致的。此步的作用就是将绑定在此事件上的处理函数逐个执行。
2. 给组件对象绑定事件处理函数
$component->attachEventHandler($name, $handler);
$component->onBeginRequest = $handler ;
yii支持一个事件绑定多个回调函数,上述的两个方法都会在已有的事件上增加新的回调函数,而不会覆盖已有回调函数。$handler即是一个PHP回调函数。
3. 在需要触发事件的时候,直接激活组件的事件,即调用事件即可
________________________实例1_____________________________________________________
我们有一个博客应用程序,我们需要在有新评论(Comment)提交到博客(Post)的时候就发一份邮件。
Comment是个用Gii生成的标准AR模型。Post也同样是Gii生成的模型,除了一些自定义的方法。我们需要定义一个事件NewCommentEvent来存储Post和Comment 两个模型和句柄类Notifier,它将处理工作。
1.让我们开始创建protected/components/NewCommentEvent.php:
class NewCommentEvent extends CModelEvent {
public $comment;
public $post;
}
2.现在我们去看看protected/models/Post.php。为了突出显示添加了什么,我们省略了所有标准的AR方法。
class Post extends CActiveRecord {
// 给添加评论到当前提交上定义方法
function addComment(Comment $comment){
$comment->post_id = $this->id;
// 创建事件类实例
$event = new NewCommentEvent($this);
$event->post = $this;
$event->comment = $comment;
// 触发事件
$this->onNewComment($event);
return $event->isValid;
}
// 定义 onNewComment 事件
public function onNewComment($event) {
// 事实上事件是在这里触发的.这样的话我们可以使用
// onNewComment 方法来取代 raiseEvent.
$this->raiseEvent('onNewComment', $event);
}
}
3.现在,实现Notifie。创建 protected/components/Notifier.php输入如下代码:
class Notifier {
function comment($event){
$text = "There was new comment from {$event->comment->author}
on post {$event->post->title}";
mail('[email protected]', 'New comment', $text);
}
}
4.现在是时候在protected/controllers/PostController.php中一起进行操作了。
class PostController extends CController
{
unction actionAddComment()
{
$post = Post::model()->findByPk(10);
$notifier = new Notifier();
// 附加事件句柄
$post->onNewComment = array($notifier, 'comment');
// 在真实的应用中,数据应来自$_POST
$comment = new Comment();
$comment->author = 'Sam Dark';
$comment->text = 'Yii events are amazing!';
// 添加评论
$post->addComment($comment);
}
}
5.所有的评论都将被添加后,管理员将会收到一份相关的邮件。