CI框架 -- 核心文件 之 Common.php
system/core/Common.php 文件中可以定义 公共函数,我们可以在这里定义自己的公共函数。在任何情况下你都能够使用这些函数。使用他们不需要载入任何类库或辅助函数。
接下来分析下该文件中自带的一些方法:
- <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
- // ------------------------------------------------------------------------
- /**
- * Common Functions
- */
- /**
- * 为什么还要定义这些全局函数呢?比如说,下面有很多函数,
- * 如get_config()、config_item()这两个方法不是应该由
- * core/Config.php这个组件去做么?那个load_class()不应该由core/Loader.php去做么?
- * 把这些函数定义出来貌似 感觉架构变得不那么优雅,有点多余。
- * 其实是出于这样一种情况:
- * 比如说,如果一切和配置有关的动作都由Config组件来完成,
- * 一切加载的动作都由Loader来完成,
- * 试想一下,如果我要加载Config组件,那么,必须得通过Loader来加载,
- * 所以Loader必须比Config要更早实例化,
- * 但是如果Loader实例化的时候需要一些和Loader有关的配置信息才能实例化呢?
- * 那就必须通过Config来为它取得配置信息。
- * 这里就出现了鸡和鸡蛋的问题。。
- * 我之前写自己的框架也纠结过这样的问题,后来参考了YII框架,
- * 发现它里面其实都有同样的问题,它里面有个Exception的组件,
- * 但是在加载这个Exception组件之前,在加载其它组件的时候,
- * 如果出错了,那谁来处理异常和错误信息呢?答案就是先定义一些公共的函数。
- * 所以这些公共函数就很好地解决了这个问题,这也是为什么Common.php要很早被引入。
- *
- */
- // ------------------------------------------------------------------------
- /**
- * Determines if the current version of PHP is greater then the supplied value
- */
- if ( ! function_exists('is_php'))
- {
- //判断当前php版本是不是$version以上的。调用version_compare()这个函数。
- function is_php($version = '5.0.0')
- {
- static $_is_php;
- $version = (string)$version;
- if ( ! isset($_is_php[$version]))
- {
- //PHP_VERION能够获得当前php版本。
- $_is_php[$version] = (version_compare(PHP_VERSION, $version) < 0)
- ? FALSE : TRUE;
- }
- return $_is_php[$version];
- }
- }
- // ------------------------------------------------------------------------
- /**
- * Tests for file writability
- */
- if ( ! function_exists('is_really_writable'))
- {
- //该函数和php官方手册上面写的差不多,兼容linux/Unix和windows系统:
- //http://www.php.net/manual/en/function.is-writable.php
- function is_really_writable($file)
- {
- //DIRECTORY_SEPARATOR是系统的目录分割符。利用它的值可以知道当前是不是linux系统。
- if (DIRECTORY_SEPARATOR == '/' AND @ini_get("safe_mode") == FALSE)
- {
- //如果是linux系统的话,那么可以直接调用此方法来判断文件是否可写。
- return is_writable($file);
- }
- //如果是windows系统,则尝试写入一个文件来判断。
- if (is_dir($file))
- {
- //如果是目录,则创建一个随机命名的文件。
- $file = rtrim($file, '/').'/'.md5(mt_rand(1,100).mt_rand(1,100));
- //如果文件不能创建,则返回不可写。
- if (($fp = @fopen($file, FOPEN_WRITE_CREATE)) === FALSE)
- {
- return FALSE;
- }
- fclose($fp);
- //删除刚才的文件。
- @chmod($file, DIR_WRITE_MODE);
- @unlink($file);
- return TRUE;
- }
- elseif ( ! is_file($file)
- OR ($fp = @fopen($file, FOPEN_WRITE_CREATE)) === FALSE)
- {
- //如果是一个文件,而通过写入方式打不开,则返回不可写。
- return FALSE;
- }
- fclose($fp);
- return TRUE;
- }
- }
- // ------------------------------------------------------------------------
- /**
- * Class registry
- */
- if ( ! function_exists('load_class'))
- {
- //加载类。默认是加载libraries里面的,如果要加载核心组件,$directory就为'core'
- function &load_class($class, $directory = 'libraries', $prefix = 'CI_')
- {
- //用一个静态数组,保存已经加载过的类的实例,防止多次实例消耗资源,实现单例化。
- static $_classes = array();
- // Does the class exist? If so, we're done...
- if (isset($_classes[$class]))
- {
- return $_classes[$class];//如果已经保存在这里,就返回它。
- }
- $name = FALSE;
- //这里,如果应用目录下有和系统目录下相同的类的话,优先引入应用目录,也就是你自己定义的。
- foreach (array(APPPATH, BASEPATH) as $path)
- {
- if (file_exists($path.$directory.'/'.$class.'.php'))
- {
- $name = $prefix.$class;
- if (class_exists($name) === FALSE)
- {
- require($path.$directory.'/'.$class.'.php');
- }
- break;
- }
- }
- //这里就用到的前缀扩展,如果在应用目录相应的目录下,有自己写的一些对CI库的扩展,
- //那么我们加载的是它,而不是原来的。因为我们写的扩展是继承了CI原来的。
- //所以可以看出,即使是CI的核心组件(core/下面的)我们都可以为之进行扩展。
- if (file_exists(APPPATH.$directory.'/'
- .config_item('subclass_prefix').$class.'.php'))
- {
- $name = config_item('subclass_prefix').$class;
- if (class_exists($name) === FALSE)
- {
- require(APPPATH.$directory.'/'.config_item('subclass_prefix').$class.'.php');
- }
- }
- // Did we find the class?
- if ($name === FALSE)
- {
- //这里用的是exit();来提示错误,而不是用show_error();
- //这是因为这个load_class的错误有可能
- //在加载Exception组件之前发。
- exit('Unable to locate the specified class: '.$class.'.php');
- }
- // Keep track of what we just loaded
- //这个函数只是用来记录已经被加载过的类的类名而已。
- is_loaded($class);
- $_classes[$class] = new $name();
- return $_classes[$class];
- }
- }
- // --------------------------------------------------------------------
- /**
- * Keeps track of which libraries have been loaded. This function is
- * called by the load_class() function above
- */
- if ( ! function_exists('is_loaded'))
- {
- //记录有哪些类是已经被加载的。
- function is_loaded($class = '')
- {
- static $_is_loaded = array();
- if ($class != '')
- {
- $_is_loaded[strtolower($class)] = $class;
- }
- return $_is_loaded;
- }
- }
- // ------------------------------------------------------------------------
- /**
- * Loads the main config.php file
- */
- if ( ! function_exists('get_config'))
- {
- //这个是读取配置信息的函数,在Config类被实例化之前,由它暂负责。
- //而在Config类被实例化之前,我们需要读取的配置信息,
- //其实仅仅是config.php这个主配置文件的。所以这个方法是不能读出
- //config/下其它配置文件的信息的。
- //这个$replace参数,是提供一个临时替换配置信息的机会,仅一次,因为执行一次后,
- //配置信息都会保存在静态变量$_config中,不能改变。
- function &get_config($replace = array())
- {
- static $_config;
- if (isset($_config))
- {
- return $_config[0];
- }
- // Is the config file in the environment folder?
- if ( ! defined('ENVIRONMENT') OR
- ! file_exists($file_path = APPPATH.'config/'.ENVIRONMENT.'/config.php'))
- {
- $file_path = APPPATH.'config/config.php';
- }
- // Fetch the config file
- if ( ! file_exists($file_path))
- {
- exit('The configuration file does not exist.');
- }
- require($file_path);
- // Does the $config array exist in the file?
- if ( ! isset($config) OR ! is_array($config))
- {
- exit('Your config file does not appear to be formatted correctly.');
- }
- // Are any values being dynamically replaced?
- if (count($replace) > 0)
- {
- foreach ($replace as $key => $val)
- {
- if (isset($config[$key]))
- {
- $config[$key] = $val;
- }
- }
- }
- return $_config[0] =& $config;
- }
- }
- // ------------------------------------------------------------------------
- /**
- * Returns the specified config item
- */
- if ( ! function_exists('config_item'))
- {
- //取得配置数组中某个元素。
- function config_item($item)
- {
- static $_config_item = array();
- if ( ! isset($_config_item[$item]))
- {
- $config =& get_config();
- if ( ! isset($config[$item]))
- {
- return FALSE;
- }
- $_config_item[$item] = $config[$item];
- }
- return $_config_item[$item];
- }
- }
- // ------------------------------------------------------------------------
- /**
- * Error Handler
- */
- //这里的show_error和下面的show_404以及 _exception_handler这三个错误的处理,
- //实质都是由Exception组件完成的。
- //详见core/Exception.php.
- if ( ! function_exists('show_error'))
- {
- function show_error($message, $status_code = 500,
- $heading = 'An Error Was Encountered')
- {
- $_error =& load_class('Exceptions', 'core');
- echo $_error->show_error($heading, $message, 'error_general', $status_code);
- exit;
- }
- }
- // ------------------------------------------------------------------------
- /**
- * 404 Page Handler
- */
- if ( ! function_exists('show_404'))
- {
- function show_404($page = '', $log_error = TRUE)
- {
- $_error =& load_class('Exceptions', 'core');
- $_error->show_404($page, $log_error);
- exit;
- }
- }
- // ------------------------------------------------------------------------
- /**
- * Error Logging Interface
- */
- if ( ! function_exists('log_message'))
- {
- function log_message($level = 'error', $message, $php_error = FALSE)
- {
- static $_log;
- if (config_item('log_threshold') == 0)
- {
- return;
- }
- $_log =& load_class('Log');
- $_log->write_log($level, $message, $php_error);
- }
- }
- // ------------------------------------------------------------------------
- /**
- * Set HTTP Status Header
- */
- if ( ! function_exists('set_status_header'))
- {
- function set_status_header($code = 200, $text = '')
- {
- //此函数构造一个响应头。$stati为响应码与其响应说明。
- $stati = array(
- 200 => 'OK',
- 201 => 'Created',
- 202 => 'Accepted',
- 203 => 'Non-Authoritative Information',
- 204 => 'No Content',
- 205 => 'Reset Content',
- 206 => 'Partial Content',
- 300 => 'Multiple Choices',
- 301 => 'Moved Permanently',
- 302 => 'Found',
- 304 => 'Not Modified',
- 305 => 'Use Proxy',
- 307 => 'Temporary Redirect',
- 400 => 'Bad Request',
- 401 => 'Unauthorized',
- 403 => 'Forbidden',
- 404 => 'Not Found',
- 405 => 'Method Not Allowed',
- 406 => 'Not Acceptable',
- 407 => 'Proxy Authentication Required',
- 408 => 'Request Timeout',
- 409 => 'Conflict',
- 410 => 'Gone',
- 411 => 'Length Required',
- 412 => 'Precondition Failed',
- 413 => 'Request Entity Too Large',
- 414 => 'Request-URI Too Long',
- 415 => 'Unsupported Media Type',
- 416 => 'Requested Range Not Satisfiable',
- 417 => 'Expectation Failed',
- 500 => 'Internal Server Error',
- 501 => 'Not Implemented',
- 502 => 'Bad Gateway',
- 503 => 'Service Unavailable',
- 504 => 'Gateway Timeout',
- 505 => 'HTTP Version Not Supported'
- );
- //如果调用此函数本身出错,则发出一个错误。
- if ($code == '' OR ! is_numeric($code))
- {
- show_error('Status codes must be numeric', 500);
- }
- if (isset($stati[$code]) AND $text == '')
- {
- $text = $stati[$code];
- }
- //如果$text为空,一般是因为调用此函数时,给的响应码不正确同时又没有写出响应报文信息。
- if ($text == '')
- {
- show_error('No status text available.
- Please check your status code number or supply your own message text.', 500);
- }
- //取得当前协议。
- $server_protocol = (isset($_SERVER['SERVER_PROTOCOL']))
- ? $_SERVER['SERVER_PROTOCOL'] : FALSE;
- //php_sapi_name()方法可以获得PHP与服务器之间的接口类型,
- //下面是以cgi类型和以服务器模块形式类型的不同发出响应的方式。
- if (substr(php_sapi_name(), 0, 3) == 'cgi')
- {
- header("Status: {$code} {$text}", TRUE);
- }
- elseif ($server_protocol == 'HTTP/1.1' OR $server_protocol == 'HTTP/1.0')
- {
- header($server_protocol." {$code} {$text}", TRUE, $code);
- }
- else
- {
- header("HTTP/1.1 {$code} {$text}", TRUE, $code);
- }
- }
- }
- // --------------------------------------------------------------------
- /**
- * Exception Handler
- */
- if ( ! function_exists('_exception_handler'))
- {
- //在CodeIgniter.php中执行set_error_handler('_exception_handler');后,
- //以后一切非致命(非fatal)错误信息都由它处理。
- //触发错误的时候,会产生几个参数,错误级别(号),错误信息,错误文件,错误行。
- function _exception_handler($severity, $message, $filepath, $line)
- {
- /**
- * 有关错误等级的内容可看:
- * http://blog.163.com/wu_guoqing/blog/static/19653701820127269312682/
- * E_STRICT对于大多数情况来说都是没多大作用的错误提示,
- * 这里CI把它屏蔽掉,如果实在要查看,可以查看日志文件。
- */
- if ($severity == E_STRICT)
- {
- return;
- }
- //真正起到错误处理的是Exception组件。
- $_error =& load_class('Exceptions', 'core');
- /*
- * 注意下面的符号是&而不是&&,php的错误等级的值都是有规律的,
- * 例如1,2,4,8...(1,10,100,1000)等等,实际上,php是通过位运算来实现的,
- * 使得错误控制更精准。(类似linux的权限控制,rwx)
- * 在设置error_reporting()的时候,可通过E_XX|E_YY|E_ZZ的形式来设置,
- * 而判断的时候则通过E_XX&error_repoorting()来判断
- * E_XX有没有设置。例如1,10,100,1000相或|,则值为1111,
- * 则以后1,10,100,1000中任意一个与1111相&,值都为它本身。
- * 而E_ALL可以看到是除E_STRICT之外其它等级的“或(|)运算”。
- * 个人理解,之所以E_ALL的值是不同版本有所不同的,是
- * 因为有时候会加入新的错误级别,从而导致这个E_ALL的值也不一样。
- */
- if (($severity & error_reporting()) == $severity)
- {
- //如果符合则交给Exception组件的show_php_error();进行处理。
- $_error->show_php_error($severity, $message, $filepath, $line);
- }
- //下面两行只是根据配置文件判断要不要log错误信息而已。
- if (config_item('log_threshold') == 0)
- {
- return;
- }
- $_error->log_exception($severity, $message, $filepath, $line);
- }
- }
- // --------------------------------------------------------------------
- /**
- * Remove Invisible Characters
- */
- if ( ! function_exists('remove_invisible_characters'))
- {
- function remove_invisible_characters($str, $url_encoded = TRUE)
- {
- $non_displayables = array();
- // every control character except newline (dec 10)
- // carriage return (dec 13), and horizontal tab (dec 09)
- if ($url_encoded)
- {
- $non_displayables[] = '/%0[0-8bcef]/'; // url encoded 00-08, 11, 12, 14, 15
- $non_displayables[] = '/%1[0-9a-f]/'; // url encoded 16-31
- }
- $non_displayables[] = '/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S';
- // 00-08, 11, 12, 14-31, 127
- do
- {
- $str = preg_replace($non_displayables, '', $str, -1, $count);
- }
- while ($count);
- return $str;
- }
- }
- // ------------------------------------------------------------------------
- /**
- * Returns HTML escaped variable
- */
- if ( ! function_exists('html_escape'))
- {
- function html_escape($var)
- {
- if (is_array($var))
- {
- return array_map('html_escape', $var);
- }
- else
- {
- return htmlspecialchars($var, ENT_QUOTES, config_item('charset'));
- }
- }
- }
CI框架 -- 核心文件 之 Common.php的更多相关文章
- CI框架 -- 核心文件 之 Hooks.php
钩子 - 扩展框架核心 CodeIgniter 的钩子特性提供了一种方法来修改框架的内部运作流程,而无需修改 核心文件.CodeIgniter 的运行遵循着一个特定的流程,你可以参考这个页面的 应用程 ...
- CI框架 -- 核心文件 之 Exceptions.php
使用CI框架,我们通常使用一下三个函数处理错误: show_error('消息' [, int $status_code = 500 ] ) show_404('页面' [, 'log_error'] ...
- CI框架 -- 核心文件 之 Loader.php(加载器)
顾名思义,装载器就是加载元素的,使用CI时,经常加载的有: 加载类库文件:$this->load->library() 加载视图文件:$this->load->view() ...
- CI框架 -- 核心文件 之 config.php
Config:该文件包含CI_Config类,这个类包含启用配置文件来管理的方法 /** * 加载配置文件 * * @param string $file 配置文件名 * @param bool $u ...
- CI框架 -- 核心文件 之 Output.php(输出类文件)
CI输出类Output.php的功能是将最终web页面发送给浏览器,这里面的东西可能是你用的最少的.你使用装载器加载了一个视图文件, 这个视图文件的内容会自动传递给输出类对象, 然后呢,在方法执行完毕 ...
- CI框架 -- 核心文件 之 Benchmark.php
Benchmark.php文件中定义的CI_Benchmark类可以让你标记点,并计算它们之间的时间差.还可以显示内存消耗. Benchmarking类库,它是被系统自动被加载的,不需要手工加载 cl ...
- CI框架 -- 核心文件 之 Model.php
class CI_Model { /** * Class constructor * * @return void */ public function __construct() { log_mes ...
- CI框架 -- 核心文件 之 Input.php(输入数据处理文件)
class CI_Input { //用户ip地址 protected $ip_address = FALSE; //用户浏览器地址 protected $user_agent = FALSE; // ...
- CI框架 -- 核心文件 之 Lang.php(加载语言包)
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); class CI_Lang { var $l ...
随机推荐
- 【ARM】2440裸机系列-RTC数字时钟
功能 裸机程序,实现LCD显示数字时钟 主要代码 1)背景绘制 void Brush_ U32 c) { int x,y ; for ( y = 0 ; y < LCD_HEIGHT ; y ...
- 使用BC库解密出现no such provider错误
使用BC库解密出现no such provider错误 错误提示如下: Exception in thread "main" java.security.NoSuchProvide ...
- hive的row_number()函数
hive的row_number()函数 功能 用于分组,比方说依照uuid分组 组内可以依照某个属性排序,比方说依照uuid分组,组内按照imei排序 语法为row_number() over (pa ...
- 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 ...
- PowerShell实现基于SharePoint的网站HomePage Auto-Upgrade Solution
*** Solution Auto-Upgrade Solution Tuesday, January 06, 2015 PS:该项目为公司项目,我还是给他的名字屏蔽掉吧,这是我用PowerShell ...
- hdu3938(最小生成树,推荐)
题意描述:简单的讲就是,给你一张无向图,求有多少条路径使得路径上的花费小于L,这里路径上的花费是这样规定的,a.b两点之间的多条路径中的最长的边最小值! 思路:这题目有多个询问,肯定要用离线输出.思路 ...
- logrotate 日志轮询(转存)
1.建立/etc/logrotate.d/nginx文件[1] vim /etc/logrotate.d/nginx 2.写入如下内容: /var/log/nginx/*log { daily rot ...
- Notepad++的右键菜单
这种方法可以重复利用,如果下次它又消失了,你可以再导入一次就OK了.比如我们创建一个叫 notepad++.reg的文件,将下面的内容拷贝进去保存 Windows Registry Editor Ve ...
- RGB与CMYK以及加色与减色
转载自:http://blog.csdn.net/tohmin/article/details/4761930 黑白色配色与RGB.CMYK 1. 光学三原色与印刷三原色 光学与印刷三原色, 相信大家 ...
- C#学习笔记(19)——使用IComparer(百度文库)
说明(2017-7-24 19:15:15): 1. 百度文库里的一篇文章,觉得讲的比较好.原文地址:https://wenku.baidu.com/view/b53cd250ad02de80d4d8 ...