checker.php 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. <?php
  2. /**
  3. * Requirements Checker: This script will check if your system meets
  4. * the requirements for running ThinkPHP Framework.
  5. *
  6. * This file is part of the ThinkPHP Framework 参考了nette框架(http://nette.org)
  7. *
  8. * For the full copyright and license information, please view
  9. * the file license.txt that was distributed with this source code.
  10. */
  11. /**
  12. * Check PHP configuration.
  13. */
  14. foreach (array('function_exists', 'version_compare', 'extension_loaded', 'ini_get') as $function) {
  15. if (!function_exists($function)) {
  16. die("Error: function '$function' is required by ThinkPHP Framework and this Requirements Checker.");
  17. }
  18. }
  19. /**
  20. * Check assets目录, 模板文件必须可读
  21. */
  22. define('TEMPLATE_FILE', __DIR__ . '/assets/checker.phtml');
  23. if (!is_readable(TEMPLATE_FILE)) {
  24. die("Error: 模板文件不可读.检查assets目录(发布的部分),应当存在,可读且包含可读的模板文件.");
  25. }
  26. /**
  27. * Check ThinkPHP Framework requirements.
  28. */
  29. define('CHECKER_VERSION', '1.0');
  30. $tests[] = array(
  31. 'title' => 'Web服务器',
  32. 'message' => $_SERVER['SERVER_SOFTWARE'],
  33. );
  34. $tests[] = array(
  35. 'title' => 'PHP版本',
  36. 'required' => TRUE,
  37. 'passed' => version_compare(PHP_VERSION, '5.2.0', '>='),
  38. 'message' => PHP_VERSION,
  39. 'description' => '你的PHP太低了.ThinkPHP框架需要至少PHP 5.2.0或更高.',
  40. );
  41. $tests[] = array(
  42. 'title' => 'Memory限制',
  43. 'message' => ini_get('memory_limit'),
  44. );
  45. $tests['hf'] = array(
  46. 'title' => '.htaccess文件保护',
  47. 'required' => FALSE,
  48. 'description' => '通过<code>.htaccess</code>的File保护不支持.你必须小心的放入文件到document_root目录.',
  49. 'script' => '<script src="assets/denied/checker.js"></script><script>displayResult("hf", typeof fileProtectionChecker == "undefined")</script>',
  50. );
  51. $tests['hr'] = array(
  52. 'title' => '.htaccess mod_rewrite',
  53. 'required' => FALSE,
  54. 'description' => 'Mod_rewrite可能不支持.你将无法使用Cool URL(URL_MODEL=2不启作用,入口文件无法隐藏).',
  55. 'script' => '<script src="assets/rewrite/checker"></script><script>displayResult("hr", typeof modRewriteChecker == "boolean")</script>',
  56. );
  57. $tests[] = array(
  58. 'title' => '函数ini_set()',
  59. 'required' => FALSE,
  60. 'passed' => function_exists('ini_set'),
  61. 'description' => '函数<code>ini_set()</code>不支持.部分ThinkPHP框架功能可能工作不正常.',
  62. );
  63. $tests[] = array(
  64. 'title' => '函数error_reporting()',
  65. 'required' => TRUE,
  66. 'passed' => function_exists('error_reporting'),
  67. 'description' => '函数<code>error_reporting()</code>不支持. ThinkPHP框架需要这个被启用',
  68. );
  69. // $tests[] = array(
  70. // 'title' => 'Function flock()',
  71. // 'required' => TRUE,
  72. // 'passed' => flock(fopen(__FILE__, 'r'), LOCK_SH),
  73. // 'description' => 'Function <code>flock()</code> is not supported on this filesystem. ThinkPHP Framework requires this to process atomic file operations.',
  74. // );
  75. $tests[] = array(
  76. 'title' => 'Register_globals',
  77. 'required' => TRUE,
  78. 'passed' => iniFlag('register_globals'),
  79. 'message' => '启用',
  80. 'errorMessage' => '不支持',
  81. 'description' => '配置Configuration显示<code>register_globals</code>禁用了. ThinkPHP框架要求此项开启.',
  82. );
  83. // $tests[] = array(
  84. // 'title' => 'Variables_order',
  85. // 'required' => TRUE,
  86. // 'passed' => strpos(ini_get('variables_order'), 'G') !== FALSE && strpos(ini_get('variables_order'), 'P') !== FALSE && strpos(ini_get('variables_order'), 'C') !== FALSE,
  87. // 'description' => 'Configuration directive <code>variables_order</code> is missing. ThinkPHP Framework requires this to be set.',
  88. // );
  89. $tests[] = array(
  90. 'title' => 'Session auto-start',
  91. 'required' => FALSE,
  92. 'passed' => session_id() === '' && !defined('SID'),
  93. 'description' => 'Session auto-start启用了. ThinkPHP框架默认情况下,初始化之后系统会自动启动session.',
  94. );
  95. $tests[] = array(
  96. 'title' => 'Reflection扩展',
  97. 'required' => TRUE,
  98. 'passed' => class_exists('ReflectionFunction'),
  99. 'description' => 'ThinkPHP必须开启Reflection扩展.',
  100. );
  101. // $tests[] = array(
  102. // 'title' => 'SPL extension',
  103. // 'required' => TRUE,
  104. // 'passed' => extension_loaded('SPL'),
  105. // 'description' => 'SPL extension is required.',
  106. // );
  107. $tests[] = array(
  108. 'title' => 'PCRE扩展',
  109. 'required' => TRUE,
  110. 'passed' => extension_loaded('pcre') && @preg_match('/pcre/u', 'pcre'),
  111. 'message' => '支持并且工作正常',
  112. 'errorMessage' => '禁用或者不支持UTF-8',
  113. 'description' => 'PCRE扩展推荐开启并支持UTF-8.',
  114. );
  115. $tests[] = array(
  116. 'title' => 'ICONV扩展',
  117. 'required' => TRUE,
  118. 'passed' => extension_loaded('iconv') && (ICONV_IMPL !== 'unknown') && @iconv('UTF-16', 'UTF-8//IGNORE', iconv('UTF-8', 'UTF-16//IGNORE', 'test')) === 'test',
  119. 'message' => '支持并且工作正常',
  120. 'errorMessage' => '禁用或者工作不正常',
  121. 'description' => 'ICONV扩展必须且工作正常.',
  122. );
  123. // $tests[] = array(
  124. // 'title' => 'PHP tokenizer',
  125. // 'required' => TRUE,
  126. // 'passed' => extension_loaded('tokenizer'),
  127. // 'description' => 'PHP tokenizer is required.',
  128. // );
  129. $tests[] = array(
  130. 'title' => 'PDO扩展',
  131. 'required' => FALSE,
  132. 'passed' => $pdo = extension_loaded('pdo') && PDO::getAvailableDrivers(),
  133. 'message' => $pdo ? '可用驱动有drivers: ' . implode(' ', PDO::getAvailableDrivers()) : NULL,
  134. 'description' => 'PDO扩展或者PDO驱动不支持.你将不能使用<code>ThinkPHP\DbPdo</code>.',
  135. );
  136. $tests[] = array(
  137. 'title' => '多字节字符串扩展',
  138. 'required' => FALSE,
  139. 'passed' => extension_loaded('mbstring'),
  140. 'description' => 'Multibyte String扩展不支持.一些国际化组件可能无法正常工作.',
  141. );
  142. $tests[] = array(
  143. 'title' => '多字节字符串overloading函数',
  144. 'required' => TRUE,
  145. 'passed' => !extension_loaded('mbstring') || !(mb_get_info('func_overload') & 2),
  146. 'message' => '禁用',
  147. 'errorMessage' => '启用',
  148. 'description' => '启用了多字节字符串重载函数. ThinkPHP框架要求这项被禁用.如果它开启着,一些字符串函数将可能工作不正常.',
  149. );
  150. $tests[] = array(
  151. 'title' => 'Memcache扩展',
  152. 'required' => FALSE,
  153. 'passed' => extension_loaded('memcache'),
  154. 'description' => 'Memcache扩展不支持.你将不能使用<code>Memcache作为ThinkPHP的缓存方式</code>.',
  155. );
  156. $tests[] = array(
  157. 'title' => 'GD扩展',
  158. 'required' => TRUE,
  159. 'passed' => extension_loaded('gd'),
  160. 'description' => 'GD扩展不支持. 你将不能使用<code>ThinkPHP\Image</code>类.',
  161. );
  162. $tests[] = array(
  163. 'title' => 'Imagick扩展',
  164. 'required' => FALSE,
  165. 'passed' => extension_loaded('imagick'),
  166. 'description' => 'Imagick扩展不支持. 你将不能使用Imagick进行高效图像处理.',
  167. );
  168. // $tests[] = array(
  169. // 'title' => 'Bundled GD extension',
  170. // 'required' => FALSE,
  171. // 'passed' => extension_loaded('gd') && GD_BUNDLED,
  172. // 'description' => 'Bundled GD extension is absent. You will not be able to use some functions such as <code>ThinkPHP\Image::filter()</code> or <code>ThinkPHP\Image::rotate()</code>.',
  173. // );
  174. $tests[] = array(
  175. 'title' => 'Fileinfo扩展 或 mime_content_type()',
  176. 'required' => FALSE,
  177. 'passed' => extension_loaded('fileinfo') || function_exists('mime_content_type'),
  178. 'description' => 'Fileinfo 扩展或者 函数<code>mime_content_type()</code> 不支持.你将不能检测上传文件的mime类型.',
  179. );
  180. // $tests[] = array(
  181. // 'title' => 'HTTP_HOST or SERVER_NAME',
  182. // 'required' => TRUE,
  183. // 'passed' => isset($_SERVER["HTTP_HOST"]) || isset($_SERVER["SERVER_NAME"]),
  184. // 'message' => 'Present',
  185. // 'errorMessage' => 'Absent',
  186. // 'description' => 'Either <code>$_SERVER["HTTP_HOST"]</code> or <code>$_SERVER["SERVER_NAME"]</code> must be available for resolving host name.',
  187. // );
  188. $tests[] = array(
  189. 'title' => 'REQUEST_URI 或 ORIG_PATH_INFO',
  190. 'required' => TRUE,
  191. 'passed' => isset($_SERVER["REQUEST_URI"]) || isset($_SERVER["ORIG_PATH_INFO"]),
  192. 'message' => '支持',
  193. 'errorMessage' => '不支持',
  194. 'description' => ' <code>$_SERVER["REQUEST_URI"]</code> 或者<code>$_SERVER["ORIG_PATH_INFO"]</code>必学能获取到用于分解请求的URL.',
  195. );
  196. // $tests[] = array(
  197. // 'title' => 'DOCUMENT_ROOT & SCRIPT_FILENAME or SCRIPT_NAME',
  198. // 'required' => TRUE,
  199. // 'passed' => isset($_SERVER['DOCUMENT_ROOT'], $_SERVER['SCRIPT_FILENAME']) || isset($_SERVER['SCRIPT_NAME']),
  200. // 'message' => 'Present',
  201. // 'errorMessage' => 'Absent',
  202. // 'description' => '<code>$_SERVER["DOCUMENT_ROOT"]</code> and <code>$_SERVER["SCRIPT_FILENAME"]</code> or <code>$_SERVER["SCRIPT_NAME"]</code> must be available for resolving script file path.',
  203. // );
  204. // $tests[] = array(
  205. // 'title' => 'SERVER_ADDR or LOCAL_ADDR',
  206. // 'required' => TRUE,
  207. // 'passed' => isset($_SERVER["SERVER_ADDR"]) || isset($_SERVER["LOCAL_ADDR"]),
  208. // 'message' => 'Present',
  209. // 'errorMessage' => 'Absent',
  210. // 'description' => '<code>$_SERVER["SERVER_ADDR"]</code> or <code>$_SERVER["LOCAL_ADDR"]</code> must be available for detecting development / production mode.',
  211. // );
  212. paint($tests);
  213. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
  214. /**
  215. * Paints checker.
  216. * @param array
  217. * @return void
  218. */
  219. function paint($requirements){
  220. $errors = $warnings = FALSE;
  221. foreach ($requirements as $id => $requirement){
  222. $requirements[$id] = $requirement = (object) $requirement;
  223. if (isset($requirement->passed) && !$requirement->passed) {
  224. if ($requirement->required) {
  225. $errors = TRUE;
  226. } else {
  227. $warnings = TRUE;
  228. }
  229. }
  230. }
  231. require TEMPLATE_FILE;
  232. }
  233. /**
  234. * 获取配置项的布尔值.
  235. * @param string 配置项名称
  236. * @return bool
  237. */
  238. function iniFlag($var){
  239. $status = strtolower(ini_get($var));
  240. return $status === 'on' || $status === 'true' || $status === 'yes' || (int) $status;
  241. }