`
月影无痕
  • 浏览: 1003478 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Yii的组件机制之一:组件基础类CComponent分析

 
阅读更多

Yii的组件机制

组件机制,是Yii整个体系的思想精髓,在使用Yii之前,最应该先了解其组件机制,如果不了解这个机制,那么阅读Yii源代码会非常吃力。组件机制给Yii框架赋予了无穷的灵活性和可扩展性,可以毫不夸张地说,Yii框架的基础结构就是组件。大到CApplication对象、控制器、路由管理器(urlManager),小到一些其它插件,均是以组件形式存在的。

什么是Yii组件?

Yii中几乎所有可实例化并继承自CComponent的类,均可称为组件。

组件的特点是什么?

继承自CComponent类(直接继承或间接继承),拥有事件及行为机制,可在配置文件中定义其各个属性。

如何创建一个组件?

编写自定义类,并继承自CComponent类即可。

CComponent类是所有组件的基类,这个类在Yii框架中至关重要。具体来说,这个类主要实现以下三大功能:

1. 通过利用php的魔术方法__set, __get实现定义类的属性。也就是说一个组件的属性除了使用已经定义过的public成员属性,还可以利用CComponent实现的功能,通过扩展setXXX, getXXX方法扩展属性的设置和获取,对一些特殊的属性,我们可能希望在设置它之时就验证其是格式正确,此时就比较有用。
class webpage extends CComponent {

public $title;

private $_url;

public function setUrl($value='') {

if(is_url($value)){ 

$this->_url = $value;

}

}

public function getUrl() {

return $this->_url ;

}

}

$page = new webpage();

$page->title = "page title";

$page->url = "/index.php";  # call $page->seturl("/index.php");

echo $page->url   #$page->geturl();

也就是说,如果一个组件定义了setXXX, getXXX,那么就可以在类外部使用普通的属性访问形式。

2. 同样利用setter, getter实现事件处理接口绑定。事件机制在Yii中也是无处不大,Yii使用大量的事件机制来实现组件之间的功能调用(观察者模式)。

那么,如何给组件定义一个事件呢?Yii规定onXX形式的方法,即称为事件,如以下定义:
class form extends CComponent {

public function onSubmit($event) {

$this->raiseEvent('onSubmit',  $event);

}

}

使用以上固定代码,就给car组件创建了一个onStop事件。但是绑定事件究竟有何用处呢? 绑定事件的作用就是当组件产生一系列事件时,将自己的事件通过事件处理器,通知到绑定的各个对象上。例如我们希望当表单提交的时候,将此事件通知给日志组件让其记录之。

$form = new form();

$form ->attachEventHandler( 'onSubmit',  array($logOjbect, "saveLog") );

$form->data = $_POST;

$form->onSubmit( new CEvent($form, array('data'=>$_POST) ) ); #激活事件执行,并调用事件处理接口logObject::saveLog

logObject的代码可能如下:
class logObject {

public function saveLog($event) {

$event->sender === $form;

$event->params ;

}

}

显然这种方式远比传统方式调用更灵活,概念方式上也更先进一些。

另外,可以使用setter方法绑定事件:

$form->onSubmit = array($logOjbect, "saveLog") ;

注意:form类并未定义onSubmit成员属性。

同时,Yii实现了同一个事件绑定多个处理接口的机制,类似JavaScript中的addEventListener

事件处理器接口柳芽,以phpcallback类型格式为标准,详情参阅以下内容:http://php.net/manual/en/language.types.callable.php

YiiCLogRouter::init()中的代码:
Yii::app()->attachEventHandler('onEndRequest',array($this,'processLogs'));

当然也可以写成Yii::app()->onEndRequest = array($this,'processLogs');

CApplication中定义了onEndRequest事件:
public function onEndRequest($event){

if(!$this->_ended){

$this->_ended=true;

$this->raiseEvent('onEndRequest',$event);

}

}

定义了事件,并给事件绑定了处理器还不够,还得在合适的地方激活事件,如CApplication::run()方法中的逻辑:


public function run(){

if($this->hasEventHandler('onBeginRequest'))      

$this->onBeginRequest(new CEvent($this));

$this->processRequest();

if($this->hasEventHandler('onEndRequest'))

$this->onEndRequest(new CEvent($this));

}

也就说,要实现组件的事件机制,需要定义事件,绑定事件处理接口,激活事件

行为机制

yii的行为机制,可以简单地认为就是一个组件将其它对象的方法或属性直接拿来使用(就如php 5.4引入的trait结构,与行为作用就类似)

trait SayWorld {

    public function sayHello() {

        echo 'hello world!';

    }

}

class MyHelloWorld extends Base {

    use SayWorld;

}

$o = new MyHelloWorld();

$o->sayHello();

输出 hello world!

一个行为,就是一个特殊的类,其定义了各种事件及其处理流程,我们先定义一个行为类,包含事件及其对应的方法。

class MyAppBehavior extends CBehavior {    

    public $status = "app behavior ended.";    

    public function events() {

        return array(

            'onEndRequest' => 'appEnd',  #指定组件的onEndRequest事件发生后,调用行为的appEnd

        );

    }

    

    public function appEnd($event = null) {

        echo get_class($this);

    }

}

$app->attachBehavior('myapp','MyAppBehavior');

$app->run();

echo $app->status ;

我们发现行为的方法及属性,都是可以被组件直接使用的。

另外一个常见的例子,我们经常要对用户输入的内容进行过滤处理,比如防止其输入html标签,这种情况下,我们也可以考虑使用行为机制处理之。

$form = new FormModel;

If($_POST) {

$form->attributes = $_POST ;

$form->attachBehavior('myFilter', array(

'class' => '',

'strip_tags' => true ,

));

$form->filter(new CEvent($form) ) ;

}

class myHtmlFilter extends CBehavior {

public $strip_tags = false ;

public function events() {

return array(

'filter' => 'filterHtml',

);

}

public function filterHtml($event) {

if($event->sender instanceof CFormModel) {

$input = $event->sender->attributes ;

$event->sender->attributes = $this->filter($input);

}

}

public function filter(&$data) {

return is_array($data)?array_map(array($this, 'filter'),$data):strip_tags($data);

}

}

经过以上例子,可以发现行为方法可以以组件普通方法直接运行。行为有何用处,我目前还没有完全体会到其优势。

<!--EndFragment-->
1
0
分享到:
评论

相关推荐

    Yii 2.0.13.1.zip

    通过一个简单的命令行工具yiic可以快速创建一个web应用程序的代码框架,开发者可以在生成的代码框架基础上添加业务逻辑,以快速完成应用程序的开发。 Yii 2.0.12 更新日志:2017-11-14 测试测试覆盖对于早期检测...

    yii-coding-standard:Yii Framework PHP CodeSniffer编码标准

    Yii Framework PHP CodeSniffer编码标准(官方仓库) 您可以在此处阅读有关Yii标准的信息: : 如何安装安装PEAR: http://pear.php.net/manual/en/installation.getting.php 安装PHP_CodeSniffer: pear install ...

    YII多种缓存机制

    YII 多种缓存机制的运用 如文件缓存内存缓存 动态缓存等

    yii-resque, 基于 php Resque的Yii组件,基于.zip

    yii-resque, 基于 php Resque的Yii组件,基于 Resque我是 php的一个组件,它基于 php-resque resque和 php-resque-scheduler的组件,我们还通过使用 ResqueBoard测试了日志处理程序 using 。需求php函数扩展。Red

    yii2-jstree:Yii2 jsTree 组件

    Yii2 jsTree 组件jsTree 是 jquery 插件,提供交互式树。 它是完全免费的、开源的,并在 MIT 许可下分发。 jsTree 易于扩展、主题化和可配置,它支持 HTML 和 JSON 数据源以及 AJAX 加载。 这个包允许你在几分钟内将...

    yii2-settings:Yii2 设置组件

    Yii2 设置组件 安装 安装此扩展的首选方法是通过 。 要么跑 php composer.phar require --prefer-dist pendalf89/yii2-settings "*" 或添加 "pendalf89/yii2-settings": "*" 到composer.json文件的 require 部分...

    yii2-bootstrap4:Yii 2 Bootstrap 4扩展

    Twitter Bootstrap 4 Yii 2... 它按照Yii小部件封装了组件和插件,因此在Yii应用程序中使用Bootstrap组件/插件非常容易。 有关许可证信息,请检查文件。 文档位于 。 安装 安装此扩展的首选方法是通过 。 无论运行 ...

    yii-event-interceptor:一个组件,允许拦截观察到的组件引发的事件

    EventInterceptor 是一个 CComponent,每当观察到的组件引发事件时,它就会引发 onEventIntercepted 事件。 onEventIntercepted 事件包含被拦截事件的名称,以及被拦截事件本身。 它主要是作为其他组件的工具,可以...

    Yii 2.0进阶版 高级组件 优化京东平台

    Yii 2.0进阶版 高级组件 优化京东平台 包括前后台源代码,使用php 实现数据库mysql

    Yii框架应用组件用法实例分析

    本文实例讲述了Yii框架应用组件用法。分享给大家供大家参考,...\Yii::$app-&gt;componentID 例如,可以使用 \Yii::$app-&gt;db 来获取到已注册到应用的 DB connection, 使用 \Yii::$app-&gt;cache 来获取到已注册到应用的 p

    yii-tags-dependency:基于Yii框架的Dependency机制验证缓存相关性

    基于 Yii 框架和标签的依赖机制验证缓存相关性,标签也存储在缓存中 基于 Косыгин Александр &lt; &gt; 在描述的想法 通过 Composer 安装 php composer.phar 需要 intersvyaz/yii-tags-dependency:* ...

    yii2-weui:为yii2封装weui组件

    yii2-weuiWeUI for Yii 2为Yii2封装weui组件,让微信开发更简单本组件为车卡通微信会员管理系统而做,]]authorfufudaoanu-zhangnuowei000InstallationInstall With ComposerThe preferred way to install this ...

    yii2-fullcalendar:Yii 2组件,可轻松实现全日历集成

    Yii2全日历组件 安装 安装此扩展的首选方法是通过 。 要安装,请运行 $ php composer.phar require edofre/yii2-fullcalendar "V1.0.11" 或添加 "edofre/yii2-fullcalendar": "V1.0.11" 到composer.json文件的...

    yii2-elasticsearch:Yii 2 Elasticsearch 扩展

    Yii 2 的 Elasticsearch 查询和 ActiveRecord 这个扩展为提供了集成。 它包括基本的查询/搜索支持,还实现了ActiveRecord模式,允许您在 Elasticsearch 中存储活动记录。 有关许可证信息,请检查文件。 文档位于 。...

    Yii核心组件AssetManager原理分析

    主要介绍了Yii核心组件AssetManager原理分析,较为详细的分析了AssetManager组件的原理与实现过程,有助于深入了解yii框架的特性,需要的朋友可以参考下

    yii2-curl:用于 curl 的 Yii2 组件

    php composer.phar require --prefer-dist peterfrench/yii2-curl " * " 一旦 composer 安装了扩展,在您的配置文件中包含该组件。 'curl' =&gt; ['class' =&gt; 'peterfrench\curl\Curl' ,'options' =&gt; [/* curl options...

    yii2.0 标签组件

    yii2.0 tags标签组件下载。

    yii2-beanstalk:Yii2 beantalk Web和控制台组件

    Yii2 Web和控制台组件,它是顶部的接口。 感谢所做的如此完整的工作。 如何使用? 使用Composer安装 只需在composer.json文件中的require对象下添加该行即可。 { " require " : { ... " udokmeci/yii2-beanstalk...

    Yii 2.0高级组件优化京东电商平台

    Yii 2.0 高级组件 ES/Redis/ Sentry 优化京东平台 Yii 2.0 高级组件 ES/Redis/ Sentry 优化京东平台

    yii2-bootstrap:Yii 2 Bootstrap 3扩展

    Twitter Yii 2的Bootstrap... 它根据Yii小部件封装了组件和插件,因此在Yii应用程序中使用Bootstrap组件/插件非常容易。 有关许可证信息,请检查文件。 文档位于 。 安装 安装此扩展的首选方法是通过 。 无论运行 ...

Global site tag (gtag.js) - Google Analytics