接上一章的内容,我们继续来看Think.class.php文件的start方法
static public function start() { // 注册AUTOLOAD方法 spl_autoload_register('ThinkThink::autoload'); // 设定错误和异常处理 register_shutdown_function('ThinkThink::fatalError'); set_error_handler('ThinkThink::appError'); set_exception_handler('ThinkThink::appException'); // 初始化文件存储方式 Storage::connect(STORAGE_TYPE);
spl_autoloader,很常见的自动加载类的函数,现在任何框架都会实现这个方式。
register_shutdown_function('ThinkThink::fatalError'); 对致命错误进行的报错进行重写 set_error_handler('ThinkThink::appError'); 对error级别错误报错进行重写 set_exception_handler('ThinkThink::appException'); 对异常报错进行的重写
// 初始化文件存储方式 Storage::connect(STORAGE_TYPE);
static public function connect($type='File',$options=array()) { $class = 'Think\Storage\Driver\'.ucwords($type); self::$handler = new $class($options); }
这里是初始化文件存储方式的代码,首先用Storge::connect来加载文件,然后又通过$class变量来选择对应的文件系统。这种设计模式我目前还没想到是什么,感觉是工厂模式,不过又像是其他的,自己基础不牢,回去后再看下吧。
$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 = include is_file(CONF_PATH.'core.php')?CONF_PATH.'core.php':MODE_PATH.APP_MODE.'.php'; // 加载核心文件 foreach ($mode['core'] as $file){ if(is_file($file)) { include $file; if(!APP_DEBUG) $content .= compile($file); } }
这里是看是否有运行缓存文件,如果有并且是DEBUG模式,直接加载缓存文件,否则将删除缓存文件。
读取应用模式,这里先找dirname($_SERVER['SCRIPT_FILENAME']).'/') . Common/Conf/core.php 中寻找,如果没有则加载Mode/sae.php
<?php // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK IT ] // +---------------------------------------------------------------------- // | Copyright (c) 2006-2014 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- // | Author: luofei614 <weibo.com/luofei614> // +---------------------------------------------------------------------- /** * ThinkPHP SAE应用模式定义文件 */ return array( // 配置文件 'config' => array( THINK_PATH.'Conf/convention.php', // 系统惯例配置 CONF_PATH.'config'.CONF_EXT, // 应用公共配置 MODE_PATH.'Sae/convention.php',//[sae] sae的惯例配置 ), // 别名定义 'alias' => array( 'ThinkLog' => CORE_PATH . 'Log'.EXT, 'ThinkLogDriverFile' => CORE_PATH . 'Log/Driver/File'.EXT, 'ThinkException' => CORE_PATH . 'Exception'.EXT, 'ThinkModel' => CORE_PATH . 'Model'.EXT, 'ThinkDb' => CORE_PATH . 'Db'.EXT, 'ThinkTemplate' => CORE_PATH . 'Template'.EXT, 'ThinkCache' => CORE_PATH . 'Cache'.EXT, 'ThinkCacheDriverFile' => CORE_PATH . 'Cache/Driver/File'.EXT, 'ThinkStorage' => CORE_PATH . 'Storage'.EXT, ), // 函数和类文件 'core' => array( THINK_PATH.'Common/functions.php', COMMON_PATH.'Common/function.php', CORE_PATH . 'Hook'.EXT, CORE_PATH . 'App'.EXT, CORE_PATH . 'Dispatcher'.EXT, //CORE_PATH . 'Log'.EXT, CORE_PATH . 'Route'.EXT, CORE_PATH . 'Controller'.EXT, CORE_PATH . 'View'.EXT, BEHAVIOR_PATH . 'ParseTemplateBehavior'.EXT, BEHAVIOR_PATH . 'ContentReplaceBehavior'.EXT, ), // 行为扩展定义 'tags' => array( 'app_begin' => array( 'BehaviorReadHtmlCacheBehavior', // 读取静态缓存 ), 'app_end' => array( 'BehaviorShowPageTraceBehavior', // 页面Trace显示 ), 'view_parse' => array( 'BehaviorParseTemplateBehavior', // 模板解析 支持PHP、内置模板引擎和第三方模板引擎 ), 'template_filter'=> array( 'BehaviorContentReplaceBehavior', // 模板输出替换 ), 'view_filter' => array( 'BehaviorWriteHtmlCacheBehavior', // 写入静态缓存 ), ), );
这里就是sae.php的内容,配置文件,函数和类文件行文扩展定义都放到了一个数组里。这里我并不明白框架这么做有什么好处。看到这里,框架所需要的文件基本都已经包括进来了。
foreach ($mode['core'] as $file){ if(is_file($file)) { include $file; if(!APP_DEBUG) $content .= compile($file); } }
到这里有点明白了,放数组里,循环加载所需的核心文件。以后再需要其他新文件,在数组里加配置就可以了。这里的compile主要是为了清除文件中可能会有的一些可能导致语法错误的code.
foreach ($mode['config'] as $key=>$file){ is_numeric($key)?C(load_config($file)):C($key,load_config($file)); }
加载配置模式的配置文件
function load_config($file,$parse=CONF_PARSE){ $ext = pathinfo($file,PATHINFO_EXTENSION); switch($ext){ case 'php': return include $file; case 'ini': return parse_ini_file($file); case 'yaml': return yaml_parse_file($file); case 'xml': return (array)simplexml_load_file($file); case 'json': return json_decode(file_get_contents($file), true); default: if(function_exists($parse)){ return $parse($file); }else{ E(L('_NOT_SUPPORT_').':'.$ext); } } }
根据不同的文件选取不同的方法加载,如果是无法识别的文件,则需要在配置文件中设置,否则会选择配置的语言报错。