1. Yii源码阅读笔记 - 错误/异常处理

    概述

    PHP区分“错误”(Error)和“异常”(Exception)。“错误”通常是由PHP内部函数抛出,表示运行时问题,当然也可以通过函数trigger_erroruser_error抛出一个用户级别的error/warning/notice信息。但在引入面向对象之后,相比使用trigger_error抛出错误,使用throw抛出异常更常用。

    对于“错误”,PHP允许配置报告哪些级别/类型错误、是否(向用户)展示错误、是否对错误记录日志、错误日志记到哪,分别对应php.ini中的配置项:error_reportingdisplay_errorslog_errorserror_log。详细信息见这里

    对于应用程序内层调用抛出的“异常”,一般可以在外层中使用try...catch来捕获并自定义处理过程。但对于“错误”(PHP运行时抛出或者应用程序使用trigger_error抛出的)或者对于-无法使用try...catch来捕获可能的异常/为了做到即使忘记捕获的异常也能得到自定义处理-的情况,该怎么办 …

    Tagged as : PHP Yii 笔记 总结
  2. Yii源码阅读笔记 - 自定义类自动加载

    前两天突然发现:之前的阅读笔记对于Yii应用中如何自动加载自定义类的问题没有解释。这里的自定义类是指非Yii框架本身的类。

    关于组件类的配置加载已在 Yii源码阅读笔记 - 组件集成 一文中做了较为详细的说明, 所以这里不再涉及。

    本文主要解释以下两点:

    1. Yii框架是如何找到请求对应的自定义控制器类?
    2. 在自定义控制器类中使用其他类(如Model类、或其他任意目录下文件中定义的类)时,Yii框架是如何自动加载的?

    Yii源码阅读笔记 - 应用模块化 一文中介绍类 CWebApplication 中的方法 createController , 该方法根据目标路由找到对应的控制器类文件并加载,方法中有行代码:

    $basePath=$owner->getControllerPath();
    

    这里的 getControllerPath 会返回当前应用或模块下的控制器类的存放目录,对应应用级与模块级,其实现有两处,其一是在类 CWebApplication 中:

    /**
     * @return string the directory that contains the controller classes. Defaults to 'protected/controllers'.
     */
    public function …
    Tagged as : PHP Yii 笔记 总结
  3. Yii源码阅读笔记 - 日志组件

    使用

    Yii框架为开发者提供两个静态方法进行日志记录:

    Yii::log($message, $level, $category);
    Yii::trace($message, $category);
    

    两者的区别在于后者依赖于应用开启调试模式,即定义常量YII_DEBUG:

    defined('YII_DEBUG') or define('YII_DEBUG', true);
    

    Yii::log方法的调用需要指定message的level和category。category是格式为“xxx.yyy.zzz”的路径别名字符串,比如日志是在yii/framework/web/CController类中记录的,那么category为“system.web.CController”。level应为以下几种之一:

    • trace:Yii::trace方法即是使用的这个level。用于跟踪执行流
    • info:记录通用信息日志
    • profile:用于性能分析
    • warning:用于记录警告日志
    • error:用于记录重大错误日志

    要想日志真的输出到文件、邮件、web页面等地方 …

    Tagged as : PHP Yii 笔记 总结
  4. Yii源码阅读笔记 - 应用模块化

    概述

    Yii框架有个“模块(Module)”的概念,与“应用(Application)”类似,模块必须归属于一个父模块或者一个应用,模块不能单独部署,一个应用不一定要分模块。

    由此可以看到,Yii的“模块”和“应用”类似于Django框架中的“应用(App)”和“项目(Project)”。

    当一个应用的规模大到一定的程度 - 可能涉及多个团队来开发,就应该考虑分“模块”开发。“模块”通常对应应用的一个相对独立的功能。

    一个模块化的Yii框架应用的工程目录结构大致示例如下:

    Yii-WebApp-Modules

    上图所示项目有一个名为“forum”的模块,该模块下也有自己的componentscontrollersmodelsviewsextensions目录,与一个普通的/不分模块的Yii框架Web应用的项目结构非常相似。

    Yii框架模块化应用的所有模块默认都是放在protected/modules目录下,每个模块的内容又各自放在以模块ID(如forum …

    Tagged as : PHP Yii 笔记 总结
  5. Yii源码阅读笔记 - 缓存

    概述

    从之前的文章Yii源码阅读笔记 - 路由解析Yii源码阅读笔记 - Model层实现可以看到Yii框架对于解析好的路由规则数据表的schema都会根据条件尝试读写缓存 来提高应用性能。

    但缓存组件并非核心组件,需要额外的配置,默认ID为cache,如果不使用该ID,那么就得注意同时配置好框架中使用缓存的组件。

    恰当地使用缓存组件,能明显地提高应用的性能。

    针对不同的缓存后端(backend),Yii框架提供了多种缓存组件,如文件缓存(CFileCache)、Memcached缓存(CMemCache)、Redis缓存(CRedisCache)等。这些缓存组件(除CDummyCache外,CDummyCache并不是一个有效的缓存组件)均直接继承自抽象类CCache(见文件yii/framework/caching/CCache.php)。

    下面以使用Memcached缓存为例,分析Yii框架缓存组件的实现。

    分析

    CMemcache所在的整个继承树(CMemcache -> CCache -> CApplicationComponent …

    Tagged as : PHP Yii 笔记 总结
  6. Yii源码阅读笔记 - 模板引擎集成

    概述

    通常我们会使用模板引擎来渲染HTML页面,而不是使用HTML代码中插入PHP代码的方式来编写动态页面。Yii框架中模板引擎也是作为组件引入的,默认ID为viewRenderer, 但从Yii源码阅读笔记 - 组件集成可以看到Yii Web应用加载的核心组件中并没有viewRenderer,所以需要自己配置。 Yii提供了一个直接可用的模板引擎组件类CPradoViewRenderer(见文件yii/framework/web/renderers/CPradoViewRenderer.php),该模板引擎类让开发者可以使用类Prado框架的模板语法。

    如果你想使用Smarty这种第三方模板引擎,有两种方式将模板引擎引入Yii中使用(以Smarty为例):

    1. 将Smarty封装成一个Yii的普通组件,然后配置加载到Yii::app()。假设组件ID为smarty,那么就可以通过Yii::app()->smarty来调用组件。
    2. 参考CPradoViewRenderer类的实现,将Smarty封装成一个模板引擎组件,并以ID为viewRenderer进行配置加载。

    相比而言,第二种方式更好。原因是:第一种方式由于每种第三方模板引擎的接口不一样,如果应用要替换模板引擎,就需要修改控制器类中的代码。而第二种方式由于第三方组件统一封装成Yii框架定义的模板引擎接口形式, 所以如果要替换模板引擎,只需修改自定义模板引擎组件类的接口实现就可以了。这样调用模板引擎的代码逻辑就只依赖接口形式,而不是依赖于接口实现,从而实现解耦。

    本文主要分析第二种方式的实现。

    分析

    Yii中对页面模板进行渲染可以调用 …

    Tagged as : PHP Yii 笔记 总结
  7. Yii源码阅读笔记 - Model层实现

    概述

    Yii中,对Model层的使用,有两种方式:

    1. 通过类CDbConnection和CDbCommand来操作
    2. 使用ORM形式:编写model类继承自抽象类CActiveRecord

    第1种方式的示例如下:

    <?php
    $connection = Yii::app()->db;  // 或者Yii::app()->getComponent('db');
    $queryResult = $connection->createCommand($sql)->queryRow();
    

    第2种方式中编写的model类可能需要实现方法getDbConnectionmodeltableName

    在实现上,第2种方式是基于第1种方式的,即第2种方式的抽象程度更高。Yii没有屏蔽第1种方式,这样能让开发者按需选择。 但我个人并不喜欢这样,两种方式同时存在,会导致应用的model实现稍显混乱。

    分析

    Yii框架model层的入口为CDbConnection类,该类有很多public的属性可供配置,如connectionStringusernamepassword等。

    根据Yii源码阅读笔记 - 组件集成一文可知,组件初始化时会调用init方法。 类CDbConnection的init类实现如下:

    public function …
    Tagged as : PHP Yii 笔记 总结
  8. Yii源码阅读笔记 - 组件集成

    概述

    Yii框架将各种功能封装成组件,使用时按需配置加载,从而提高应用的性能。内置的组件又分为核心组件与非核心组件,核心组件是任何Web应用和Console应用都需要的。 此外,应用开发者还可以按照一定规则封装配置使用自己的功能组件。Yii会把应用需要的组件都加载到应用容器Yii::app()中,使得组件的使用方式一致方便。

    基于Yii框架开发应用需要理解如何配置组件、如何开发自己的组件,对应着需要理解Yii是如何注册加载组件的。

    分析

    Yii源码阅读笔记 - 请求处理基本流程一文可知,Yii加载组件的入口为抽象类CApplication构造方法中的以下两行代码:

    $this->registerCoreComponents();
    $this->configure($config);
    

    registerCoreComponents方法定义于类CWebApplication中,用于加载Web应用的核心组件,组件列表如下:

    array(
        // 核心组件
        'coreMessages'=>array(
            'class'=>'CPhpMessageSource',
            'language'=>'en_us',
            'basePath'=>YII_PATH.DIRECTORY_SEPARATOR.'messages',
        ),
        'db'=>array(
            'class'=>'CDbConnection',
        ),
        'messages'=>array(
            'class …
    Tagged as : PHP Yii 笔记 总结

Page 1 / 2