runtime.php 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2006-2012 http://thinkphp.cn All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8. // +----------------------------------------------------------------------
  9. // | Author: liu21st <liu21st@gmail.com>
  10. // +----------------------------------------------------------------------
  11. /**
  12. * ThinkPHP 运行时文件 编译后不再加载
  13. * @category Think
  14. * @package Common
  15. * @author liu21st <liu21st@gmail.com>
  16. */
  17. defined('THINK_PATH') or exit();
  18. if(version_compare(PHP_VERSION,'5.2.0','<')) die('require PHP > 5.2.0 !');
  19. // 版本信息
  20. define('THINK_VERSION', '3.1.3');
  21. // 系统信息
  22. if(version_compare(PHP_VERSION,'5.4.0','<')) {
  23. ini_set('magic_quotes_runtime',0);
  24. define('MAGIC_QUOTES_GPC',get_magic_quotes_gpc()?True:False);
  25. }else{
  26. define('MAGIC_QUOTES_GPC',false);
  27. }
  28. define('IS_CGI',substr(PHP_SAPI, 0,3)=='cgi' ? 1 : 0 );
  29. define('IS_WIN',strstr(PHP_OS, 'WIN') ? 1 : 0 );
  30. define('IS_CLI',PHP_SAPI=='cli'? 1 : 0);
  31. // 项目名称
  32. defined('APP_NAME') or define('APP_NAME', basename(dirname($_SERVER['SCRIPT_FILENAME'])));
  33. if(!IS_CLI) {
  34. // 当前文件名
  35. if(!defined('_PHP_FILE_')) {
  36. if(IS_CGI) {
  37. //CGI/FASTCGI模式下
  38. $_temp = explode('.php',$_SERVER['PHP_SELF']);
  39. define('_PHP_FILE_', rtrim(str_replace($_SERVER['HTTP_HOST'],'',$_temp[0].'.php'),'/'));
  40. }else {
  41. define('_PHP_FILE_', rtrim($_SERVER['SCRIPT_NAME'],'/'));
  42. }
  43. }
  44. if(!defined('__ROOT__')) {
  45. // 网站URL根目录
  46. if( strtoupper(APP_NAME) == strtoupper(basename(dirname(_PHP_FILE_))) ) {
  47. $_root = dirname(dirname(_PHP_FILE_));
  48. }else {
  49. $_root = dirname(_PHP_FILE_);
  50. }
  51. define('__ROOT__', (($_root=='/' || $_root=='\\')?'':$_root));
  52. }
  53. //支持的URL模式
  54. define('URL_COMMON', 0); //普通模式
  55. define('URL_PATHINFO', 1); //PATHINFO模式
  56. define('URL_REWRITE', 2); //REWRITE模式
  57. define('URL_COMPAT', 3); // 兼容模式
  58. }
  59. // 路径设置 可在入口文件中重新定义 所有路径常量都必须以/ 结尾
  60. defined('CORE_PATH') or define('CORE_PATH', THINK_PATH.'Lib/'); // 系统核心类库目录
  61. defined('EXTEND_PATH') or define('EXTEND_PATH', THINK_PATH.'Extend/'); // 系统扩展目录
  62. defined('MODE_PATH') or define('MODE_PATH', EXTEND_PATH.'Mode/'); // 模式扩展目录
  63. defined('ENGINE_PATH') or define('ENGINE_PATH', EXTEND_PATH.'Engine/'); // 引擎扩展目录
  64. defined('VENDOR_PATH') or define('VENDOR_PATH', EXTEND_PATH.'Vendor/'); // 第三方类库目录
  65. defined('LIBRARY_PATH') or define('LIBRARY_PATH', EXTEND_PATH.'Library/'); // 扩展类库目录
  66. defined('COMMON_PATH') or define('COMMON_PATH', APP_PATH.'Common/'); // 项目公共目录
  67. defined('LIB_PATH') or define('LIB_PATH', APP_PATH.'Lib/'); // 项目类库目录
  68. defined('CONF_PATH') or define('CONF_PATH', APP_PATH.'Conf/'); // 项目配置目录
  69. defined('LANG_PATH') or define('LANG_PATH', APP_PATH.'Lang/'); // 项目语言包目录
  70. defined('TMPL_PATH') or define('TMPL_PATH', APP_PATH.'Tpl/'); // 项目模板目录
  71. defined('HTML_PATH') or define('HTML_PATH', APP_PATH.'Html/'); // 项目静态目录
  72. defined('LOG_PATH') or define('LOG_PATH', RUNTIME_PATH.'Logs/'); // 项目日志目录
  73. defined('TEMP_PATH') or define('TEMP_PATH', RUNTIME_PATH.'Temp/'); // 项目缓存目录
  74. defined('DATA_PATH') or define('DATA_PATH', RUNTIME_PATH.'Data/'); // 项目数据目录
  75. defined('CACHE_PATH') or define('CACHE_PATH', RUNTIME_PATH.'Cache/'); // 项目模板缓存目录
  76. // 为了方便导入第三方类库 设置Vendor目录到include_path
  77. set_include_path(get_include_path() . PATH_SEPARATOR . VENDOR_PATH);
  78. // 加载运行时所需要的文件 并负责自动目录生成
  79. function load_runtime_file() {
  80. // 加载系统基础函数库
  81. require THINK_PATH.'Common/common.php';
  82. // 读取核心文件列表
  83. $list = array(
  84. CORE_PATH.'Core/Think.class.php',
  85. CORE_PATH.'Core/ThinkException.class.php', // 异常处理类
  86. CORE_PATH.'Core/Behavior.class.php',
  87. );
  88. // 加载模式文件列表
  89. foreach ($list as $key=>$file){
  90. if(is_file($file)) require_cache($file);
  91. }
  92. // 加载系统类库别名定义
  93. alias_import(include THINK_PATH.'Conf/alias.php');
  94. // 检查项目目录结构 如果不存在则自动创建
  95. if(!is_dir(LIB_PATH)) {
  96. // 创建项目目录结构
  97. build_app_dir();
  98. }elseif(!is_dir(CACHE_PATH)){
  99. // 检查缓存目录
  100. check_runtime();
  101. }elseif(APP_DEBUG){
  102. // 调试模式切换删除编译缓存
  103. if(is_file(RUNTIME_FILE)) unlink(RUNTIME_FILE);
  104. }
  105. }
  106. // 检查缓存目录(Runtime) 如果不存在则自动创建
  107. function check_runtime() {
  108. if(!is_dir(RUNTIME_PATH)) {
  109. mkdir(RUNTIME_PATH);
  110. }elseif(!is_writeable(RUNTIME_PATH)) {
  111. header('Content-Type:text/html; charset=utf-8');
  112. exit('目录 [ '.RUNTIME_PATH.' ] 不可写!');
  113. }
  114. mkdir(CACHE_PATH); // 模板缓存目录
  115. if(!is_dir(LOG_PATH)) mkdir(LOG_PATH); // 日志目录
  116. if(!is_dir(TEMP_PATH)) mkdir(TEMP_PATH); // 数据缓存目录
  117. if(!is_dir(DATA_PATH)) mkdir(DATA_PATH); // 数据文件目录
  118. return true;
  119. }
  120. // 创建编译缓存
  121. function build_runtime_cache($append='') {
  122. // 生成编译文件
  123. $defs = get_defined_constants(TRUE);
  124. $content = '$GLOBALS[\'_beginTime\'] = microtime(TRUE);';
  125. if(defined('RUNTIME_DEF_FILE')) { // 编译后的常量文件外部引入
  126. file_put_contents(RUNTIME_DEF_FILE,'<?php '.array_define($defs['user']));
  127. $content .= 'require \''.RUNTIME_DEF_FILE.'\';';
  128. }else{
  129. $content .= array_define($defs['user']);
  130. }
  131. $content .= 'set_include_path(get_include_path() . PATH_SEPARATOR . VENDOR_PATH);';
  132. // 读取核心编译文件列表
  133. $list = array(
  134. THINK_PATH.'Common/common.php',
  135. CORE_PATH.'Core/Think.class.php',
  136. CORE_PATH.'Core/ThinkException.class.php',
  137. CORE_PATH.'Core/Behavior.class.php',
  138. );
  139. foreach ($list as $file){
  140. $content .= compile($file);
  141. }
  142. // 系统行为扩展文件统一编译
  143. $content .= build_tags_cache();
  144. $alias = include THINK_PATH.'Conf/alias.php';
  145. $content .= 'alias_import('.var_export($alias,true).');';
  146. // 编译框架默认语言包和配置参数
  147. $content .= $append."\nL(".var_export(L(),true).");C(".var_export(C(),true).');G(\'loadTime\');Think::Start();';
  148. file_put_contents(RUNTIME_FILE,strip_whitespace('<?php '.str_replace("defined('THINK_PATH') or exit();",' ',$content)));
  149. }
  150. // 编译系统行为扩展类库
  151. function build_tags_cache() {
  152. $tags = C('extends');
  153. $content = '';
  154. foreach ($tags as $tag=>$item){
  155. foreach ($item as $key=>$name) {
  156. $content .= is_int($key)?compile(CORE_PATH.'Behavior/'.$name.'Behavior.class.php'):compile($name);
  157. }
  158. }
  159. return $content;
  160. }
  161. // 创建项目目录结构
  162. function build_app_dir() {
  163. // 没有创建项目目录的话自动创建
  164. if(!is_dir(APP_PATH)) mkdir(APP_PATH,0755,true);
  165. if(is_writeable(APP_PATH)) {
  166. $dirs = array(
  167. LIB_PATH,
  168. RUNTIME_PATH,
  169. CONF_PATH,
  170. COMMON_PATH,
  171. LANG_PATH,
  172. CACHE_PATH,
  173. TMPL_PATH,
  174. TMPL_PATH.C('DEFAULT_THEME').'/',
  175. LOG_PATH,
  176. TEMP_PATH,
  177. DATA_PATH,
  178. LIB_PATH.'Model/',
  179. LIB_PATH.'Action/',
  180. LIB_PATH.'Behavior/',
  181. LIB_PATH.'Widget/',
  182. );
  183. foreach ($dirs as $dir){
  184. if(!is_dir($dir)) mkdir($dir,0755,true);
  185. }
  186. // 写入目录安全文件
  187. build_dir_secure($dirs);
  188. // 写入初始配置文件
  189. if(!is_file(CONF_PATH.'config.php'))
  190. file_put_contents(CONF_PATH.'config.php',"<?php\nreturn array(\n\t//'配置项'=>'配置值'\n);\n?>");
  191. // 写入测试Action
  192. if(!is_file(LIB_PATH.'Action/IndexAction.class.php'))
  193. build_first_action();
  194. }else{
  195. header('Content-Type:text/html; charset=utf-8');
  196. exit('项目目录不可写,目录无法自动生成!<BR>请使用项目生成器或者手动生成项目目录~');
  197. }
  198. }
  199. // 创建测试Action
  200. function build_first_action() {
  201. $content = file_get_contents(THINK_PATH.'Tpl/default_index.tpl');
  202. file_put_contents(LIB_PATH.'Action/IndexAction.class.php',$content);
  203. }
  204. // 生成目录安全文件
  205. function build_dir_secure($dirs=array()) {
  206. // 目录安全写入
  207. if(defined('BUILD_DIR_SECURE') && BUILD_DIR_SECURE) {
  208. defined('DIR_SECURE_FILENAME') or define('DIR_SECURE_FILENAME', 'index.html');
  209. defined('DIR_SECURE_CONTENT') or define('DIR_SECURE_CONTENT', ' ');
  210. // 自动写入目录安全文件
  211. $content = DIR_SECURE_CONTENT;
  212. $files = explode(',', DIR_SECURE_FILENAME);
  213. foreach ($files as $filename){
  214. foreach ($dirs as $dir)
  215. file_put_contents($dir.$filename,$content);
  216. }
  217. }
  218. }
  219. // 加载运行时所需文件
  220. load_runtime_file();
  221. // 记录加载文件时间
  222. G('loadTime');
  223. // 执行入口
  224. Think::Start();