| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109 | <?php// +----------------------------------------------------------------------// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]// +----------------------------------------------------------------------// | Copyright (c) 2006-2014 http://thinkphp.cn All rights reserved.// +----------------------------------------------------------------------// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )// +----------------------------------------------------------------------// | Author: liu21st <liu21st@gmail.com>// +----------------------------------------------------------------------/** * Think API模式函数库 *//** * 获取和设置配置参数 支持批量定义 * @param string|array $name 配置变量 * @param mixed $value 配置值 * @param mixed $default 默认值 * @return mixed */function C($name=null, $value=null,$default=null) {    static $_config = array();    // 无参数时获取所有    if (empty($name)) {        return $_config;    }    // 优先执行设置获取或赋值    if (is_string($name)) {        if (!strpos($name, '.')) {            $name = strtolower($name);            if (is_null($value))                return isset($_config[$name]) ? $_config[$name] : $default;            $_config[$name] = $value;            return;        }        // 二维数组设置和获取支持        $name = explode('.', $name);        $name[0]   =  strtolower($name[0]);        if (is_null($value))            return isset($_config[$name[0]][$name[1]]) ? $_config[$name[0]][$name[1]] : $default;        $_config[$name[0]][$name[1]] = $value;        return;    }    // 批量设置    if (is_array($name)){        $_config = array_merge($_config, array_change_key_case($name));        return;    }    return null; // 避免非法参数}/** * 加载配置文件 支持格式转换 仅支持一级配置 * @param string $file 配置文件名 * @param string $parse 配置解析方法 有些格式需要用户自己解析 * @return void */function load_config($file,$parse=CONF_PARSE){    $ext  = pathinfo($file,PATHINFO_EXTENSION);    switch($ext){        case 'php':            return include $file;        case 'ini':            return parse_ini_file($file);        case 'yaml':            return yaml_parse_file($file);        case 'xml':             return (array)simplexml_load_file($file);        case 'json':            return json_decode(file_get_contents($file), true);        default:            if(function_exists($parse)){                return $parse($file);            }else{                E(L('_NOT_SUPPORT_').':'.$ext);            }    }}/** * 抛出异常处理 * @param string $msg 异常消息 * @param integer $code 异常代码 默认为0 * @return void */function E($msg, $code=0) {    throw new Think\Exception($msg, $code);}/** * 记录和统计时间(微秒)和内存使用情况 * 使用方法: * <code> * G('begin'); // 记录开始标记位 * // ... 区间运行代码 * G('end'); // 记录结束标签位 * echo G('begin','end',6); // 统计区间运行时间 精确到小数后6位 * echo G('begin','end','m'); // 统计区间内存使用情况 * 如果end标记位没有定义,则会自动以当前作为标记位 * 其中统计内存使用需要 MEMORY_LIMIT_ON 常量为true才有效 * </code> * @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.'}';}/** * 获取输入参数 支持过滤和默认值 * 使用方法: * <code> * I('id',0); 获取id参数 自动判断get或者post * I('post.name','','htmlspecialchars'); 获取$_POST['name'] * I('get.'); 获取$_GET * </code> * @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; }/** * 设置和获取统计数据 * 使用方法: * <code> * N('db',1); // 记录数据库操作次数 * N('read',1); // 记录读取次数 * echo N('db'); // 获取当前页面数据库的所有操作次数 * echo N('read'); // 获取当前页面读取次数 * </code> * @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 .= "<<<THINK\n";                    break;                case T_END_HEREDOC:                    $stripStr .= "THINK;\n";                    for($k = $i+1; $k < $j; $k++) {                        if(is_string($tokens[$k]) && $tokens[$k] == ';') {                            $i = $k;                            break;                        } else if($tokens[$k][0] == T_CLOSE_TAG) {                            break;                        }                    }                    break;                default:                    $last_space = false;                    $stripStr  .= $tokens[$i][1];            }        }    }    return $stripStr;}/** * 浏览器友好的变量输出 * @param mixed $var 变量 * @param boolean $echo 是否输出 默认为True 如果为false 则返回输出字符串 * @param string $label 标签 默认为空 * @param boolean $strict 是否严谨 默认为true * @return void|string */function dump($var, $echo=true, $label=null, $strict=true) {    $label = ($label === null) ? '' : rtrim($label) . ' ';    if (!$strict) {        if (ini_get('html_errors')) {            $output = print_r($var, true);            $output = '<pre>' . $label . htmlspecialchars($output, ENT_QUOTES) . '</pre>';        } else {            $output = $label . print_r($var, true);        }    } else {        ob_start();        var_dump($var);        $output = ob_get_clean();        if (!extension_loaded('xdebug')) {            $output = preg_replace('/\]\=\>\n(\s+)/m', '] => ', $output);            $output = '<pre>' . $label . htmlspecialchars($output, ENT_QUOTES) . '</pre>';        }    }    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    = "<meta http-equiv='Refresh' content='{$time};URL={$url}'>";        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 version=\"1.0\" encoding=\"{$encoding}\"?>";    $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 .= ' ';    }}
 |