* G('begin'); // 记录开始标记位
 * // ... 区间运行代码
 * G('end'); // 记录结束标签位
 * echo G('begin','end',6); // 统计区间运行时间 精确到小数后6位
 * echo G('begin','end','m'); // 统计区间内存使用情况
 * 如果end标记位没有定义,则会自动以当前作为标记位
 * 其中统计内存使用需要 MEMORY_LIMIT_ON 常量为true才有效
 * 
 * @param string $start 开始标签
 * @param string $end 结束标签
 * @param integer|string $dec 小数位或者m
 * @return mixed
 */
function G($start,$end='',$dec=4) {
    static $_info       =   array();
    static $_mem        =   array();
    if(is_float($end)) { // 记录时间
        $_info[$start]  =   $end;
    }elseif(!empty($end)){ // 统计时间和内存使用
        if(!isset($_info[$end])) $_info[$end]       =  microtime(TRUE);
        if(MEMORY_LIMIT_ON && $dec=='m'){
            if(!isset($_mem[$end])) $_mem[$end]     =  memory_get_usage();
            return number_format(($_mem[$end]-$_mem[$start])/1024);
        }else{
            return number_format(($_info[$end]-$_info[$start]),$dec);
        }
    }else{ // 记录时间和内存使用
        $_info[$start]  =  microtime(TRUE);
        if(MEMORY_LIMIT_ON) $_mem[$start]           =  memory_get_usage();
    }
}
/**
 * 获取和设置语言定义(不区分大小写)
 * @param string|array $name 语言变量
 * @param string $value 语言值
 * @return mixed
 */
function L($name=null, $value=null) {
    static $_lang = array();
    // 空参数返回所有定义
    if (empty($name))
        return $_lang;
    // 判断语言获取(或设置)
    // 若不存在,直接返回全大写$name
    if (is_string($name)) {
        $name = strtoupper($name);
        if (is_null($value))
            return isset($_lang[$name]) ? $_lang[$name] : $name;
        $_lang[$name] = $value; // 语言定义
        return;
    }
    // 批量定义
    if (is_array($name))
        $_lang = array_merge($_lang, array_change_key_case($name, CASE_UPPER));
    return;
}
/**
 * 添加和获取页面Trace记录
 * @param string $value 变量
 * @param string $label 标签
 * @param string $level 日志级别
 * @param boolean $record 是否记录日志
 * @return void
 */
function trace($value='[think]',$label='',$level='DEBUG',$record=false) {
    return Think\Think::trace($value,$label,$level,$record);
}
/**
 * 编译文件
 * @param string $filename 文件名
 * @return string
 */
function compile($filename) {
    $content    =   php_strip_whitespace($filename);
    $content    =   trim(substr($content, 5));
    // 替换预编译指令
    $content    =   preg_replace('/\/\/\[RUNTIME\](.*?)\/\/\[\/RUNTIME\]/s', '', $content);
    if(0===strpos($content,'namespace')){
        $content    =   preg_replace('/namespace\s(.*?);/','namespace \\1{',$content,1);
    }else{
        $content    =   'namespace {'.$content;
    }
    if ('?>' == substr($content, -2))
        $content    = substr($content, 0, -2);
    return $content.'}';
}
/**
 * 获取输入参数 支持过滤和默认值
 * 使用方法:
 * 
 * I('id',0); 获取id参数 自动判断get或者post
 * I('post.name','','htmlspecialchars'); 获取$_POST['name']
 * I('get.'); 获取$_GET
 * 
 * @param string $name 变量的名称 支持指定类型
 * @param mixed $default 不存在的时候默认值
 * @param mixed $filter 参数过滤方法
 * @param mixed $datas 要获取的额外数据源
 * @return mixed
 */
function I($name,$default='',$filter=null,$datas=null) {
	if(strpos($name,'/')){ // 指定修饰符
		list($name,$type) 	=	explode('/',$name,2);
	}
    if(strpos($name,'.')) { // 指定参数来源
        list($method,$name) =   explode('.',$name,2);
    }else{ // 默认为自动判断
        $method =   'param';
    }
    switch(strtolower($method)) {
        case 'get'     :   $input =& $_GET;break;
        case 'post'    :   $input =& $_POST;break;
        case 'put'     :   parse_str(file_get_contents('php://input'), $input);break;
        case 'param'   :
            switch($_SERVER['REQUEST_METHOD']) {
                case 'POST':
                    $input  =  $_POST;
                    break;
                case 'PUT':
                    parse_str(file_get_contents('php://input'), $input);
                    break;
                default:
                    $input  =  $_GET;
            }
            break;
        case 'path'    :   
            $input  =   array();
            if(!empty($_SERVER['PATH_INFO'])){
                $depr   =   C('URL_PATHINFO_DEPR');
                $input  =   explode($depr,trim($_SERVER['PATH_INFO'],$depr));            
            }
            break;
        case 'request' :   $input =& $_REQUEST;   break;
        case 'session' :   $input =& $_SESSION;   break;
        case 'cookie'  :   $input =& $_COOKIE;    break;
        case 'server'  :   $input =& $_SERVER;    break;
        case 'globals' :   $input =& $GLOBALS;    break;
        case 'data'    :   $input =& $datas;      break;
        default:
            return NULL;
    }
    if(''==$name) { // 获取全部变量
        $data       =   $input;
        $filters    =   isset($filter)?$filter:C('DEFAULT_FILTER');
        if($filters) {
            if(is_string($filters)){
                $filters    =   explode(',',$filters);
            }
            foreach($filters as $filter){
                $data   =   array_map_recursive($filter,$data); // 参数过滤
            }
        }
    }elseif(isset($input[$name])) { // 取值操作
        $data       =   $input[$name];
        $filters    =   isset($filter)?$filter:C('DEFAULT_FILTER');
        if($filters) {
            if(is_string($filters)){
                $filters    =   explode(',',$filters);
            }elseif(is_int($filters)){
                $filters    =   array($filters);
            }
            
            foreach($filters as $filter){
                if(function_exists($filter)) {
                    $data   =   is_array($data) ? array_map_recursive($filter,$data) : $filter($data); // 参数过滤
                }elseif(0===strpos($filter,'/')){
                	// 支持正则验证
                	if(1 !== preg_match($filter,(string)$data)){
                		return   isset($default) ? $default : NULL;
                	}
                }else{
                    $data   =   filter_var($data,is_int($filter) ? $filter : filter_id($filter));
                    if(false === $data) {
                        return   isset($default) ? $default : NULL;
                    }
                }
            }
        }
        if(!empty($type)){
        	switch(strtolower($type)){
        		case 's':   // 字符串
        			$data 	=	(string)$data;
        			break;
        		case 'a':	// 数组
        			$data 	=	(array)$data;
        			break;
        		case 'd':	// 数字
        			$data 	=	(int)$data;
        			break;
        		case 'f':	// 浮点
        			$data 	=	(float)$data;
        			break;
        		case 'b':	// 布尔
        			$data 	=	(boolean)$data;
        			break;
        	}
        }
    }else{ // 变量默认值
        $data       =    isset($default)?$default:NULL;
    }
    is_array($data) && array_walk_recursive($data,'think_filter');
    return $data;
}
function array_map_recursive($filter, $data) {
     $result = array();
     foreach ($data as $key => $val) {
         $result[$key] = is_array($val)
             ? array_map_recursive($filter, $val)
             : call_user_func($filter, $val);
     }
     return $result;
 }
/**
 * 设置和获取统计数据
 * 使用方法:
 * 
 * N('db',1); // 记录数据库操作次数
 * N('read',1); // 记录读取次数
 * echo N('db'); // 获取当前页面数据库的所有操作次数
 * echo N('read'); // 获取当前页面读取次数
 * 
 * @param string $key 标识位置
 * @param integer $step 步进值
 * @return mixed
 */
function N($key, $step=0,$save=false) {
    static $_num    = array();
    if (!isset($_num[$key])) {
        $_num[$key] = (false !== $save)? S('N_'.$key) :  0;
    }
    if (empty($step))
        return $_num[$key];
    else
        $_num[$key] = $_num[$key] + (int) $step;
    if(false !== $save){ // 保存结果
        S('N_'.$key,$_num[$key],$save);
    }
}
/**
 * 字符串命名风格转换
 * type 0 将Java风格转换为C的风格 1 将C风格转换为Java的风格
 * @param string $name 字符串
 * @param integer $type 转换类型
 * @return string
 */
function parse_name($name, $type=0) {
    if ($type) {
        return ucfirst(preg_replace_callback('/_([a-zA-Z])/', function($match){return strtoupper($match[1]);}, $name));
    } else {
        return strtolower(trim(preg_replace("/[A-Z]/", "_\\0", $name), "_"));
    }
}
/**
 * 优化的require_once
 * @param string $filename 文件地址
 * @return boolean
 */
function require_cache($filename) {
    static $_importFiles = array();
    if (!isset($_importFiles[$filename])) {
        if (file_exists_case($filename)) {
            require $filename;
            $_importFiles[$filename] = true;
        } else {
            $_importFiles[$filename] = false;
        }
    }
    return $_importFiles[$filename];
}
/**
 * 区分大小写的文件存在判断
 * @param string $filename 文件地址
 * @return boolean
 */
function file_exists_case($filename) {
    if (is_file($filename)) {
        if (IS_WIN && APP_DEBUG) {
            if (basename(realpath($filename)) != basename($filename))
                return false;
        }
        return true;
    }
    return false;
}
/**
 * 导入所需的类库 同java的Import 本函数有缓存功能
 * @param string $class 类库命名空间字符串
 * @param string $baseUrl 起始路径
 * @param string $ext 导入的文件扩展名
 * @return boolean
 */
function import($class, $baseUrl = '', $ext=EXT) {
    static $_file = array();
    $class = str_replace(array('.', '#'), array('/', '.'), $class);
    if (isset($_file[$class . $baseUrl]))
        return true;
    else
        $_file[$class . $baseUrl] = true;
    $class_strut     = explode('/', $class);
    if (empty($baseUrl)) {
        if ('@' == $class_strut[0] || MODULE_NAME == $class_strut[0]) {
            //加载当前模块的类库
            $baseUrl = MODULE_PATH;
            $class   = substr_replace($class, '', 0, strlen($class_strut[0]) + 1);
        }elseif (in_array($class_strut[0],array('Think','Org','Behavior','Com','Vendor')) || is_dir(LIB_PATH.$class_strut[0])) {
            // 系统类库包和第三方类库包
            $baseUrl = LIB_PATH;
        }else { // 加载其他模块的类库
            $baseUrl = APP_PATH;
        }
    }
    if (substr($baseUrl, -1) != '/')
        $baseUrl    .= '/';
    $classfile       = $baseUrl . $class . $ext;
    if (!class_exists(basename($class),false)) {
        // 如果类不存在 则导入类库文件
        return require_cache($classfile);
    }
}
/**
 * 基于命名空间方式导入函数库
 * load('@.Util.Array')
 * @param string $name 函数库命名空间字符串
 * @param string $baseUrl 起始路径
 * @param string $ext 导入的文件扩展名
 * @return void
 */
function load($name, $baseUrl='', $ext='.php') {
    $name = str_replace(array('.', '#'), array('/', '.'), $name);
    if (empty($baseUrl)) {
        if (0 === strpos($name, '@/')) {//加载当前模块函数库
            $baseUrl    =   MODULE_PATH.'Common/';
            $name       =   substr($name, 2);
        } else { //加载其他模块函数库
            $array      =   explode('/', $name);
            $baseUrl    =   APP_PATH . array_shift($array).'/Common/';
            $name       =   implode('/',$array);
        }
    }
    if (substr($baseUrl, -1) != '/')
        $baseUrl       .= '/';
    require_cache($baseUrl . $name . $ext);
}
/**
 * 快速导入第三方框架类库 所有第三方框架的类库文件统一放到 系统的Vendor目录下面
 * @param string $class 类库
 * @param string $baseUrl 基础目录
 * @param string $ext 类库后缀
 * @return boolean
 */
function vendor($class, $baseUrl = '', $ext='.php') {
    if (empty($baseUrl))
        $baseUrl = VENDOR_PATH;
    return import($class, $baseUrl, $ext);
}
/**
 * D函数用于实例化模型类 格式 [资源://][模块/]模型
 * @param string $name 资源地址
 * @param string $layer 模型层名称
 * @return Model
 */
function D($name='',$layer='') {
    if(empty($name)) return new Think\Model;
    static $_model  =   array();
    $layer          =   $layer? : C('DEFAULT_M_LAYER');
    if(isset($_model[$name.$layer]))
        return $_model[$name.$layer];
    $class          =   parse_res_name($name,$layer);
    if(class_exists($class)) {
        $model      =   new $class(basename($name));
    }elseif(false === strpos($name,'/')){
        // 自动加载公共模块下面的模型
        $class      =   '\\Common\\'.$layer.'\\'.$name.$layer;
        $model      =   class_exists($class)? new $class($name) : new Think\Model($name);
    }else {
        Think\Log::record('D方法实例化没找到模型类'.$class,Think\Log::NOTICE);
        $model      =   new Think\Model(basename($name));
    }
    $_model[$name.$layer]  =  $model;
    return $model;
}
/**
 * M函数用于实例化一个没有模型文件的Model
 * @param string $name Model名称 支持指定基础模型 例如 MongoModel:User
 * @param string $tablePrefix 表前缀
 * @param mixed $connection 数据库连接信息
 * @return Model
 */
function M($name='', $tablePrefix='',$connection='') {
    static $_model  = array();
    if(strpos($name,':')) {
        list($class,$name)    =  explode(':',$name);
    }else{
        $class      =   'Think\\Model';
    }
    $guid           =   (is_array($connection)?implode('',$connection):$connection).$tablePrefix . $name . '_' . $class;
    if (!isset($_model[$guid]))
        $_model[$guid] = new $class($name,$tablePrefix,$connection);
    return $_model[$guid];
}
/**
 * 解析资源地址并导入类库文件
 * 例如 module/controller addon://module/behavior
 * @param string $name 资源地址 格式:[扩展://][模块/]资源名
 * @param string $layer 分层名称
 * @return string
 */
function parse_res_name($name,$layer,$level=1){
    if(strpos($name,'://')) {// 指定扩展资源
        list($extend,$name)  =   explode('://',$name);
    }else{
        $extend  =   '';
    }
    if(strpos($name,'/') && substr_count($name, '/')>=$level){ // 指定模块
        list($module,$name) =  explode('/',$name,2);
    }else{
        $module =   MODULE_NAME;
    }
    $array  =   explode('/',$name);
    $class  =   $module.'\\'.$layer;
    foreach($array as $name){
        $class  .=   '\\'.parse_name($name, 1);
    }
    // 导入资源类库
    if($extend){ // 扩展资源
        $class      =   $extend.'\\'.$class;
    }
    return $class.$layer;
}
/**
 * A函数用于实例化控制器 格式:[资源://][模块/]控制器
 * @param string $name 资源地址
 * @param string $layer 控制层名称
 * @param integer $level 控制器层次
 * @return Controller|false
 */
function A($name,$layer='',$level='') {
    static $_action = array();
    $layer  =   $layer? : C('DEFAULT_C_LAYER');
    $level  =   $level? : ($layer == C('DEFAULT_C_LAYER')?C('CONTROLLER_LEVEL'):1);
    if(isset($_action[$name.$layer]))
        return $_action[$name.$layer];
    $class  =   parse_res_name($name,$layer,$level);
    if(class_exists($class)) {
        $action             =   new $class();
        $_action[$name.$layer]     =   $action;
        return $action;
    }else {
        return false;
    }
}
/**
 * 远程调用控制器的操作方法 URL 参数格式 [资源://][模块/]控制器/操作
 * @param string $url 调用地址
 * @param string|array $vars 调用参数 支持字符串和数组
 * @param string $layer 要调用的控制层名称
 * @return mixed
 */
function R($url,$vars=array(),$layer='') {
    $info   =   pathinfo($url);
    $action =   $info['basename'];
    $module =   $info['dirname'];
    $class  =   A($module,$layer);
    if($class){
        if(is_string($vars)) {
            parse_str($vars,$vars);
        }
        return call_user_func_array(array(&$class,$action.C('ACTION_SUFFIX')),$vars);
    }else{
        return false;
    }
}
/**
 * 执行某个行为
 * @param string $name 行为名称
 * @param Mixed $params 传入的参数
 * @return void
 */
function B($name, &$params=NULL) {
    if(strpos($name,'/')){
        list($name,$tag) = explode('/',$name);
    }else{
        $tag     =   'run';
    }
    return \Think\Hook::exec($name,$tag,$params);
}
/**
 * 去除代码中的空白和注释
 * @param string $content 代码内容
 * @return string
 */
function strip_whitespace($content) {
    $stripStr   = '';
    //分析php源码
    $tokens     = token_get_all($content);
    $last_space = false;
    for ($i = 0, $j = count($tokens); $i < $j; $i++) {
        if (is_string($tokens[$i])) {
            $last_space = false;
            $stripStr  .= $tokens[$i];
        } else {
            switch ($tokens[$i][0]) {
                //过滤各种PHP注释
                case T_COMMENT:
                case T_DOC_COMMENT:
                    break;
                //过滤空格
                case T_WHITESPACE:
                    if (!$last_space) {
                        $stripStr  .= ' ';
                        $last_space = true;
                    }
                    break;
                case T_START_HEREDOC:
                    $stripStr .= "<<' . $label . htmlspecialchars($output, ENT_QUOTES) . ''; } } if ($echo) { echo($output); return null; }else return $output; } /** * URL重定向 * @param string $url 重定向的URL地址 * @param integer $time 重定向的等待时间(秒) * @param string $msg 重定向前的提示信息 * @return void */ function redirect($url, $time=0, $msg='') { //多行URL地址支持 $url = str_replace(array("\n", "\r"), '', $url); if (empty($msg)) $msg = "系统将在{$time}秒之后自动跳转到{$url}!"; if (!headers_sent()) { // redirect if (0 === $time) { header('Location: ' . $url); } else { header("refresh:{$time};url={$url}"); echo($msg); } exit(); } else { $str = ""; if ($time != 0) $str .= $msg; exit($str); } } /** * 缓存管理 * @param mixed $name 缓存名称,如果为数组表示进行缓存设置 * @param mixed $value 缓存值 * @param mixed $options 缓存参数 * @return mixed */ function S($name,$value='',$options=null) { static $cache = ''; if(is_array($options) && empty($cache)){ // 缓存操作的同时初始化 $type = isset($options['type'])?$options['type']:''; $cache = Think\Cache::getInstance($type,$options); }elseif(is_array($name)) { // 缓存初始化 $type = isset($name['type'])?$name['type']:''; $cache = Think\Cache::getInstance($type,$name); return $cache; }elseif(empty($cache)) { // 自动初始化 $cache = Think\Cache::getInstance(); } if(''=== $value){ // 获取缓存 return $cache->get($name); }elseif(is_null($value)) { // 删除缓存 return $cache->rm($name); }else { // 缓存数据 if(is_array($options)) { $expire = isset($options['expire'])?$options['expire']:NULL; }else{ $expire = is_numeric($options)?$options:NULL; } return $cache->set($name, $value, $expire); } } /** * 快速文件数据读取和保存 针对简单类型数据 字符串、数组 * @param string $name 缓存名称 * @param mixed $value 缓存值 * @param string $path 缓存路径 * @return mixed */ function F($name, $value='', $path=DATA_PATH) { static $_cache = array(); $filename = $path . $name . '.php'; if ('' !== $value) { if (is_null($value)) { // 删除缓存 if(false !== strpos($name,'*')){ return false; // TODO }else{ unset($_cache[$name]); return Think\Storage::unlink($filename,'F'); } } else { Think\Storage::put($filename,serialize($value),'F'); // 缓存数据 $_cache[$name] = $value; return ; } } // 获取缓存数据 if (isset($_cache[$name])) return $_cache[$name]; if (Think\Storage::has($filename,'F')){ $value = unserialize(Think\Storage::read($filename,'F')); $_cache[$name] = $value; } else { $value = false; } return $value; } /** * 根据PHP各种类型变量生成唯一标识号 * @param mixed $mix 变量 * @return string */ function to_guid_string($mix) { if (is_object($mix)) { return spl_object_hash($mix); } elseif (is_resource($mix)) { $mix = get_resource_type($mix) . strval($mix); } else { $mix = serialize($mix); } return md5($mix); } /** * XML编码 * @param mixed $data 数据 * @param string $root 根节点名 * @param string $item 数字索引的子节点名 * @param string $attr 根节点属性 * @param string $id 数字索引子节点key转换的属性名 * @param string $encoding 数据编码 * @return string */ function xml_encode($data, $root='think', $item='item', $attr='', $id='id', $encoding='utf-8') { if(is_array($attr)){ $_attr = array(); foreach ($attr as $key => $value) { $_attr[] = "{$key}=\"{$value}\""; } $attr = implode(' ', $_attr); } $attr = trim($attr); $attr = empty($attr) ? '' : " {$attr}"; $xml = ""; $xml .= "<{$root}{$attr}>"; $xml .= data_to_xml($data, $item, $id); $xml .= "{$root}>"; return $xml; } /** * 数据XML编码 * @param mixed $data 数据 * @param string $item 数字索引时的节点名称 * @param string $id 数字索引key转换为的属性名 * @return string */ function data_to_xml($data, $item='item', $id='id') { $xml = $attr = ''; foreach ($data as $key => $val) { if(is_numeric($key)){ $id && $attr = " {$id}=\"{$key}\""; $key = $item; } $xml .= "<{$key}{$attr}>"; $xml .= (is_array($val) || is_object($val)) ? data_to_xml($val, $item, $id) : $val; $xml .= "{$key}>"; } return $xml; } /** * session管理函数 * @param string|array $name session名称 如果为数组则表示进行session设置 * @param mixed $value session值 * @return mixed */ function session($name,$value='') { $prefix = C('SESSION_PREFIX'); if(is_array($name)) { // session初始化 在session_start 之前调用 if(isset($name['prefix'])) C('SESSION_PREFIX',$name['prefix']); if(C('VAR_SESSION_ID') && isset($_REQUEST[C('VAR_SESSION_ID')])){ session_id($_REQUEST[C('VAR_SESSION_ID')]); }elseif(isset($name['id'])) { session_id($name['id']); } if('common' != APP_MODE){ // 其它模式可能不支持 ini_set('session.auto_start', 0); } if(isset($name['name'])) session_name($name['name']); if(isset($name['path'])) session_save_path($name['path']); if(isset($name['domain'])) ini_set('session.cookie_domain', $name['domain']); if(isset($name['expire'])) ini_set('session.gc_maxlifetime', $name['expire']); if(isset($name['use_trans_sid'])) ini_set('session.use_trans_sid', $name['use_trans_sid']?1:0); if(isset($name['use_cookies'])) ini_set('session.use_cookies', $name['use_cookies']?1:0); if(isset($name['cache_limiter'])) session_cache_limiter($name['cache_limiter']); if(isset($name['cache_expire'])) session_cache_expire($name['cache_expire']); if(isset($name['type'])) C('SESSION_TYPE',$name['type']); if(C('SESSION_TYPE')) { // 读取session驱动 $type = C('SESSION_TYPE'); $class = strpos($type,'\\')? $type : 'Think\\Session\\Driver\\'. ucwords(strtolower($type)); $hander = new $class(); session_set_save_handler( array(&$hander,"open"), array(&$hander,"close"), array(&$hander,"read"), array(&$hander,"write"), array(&$hander,"destroy"), array(&$hander,"gc")); } // 启动session if(C('SESSION_AUTO_START')) session_start(); }elseif('' === $value){ if(0===strpos($name,'[')) { // session 操作 if('[pause]'==$name){ // 暂停session session_write_close(); }elseif('[start]'==$name){ // 启动session session_start(); }elseif('[destroy]'==$name){ // 销毁session $_SESSION = array(); session_unset(); session_destroy(); }elseif('[regenerate]'==$name){ // 重新生成id session_regenerate_id(); } }elseif(0===strpos($name,'?')){ // 检查session $name = substr($name,1); if(strpos($name,'.')){ // 支持数组 list($name1,$name2) = explode('.',$name); return $prefix?isset($_SESSION[$prefix][$name1][$name2]):isset($_SESSION[$name1][$name2]); }else{ return $prefix?isset($_SESSION[$prefix][$name]):isset($_SESSION[$name]); } }elseif(is_null($name)){ // 清空session if($prefix) { unset($_SESSION[$prefix]); }else{ $_SESSION = array(); } }elseif($prefix){ // 获取session if(strpos($name,'.')){ list($name1,$name2) = explode('.',$name); return isset($_SESSION[$prefix][$name1][$name2])?$_SESSION[$prefix][$name1][$name2]:null; }else{ return isset($_SESSION[$prefix][$name])?$_SESSION[$prefix][$name]:null; } }else{ if(strpos($name,'.')){ list($name1,$name2) = explode('.',$name); return isset($_SESSION[$name1][$name2])?$_SESSION[$name1][$name2]:null; }else{ return isset($_SESSION[$name])?$_SESSION[$name]:null; } } }elseif(is_null($value)){ // 删除session if($prefix){ unset($_SESSION[$prefix][$name]); }else{ unset($_SESSION[$name]); } }else{ // 设置session if($prefix){ if (!is_array($_SESSION[$prefix])) { $_SESSION[$prefix] = array(); } $_SESSION[$prefix][$name] = $value; }else{ $_SESSION[$name] = $value; } } } /** * Cookie 设置、获取、删除 * @param string $name cookie名称 * @param mixed $value cookie值 * @param mixed $options cookie参数 * @return mixed */ function cookie($name, $value='', $option=null) { // 默认设置 $config = array( 'prefix' => C('COOKIE_PREFIX'), // cookie 名称前缀 'expire' => C('COOKIE_EXPIRE'), // cookie 保存时间 'path' => C('COOKIE_PATH'), // cookie 保存路径 'domain' => C('COOKIE_DOMAIN'), // cookie 有效域名 ); // 参数设置(会覆盖黙认设置) if (!is_null($option)) { if (is_numeric($option)) $option = array('expire' => $option); elseif (is_string($option)) parse_str($option, $option); $config = array_merge($config, array_change_key_case($option)); } // 清除指定前缀的所有cookie if (is_null($name)) { if (empty($_COOKIE)) return; // 要删除的cookie前缀,不指定则删除config设置的指定前缀 $prefix = empty($value) ? $config['prefix'] : $value; if (!empty($prefix)) {// 如果前缀为空字符串将不作处理直接返回 foreach ($_COOKIE as $key => $val) { if (0 === stripos($key, $prefix)) { setcookie($key, '', time() - 3600, $config['path'], $config['domain']); unset($_COOKIE[$key]); } } } return; } $name = $config['prefix'] . $name; if ('' === $value) { if(isset($_COOKIE[$name])){ $value = $_COOKIE[$name]; if(0===strpos($value,'think:')){ $value = substr($value,6); return array_map('urldecode',json_decode(MAGIC_QUOTES_GPC?stripslashes($value):$value,true)); }else{ return $value; } }else{ return null; } } else { if (is_null($value)) { setcookie($name, '', time() - 3600, $config['path'], $config['domain']); unset($_COOKIE[$name]); // 删除指定cookie } else { // 设置cookie if(is_array($value)){ $value = 'think:'.json_encode(array_map('urlencode',$value)); } $expire = !empty($config['expire']) ? time() + intval($config['expire']) : 0; setcookie($name, $value, $expire, $config['path'], $config['domain']); $_COOKIE[$name] = $value; } } } /** * 加载动态扩展文件 * @return void */ function load_ext_file($path) { // 加载自定义外部文件 if(C('LOAD_EXT_FILE')) { $files = explode(',',C('LOAD_EXT_FILE')); foreach ($files as $file){ $file = $path.'Common/'.$file.'.php'; if(is_file($file)) include $file; } } // 加载自定义的动态配置文件 if(C('LOAD_EXT_CONFIG')) { $configs = C('LOAD_EXT_CONFIG'); if(is_string($configs)) $configs = explode(',',$configs); foreach ($configs as $key=>$config){ $file = $path.'Conf/'.$config.'.php'; if(is_file($file)) { is_numeric($key)?C(include $file):C($key,include $file); } } } } /** * 获取客户端IP地址 * @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字 * @return mixed */ function get_client_ip($type = 0) { $type = $type ? 1 : 0; static $ip = NULL; if ($ip !== NULL) return $ip[$type]; if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); $pos = array_search('unknown',$arr); if(false !== $pos) unset($arr[$pos]); $ip = trim($arr[0]); }elseif (isset($_SERVER['HTTP_CLIENT_IP'])) { $ip = $_SERVER['HTTP_CLIENT_IP']; }elseif (isset($_SERVER['REMOTE_ADDR'])) { $ip = $_SERVER['REMOTE_ADDR']; } // IP地址合法验证 $long = sprintf("%u",ip2long($ip)); $ip = $long ? array($ip, $long) : array('0.0.0.0', 0); return $ip[$type]; } /** * 发送HTTP状态 * @param integer $code 状态码 * @return void */ function send_http_status($code) { static $_status = array( // Success 2xx 200 => 'OK', // Redirection 3xx 301 => 'Moved Permanently', 302 => 'Moved Temporarily ', // 1.1 // Client Error 4xx 400 => 'Bad Request', 403 => 'Forbidden', 404 => 'Not Found', // Server Error 5xx 500 => 'Internal Server Error', 503 => 'Service Unavailable', ); if(isset($_status[$code])) { header('HTTP/1.1 '.$code.' '.$_status[$code]); // 确保FastCGI模式下正常 header('Status:'.$code.' '.$_status[$code]); } } // 不区分大小写的in_array实现 function in_array_case($value,$array){ return in_array(strtolower($value),array_map('strtolower',$array)); } function think_filter(&$value){ // TODO 其他安全过滤 // 过滤查询特殊字符 if(preg_match('/^(EXP|NEQ|GT|EGT|LT|ELT|OR|XOR|LIKE|NOTLIKE|NOT BETWEEN|NOTBETWEEN|BETWEEN|NOTIN|NOT IN|IN)$/i',$value)){ $value .= ' '; } }