接下来我们探讨的就是它的common.php,它提供了一些函数,这些函数都是功能的罗列,但是不代表它和类一点关系也没有,它往往是在该函数里实例化一个类,然后调用该类的方法.这是一个核心的函数库,它提供的一些功能也是非常的重要,比如类的加载,html标签的转化,读取配置,显示错误,日志处理,http状态的处理等等吧.
这一节说实话,要想说点东西,恐怕不容易,我们还是仔细分析下它的源码,这里用到的较多的类就是Exception类,即异常类,然后就是Log类,即日志类.好的,多说无益,一切尽在代码里,代码我是通读的,而且做了自我感觉详尽的注释,对我自己和对大家都是很有帮助的把.
如下几点尤其值得注意:
1.静态数据的应用,可以避免多次初始化,很多数据往往是一次初始化,其他调用的时候只需要返回即可了,所以,静态数据很重要,而诸如配置数据又会经常调用.
2.在函数里调用类的实例,会让oop和aop的使用互补起来.
3.参数为数组和为数组的元素之间的灵活转化,很好用,这一点也希望大家能够经常想到.
4.还有一个是用到了操作系统的判断,这一点对于php这种学习主要在windows下,应用主要在linux下的语言很重要的.
-
<?php
-
//如果没有定义基路径,则不是从入口文件引用的,为非法引用
-
if ( ! defined('BASEPATH')) exit('No direct script access allowed');
-
-
-
//is_php()函数用来判断版本,返回布尔值.
-
//参数为php的版本.
-
if ( ! function_exists('is_php'))
-
{
-
function is_php($version = '5.0.0')
-
{
-
//注意该变量为静态的,就是说只需要判断一次即可.
-
//该变量为布尔值.
-
static $_is_php;
-
//转化为字符串格式.
-
$version = (string)$version;
-
-
if ( ! isset($_is_php[$version]))
-
{
-
//如果版本低于5.0.0,则返回false,否则返回true.
-
$_is_php[$version] = (version_compare(PHP_VERSION, $version) < 0) ? FALSE : TRUE;
-
}
-
-
return $_is_php[$version];
-
}
-
}
-
-
//该函数用于判断是否可写,并且需要做到和操作系统无关
-
if ( ! function_exists('is_really_writable'))
-
{
-
function is_really_writable($file)
-
{
-
//如果我们在一个Unix服务器并且关了安全模式的话,我们调用is_writeable
-
if (DIRECTORY_SEPARATOR == '/' AND @ini_get("safe_mode") == FALSE)
-
{
-
return is_writable($file);
-
}
-
-
-
//否则就是windows服务器,
-
//对于$file是一个目录的话,则随机生成文件试一试.
-
if (is_dir($file))
-
{
-
$file = rtrim($file, '/').'/'.md5(mt_rand(1,100).mt_rand(1,100));
-
//如果文件打不开,则返回false.
-
if (($fp = @fopen($file, FOPEN_WRITE_CREATE)) === FALSE)
-
{
-
return FALSE;
-
}
-
-
fclose($fp);
-
@chmod($file, DIR_WRITE_MODE);
-
@unlink($file);
-
return TRUE;
-
}
-
//如果$file不是一个文件或者虽然是文件,但是它文件打开失败.
-
elseif ( ! is_file($file) OR ($fp = @fopen($file, FOPEN_WRITE_CREATE)) === FALSE)
-
{
-
return FALSE;
-
}
-
-
fclose($fp);
-
return TRUE;
-
}
-
}
-
-
-
-
//该函数用于加载一个类,返回类型为该类的一个实例.
-
if ( ! function_exists('load_class'))
-
{
-
function &load_class($class, $directory = 'libraries', $prefix = 'CI_')
-
{
-
//已经加载的类组成的数组.
-
static $_classes = array();
-
-
//如果该类存在,直接返回
-
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;
-
}
-
}
-
-
//如果这个类是一个扩展类,则我们同样可以加载它.
-
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');
-
}
-
}
-
-
// 我们是否找到了这个类.
-
if ($name === FALSE)
-
{
-
//我们使用exit()而不是show_error(),这样可以避免在异常类里面自身的引用.
-
exit('Unable to locate the specified class: '.$class.'.php');
-
}
-
-
//保持我们加载过的类的痕迹.
-
is_loaded($class);
-
-
$_classes[$class] = new $name();
-
return $_classes[$class];
-
}
-
}
-
-
//判断类是否被加载
-
if ( ! function_exists('is_loaded'))
-
{
-
function &is_loaded($class = '')
-
{
-
static $_is_loaded = array();
-
-
if ($class != '')
-
{
-
$_is_loaded[strtolower($class)] = $class;
-
}
-
-
return $_is_loaded;
-
}
-
}
-
-
-
-
//读取配置,并且提供了替换配置的功能.
-
if ( ! function_exists('get_config'))
-
{
-
function &get_config($replace = array())
-
{
-
static $_config;//定义为静态的,一次初始化即永久引用
-
//如果配置项已存在,说明已经完成了,直接返回即可.
-
//这里也说明了,如果该函数执行过,那么$replace将起不到作用.
-
if (isset($_config))
-
{
-
return $_config[0];
-
}
-
-
// 判断是否指定了应用环境
-
if ( ! defined('ENVIRONMENT') OR ! file_exists($file_path = APPPATH.'config/'.ENVIRONMENT.'/config.php'))
-
{
-
//注意APPPATH是在入口文件里定义的
-
$file_path = APPPATH.'config/config.php';
-
-
}
-
//判断文件路径是否存在.
-
if ( ! file_exists($file_path))
-
{
-
exit('The configuration file does not exist.');
-
}
-
-
require($file_path);
-
-
//注意这里的$config是在$file_path里定义的,此处引用它
-
if ( ! isset($config) OR ! is_array($config))
-
{
-
//说明配置文件存在,但是配置文件里的格式写错了.
-
exit('Your config file does not appear to be formatted correctly.');
-
}
-
-
//检验是否需要动态的替换.
-
if (count($replace) > 0)
-
{
-
foreach ($replace as $key => $val)
-
{
-
if (isset($config[$key]))
-
{
-
$config[$key] = $val;
-
}
-
}
-
}
-
-
return $_config[0] =& $config;
-
}
-
}
-
-
// 返回特定的配置项
-
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];
-
}
-
}
-
-
-
//展示错误,需要调用Exceptions这个类.
-
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,其实也是在Exception类里面定义好的一个方法.
-
if ( ! function_exists('show_404'))
-
{
-
function show_404($page = '', $log_error = TRUE)
-
{
-
$_error =& load_class('Exceptions', 'core');
-
$_error->show_404($page, $log_error);
-
exit;
-
}
-
}
-
-
//日志信息,这里用到了Log类来处理.
-
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);
-
}
-
}
-
-
//设置http状态码
-
if ( ! function_exists('set_status_header'))
-
{
-
function set_status_header($code = 200, $text = '')
-
{
-
$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];
-
}
-
-
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;
-
-
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);
-
}
-
}
-
}
-
-
//异常处理函数.
-
if ( ! function_exists('_exception_handler'))
-
{
-
function _exception_handler($severity, $message, $filepath, $line)
-
{
-
//我们不需要修改"strict"模式,因为它们会包含很多多余信息的
-
//比如你在php5的环境下运行php4风格的代码(比如不加public等前缀)
-
//你会得到一个不被赞成的可以忽视的注意点.
-
if ($severity == E_STRICT)
-
{
-
return;
-
}
-
//实例化异常类,此处的$_error为Exception的一个实例.
-
$_error =& load_class('Exceptions', 'core');
-
-
//我们根据报错级别 来判断是否需要显示该错误.
-
if (($severity & error_reporting()) == $severity)
-
{
-
$_error->show_php_error($severity, $message, $filepath, $line);
-
}
-
-
//我们是否需要把它们记录到日志里去??
-
if (config_item('log_threshold') == 0)
-
{
-
return;
-
}
-
-
$_error->log_exception($severity, $message, $filepath, $line);
-
}
-
}
-
-
//删除不可见字符
-
if ( ! function_exists('remove_invisible_characters'))
-
{
-
function remove_invisible_characters($str, $url_encoded = TRUE)
-
{
-
$non_displayables = array();
-
-
-
//#10表示换行,#13表示回车,#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;
-
}
-
}
-
-
-
//html_escape把相应的html标签转化为字符串,可以在一定程度上防注入.
-
if ( ! function_exists('html_escape'))
-
{
-
function html_escape($var)
-
{
-
-
if (is_array($var))
-
{
-
//返回经过html_escape单个处理之后的数组.
-
return array_map('html_escape', $var);
-
}
-
else
-
{
-
//把html标签转化为字符串.
-
return htmlspecialchars($var, ENT_QUOTES, config_item('charset'));
-
}
-
}
-
}
阅读(1646) | 评论(1) | 转发(0) |