system/core/Common.php 文件中可以定义 公共函数,我们可以在这里定义自己的公共函数。在任何情况下你都能够使用这些函数。使用他们不需要载入任何类库或辅助函数。

接下来分析下该文件中自带的一些方法:

  1. <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
  2.  
  3. // ------------------------------------------------------------------------
  4.  
  5. /**
  6. * Common Functions
  7. */
  8.  
  9. /**
  10. * 为什么还要定义这些全局函数呢?比如说,下面有很多函数,
  11. * 如get_config()、config_item()这两个方法不是应该由
  12. * core/Config.php这个组件去做么?那个load_class()不应该由core/Loader.php去做么?
  13. * 把这些函数定义出来貌似 感觉架构变得不那么优雅,有点多余。
  14. * 其实是出于这样一种情况:
  15. * 比如说,如果一切和配置有关的动作都由Config组件来完成,
  16. * 一切加载的动作都由Loader来完成,
  17. * 试想一下,如果我要加载Config组件,那么,必须得通过Loader来加载,
  18. * 所以Loader必须比Config要更早实例化,
  19. * 但是如果Loader实例化的时候需要一些和Loader有关的配置信息才能实例化呢?
  20. * 那就必须通过Config来为它取得配置信息。
  21. * 这里就出现了鸡和鸡蛋的问题。。
  22. * 我之前写自己的框架也纠结过这样的问题,后来参考了YII框架,
  23. * 发现它里面其实都有同样的问题,它里面有个Exception的组件,
  24. * 但是在加载这个Exception组件之前,在加载其它组件的时候,
  25. * 如果出错了,那谁来处理异常和错误信息呢?答案就是先定义一些公共的函数。
  26. * 所以这些公共函数就很好地解决了这个问题,这也是为什么Common.php要很早被引入。
  27. *
  28. */
  29.  
  30. // ------------------------------------------------------------------------
  31.  
  32. /**
  33. * Determines if the current version of PHP is greater then the supplied value
  34. */
  35. if ( ! function_exists('is_php'))
  36. {
  37. //判断当前php版本是不是$version以上的。调用version_compare()这个函数。
  38. function is_php($version = '5.0.0')
  39. {
  40. static $_is_php;
  41. $version = (string)$version;
  42.  
  43. if ( ! isset($_is_php[$version]))
  44. {
  45. //PHP_VERION能够获得当前php版本。
  46. $_is_php[$version] = (version_compare(PHP_VERSION, $version) < 0)
  47. ? FALSE : TRUE;
  48. }
  49.  
  50. return $_is_php[$version];
  51. }
  52. }
  53.  
  54. // ------------------------------------------------------------------------
  55.  
  56. /**
  57. * Tests for file writability
  58. */
  59. if ( ! function_exists('is_really_writable'))
  60. {
  61. //该函数和php官方手册上面写的差不多,兼容linux/Unix和windows系统:
  62. //http://www.php.net/manual/en/function.is-writable.php
  63. function is_really_writable($file)
  64. {
  65.  
  66. //DIRECTORY_SEPARATOR是系统的目录分割符。利用它的值可以知道当前是不是linux系统。
  67. if (DIRECTORY_SEPARATOR == '/' AND @ini_get("safe_mode") == FALSE)
  68. {
  69. //如果是linux系统的话,那么可以直接调用此方法来判断文件是否可写。
  70. return is_writable($file);
  71. }
  72.  
  73. //如果是windows系统,则尝试写入一个文件来判断。
  74.  
  75. if (is_dir($file))
  76. {
  77. //如果是目录,则创建一个随机命名的文件。
  78. $file = rtrim($file, '/').'/'.md5(mt_rand(1,100).mt_rand(1,100));
  79.  
  80. //如果文件不能创建,则返回不可写。
  81. if (($fp = @fopen($file, FOPEN_WRITE_CREATE)) === FALSE)
  82. {
  83. return FALSE;
  84. }
  85.  
  86. fclose($fp);
  87. //删除刚才的文件。
  88. @chmod($file, DIR_WRITE_MODE);
  89. @unlink($file);
  90. return TRUE;
  91. }
  92. elseif ( ! is_file($file)
  93. OR ($fp = @fopen($file, FOPEN_WRITE_CREATE)) === FALSE)
  94. {
  95. //如果是一个文件,而通过写入方式打不开,则返回不可写。
  96. return FALSE;
  97. }
  98.  
  99. fclose($fp);
  100. return TRUE;
  101. }
  102. }
  103.  
  104. // ------------------------------------------------------------------------
  105.  
  106. /**
  107. * Class registry
  108. */
  109. if ( ! function_exists('load_class'))
  110. {
  111. //加载类。默认是加载libraries里面的,如果要加载核心组件,$directory就为'core'
  112. function &load_class($class, $directory = 'libraries', $prefix = 'CI_')
  113. {
  114.  
  115. //用一个静态数组,保存已经加载过的类的实例,防止多次实例消耗资源,实现单例化。
  116. static $_classes = array();
  117. // Does the class exist? If so, we're done...
  118. if (isset($_classes[$class]))
  119. {
  120. return $_classes[$class];//如果已经保存在这里,就返回它。
  121. }
  122. $name = FALSE;
  123. //这里,如果应用目录下有和系统目录下相同的类的话,优先引入应用目录,也就是你自己定义的。
  124. foreach (array(APPPATH, BASEPATH) as $path)
  125. {
  126. if (file_exists($path.$directory.'/'.$class.'.php'))
  127. {
  128. $name = $prefix.$class;
  129. if (class_exists($name) === FALSE)
  130. {
  131. require($path.$directory.'/'.$class.'.php');
  132. }
  133. break;
  134. }
  135. }
  136. //这里就用到的前缀扩展,如果在应用目录相应的目录下,有自己写的一些对CI库的扩展,
  137. //那么我们加载的是它,而不是原来的。因为我们写的扩展是继承了CI原来的。
  138. //所以可以看出,即使是CI的核心组件(core/下面的)我们都可以为之进行扩展。
  139. if (file_exists(APPPATH.$directory.'/'
  140. .config_item('subclass_prefix').$class.'.php'))
  141. {
  142. $name = config_item('subclass_prefix').$class;
  143. if (class_exists($name) === FALSE)
  144. {
  145. require(APPPATH.$directory.'/'.config_item('subclass_prefix').$class.'.php');
  146. }
  147. }
  148. // Did we find the class?
  149. if ($name === FALSE)
  150. {
  151. //这里用的是exit();来提示错误,而不是用show_error();
  152. //这是因为这个load_class的错误有可能
  153. //在加载Exception组件之前发。
  154. exit('Unable to locate the specified class: '.$class.'.php');
  155. }
  156. // Keep track of what we just loaded
  157. //这个函数只是用来记录已经被加载过的类的类名而已。
  158. is_loaded($class);
  159. $_classes[$class] = new $name();
  160. return $_classes[$class];
  161. }
  162. }
  163. // --------------------------------------------------------------------
  164. /**
  165. * Keeps track of which libraries have been loaded. This function is
  166. * called by the load_class() function above
  167. */
  168. if ( ! function_exists('is_loaded'))
  169. {
  170. //记录有哪些类是已经被加载的。
  171. function is_loaded($class = '')
  172. {
  173. static $_is_loaded = array();
  174. if ($class != '')
  175. {
  176. $_is_loaded[strtolower($class)] = $class;
  177. }
  178. return $_is_loaded;
  179. }
  180. }
  181. // ------------------------------------------------------------------------
  182. /**
  183. * Loads the main config.php file
  184. */
  185. if ( ! function_exists('get_config'))
  186. {
  187. //这个是读取配置信息的函数,在Config类被实例化之前,由它暂负责。
  188. //而在Config类被实例化之前,我们需要读取的配置信息,
  189. //其实仅仅是config.php这个主配置文件的。所以这个方法是不能读出
  190. //config/下其它配置文件的信息的。
  191. //这个$replace参数,是提供一个临时替换配置信息的机会,仅一次,因为执行一次后,
  192. //配置信息都会保存在静态变量$_config中,不能改变。
  193. function &get_config($replace = array())
  194. {
  195. static $_config;
  196. if (isset($_config))
  197. {
  198. return $_config[0];
  199. }
  200. // Is the config file in the environment folder?
  201. if ( ! defined('ENVIRONMENT') OR
  202. ! file_exists($file_path = APPPATH.'config/'.ENVIRONMENT.'/config.php'))
  203. {
  204. $file_path = APPPATH.'config/config.php';
  205. }
  206. // Fetch the config file
  207. if ( ! file_exists($file_path))
  208. {
  209. exit('The configuration file does not exist.');
  210. }
  211. require($file_path);
  212. // Does the $config array exist in the file?
  213. if ( ! isset($config) OR ! is_array($config))
  214. {
  215. exit('Your config file does not appear to be formatted correctly.');
  216. }
  217. // Are any values being dynamically replaced?
  218. if (count($replace) > 0)
  219. {
  220. foreach ($replace as $key => $val)
  221. {
  222. if (isset($config[$key]))
  223. {
  224. $config[$key] = $val;
  225. }
  226. }
  227. }
  228. return $_config[0] =& $config;
  229. }
  230. }
  231. // ------------------------------------------------------------------------
  232. /**
  233. * Returns the specified config item
  234. */
  235. if ( ! function_exists('config_item'))
  236. {
  237. //取得配置数组中某个元素。
  238. function config_item($item)
  239. {
  240. static $_config_item = array();
  241. if ( ! isset($_config_item[$item]))
  242. {
  243. $config =& get_config();
  244. if ( ! isset($config[$item]))
  245. {
  246. return FALSE;
  247. }
  248. $_config_item[$item] = $config[$item];
  249. }
  250. return $_config_item[$item];
  251. }
  252. }
  253. // ------------------------------------------------------------------------
  254. /**
  255. * Error Handler
  256. */
  257. //这里的show_error和下面的show_404以及 _exception_handler这三个错误的处理,
  258. //实质都是由Exception组件完成的。
  259. //详见core/Exception.php.
  260. if ( ! function_exists('show_error'))
  261. {
  262. function show_error($message, $status_code = 500,
  263. $heading = 'An Error Was Encountered')
  264. {
  265. $_error =& load_class('Exceptions', 'core');
  266. echo $_error->show_error($heading, $message, 'error_general', $status_code);
  267. exit;
  268. }
  269. }
  270. // ------------------------------------------------------------------------
  271. /**
  272. * 404 Page Handler
  273. */
  274. if ( ! function_exists('show_404'))
  275. {
  276. function show_404($page = '', $log_error = TRUE)
  277. {
  278. $_error =& load_class('Exceptions', 'core');
  279. $_error->show_404($page, $log_error);
  280. exit;
  281. }
  282. }
  283. // ------------------------------------------------------------------------
  284. /**
  285. * Error Logging Interface
  286. */
  287. if ( ! function_exists('log_message'))
  288. {
  289. function log_message($level = 'error', $message, $php_error = FALSE)
  290. {
  291. static $_log;
  292. if (config_item('log_threshold') == 0)
  293. {
  294. return;
  295. }
  296. $_log =& load_class('Log');
  297. $_log->write_log($level, $message, $php_error);
  298. }
  299. }
  300. // ------------------------------------------------------------------------
  301. /**
  302. * Set HTTP Status Header
  303. */
  304. if ( ! function_exists('set_status_header'))
  305. {
  306. function set_status_header($code = 200, $text = '')
  307. {
  308. //此函数构造一个响应头。$stati为响应码与其响应说明。
  309. $stati = array(
  310. 200 => 'OK',
  311. 201 => 'Created',
  312. 202 => 'Accepted',
  313. 203 => 'Non-Authoritative Information',
  314. 204 => 'No Content',
  315. 205 => 'Reset Content',
  316. 206 => 'Partial Content',
  317. 300 => 'Multiple Choices',
  318. 301 => 'Moved Permanently',
  319. 302 => 'Found',
  320. 304 => 'Not Modified',
  321. 305 => 'Use Proxy',
  322. 307 => 'Temporary Redirect',
  323. 400 => 'Bad Request',
  324. 401 => 'Unauthorized',
  325. 403 => 'Forbidden',
  326. 404 => 'Not Found',
  327. 405 => 'Method Not Allowed',
  328. 406 => 'Not Acceptable',
  329. 407 => 'Proxy Authentication Required',
  330. 408 => 'Request Timeout',
  331. 409 => 'Conflict',
  332. 410 => 'Gone',
  333. 411 => 'Length Required',
  334. 412 => 'Precondition Failed',
  335. 413 => 'Request Entity Too Large',
  336. 414 => 'Request-URI Too Long',
  337. 415 => 'Unsupported Media Type',
  338. 416 => 'Requested Range Not Satisfiable',
  339. 417 => 'Expectation Failed',
  340. 500 => 'Internal Server Error',
  341. 501 => 'Not Implemented',
  342. 502 => 'Bad Gateway',
  343. 503 => 'Service Unavailable',
  344. 504 => 'Gateway Timeout',
  345. 505 => 'HTTP Version Not Supported'
  346. );
  347. //如果调用此函数本身出错,则发出一个错误。
  348. if ($code == '' OR ! is_numeric($code))
  349. {
  350. show_error('Status codes must be numeric', 500);
  351. }
  352. if (isset($stati[$code]) AND $text == '')
  353. {
  354. $text = $stati[$code];
  355. }
  356. //如果$text为空,一般是因为调用此函数时,给的响应码不正确同时又没有写出响应报文信息。
  357. if ($text == '')
  358. {
  359. show_error('No status text available.
  360. Please check your status code number or supply your own message text.', 500);
  361. }
  362. //取得当前协议。
  363. $server_protocol = (isset($_SERVER['SERVER_PROTOCOL']))
  364. ? $_SERVER['SERVER_PROTOCOL'] : FALSE;
  365. //php_sapi_name()方法可以获得PHP与服务器之间的接口类型,
  366. //下面是以cgi类型和以服务器模块形式类型的不同发出响应的方式。
  367. if (substr(php_sapi_name(), 0, 3) == 'cgi')
  368. {
  369. header("Status: {$code} {$text}", TRUE);
  370. }
  371. elseif ($server_protocol == 'HTTP/1.1' OR $server_protocol == 'HTTP/1.0')
  372. {
  373. header($server_protocol." {$code} {$text}", TRUE, $code);
  374. }
  375. else
  376. {
  377. header("HTTP/1.1 {$code} {$text}", TRUE, $code);
  378. }
  379. }
  380. }
  381. // --------------------------------------------------------------------
  382. /**
  383. * Exception Handler
  384. */
  385. if ( ! function_exists('_exception_handler'))
  386. {
  387. //在CodeIgniter.php中执行set_error_handler('_exception_handler');后,
  388. //以后一切非致命(非fatal)错误信息都由它处理。
  389. //触发错误的时候,会产生几个参数,错误级别(号),错误信息,错误文件,错误行。
  390. function _exception_handler($severity, $message, $filepath, $line)
  391. {
  392. /**
  393. * 有关错误等级的内容可看:
  394. * http://blog.163.com/wu_guoqing/blog/static/19653701820127269312682/
  395. * E_STRICT对于大多数情况来说都是没多大作用的错误提示,
  396. * 这里CI把它屏蔽掉,如果实在要查看,可以查看日志文件。
  397. */
  398. if ($severity == E_STRICT)
  399. {
  400. return;
  401. }
  402. //真正起到错误处理的是Exception组件。
  403. $_error =& load_class('Exceptions', 'core');
  404. /*
  405. * 注意下面的符号是&而不是&&,php的错误等级的值都是有规律的,
  406. * 例如1,2,4,8...(1,10,100,1000)等等,实际上,php是通过位运算来实现的,
  407. * 使得错误控制更精准。(类似linux的权限控制,rwx)
  408. * 在设置error_reporting()的时候,可通过E_XX|E_YY|E_ZZ的形式来设置,
  409. * 而判断的时候则通过E_XX&error_repoorting()来判断
  410. * E_XX有没有设置。例如1,10,100,1000相或|,则值为1111,
  411. * 则以后1,10,100,1000中任意一个与1111相&,值都为它本身。
  412. * 而E_ALL可以看到是除E_STRICT之外其它等级的“或(|)运算”。
  413. * 个人理解,之所以E_ALL的值是不同版本有所不同的,是
  414. * 因为有时候会加入新的错误级别,从而导致这个E_ALL的值也不一样。
  415. */
  416. if (($severity & error_reporting()) == $severity)
  417. {
  418. //如果符合则交给Exception组件的show_php_error();进行处理。
  419. $_error->show_php_error($severity, $message, $filepath, $line);
  420. }
  421. //下面两行只是根据配置文件判断要不要log错误信息而已。
  422. if (config_item('log_threshold') == 0)
  423. {
  424. return;
  425. }
  426. $_error->log_exception($severity, $message, $filepath, $line);
  427. }
  428. }
  429. // --------------------------------------------------------------------
  430. /**
  431. * Remove Invisible Characters
  432. */
  433. if ( ! function_exists('remove_invisible_characters'))
  434. {
  435. function remove_invisible_characters($str, $url_encoded = TRUE)
  436. {
  437. $non_displayables = array();
  438. // every control character except newline (dec 10)
  439. // carriage return (dec 13), and horizontal tab (dec 09)
  440. if ($url_encoded)
  441. {
  442. $non_displayables[] = '/%0[0-8bcef]/'; // url encoded 00-08, 11, 12, 14, 15
  443. $non_displayables[] = '/%1[0-9a-f]/'; // url encoded 16-31
  444. }
  445. $non_displayables[] = '/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S';
  446. // 00-08, 11, 12, 14-31, 127
  447. do
  448. {
  449. $str = preg_replace($non_displayables, '', $str, -1, $count);
  450. }
  451. while ($count);
  452. return $str;
  453. }
  454. }
  455. // ------------------------------------------------------------------------
  456. /**
  457. * Returns HTML escaped variable
  458. */
  459. if ( ! function_exists('html_escape'))
  460. {
  461. function html_escape($var)
  462. {
  463. if (is_array($var))
  464. {
  465. return array_map('html_escape', $var);
  466. }
  467. else
  468. {
  469. return htmlspecialchars($var, ENT_QUOTES, config_item('charset'));
  470. }
  471. }
  472. }

CI框架 -- 核心文件 之 Common.php的更多相关文章

  1. CI框架 -- 核心文件 之 Hooks.php

    钩子 - 扩展框架核心 CodeIgniter 的钩子特性提供了一种方法来修改框架的内部运作流程,而无需修改 核心文件.CodeIgniter 的运行遵循着一个特定的流程,你可以参考这个页面的 应用程 ...

  2. CI框架 -- 核心文件 之 Exceptions.php

    使用CI框架,我们通常使用一下三个函数处理错误: show_error('消息' [, int $status_code = 500 ] ) show_404('页面' [, 'log_error'] ...

  3. CI框架 -- 核心文件 之 Loader.php(加载器)

    顾名思义,装载器就是加载元素的,使用CI时,经常加载的有: 加载类库文件:$this->load->library()   加载视图文件:$this->load->view() ...

  4. CI框架 -- 核心文件 之 config.php

    Config:该文件包含CI_Config类,这个类包含启用配置文件来管理的方法 /** * 加载配置文件 * * @param string $file 配置文件名 * @param bool $u ...

  5. CI框架 -- 核心文件 之 Output.php(输出类文件)

    CI输出类Output.php的功能是将最终web页面发送给浏览器,这里面的东西可能是你用的最少的.你使用装载器加载了一个视图文件, 这个视图文件的内容会自动传递给输出类对象, 然后呢,在方法执行完毕 ...

  6. CI框架 -- 核心文件 之 Benchmark.php

    Benchmark.php文件中定义的CI_Benchmark类可以让你标记点,并计算它们之间的时间差.还可以显示内存消耗. Benchmarking类库,它是被系统自动被加载的,不需要手工加载 cl ...

  7. CI框架 -- 核心文件 之 Model.php

    class CI_Model { /** * Class constructor * * @return void */ public function __construct() { log_mes ...

  8. CI框架 -- 核心文件 之 Input.php(输入数据处理文件)

    class CI_Input { //用户ip地址 protected $ip_address = FALSE; //用户浏览器地址 protected $user_agent = FALSE; // ...

  9. CI框架 -- 核心文件 之 Lang.php(加载语言包)

    <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); class CI_Lang { var $l ...

随机推荐

  1. 【ARM】2440裸机系列-RTC数字时钟

    功能 裸机程序,实现LCD显示数字时钟 主要代码   1)背景绘制 void Brush_ U32 c) { int x,y ; for ( y = 0 ; y < LCD_HEIGHT ; y ...

  2. 使用BC库解密出现no such provider错误

    使用BC库解密出现no such provider错误 错误提示如下: Exception in thread "main" java.security.NoSuchProvide ...

  3. hive的row_number()函数

    hive的row_number()函数 功能 用于分组,比方说依照uuid分组 组内可以依照某个属性排序,比方说依照uuid分组,组内按照imei排序 语法为row_number() over (pa ...

  4. Upgrade Bash to 4+ on OS X

    http://buddylindsey.com/upgrade-bash-to-4-on-os-x/ Unfortunately, Apple has decided to ship an old v ...

  5. PowerShell实现基于SharePoint的网站HomePage Auto-Upgrade Solution

    *** Solution Auto-Upgrade Solution Tuesday, January 06, 2015 PS:该项目为公司项目,我还是给他的名字屏蔽掉吧,这是我用PowerShell ...

  6. hdu3938(最小生成树,推荐)

    题意描述:简单的讲就是,给你一张无向图,求有多少条路径使得路径上的花费小于L,这里路径上的花费是这样规定的,a.b两点之间的多条路径中的最长的边最小值! 思路:这题目有多个询问,肯定要用离线输出.思路 ...

  7. logrotate 日志轮询(转存)

    1.建立/etc/logrotate.d/nginx文件[1] vim /etc/logrotate.d/nginx 2.写入如下内容: /var/log/nginx/*log { daily rot ...

  8. Notepad++的右键菜单

    这种方法可以重复利用,如果下次它又消失了,你可以再导入一次就OK了.比如我们创建一个叫 notepad++.reg的文件,将下面的内容拷贝进去保存 Windows Registry Editor Ve ...

  9. RGB与CMYK以及加色与减色

    转载自:http://blog.csdn.net/tohmin/article/details/4761930 黑白色配色与RGB.CMYK 1. 光学三原色与印刷三原色 光学与印刷三原色, 相信大家 ...

  10. C#学习笔记(19)——使用IComparer(百度文库)

    说明(2017-7-24 19:15:15): 1. 百度文库里的一篇文章,觉得讲的比较好.原文地址:https://wenku.baidu.com/view/b53cd250ad02de80d4d8 ...