`

Yii分析1:web程序入口(3)

阅读更多

接上篇:Yii分析1:web程序入口(2)

 

本文分析前两篇文章用到的一些函数。

 

上一篇提到在preloadComponents的时候会调用getComponent,我们来看一下getComponent的细节:

 

Yii_PATH/base/CModule.php

    //第二个参数标识如果是空则创建之,默认为true
    public function getComponent($id,$createIfNull=true)
    {
        if(isset($this->_components[$id]))
            return $this->_components[$id];        
        //_componentConfig是在configure方法中由setComponents中已经保存的变量
        else if(isset($this->_componentConfig[$id]) && $createIfNull)
        {
            $config=$this->_componentConfig[$id];
            unset($this->_componentConfig[$id]); 
            //如果没有设置enable参数或者enable参数为true
            if(!isset($config['enabled']) || $config['enabled'])
            { 
                Yii::trace("Loading \"$id\" application component",'system.web.CModule');
                unset($config['enabled']); 
                //创建组件,并完成初始化
                $component=Yii::createComponent($config);
                $component->init();
                return $this->_components[$id]=$component;
            }
        }
    }

 

下面是Yii::createComponent的实现:

    public static function createComponent($config)
    {

        //如果配置项内容是一个字符串,则它是类名,如果是数组,那么数组的class成员是类名
        if(is_string($config))
        {
            $type=$config;
            $config=array();
        }
        else if(isset($config['class']))
        {
            $type=$config['class'];
            unset($config['class']);
        }
        else
            throw new CException(Yii::t('yii','Object configuration must be an array containing a "class" element.'));  
        //如果类不存在,则使用import来引入,而不是用autoload
        if(!class_exists($type,false))
            $type=Yii::import($type,true);  

        //创建组件时,可以带更多的初始值进行初始化
        if(($n=func_num_args())>1)
        {
            $args=func_get_args();
            if($n===2)
                $object=new $type($args[1]);
            else if($n===3)
                $object=new $type($args[1],$args[2]);
            else if($n===4)
                $object=new $type($args[1],$args[2],$args[3]);
            else
            {
                unset($args[0]);
                $class=new ReflectionClass($type);
                // Note: ReflectionClass::newInstanceArgs() is available for PHP 5.1.3+
                // $object=$class->newInstanceArgs($args);
                //如果参数大于4个,那么调用newInstance方法来进行初始化
                $object=call_user_func_array(array($class,'newInstance'),$args);
            }
        }
        else
            $object=new $type;  

        //将配置中的配置项赋值给组件的成员
        foreach($config as $key=>$value)
            $object->$key=$value;

        return $object;

 

=========================================================================

 

我们再来看看errorhandler和exceptionhandler:

 

Yii_PATH/base/CApplication.php

    public function handleError($code,$message,$file,$line)
    {
        if($code & error_reporting())
        {
            // disable error capturing to avoid recursive errors
            //恢复原错误handler(内建的错误handler),避免本函数触发错误handler,从而递归调用
            restore_error_handler();
            restore_exception_handler();

            $log="$message ($file:$line)";
            if(isset($_SERVER['REQUEST_URI']))
                $log.=' REQUEST_URI='.$_SERVER['REQUEST_URI'];
            Yii::log($log,CLogger::LEVEL_ERROR,'php');

            try
            {  
 
                //使用一个error事件类来触发error事件,然后显示log信息,这里暂不分析
                $event=new CErrorEvent($this,$code,$message,$file,$line);
                $this->onError($event);
                if(!$event->handled)
                {
                    // try an error handler
                    if(($handler=$this->getErrorHandler())!==null)
                        $handler->handle($event);
                    else
                        $this->displayError($code,$message,$file,$line);
                }
            }
            catch(Exception $e)
            {
                $this->displayException($e);
            }
            $this->end(1);
        }
    }

dispalyError代码如下:

    public function displayError($code,$message,$file,$line)                      
    {           
        //如果是调试,打印调用栈,否则不打印
        if(YII_DEBUG)
        {           
            echo "<h1>PHP Error [$code]</h1>\n";
            echo "<p>$message ($file:$line)</p>\n";
            echo '<pre>';
            debug_print_backtrace();
            echo '</pre>';                                                        
        }               
        else
        {                   
            echo "<h1>PHP Error [$code]</h1>\n";                                  
            echo "<p>$message</p>\n";                                             
        }       
    }      
 

 

参考:

设定了error hanlder之后,某些级别的错误是不会触发设置的函数的,例如:E_ERROR(运行期错误,如内存分配错误),E_PARSE(解释错误,即语法),E_CORE_ERROR(在PHP内核startup阶段发生的错误),E_CORE_WARNING(在PHP内核startup阶段发生的warning),E_COMPILE_ERROR(编译错误,zend引擎生成),E_COMPILE_WARNING(编译warning,zend引擎生成)

关于startup和zend引擎请参考php内核方面的资料
 

handleException与Error相似:

    public function handleException($exception)
    {
        // disable error capturing to avoid recursive errors
        restore_error_handler();
        restore_exception_handler();

        $category='exception.'.get_class($exception);
        //如果是Http异常,获取状态码
        if($exception instanceof CHttpException)
            $category.='.'.$exception->statusCode;
        $message=(string)$exception;
        if(isset($_SERVER['REQUEST_URI']))
            $message.=' REQUEST_URI='.$_SERVER['REQUEST_URI'];
        Yii::log($message,CLogger::LEVEL_ERROR,$category);


        //接下来同handleError
        try
        {
            $event=new CExceptionEvent($this,$exception);
            $this->onException($event);
            if(!$event->handled)
            {
                // try an error handler
                if(($handler=$this->getErrorHandler())!==null)
                    $handler->handle($event);
                else
                    $this->displayException($exception);
            }
        }
        catch(Exception $e)
        {
            $this->displayException($e);
        }
        $this->end(1);
    }
 

参考:

call_user_function可以传递儿女和内置的或者用户自定义的函数,除了语言结构如array(), echo(), empty(), eval(), exit(), isset(), list(), print(), unset()
 

 

 

 

 

 

4
5
分享到:
评论

相关推荐

    Yii框架快速入门

    ### Yii框架快速入门详解 #### 一、Yii框架概述 ...通过深入理解其核心概念,如入口脚本、应用程序以及MVC架构的运用,开发者可以充分利用Yii的强大功能,快速构建出稳定、高效且可维护的Web应用。

    yii2.0基础高级应用程序模板

    Yii 2.0 是一款基于组件的高性能 PHP 框架,用于开发 Web 2.0 应用程序。此框架提供了丰富的特性,包括 MVC(模型-视图-控制器)架构模式、活动记录(Active Record)、依赖注入(Dependency Injection)、单元测试...

    Yii2的基本应用程序模板 yii-basic-app-2.0.12

    "yii-basic-app-2.0.12"是Yii2框架的一个基础应用程序模板,适用于初学者和小型项目。这个模板提供了构建Web应用的基本结构和配置,让开发者能够快速上手。 1. **目录结构**: - `config`:包含应用程序的配置文件...

    php yii源码分析

    入口文件是每个 Web 应用程序的起点,对于 Yii 而言,`index.php` 文件是应用的入口。在这个文件中,Yii 的主要配置和初始化过程发生。例如,`$yii` 变量指向了框架的核心入口点 `yii.php`,而 `$config` 指向应用...

    YII2框架代码

    2. 高级版YII2框架:适用于大型复杂的Web应用程序,提供了更清晰的模块化结构和多应用支持。高级版分为前端和后端两个独立的应用,每个应用都有自己的入口脚本、控制器、模型和视图,以及独立的配置,可以更好地分离...

    Yii_PHP_框架分析

    Yii PHP 框架分析 Yii 是一个高性能的,基于组件的 PHP 框架,用于开发 Web2.0 应用程序。本分析将深入探讨 Yii 的基本操作,包括...通过深入理解这些基础知识,开发者能够更好地利用 Yii 构建高质量的 Web 应用程序。

    yii1.1版本资料整理

    1. 高重用性:Yii框架设计了大量可重用的组件和功能模块,以便开发者可以简单地复用这些模块来快速构建应用程序。 2. 高效性:Yii使用懒加载和数据缓存等技术手段,减少了不必要的资源消耗,显著提高了应用程序的...

    新下载的yii2,yii framework

    Yii2 是一个高性能的、基于组件的 PHP 框架,用于开发Web应用程序。它遵循“简洁即高效”的设计理念,提供了丰富的特性,如MVC(Model-View-Controller)、I18N/L10N(国际化和本地化)、缓存管理、数据库抽象层以及...

    Yii框架执行流程及部分源码分析

    1. **程序结构及配置** Yii的项目结构通常包含以下关键部分: - `protected`:存放应用的核心代码,如模型、控制器、配置文件等。 - `runtime`:运行时目录,存储日志、缓存文件等。 - `webroot`:网站的公共...

    yii-usermanager:基于 Yii 框架构建的用户管理应用程序

    - `web/`:Web 根目录,包含入口脚本、静态资源(CSS、JS 文件)等。 - `.gitignore`:定义了版本控制系统忽略的文件和目录。 - `composer.json`:定义项目依赖和元数据,用于 Composer 包管理。 - `README.md`:...

    Yii_PHP_框架源码分析.pdf

    Yii是一个基于PHP语言的开源Web应用框架,提供了许多便捷的功能和工具来帮助开发者快速构建Web应用程序。本文主要对Yii框架的源码进行分析,探究其内部机制和实现原理。 1. 启动机制 Yii框架的启动机制是通过index...

    yii框架中文手册教程

    1. 性能优越:Yii框架采用了各种优化技术,保证了Web应用的高性能,尤其在处理大量数据和高流量的Web应用时表现优异。 2. 组件化设计:Yii框架采用基于组件的设计模式,开发者可以通过复用组件快速组装出复杂的Web...

    Yii中文教程

    值得注意的是,并非所有Yii脚本都需要暴露给Web用户,仅需确保入口脚本可供访问即可。 - **环境检测**:安装完成后可以通过浏览器访问`http://hostname/path/to/yii/requirements/index.php`以检查服务器是否满足...

    Yii框架学习笔记.pdf

    1. **项目入口脚本**:在Yii框架中,项目的入口脚本通常命名为index.php,该脚本包含引导文件yii.php和配置文件main.php。index.php脚本会设置两个关键常量YII_DEBUG和YII_TRACE_LEVEL,分别用于控制调试模式的开启...

    Yii Blog Book

    - **框架概念**:Yii是一个高性能的PHP框架,专为快速开发安全且健壮的Web应用程序而设计。它支持敏捷开发和测试驱动开发,并且具有丰富的功能集,如缓存支持、错误处理、认证管理等。 - **安装过程**: - **下载*...

    yii框架教程

    ### Yii 框架教程详解 ...掌握了这些基础知识后,开发者可以更有效地利用 Yii 构建稳定、高效的 Web 应用程序。未来还可以深入研究更多高级特性,如模块化开发、安全性强化等,以满足更复杂的应用场景需求。

    Yii教案素材整理

    它遵循MVC(模型-视图-控制器)设计模式,使得开发者能够快速构建和维护复杂的Web应用程序。Yii框架以其高性能、安全性、可定制性而受到广大开发者的青睐。本篇教案素材整理详细讲解了Yii框架的基本概念、安装方法...

    yii源码

    Yii源码的分析对于理解其工作原理、优化代码以及自定义扩展功能至关重要。 首先,Yii 2是该框架的最新版本,其核心设计理念是简洁、高效和可扩展。它采用了面向对象的设计模式,如单例、工厂、策略等,使得代码组织...

    YII快速入门教程

    - **作用**: 初始化环境变量、加载配置文件、创建Web应用程序实例并运行。 - **示例代码**: ```php $yii = dirname(__FILE__) . '/../../framework/yii.php'; // Yii框架位置 $config = dirname(__FILE__) . '/...

Global site tag (gtag.js) - Google Analytics