thinkphp源码解析 (Version 3.1) -2 /Lib/Core/Think.class
2016-01-13 20:20
741 查看
thinkphp源码解析 (Version 3.1) -2
/Lib/Core/Think.classprivate static $_instance = array();
单例模式
类的静态成员变量是所有实例共用的
调用的时候可以通过对象调用,也可以通过类直接调用
start()
register_shutdown_function(array('Think','fatalError'));
给当前类注册一个函数,此函数能够在脚本终止前回调注册的函数
程序在运行的时候可能存在执行超时,或强制关闭等情况,但这种情况下默认的提示是非常不友好的。
如果使用 register_shutdown_function()函数捕获异常,就能提供更加友好的错误展示方式,同时可以实现一些功能的后续操作,如执行完成 后的临时数据清理,包括临时文件等。
warning:如果使用了该函数,会完全绕过标准的 PHP 错误处理函数。
三种情况下该函数会执行:
1、当页面被用户强制停止时
2、当程序代码运行超时时
3、当PHP代码执行完成时,代码执行存在异常和错误、警告
set_error_handler(array('Think','appError'));
set_error_handler() 函数设置用户自定义的错误处理函数。
该函数用于创建运行时期间的用户自己的错误处理方法。
该函数会返回旧的错误处理程序,若失败,则返回 null。
set_error_handler(error_function,error_types)
set_exception_handler(array('Think','appException'));
set_exception_handler() 函数设置用户自定义的异常处理函数。
throw new Execption(‘foo’) 的时候,那么当执行这个语句的时候会自动调用我们转进去的自定义函数。
set_exception_handler(exception_function)
spl_autoload_register(array('Think', 'autoload'));
将函数注册到SPL __autoload函数栈中
Think::buildApp();
预编译项目
App::run();
运行应用
buildApp()
// 加载底层惯例配置文件 C(include THINK_PATH.'Conf/convention.php'); // 读取运行模式 if(defined('MODE_NAME')) { // 模式的设置并入核心模式 $mode = include MODE_PATH.strtolower(MODE_NAME).'.php'; }else{ $mode = array(); } // 加载模式配置文件 if(isset($mode['config'])) { C( is_array($mode['config'])?$mode['config']:include $mode['config'] ); } // 加载项目配置文件 if(is_file(CONF_PATH.'config.php')) C(include CONF_PATH.'config.php'); // 加载框架底层语言包 L(include THINK_PATH.'Lang/'.strtolower(C('DEFAULT_LANG')).'.php'); // 加载模式系统行为定义 if(C('APP_TAGS_ON')) { if(isset($mode['extends'])) { C('extends',is_array($mode['extends'])?$mode['extends']:include $mode['extends']); }else{ // 默认加载系统行为扩展定义 C('extends', include THINK_PATH.'Conf/tags.php'); } } // 加载应用行为定义 if(isset($mode['tags'])) { C('tags', is_array($mode['tags'])?$mode['tags']:include $mode['tags']); }elseif(is_file(CONF_PATH.'tags.php')){ // 默认加载项目配置目录的tags文件定义 C('tags', include CONF_PATH.'tags.php'); } $compile = ''; // 读取核心编译文件列表 if(isset($mode['core'])) { $list = $mode['core']; }else{ $list = array( THINK_PATH.'Common/functions.php', // 标准模式函数库 CORE_PATH.'Core/Log.class.php', // 日志处理类 CORE_PATH.'Core/Dispatcher.class.php', // URL调度类 CORE_PATH.'Core/App.class.php', // 应用程序类 CORE_PATH.'Core/Action.class.php', // 控制器类 CORE_PATH.'Core/View.class.php', // 视图类 ); } // 项目追加核心编译列表文件 if(is_file(CONF_PATH.'core.php')) { $list = array_merge($list,include CONF_PATH.'core.php'); } foreach ($list as $file){ if(is_file($file)) { require_cache($file); if(!APP_DEBUG) $compile .= compile($file); } } // 加载项目公共文件 if(is_file(COMMON_PATH.'common.php')) { include COMMON_PATH.'common.php'; // 编译文件 if(!APP_DEBUG) $compile .= compile(COMMON_PATH.'common.php'); } // 加载模式别名定义 if(isset($mode['alias'])) { $alias = is_array($mode['alias'])?$mode['alias']:include $mode['alias']; alias_import($alias); if(!APP_DEBUG) $compile .= 'alias_import('.var_export($alias,true).');'; } // 加载项目别名定义 if(is_file(CONF_PATH.'alias.php')){ $alias = include CONF_PATH.'alias.php'; alias_import($alias); if(!APP_DEBUG) $compile .= 'alias_import('.var_export($alias,true).');'; } if(APP_DEBUG) { // 调试模式加载系统默认的配置文件 C(include THINK_PATH.'Conf/debug.php'); // 读取调试模式的应用状态 $status = C('APP_STATUS'); // 加载对应的项目配置文件 if(is_file(CONF_PATH.$status.'.php')) // 允许项目增加开发模式配置定义 C(include CONF_PATH.$status.'.php'); }else{ // 部署模式下面生成编译文件 build_runtime_cache($compile); } return ;
autoload()
(a)
if(substr($class,-8)=='Behavior') { }elseif(substr($class,-5)=='Model'){ }elseif(substr($class,-6)=='Action'){
加载行为、模型、控制器
(b)
(defined('GROUP_NAME') && require_cache(LIB_PATH.'Action/'.GROUP_NAME.'/'.$class.'.class.php')
根据分组名字、action、class引入文件
此处调用了公共函数require_cache()
static $_importFiles = array(); //创建静态数组 存活周期为栈 下次调用该数组值不变
//先判断域是否为空或者不存在
if (!isset(\$_importFiles[\$filename])) {
//再判断文件地址是否存在、
if (file_exists_case(\$filename)) {
然后require此文件 再设置数组此域为true
实现了全局加载文件列表
(c)
$paths = explode(',',C('APP_AUTOLOAD_PATH'));
根据自动加载路径设置进行尝试搜索
“
此方法的作用就是你传进去一个类,他给你返回一个该类的实例,保存在$_instance数组中,数组键为$identify,值为对应的实例。此外,此方法还支持调用类的静态方法,如果你除了传入类名外,还传入了一个该类所有的方法名,那么instance方法返回的就不会类所对应的实例了,而是返回执行了类的静态方法后,该静态方法返回的值。
static public function instance($class,$method='') { //类名+数组名作为键名 $identify = $class.$method; //$_instance是私有的静态数组变量 //如果此类已注册在数组中 if(!isset(self::$_instance[$identify])) { //如果类存在 if(class_exists($class)){ //实例化类 $o = new $class(); //方法存在则将方法返回值作为值保存在数组中 if(!empty($method) && method_exists($o,$method)) self::$_instance[$identify] = call_user_func_array(array(&$o, $method)); else //否则将类实例作为值保存到数组中 self::$_instance[$identify] = $o; } else //类不存在 halt抛出异常 halt(L('_CLASS_NOT_EXIST_').':'.$class); } //返回类的实例 return self::$_instance[$identify]; }
appError()
/** * 自定义错误处理 * @access public * @param int $errno 错误类型 * @param string $errstr 错误信息 * @param string $errfile 错误文件 * @param int $errline 错误行数 * @return void */ static public function appError($errno, $errstr, $errfile, $errline) { switch ($errno) { case E_ERROR: case E_PARSE: case E_CORE_ERROR: case E_COMPILE_ERROR: case E_USER_ERROR: // 此函数丢弃最顶层输出缓冲区的内容并关闭这个缓冲区。 // 如果想要进一步处理缓冲区的内容,必须在ob_end_clean()之前调用ob_get_contents(), // 因为当调用ob_end_clean()时缓冲区内容将被丢弃。 ob_end_clean(); // 页面压缩输出支持 if(C('OUTPUT_ENCODE')){ // ini_get() 是获取php.ini里的环境变量的值. // 不论是iis还是apache默认都只压缩html类静态文件,对于php文件需要模块配置才可支持, // 于是利用php自身功能到达gzip的效果也成为一项合理的诉求。 // 找到zlib.output_compression = Off,改成zlib.output_compression = On, // 再把;zlib.output_compression_level前面的;去掉,后面的-1改成1~5的数值。 $zlib = ini_get('zlib.output_compression'); //此函数[ob_start()]将打开输出缓冲。当输出缓冲激活后,脚本将不会输出内容(除http标头外), //相反需要输出的内容被存储在内部缓冲区中。 //内部缓冲区的内容可以用 ob_get_contents() 函数复制到一个字符串变量中。 //想要输出存储在内部缓冲区中的内容,可以使用 ob_end_flush() 函数。 if(empty($zlib)) ob_start('ob_gzhandler'); } $errorStr = "$errstr ".$errfile." 第 $errline 行."; if(C('LOG_RECORD')) Log::write("[$errno] ".$errorStr,Log::ERR); function_exists('halt')?halt($errorStr):exit('ERROR:'.$errorStr); break; case E_STRICT: case E_USER_WARNING: case E_USER_NOTICE: default: $errorStr = "[$errno] $errstr ".$errfile." 第 $errline 行."; trace($errorStr,'','NOTIC'); break; } }
appException()
/** * 自定义异常处理 * @access public * @param mixed $e 异常对象 */ static public function appException($e) { halt($e->__toString()); }
fatalError()
// 致命错误捕获 static public function fatalError() { if ($e = error_get_last()) { Think::appError($e['type'],$e['message'],$e['file'],$e['line']); } }
相关文章推荐
- php的json校验json-schema
- php中奖概率算法,可用于刮刮卡,大转盘等抽奖算法
- Laravel 传递数据到视图
- Atitit.导出excel报表的设计与实现java .net php 总
- Atitit.导出excel报表的设计与实现java .net php 总
- Atitit.导出excel报表的设计与实现java .net php 总结
- php.ini配置文件执行时间
- PHP过滤各种html标签
- php中echo等语言结构与函数差异
- php在cli命令行执行exec函数中的top命令正常,浏览器访问无输出
- php从5.4以后自带web服务器
- php笔记
- thinkphp源码解析 (Version 3.1) -1
- PHP解析带CDATA的XML方法
- 关于公司内部私拉TP-Link路由器引发的血案
- kuangbin_ShortPath M (POJ 1062)
- thinkphp实现图片上传功能
- php.ini配置与中国间隔12小时间设置方法
- php 与 ajax 获取123的案例
- php读取大文件