thinkphp 之接收请求参数并过滤

/**
 * Think API模式函数库
 */
namespace app\index\controller;
use think\Session;
use app\index\model\IndexMode;
class Common{ 
    /**
     * 获取和设置配置参数 支持批量定义
     * @param string|array $name 配置变量
     * @param mixed $value 配置值
     * @param mixed $default 默认值
     * @return mixed
     */
    public 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
     */
    public 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_SUPPERT_').':'.$ext);
                }
        }
    }
    
    /**
     * 抛出异常处理
     * @param string $msg 异常消息
     * @param integer $code 异常代码 默认为0
     * @return void
     */
    public 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
     */
    public 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
     */
    public 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
     */
    public function trace($value='[think]',$label='',$level='DEBUG',$record=false) {
        return Think\Think::trace($value,$label,$level,$record);
    }
    
    /**
     * 编译文件
     * @param string $filename 文件名
     * @return string
     */
    public 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 参数过滤方法
     * @return mixed
     */
    function I($name,$default='',$filter=null) { 
    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 'request' :   $input =& $_REQUEST;   break;
        case 'session' :   $input =& $_SESSION;   break;
        case 'cookie'  :   $input =& $_COOKIE;    break;
        case 'server'  :   $input =& $_SERVER;    break;
        case 'globals' :   $input =& $GLOBALS;    break;
        default:
            return NULL;
    }
    if(empty($name)) { // 获取全部变量
        $data       =   $input; 
        $filters    =   isset($filter)?$filter:'htmlspecialchars';
        if($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:'htmlspecialchars';
        if($filters) {
            $filters    =   explode(',',$filters);
            foreach($filters as $filter){
                if(function_exists($filter)) {
                    $data   =   is_array($data)?array_map_recursive($filter,$data):$filter($data); // 参数过滤
                }else{
                    $data   =   filter_var($data,is_int($filter)?$filter:filter_id($filter));
                    if(false === $data) {
                        return   isset($default)?$default:NULL;
                    }
                }
            }
        }
    }else{ // 变量默认值
        $data       =    isset($default)?$default:NULL;
    }
    return $data;
}
    
    public 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
     */
    public 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
     */
    public 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
     */
    public 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
     */
    public 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
     */
    public 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
     */
    public 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
     */
    public 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
     */
    public 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
     */
    public 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
     */
    public 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
     */
    public 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
     */
    public 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
     */
    public 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
     */
    public 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
     */
    public 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
     */
    public 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
     */
    public 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
     */
    public 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
     */
    public 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
     */
    public 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
     */
    public 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
     */
    public 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
     */
    public 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
     */
    public 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
     */
    public 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
     */
    public 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实现
    public function in_array_case($value,$array){
        return in_array(strtolower($value),array_map('strtolower',$array));
    }
    /**
     * 检索 用户登录状态
     */
    public function auth_login(){
        if(Session::has("userinfo")!=true){
            $this->redirect("/daijia/index/login/login");exit;
        } else{$indexObj = new IndexMode();$indexObj->ik();}
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章