ThinkPHP框架引导类分析

该类文件在:ThinkPHP/Library/Think/Think.class.php

该类可以说是ThinkPHP框架最为核心的类库,负责诸多配置加载,注册核心系统扩展(自动加载类库、异常处理、错误处理等),管理和维护类实例、别名映射,可以一说是一个框架的工厂(该类有些许面向对象弊端,比如:违背了面向对象单一职责,其负责功能复杂,关联类库和文件较多,有动一牵百的忧虑)。类中遇到的函数会在该类分析之后彻底分析,所涉及的其它类库会专门讲解。

一、类结构

namespace Think;//定义命名空间class Think {private static $_map= array();//类库别名映射private static $_instance = array();//保存类实例(这么说也不合理,等会分析该功能时具体说明)static public function start() {}//应用程序初始化static public function addMap($class, $map=”){}// 注册classmapstatic public function getMap($class=”){}// 获取classmappublic static function autoload($class) {}//类库自动加载static public function instance($class,$method=”) {}//取得对象实例 支持调用类的静态方法static public function appException($e) {}//自定义异常处理static public function appError($errno, $errstr, $errfile, $errline) {}//自定义错误处理static public function fatalError() {} // 致命错误捕获static public function halt($error) {}//错误输出static public function trace($value='[think]’,$label=”,$level=’DEBUG’,$record=false) {}//添加和获取页面Trace记录}

二、应用程序初始化start()方法分析,该方法包含一套错误和异常处理机制,非常受用。该方法作为ThinkPHP框架的引导接口,实现错误、异常处理,配置加载,别名映射,行为注册,包含运行缓存的生成,网站应用目录检测,自动类库加载行为注册。

/*** 应用程序初始化* @access public* @return void*/static public function start() {//使用spl标准库中提供__autoload()函数的默认实现,比__autoload()效率更高,更加灵活//一下可以使用spl_autoload_register(array(‘Think\Think’,’autoload’));//建议使用spl_autoload_register(__NAMESPACE__.’\Think::autoload’);实现//一下所有注册方式均可以使用上面3中形式传递参数spl_autoload_register(‘Think\Think::autoload’);//注册全局脚本"析构函数",使用该方式注册的函数,会在脚本结束前调用,大多数情况用来处理致命错误register_shutdown_function(‘Think\Think::fatalError’);//设置自定义错误处理函数,用于处理错误信息set_error_handler(‘Think\Think::appError’);//设置未异常处理函数set_exception_handler(‘Think\Think::appException’);//可以把register_shutdown_function(),set_error_handler(),set_error_handler()3个函数组合完成自定义、多元化的错误处理模块//根据STORAGE_TYPE的值设置分布式文件存储方案,Storage是一个工厂类,用于管理和维护分布式文件存储组件//后面会详细讲解Storage类,并指出设计缺陷Storage::connect(STORAGE_TYPE);//根据运行模式在运行缓存目录下生成编译缓存文件APP_MODE.’~runtime.php’,从而减少IO开销//下面会详细介绍生成缓存文件的方式$runtimefile = RUNTIME_PATH.APP_MODE.’~runtime.php’;//如果不是在调试模式,并且编译缓存文件存在,直接加载编译缓存if(!APP_DEBUG && Storage::has($runtimefile)){Storage::load($runtimefile);}else{//判断编译缓存文件是否存在,存在就删除if(Storage::has($runtimefile))Storage::unlink($runtimefile);//预编译内容变量$content = ”;//判断是否存在运行模式配置文件,如果不存在就加载MODE_PATH.APP_MODE.’.php’,运行模式配置文件会影响下列加载不同的类库和配置//运行配置文件后期会详细讲解$mode = include is_file(CONF_PATH.’core.php’)?CONF_PATH.’core.php’:MODE_PATH.APP_MODE.’.php’;//以下所有配置项加载都会根据加载的先后顺序覆盖之前的配置项,一般都是先加载ThinkPHP默认配置,再加载应用配置//core下标决定要加载的核心类和函数文件foreach ($mode[‘core’] as $file){if(is_file($file)) {include $file;//如果不是调试模式,则编译该文件内容并储存到预编译内容变量中if(!APP_DEBUG) $content .= compile($file);}}//config下标决定要加载的核心配置文件foreach ($mode[‘config’] as $key=>$file){//判断下标是否为数字,如果不是就会把该配置文件中的配置项加载到对应的键下面,相当于给配置项增加一个纬度is_numeric($key)?C(include $file):C($key,include $file);}//如果不是普通运行模式,则判断是否存在运行模式应用配置文件if(‘common’ != APP_MODE && is_file(CONF_PATH.’config_’.APP_MODE.’.php’))C(include CONF_PATH.’config_’.APP_MODE.’.php’);//alias下标记录类库别名映射规则,ThinkPHP独创别名机制,用于提升自动加载的效率if(isset($mode[‘alias’])){//由这句代码可以看出alias规则可以是一个数组,或者将规则数组单独作为一个文件self::addMap(is_array($mode[‘alias’])?$mode[‘alias’]:include $mode[‘alias’]);}//加载应用中定义的别名配置if(is_file(CONF_PATH.’alias.php’))self::addMap(include CONF_PATH.’alias.php’);//tags下标用于标识系统行为,行为扩展具体由Hook钩子类实现if(isset($mode[‘tags’])) {//由这句代码可以看出tags规则可以是一个数组,或者将规则数组单独作为一个文件Hook::import(is_array($mode[‘tags’])?$mode[‘tags’]:include $mode[‘tags’]);}//加载应用中的行为扩展配置if(is_file(CONF_PATH.’tags.php’))// 允许应用增加开发模式配置定义Hook::import(include CONF_PATH.’tags.php’);//加载框架底层语言包,有核心配置文件中的DEFAULT_LANG配置项决定L(include THINK_PATH.’Lang/’.strtolower(C(‘DEFAULT_LANG’)).’.php’);//如果不是调试模式则生成编译缓存文件if(!APP_DEBUG){//namespace {}这种方式用于声明代码块中的命名空间属于全局命名空间//这句代码用于生成加载别名映射的php代码$content .= "\nnamespace { Think\Think::addMap(".var_export(self::$_map,true).");";//L(".var_export(L(),true).");生成语言加载代码//C(".var_export(C(),true).’);生成配置项加载代码//Think\Hook::import(‘.var_export(Hook::get(),true).’);生成钩子加载代码$content .= "\nL(".var_export(L(),true).");\nC(".var_export(C(),true).’);Think\Hook::import(‘.var_export(Hook::get(),true).’);}’;//将$content变量内容去除注释和换行、空隔之后写入到运行时编译缓存文件Storage::put($runtimefile,strip_whitespace(‘<?php ‘.$content));}else{// 调试模式加载系统默认的配置文件C(include THINK_PATH.’Conf/debug.php’);// 读取应用调试配置文件if(is_file(CONF_PATH.’debug.php’))C(include CONF_PATH.’debug.php’);}}//根据APP_STATUS读取当前部署环境配置文件,常用在上线前数据库连接配置等,用于覆盖默认配置行为if(APP_STATUS && is_file(CONF_PATH.APP_STATUS.’.php’))C(include CONF_PATH.APP_STATUS.’.php’);// 设置系统时区//建议可以写成date_default_timezone_set(C(‘DEFAULT_TIMEZONE’,null,’PRC’));防止配置项读取问题导致的时区设置错误date_default_timezone_set(C(‘DEFAULT_TIMEZONE’));// 检查应用目录结构 如果不存在则自动创建if(C(‘CHECK_APP_DIR’) && !is_dir(LOG_PATH)) {//build.php负责创建应用目录结构require THINK_PATH.’Common/build.php’;}// 记录加载文件时间G(‘loadTime’);// 运行应用App::run();}天下无难事,只怕有心人。

ThinkPHP框架引导类分析

相关文章:

你感兴趣的文章:

标签云: