【thinkphp3.x】ThinkPHP/Common/runtime.php文件分析

<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2012 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------

/**
 * ThinkPHP 运行时文件 编译后不再加载
 * @category   Think
 * @package  Common
 * @author   liu21st <liu21st@gmail.com>
 */
//此文件只在第一次运行入口文件时会执行,如果不是第一次运行入口文件,则不会再执行此文件
//判断THNK_PATH是否已经被定义,如果没被定义,则终止程序
defined('THINK_PATH') or exit();
//判断当前php的版本是否大于5.2.0
if(version_compare(PHP_VERSION,'5.2.0','<'))  die('require PHP > 5.2.0 !');

//  版本信息
define('THINK_VERSION', '3.1');

//   系统信息
if(version_compare(PHP_VERSION,'5.3.0','<')) {
    set_magic_quotes_runtime(0);//是否自动在某些特殊字符前面加上反斜线
    define('MAGIC_QUOTES_GPC',get_magic_quotes_gpc()?True:False);
}else{
    define('MAGIC_QUOTES_GPC',True);
}
define('IS_CGI',substr(PHP_SAPI, 0,3)=='cgi' ? 1 : 0 );
define('IS_WIN',strstr(PHP_OS, 'WIN') ? 1 : 0 );
define('IS_CLI',PHP_SAPI=='cli'? 1   :   0);

// 项目名称,如果在入口文件中没有定义,则会将根目录作为项目的名称
defined('APP_NAME') or define('APP_NAME', basename(dirname($_SERVER['SCRIPT_FILENAME'])));
if(!IS_CLI) {//默认值为0
    // 当前文件名
    if(!defined('_PHP_FILE_')) {
        if(IS_CGI) {
            //CGI/FASTCGI模式下
            $_temp  = explode('.php',$_SERVER['PHP_SELF']);
            define('_PHP_FILE_',    rtrim(str_replace($_SERVER['HTTP_HOST'],'',$_temp[0].'.php'),'/'));
        }else {
        	//定义当前执行脚本的名称,如:/index.php    ,rtrim函数第二个参数:删除末端的'/'
            define('_PHP_FILE_',    rtrim($_SERVER['SCRIPT_NAME'],'/'));
        }
    }
    if(!defined('__ROOT__')) {
        // 网站URL根目录
        if( strtoupper(APP_NAME) == strtoupper(basename(dirname(_PHP_FILE_))) ) {
            $_root = dirname(dirname(_PHP_FILE_));
        }else {//执行这里
            $_root = dirname(_PHP_FILE_);
        }
        //定义网站的根目录
        define('__ROOT__',   (($_root=='/' || $_root=='\\')?'':$_root));
    }

    //支持的URL模式
    define('URL_COMMON',      0);   //普通模式
    define('URL_PATHINFO',    1);   //PATHINFO模式
    define('URL_REWRITE',     2);   //REWRITE模式
    define('URL_COMPAT',      3);   // 兼容模式
}

// 路径设置 可在入口文件中重新定义 所有路径常量都必须以/ 结尾
defined('CORE_PATH')    or define('CORE_PATH',      THINK_PATH.'Lib/'); // 系统核心类库目录
defined('EXTEND_PATH')  or define('EXTEND_PATH',    THINK_PATH.'Extend/'); // 系统扩展目录
defined('MODE_PATH')    or define('MODE_PATH',      EXTEND_PATH.'Mode/'); // 系统扩展目录/模式扩展目录
defined('ENGINE_PATH')  or define('ENGINE_PATH',    EXTEND_PATH.'Engine/'); // 系统扩展目录/引擎扩展目录
defined('VENDOR_PATH')  or define('VENDOR_PATH',    EXTEND_PATH.'Vendor/'); // 系统扩展目录/第三方类库目录
defined('LIBRARY_PATH') or define('LIBRARY_PATH',   EXTEND_PATH.'Library/'); // 系统扩展目录/扩展类库目录
defined('COMMON_PATH')  or define('COMMON_PATH',    APP_PATH.'Common/'); // 项目公共目录
defined('LIB_PATH')     or define('LIB_PATH',       APP_PATH.'Lib/'); // 项目类库目录
defined('CONF_PATH')    or define('CONF_PATH',      APP_PATH.'Conf/'); // 项目配置目录
defined('LANG_PATH')    or define('LANG_PATH',      APP_PATH.'Lang/'); // 项目语言包目录
defined('TMPL_PATH')    or define('TMPL_PATH',      APP_PATH.'Tpl/'); // 项目模板目录
defined('HTML_PATH')    or define('HTML_PATH',      APP_PATH.'Html/'); // 项目静态目录
defined('LOG_PATH')     or define('LOG_PATH',       RUNTIME_PATH.'Logs/'); // 项目路径/runtime/项目日志目录
defined('TEMP_PATH')    or define('TEMP_PATH',      RUNTIME_PATH.'Temp/'); // 项目路径/runtime/项目缓存目录
defined('DATA_PATH')    or define('DATA_PATH',      RUNTIME_PATH.'Data/'); // 项目路径/runtime/项目数据目录
defined('CACHE_PATH')   or define('CACHE_PATH',     RUNTIME_PATH.'Cache/'); // 项目路径/runtime/项目模板缓存目录

// 为了方便导入第三方类库 设置Vendor目录到include_path
set_include_path(get_include_path() . PATH_SEPARATOR . VENDOR_PATH);//将第三方类库的路径加入到系统变量中

// 加载运行时所需要的文件 并负责自动目录生成
function load_runtime_file() {
    // 加载系统基础函数库,D()函数、C()函数 、import()函数、vendor()函数、alias_import()、require_cache ()函数 、alias_import()函数 等都在此文件中定义
    require THINK_PATH.'Common/common.php';//路径:ThinkPHP/Common/common.php
    // 读取核心编译文件列表,//路径:ThinkPHP/Lib/Think.class.php
    $list = array(
        CORE_PATH.'Core/Think.class.php',			// 这个文件很重要,主要用来读取配置文件,编译项目等等
        CORE_PATH.'Core/ThinkException.class.php',  // 异常处理类
        CORE_PATH.'Core/Behavior.class.php',		// 行为类
    );
    // 加载模式文件列表
    foreach ($list as $key=>$file){
    	//require_cache()函数会将成功加载的文件置入静态数组变量$_importFiles[$filename]中
        if(is_file($file))  require_cache($file);//加载核心编译文件:require_cache函数在common.php文件中定义
    }

    // 加载系统类库别名定义,一个别名对应一个核心类库,如:【别名】'Db'=>【核心类库】 CORE_PATH.'Core/Db.class.php',
    /**
     * 大概有如下几个别名
     * 'Model'         => CORE_PATH.'Core/Model.class.php',
     * 'Db'            => CORE_PATH.'Core/Db.class.php',
     * 'Log'          	=> CORE_PATH.'Core/Log.class.php',
     * 'ThinkTemplate' => CORE_PATH.'Template/ThinkTemplate.class.php',
     * 'TagLib'        => CORE_PATH.'Template/TagLib.class.php',
     * 'Cache'         => CORE_PATH.'Core/Cache.class.php',
     * 'Widget'        => CORE_PATH.'Core/Widget.class.php',
     * 'TagLibCx'      => CORE_PATH.'Driver/TagLib/TagLibCx.class.php',
     */
    alias_import(include THINK_PATH.'Conf/alias.php');

    // 检查项目目录结构 如果不存在则自动创建
    if(!is_dir(LIB_PATH)) {
        // 如果不是目录,则创建项目目录结构
        build_app_dir();
    }elseif(!is_dir(CACHE_PATH)){
        // 如果不是目录,则检查缓存目录,并创建缓存目录
        check_runtime();
    }elseif(APP_DEBUG){//在调试模式开启的情况下,在运行时会删除编译文件
        // 调试模式切换删除编译缓存
        if(is_file(RUNTIME_FILE))   unlink(RUNTIME_FILE);
    }
}

// 检查缓存目录(Runtime) 如果不存在则自动创建
function check_runtime() {
    if(!is_dir(RUNTIME_PATH)) {
    	//如果runtime目录不存在,则创建runtime目录
        mkdir(RUNTIME_PATH);
    }elseif(!is_writeable(RUNTIME_PATH)) {
    	//如果runtime目录不可写,则给出提示
        header('Content-Type:text/html; charset=utf-8');
        exit('目录 [ '.RUNTIME_PATH.' ] 不可写!');
    }
    mkdir(CACHE_PATH);  // 创建项目模板缓存目录
    if(!is_dir(LOG_PATH))	mkdir(LOG_PATH);    // 日志目录
    if(!is_dir(TEMP_PATH))  mkdir(TEMP_PATH);	// 数据缓存目录
    if(!is_dir(DATA_PATH))	mkdir(DATA_PATH);	// 数据文件目录
    return true;
}

// 在调试模式开启的情况下,不会执行此函数
// 创建编译缓存,此函数会将所有要编译的内容编译到~runtime.php文件中,此文件中没有php的结束标记
function build_runtime_cache($append='') {
    // 生成编译文件
    $defs           = get_defined_constants(TRUE);//返回当前定义的所有常量组成的数组,可通过输出$defs查看效果
    $content        =  '$GLOBALS[\'_beginTime\'] = microtime(TRUE);';
    if(defined('RUNTIME_DEF_FILE')) { // 编译后的常量文件外部引入
        file_put_contents(RUNTIME_DEF_FILE,'<?php '.array_define($defs['user']));
        $content   .=  'require \''.RUNTIME_DEF_FILE.'\';';
    }else{
    	//array_define():根据数组生成常量的定义
        $content   .= array_define($defs['user']);//只有用户定义的常量
    }
    
    //第三方类库写入到环境变量中
    $content       .= 'set_include_path(get_include_path() . PATH_SEPARATOR . VENDOR_PATH);';
    
    // 读取核心编译文件列表
    $list = array(
        THINK_PATH.'Common/common.php',
        CORE_PATH.'Core/Think.class.php',
        CORE_PATH.'Core/ThinkException.class.php',
        CORE_PATH.'Core/Behavior.class.php',
    );
    
    foreach ($list as $file){
        $content .= compile($file);//循环将这些文件中的内容拼接到$content后面【注意:每个文件的内容都去除了php标记】
    }
    
    // 系统行为扩展文件统一编译
    if(C('APP_TAGS_ON')) {									//这里值为false
        $content .= build_tags_cache();
    }
    
    //包含别名文件,别名文件返回的数组数据赋值给$alias
    $alias      = include THINK_PATH.'Conf/alias.php';
    $content   .= 'alias_import('.var_export($alias,true).');';
    // 编译框架默认语言包和配置参数
    $content   .= $append."\nL(".var_export(L(),true).");C(".var_export(C(),true).');G(\'loadTime\');Think::Start();';
    file_put_contents(RUNTIME_FILE,strip_whitespace('<?php '.$content));
}

// 编译系统行为扩展类库
function build_tags_cache() {
    $tags = C('extends');//跟ThinkPHP/Conf/tags.php文件有关,可参考
    $content = '';
    foreach ($tags as $tag=>$item){
        foreach ($item as $key=>$name) {//也挺重要的,记得看一下下
            $content .= is_int($key)?compile(CORE_PATH.'Behavior/'.$name.'Behavior.class.php'):compile($name);
        }
    }
    return $content;
}

// 创建项目目录结构
function build_app_dir() {
    // 没有创建项目目录的话自动创建
    if(!is_dir(APP_PATH)) mkdir(APP_PATH,0777,true);
    if(is_writeable(APP_PATH)) {
        $dirs  = array(
            LIB_PATH,
            RUNTIME_PATH,
            CONF_PATH,
            COMMON_PATH,
            LANG_PATH,
            CACHE_PATH,
            TMPL_PATH,		//项目的模板目录,即:Tpl
            TMPL_PATH.C('DEFAULT_THEME').'/',		//项目模板目录下默认风格目录
            LOG_PATH,
            TEMP_PATH,
            DATA_PATH,
            LIB_PATH.'Model/',						//项目的模型目录
            LIB_PATH.'Action/',						//项目的控制器目录
            LIB_PATH.'Behavior/',
            LIB_PATH.'Widget/',
            );
        foreach ($dirs as $dir){
            if(!is_dir($dir))  mkdir($dir,0777,true);//循环创建项目的各个目录
        }
        // 写入目录安全文件
        build_dir_secure($dirs);
        // 写入初始配置文件
        if(!is_file(CONF_PATH.'config.php'))		// 配置文件
            file_put_contents(CONF_PATH.'config.php',"<?php\nreturn array(\n\t//'配置项'=>'配置值'\n);\n?>");
        // 写入测试Action							// 自动生成一个默认的控制器测试文件
        if(!is_file(LIB_PATH.'Action/IndexAction.class.php'))
            build_first_action();					//如果没有IndexAction.class.php文件,则生成一个测试控制器文件
    }else{
        header('Content-Type:text/html; charset=utf-8');
        exit('项目目录不可写,目录无法自动生成!<BR>请使用项目生成器或者手动生成项目目录~');
    }
}

// 创建测试Action
function build_first_action() {						//默认控制器文件中的内容
    $content = file_get_contents(THINK_PATH.'Tpl/default_index.tpl');
    file_put_contents(LIB_PATH.'Action/IndexAction.class.php',$content);
}

// 生成目录安全文件
function build_dir_secure($dirs='') {
    // 目录安全写入
    if(defined('BUILD_DIR_SECURE') && BUILD_DIR_SECURE) {
        defined('DIR_SECURE_FILENAME')  or define('DIR_SECURE_FILENAME',    'index.html');
        defined('DIR_SECURE_CONTENT')   or define('DIR_SECURE_CONTENT',     ' ');
        // 自动写入目录安全文件
        $content = DIR_SECURE_CONTENT;
        $files = explode(',', DIR_SECURE_FILENAME);
        foreach ($files as $filename){
            foreach ($dirs as $dir)
                file_put_contents($dir.$filename,$content);
        }
    }
}

// 加载运行时所需文件
load_runtime_file();
// 记录加载文件时间
G('loadTime');
// 执行入口
Think::Start();											//应用程序的初始化



如图所示:





  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
+------------------------------------------------------------------- | 感谢您使用ThinkPHP开发框架 ^_^ +------------------------------------------------------------------- | 大道至简 开发由我 WE CAN DO IT,JUST THINK +------------------------------------------------------------------- | 版本信息:ThinkPHP 3.1 Release 2012/9/5 +------------------------------------------------------------------- | Copyright(c) 2006-2012 http://thinkphp.cn All rights reserved. +------------------------------------------------------------------- [ 简介 ] ThinkPHP 是一个免费开源的,快速、简单的面向对象的 轻量级PHP开发框架, 遵循Apache2开源协议发布,是为了敏捷WEB应用开发和简化企业应用开发而 诞生的。ThinkPHP从诞生以来一直秉承简洁实用的设计原则,在保持出色的性 能和至简的代码的同时,也注重易用性。并且拥有众多的原创功能和特性,在 社区团队的积极参与下,在易用性、扩展性和性能方面不断优化和改进,众多 的典型案例确保可以稳定用于商业以及门户级的开发。 经过6年的不断积累和重构,3.0版本在框架底层的定制和扩展方面趋于完善, 使得应用的开发范围和需求适应度更加扩大,能够满足不同程度的开发人员的 需求。而且引入了全新的CBD(核心+行为+驱动)架构模式,旨在打造DIY框架 和AOP编程体验,让ThinkPHP能够在不同方面都能快速满足项目和应用的需求, 并且正式引入SAE、REST和Mongo支持。 使用ThinkPHP,你可以更方便和快捷的开发和部署应用。当然不仅仅是企业级 应用,任何PHP应用开发都可以从ThinkPHP的简单和快速的特性中受益。 ThinkPHP本身具有很多的原创特性,并且倡导大道至简,开发由我的开发理念, 用最少的代码完成更多的功能,宗旨就是让WEB应用开发更简单、更快速。 为此ThinkPHP会不断吸收和融入更好的技术以保证其新鲜和活力,提供WEB应 用开发的最佳实践!经过6年来的不断重构和改进,ThinkPHP达到了一个新的 阶段,能够满足企业开发中复杂的项目需求,足以达到企业级和门户级的开 发标准。 [ 协议 ] ThinkPHP遵循Apache2开源许可协议发布,意味着你可以免费使用ThinkPHP, 甚至允许把你的ThinkPHP应用采用商业闭源发布。 具体参考LICENSE.txt内容 [ 特性 ] CBD架构:ThinkPHP3.0版本引入了全新的CBD(核心+行为+驱动)架构模式, 打造框架底层DIY定制和类AOP编程体验。利用这一新的特性,开发人员可以 方便地通过模式扩展为自己量身定制一套属于自己或者企业的开发框架。 编译机制:独创的项目编译机制,有效减少OOP开发中文件加载的性能开销。 改进后的项目编译机制,可以支持编译文件直接作为入口载入,并且支持常量 外部载入,利于产品发布。 类库导入:采用基于类库包和命名空间的方式导入类库,让类库导入看起来更 加简单清晰,而且还支持自动加载和别名导入。为了方便项目的跨平台移植, 系统还可以严格检查加载文件的大小写。 URL和路由:系统支持普通模式、PATHINFO模式、REWRITE模式和兼容模式的 URL方式,支持不同的服务器和运行模式的部署,配合URL路由功能,让你随心 所欲的构建需要的URL地址和进行SEO优化工作。支持灵活的规则路由和正则路 由,以及路由重定向支持,带给开发人员更方便灵活的URL优化体验。 调试模式:框架提供的调试模式可以方便用于开发过程的不同阶段,包括开发、 测试和演示等任何需要的情况,不同的应用模式可以配置独立的项目配置文件。 只是小小的性能牺牲就能满足调试开发过程中的日志和分析需要,并确保将来的 部署顺利,一旦切换到部署模式则可以迅速提升性能。 ORM :简洁轻巧的ORM实现,配合简单的CURD以及AR模式,让开发效率无处不在。 数据库:支持包括Mysql、Sqlite、Pgsql、Oracle、SqlServer、Mongo等数据库, 并且内置分布式数据库和读写分离功能支持。系统支持多数据库连接和动态切换 机制,犹如企业开发的一把利刃,跨数据库应用和分布式支持从此无忧。 查询语言:内建丰富的查询机制,包括组合查询、快捷查询、复合查询、区间 查询、统计查询、定位查询、多表查询、子查询、动态查询和原生查询,让你的 数据查询简洁高效。 动态模型:无需创建任何对应的模型类,轻松完成CURD操作,支持多种模型之间 的动态切换,让你领略数据操作的无比畅快和最佳体验。 扩展模型:提供了丰富的扩展模型,包括:支持序列化字段、文本字段、只读字 段、延迟写入、乐观锁、数据分表等高级特性的高级模型;可以轻松动态地创建 数据库视图的视图模型;支持关联操作的关联模型;支持Mongo数据库的Mongo模 型等等,都可以方便的使用。 模块分组:不用担心大项目的分工协调和部署问题,分组帮你解决跨项目的难题, 还可以支持对分组的二级域名部署支持。 模板引擎:系统内建了一款卓越的基于XML的编译型模板引擎,支持两种类型的 模板标签,融合了Smarty和JSP标签库的思想,并内置布局模板功能和标签库扩展 支持。通过驱动还可以支持Smarty、EaseTemplate、TemplateLite、Smart等其他第 三方模板引擎。 AJAX支持:内置和客户端无关的AJAX数据返回方法,支持JSON、XML和EVAL类型 返回客户端,而且可以扩展返回数据格式,系统不绑定任何AJAX类库,可随意使 用自己熟悉的AJAX类库进行操作。 SAE支持:提供了新浪SAE平台的强力支持,具备“横跨性”和“平滑性”,支持本地化 开发和调试以及部署切换,让你轻松过渡到SAE开发,打造全新的SAE开发体验。 RESTFul支持:REST模式提供了RESTFul支持,为你打造全新的URL设计和访问体验, 同时为接口应用提供了支持。 多语言支持:系统支持语言包功能,项目和分组都可以有单独的语言包,并且可以 自动检测浏览器语言自动载入对应的语言包。 模式扩展:除了标准模式外,还提供了AMF、PHPRpc、Lite、Thin和Cli模式扩展支 持,针对不同级别的应用开发提供最佳核心框架,还可以自定义模式扩展。 自动验证和完成:自动完成表单数据的验证和过滤,新版新增了IP验证和有效期验 证等更多的验证方式,配合自动完成可以生成安全的数据对象。 字段类型检测:系统会自动缓存字段信息和字段类型,支持非法字段过滤和字段类 型强制转换,确保数据写入和查询更安全。 缓存机制:系统支持包括文件方式、APC、Db、Memcache、Shmop、Sqlite、Redis、 Eaccelerator和Xcache在内的动态数据缓存类型,以及可定制的静态缓存规则,并 提供了快捷方法进行存取操作。 扩展机制:系统支持包括模式扩展、行为扩展、类库扩展、驱动扩展、模型扩展、 控制器扩展、Widget扩展在内的强大灵活的扩展机制,让你不再受限于核心的不足 和无所适从,随心DIY自己的框架和扩展应用,满足企业开发中更加复杂的项目需求。 [ 要求 ] ThinkPHP3.1需要PHP5.2.0以上版本支持,可以运行在任何系统环境下面。 [ 安装 ] ThinkPHP无需安装,下载ThinkPHP核心包或者完整版之后,把解压后的目录拷贝到 你的WEB服务器或者WEB目录即可。 [ 鸣谢 ] 特别要鸣谢ThinkPHP团队和所有关注和支持ThinkPHP的用户。 [ 支持 ] 更多内容和支持请访问ThinkPHP官方网站http://thinkphp.cn/ 和论坛 http://bbs.thinkphp.cn。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值