<?php
/**
 * 核心类库
 * @copyright reginx.com
 * $Id: core.class.php 160 2013-03-05 17:28:26Z reginx $
 */
class core{

    /**
     * 应用信息
     *
     * @var unknown_type
     */
    private $_app = array();

    /**
     * 配置
     *
     * @var unknown_type
     */
    private $_conf = array();

    /**
     * 构造函数
     */
    public function __construct($appfile, $conf){

        /**
         * 关闭自动转义
         */
        PHP_VERSION < '5.3.0' && set_magic_quotes_runtime(0);

        /**
         * 安全过滤
         */
        if(isset($_GET['GLOBALS']) || isset($_POST['GLOBALS']) || isset($_COOKIE['GLOBALS']) || isset($_FILES['GLOBALS'])){
            self::error(self::L(('request-tainting')), 'Sys::initInput', 1);
        }

        /**
         * 过滤非法全局变量
         */
        if(isset($_GET['GLOBALS']) || isset($_POST['GLOBALS']) || isset($_COOKIE['GLOBALS']) || isset($_FILES['GLOBALS'])){
            self::error(core::L('request-tainting'), 'Sys::initInput', 1);
        }
        $sglobal = array('GLOBALS','_GET','_POST','_REQUEST','_COOKIE','_SERVER','_ENV','_FILES','_MISC');
        $tmpkeys = array_keys($GLOBALS);
        foreach($tmpkeys as $key){
            if(!in_array($key, $sglobal)){
                $GLOBALS[$key] = NULL;
                unset($GLOBALS[$key]);
            }
        }
        $tmpkeys = null;
        unset($tmpkeys);

        /**
         * 还原数据 , 如果被转义了.
         */
        if(function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()){
            $_GET = self::dstripslashes($_GET);
            $_POST = self::dstripslashes($_POST);
            $_COOKIE = self::dstripslashes($_COOKIE);
        }

        /**
         * 默认配置
         */
        $this->_conf = $conf;

        
        /**
         * 加载app配置信息
         */
        if(file_exists(APP_PATH . 'config/config.php')){
            $this->_conf = array_merge($this->_conf, include (APP_PATH . 'config/config.php'));
        }

        // 加载动态配置信息
        if(!empty($this->_conf['config_file']) && is_file(BASE_PATH . 'data/' . $this->_conf['config_file'])){
            $conf = include (BASE_PATH . 'data/' . $this->_conf['config_file']);
            if(!empty($conf) && is_array($conf)){
                $this->_conf = array_merge($this->_conf, $conf);
            }
            $conf = null; unset($conf);
        }

        /**
         * 生成当前配置
         */
        $this->_app = $this->_getapp($appfile);

        $GLOBALS['_APP'] = &$this->_app;

        /**
         * 设置时区
         */
        $this->timezone_set($this->_conf['time_offset']);

        /**
         * 加载语言变量
         */
        $GLOBALS['_LANG'] = lang::load($this->_conf['lang']);

        /**
         * 模板操作对象
         */
        $GLOBALS['_TPL'] = tpl::getTpl($GLOBALS['_APP']);

        /**
         * 缓存对象
         */
        $GLOBALS['_CACHE'] = cache_extra::getCacheObj($GLOBALS['_APP']);
        
        /**
         * block
         */
        if(is_file(DATA_PATH . 'install.lock') && isset($this->_app['block']) && $this->_app['block']){
            $GLOBALS['_BLOCK'] = block::getobj();
        }
        
        /**
         * 解析url
         */
        $this->_parseurl();
        
        if(isset($this->_conf['hooks']['startup'])){
            call_user_func($this->_conf['hooks']['startup']);
        }
    }

    /**
     * 设置时区
     *
     * @param unknown_type $timeoffset
     */
    public function timezone_set($timeoffset = 0){
        if(function_exists('date_default_timezone_set')){
            date_default_timezone_set('Etc/GMT' . ($timeoffset > 0 ? '-' : '+') . (abs($timeoffset)));
        }
        define('REQUEST_TIME', time());
    }

    /**
     * 检测是否为爬虫
     * @from x25
     *
     * @param mixed $ua
     * @return boolean
     */
    public function isrobot($ua = ''){
        if(IS_CLI){
            return false;
        }
        static $spiders = array('bot', 'crawl', 'spider','slurp','sohu-search','lycos','robozilla');
        static $browsers = array('msie', 'netscape', 'opera', 'konqueror', 'mozilla');
        $ua = strtolower(empty($ua) ? $_SERVER['HTTP_USER_AGENT'] : $ua);
        if(strpos($ua, 'http://') === FALSE && self::dstrpos($ua, $browsers)){
            return FALSE;
        }
        if(self::dstrpos($ua, $spiders)){
            return TRUE;
        }
        return FALSE;
    }

    /**
     * strpos 加强版 .
     *
     * ..
     *
     * @param  string $string
     * @param  array $arr
     * @param  mixed $ret
     * @return mixed
     */
    public static function dstrpos($string, $arr, $ret = FALSE){
        if(empty($string)){
            return FALSE;
        }
        foreach((array)$arr as $v){
            if(strpos($string, $v) !== FALSE){
                return $ret ? $v : TRUE;
            }
        }
        return FALSE;
    }
    /**
     * 获取应用信息
     *
     * @param mixed $appfile
     * @return array
     */
    private function _getapp($appfile){
        // 入口文件
        $appfile = defined('APP_FILE') ? APP_FILE : $appfile;
        $ret = array(
                'app_path'      => APP_PATH,
                'app_name'      => basename(dirname($appfile)),
                'app_file'      => basename($appfile),
                'app_dir'       => $this->_getappdir(),
                'app_tpl_path'  => APP_PATH . 'template/',
                'base_path'     => BASE_PATH,
                'data_path'     => BASE_PATH . 'data/',
                'inc_path'      => BASE_PATH . 'include/',
                'temp_path'     => BASE_PATH . 'data/temp/',
                'cache_path'    => BASE_PATH . 'data/cache/',
                'reginx_path'   => REGINX_PATH,
                'extra_path'    => REGINX_PATH . 'extra/',
                'plugin_path'   => BASE_PATH   . 'data/plugin/',
        );
        $ret['base_url']    = $this->_getbaseurl($ret['app_name'], $ret['app_dir'] , isset($this->_conf['app_host']) && $this->_conf['default'] ? $this->_conf['app_host'] : null);
        if(!isset($this->_conf['data_url'])){
            $ret['data_url']    = !empty($this->_conf['data_url']) ? $this->_conf['data_url'] : ($ret['base_url'] . 'data/');
        }else{
            $ret['data_url'] = $this->_conf['data_url'];
        }
        if(!isset($this->_conf['upload_url'])){
            $ret['upload_url']  = $ret['data_url']  . 'attachment/';
        }else{
            $ret['upload_url'] = $this->_conf['upload_url'];
        }
        $ret['upload_path'] = $ret['data_path'] . 'attachment/';
        $ret['plugin_url']  = $ret['data_url']  . 'plugin/';
        $ret['app_url']     = $ret['base_url']  . ($ret['app_dir'] == '/' ? '' : $ret['app_dir']);
        $ret['is_robot']    = $this->isrobot();
        $ret['html_path']   = $this->_gethtmlpath();
        $ret['html_url']    = $this->_gethtmlurl($ret['base_url']);
        $ret['db_queries']  = 0;
        foreach($ret as $k => $v){
            !defined(strtoupper($k)) && define(strtoupper($k), $v);
        }
        $ret['ctpl_url'] = $ret['curtpl_url'] = $ret['app_url'] . 'template/' . $this->_conf['tpl'] . '/';

        // 合并配置信息
        $ret = array_merge($this->_conf, $ret);
        return $ret;
    }

    /**
     * 获取html静态目录路径
     *
     * @return string
     */
    private function _gethtmlpath(){
        if(isset($this->_conf['html_dir'])){
            return realpath(BASE_PATH . $this->_conf['html_dir']) . '/';
        }
        return BASE_PATH . 'html/';
    }

    /**
     * 获取html文件目录url
     *
     * @param string $baseurl
     * @return string
     */
    private function _gethtmlurl($baseurl){
        if(isset($this->_conf['html_dir'])){
            $dir = str_replace('./', '', $this->_conf['html_dir']);
            return $baseurl . (empty($dir) ? '' : ($dir . '/'));
        }
        return $baseurl . 'html/';
    }

    /**
     * 解析生成缩略图对应的url
     *
     * @param string $image
     * @return string
     */
    public static function thumburl($image){
        $ret = 'null.gif';
        if(strpos($image , 'http://') !== false){
            $ret = $image;
        }else if(!empty($image)){
            $tmp = explode('.', $image);
            $ret = $tmp[0] . "_thumb." . $tmp[1];
        }
        return $ret;
    }

    /**
     * 删除目录
     *
     * @param String $path
     * @param Boolean $sub 是否仅删除子目录 False 则删除当前目录及下属子目录
     */
    public static function removeDir($path, $sub = FALSE){
        clearstatcache();
        $path = realpath($path);
        if(preg_match('/data' . preg_quote(DIR_SEP , '/') . '(temp|cache|backup)/i', $path) && is_dir($path)){
            foreach(glob($path . "/*") as $file){
                if(is_file($file) && file_exists($file)){
                    unlink($file);
                }else if(is_dir($file)){
                    self::removeDir($file);
                }
            }
            !$sub && rmdir($path);
        }else{
            self::error(self::L('delete-denied'), 'core::rmdir');
        }
    }

    /**
     * 反引用字符串支持数组
     *
     * @param unknown_type $str
     * @return unknown
     */
    public static function dstripslashes($str){
        if(is_array($str)){
            foreach($str as $k => $v){
                $str[$k] = self::dstripslashes($v);
            }
        }else{
            $str = stripslashes($str);
        }
        return $str;
    }

    /**
     * 获取站点Url
     *
     * @param unknown_type $name
     * @param unknown_type $dir
     * @return unknown
     */
    private function _getbaseurl($name, $dir , $default = null){
        $ret = '';
        // CLI
        if(IS_CLI){
            $ret = 'http://REGINX.CLI/';
        }
        // defult config app url
        else if(!empty($default)){
             $ret = $default;  
        }
        // auto fetch
        else{
            $sfile = strtolower("http://{$_SERVER['HTTP_HOST']}{$_SERVER['SCRIPT_NAME']}");
            $name = $name == basename($sfile, '.php') ? $name : basename($sfile, '.php');
            if(!preg_match('/^[\w\.]$/' , $name)){
                $name = 'index';
            }
            $tmp = explode($name . '.php', $sfile);
            if($dir == '/' || $dir == '\\'){
                $dir = '';
            }
            $ret =  str_replace($dir, '', array_shift($tmp));
        }
        return $ret;
    }

    /**
     * 获取lib tab 对象
     *
     * @param unknown_type $class
     * @param unknown_type $single
     * @return unknown
     */
    public static function getobj($class, $single = TRUE, $extra = NULL){
        static $objbus = array();
        if($single){
            if(!isset($objbus[$class])){
                $objbus[$class] = new $class($extra);
            }
            return $objbus[$class];
        }
        return new $class($extra);
    }

    /**
     * 获取应用目录
     *
     * @return unknown
     */
    private function _getappdir(){
        $ret = str_replace(realpath(BASE_PATH), '', realpath(APP_PATH));
        return substr($ret, 1) . '/';
    }

    /**
     * autoload
     *
     * @param unknown_type $class
     */
    public static function loader($class){
        if(!class_exists($class, FALSE)){
            $class = explode("_", $class);
            $ctype = array_pop($class);
            $class = $ctype . DIR_SEP . implode(DIR_SEP, $class);
            $path = isset($GLOBALS['_APP']['main']) && $GLOBALS['_APP']['main'] ? BASE_PATH : APP_PATH;
            $path = in_array($ctype, array('tab', 'lib', 'cls' )) ? BASE_PATH : $path;
            $file = $path . 'include' . DIR_SEP . "{$class}.{$ctype}.php";
            if(!is_file($file)){
                if($ctype == 'mod'){
                    core::getobj('mod', 1, $GLOBALS['_CORE']->_conf)->show404();
                }else{
                    self::error(self::L('not-found', $class . ".$ctype.php"), 'core::loader', 1);
                }
            }else{
                include_once ($file);
            }
        }
    }

    /**
     * 输出异常信息
     *
     * @param String $msg
     * @param String $from
     * @param Integer $level
     */
    public static function error($msg, $from = 'Sys', $log = 0, $extra = ''){
        $log && self::log($msg . ($extra ? (' extra : ' . $extra) : ''), $from);
        !IS_DEBUG && ob_end_clean();
        header('X-Powered-By: REGINX v' . REGINX_VERSION);
        $temp = '<!DOCTYPE html><html><head><title>reginx error </title>';
        $temp .= '<meta http-equiv="content-type"  content="text/html; charset=' . $GLOBALS['_APP']['charset'] . '"/>';
        $temp .= '<meta name="ROBOTS" content="NOINDEX,NOFOLLOW,NOARCHIVE" /><style type="text/css">body { background-color:';
        $temp .= ' white; color: black;font: 12px verdana, arial, sans-serif;text-align:left !important;} #container { width: 700px;} #message {background-color:';
        $temp .= ' #FFFFCC; } #bodytitle {vertical-align: top; } .bodytext { } b{font-weight:normal}';
        $temp .= ' .help  {font-size:12px; color: red;} .red {color: red;} .trace{font-size:11px;}';
        $temp .= ' a:link { font-size:12px; color: red; } a:visited{font-size:11px; color: #4e4e4e; ';
        $temp .= '} </style></head><body><table cellpadding="1" cellspacing="5" ';
        $temp .= 'id="container"><tr><td class="bodytext"><br/>error';
        $temp .= ' messages: </td></tr><tr><td class="bodytext" id="message"><ul><li>' . (is_array($msg) ? explode('<br/>', $msg) : $msg);
        $temp .= ' &nbsp;&nbsp;<a href="http://www.reginx.com/help/error/' . base64_encode($msg) . '" target="_blank"';
        $temp .= ' style="color:blue;text-decoration:none">' . self::L('get-help') . '</a></li></ul></td></tr>';
        $temp .= '<TRACE/>';
        $temp .= '<tr><td class="help"><a href="' . $GLOBALS['_APP']['app_url'] . '">' . $_SERVER['HTTP_HOST'] . '</a> ';
        $temp .= self::L('err-recorded') . ' </td></tr></table></body></html>';
        if(IS_DEBUG){
            $trace = debug_backtrace();
            $str = '<tr><td class="bodytext"><br/>trace information: <br/><ul class="trace">';
            for($i = 0; $i < sizeof($trace); $i++){
                $str .= '<li>[ #' . $i . ' line:' . sprintf('%04d', empty($trace[$i]['line']) ? 0 : $trace[$i]['line']) . ' ] ';
                $str .= ' file: ' . str_replace(BASE_PATH, '', empty($trace[$i]['file']) ? '' : $trace[$i]['file']);
                $str .= ' ' . (empty($trace[$i]['class']) ? '' : $trace[$i]['class']);
                $str .= (empty($trace[$i]['type']) ? '' : $trace[$i]['type']);
                $str .= (empty($trace[$i]['function']) ? '' : $trace[$i]['function']) . '()</li>';
            }
            $temp = str_replace('<TRACE/>', $str . '</ul></td></tr>', $temp);
        }
        echo ($temp);
        $temp = NULL;
        unset($temp);
        exit();
    }

    /**
     * 语言
     *
     * @return unknown
     */
    public static function L(){
        return $GLOBALS['_TPL']->lang(func_get_args());
    }

    /**
     * 记录日志
     *
     * @param String $msg
     */
    public static function log($error, $from = ''){
        !is_dir($GLOBALS['_APP']['data_path'] . 'log/') && mkdir($GLOBALS['_APP']['data_path'] . 'log/');
        !is_dir($GLOBALS['_APP']['data_path'] . 'log/' . $GLOBALS['_APP']['app_dir']) && mkdir($GLOBALS['_APP']['data_path'] . 'log/' . $GLOBALS['_APP']['app_dir']);
        $logfile = $GLOBALS['_APP']['data_path'] . 'log/' . $GLOBALS['_APP']['app_dir'] . (date('Y-m-d', REQUEST_TIME)) . '.log.php';
        $from = self::geturl();
        $msg  = "<?php  \n/** \n";
        $msg .= " * @ip   " . self::getip() . "\n";
        $msg .= " * @url  " . $from . "\n";
        $msg .= " * @date " . (date('Y-m-d H:i:s ', REQUEST_TIME)) . "\n";
        $msg .= " * @desc " . $error . "\n";
        $trace = debug_backtrace();
        for($i = 2; $i < sizeof($trace); $i++){
            $msg .= " # ". ($i-2) . ' line:' . sprintf('%04d', empty($trace[$i]['line']) ? 0 : $trace[$i]['line']);  
            $msg .= ' file : ' . str_replace(BASE_PATH, '', empty($trace[$i]['file']) ? '' : $trace[$i]['file']);
            $msg .= ' ' . (empty($trace[$i]['class']) ? '' : $trace[$i]['class']);
            $msg .= (empty($trace[$i]['type']) ? '' : $trace[$i]['type']);
            $msg .= (empty($trace[$i]['function']) ? '' : $trace[$i]['function']) . "(";
            $msg .= empty($trace[$i]['args']) ? '' : join(',' , $trace[$i]['args']);
            $msg .= ")\n";
        }
        $msg .= " */?>\n";
        $fp = fopen($logfile, 'a+');
        fwrite($fp, $msg);
        fclose($fp);
    }

    /**
     * 获取IP
     *
     * @return unknown
     */
    public static function getip(){
        $ip = "unkown";
        if(isset($_SERVER)){
            if(isset($_SERVER["HTTP_X_FORWARDED_FOR"])){
                $ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
            }elseif(isset($_SERVER["HTTP_CLIENT_IP"])){
                $ip = $_SERVER["HTTP_CLIENT_IP"];
            }else{
                $ip = $_SERVER["REMOTE_ADDR"];
            }
        }
        return $ip;
    }

    /**
     * 解析url(参数)
     *
     * @param unknown_type $url
     * @return unknown
     */
    private function _parseurl(){
        $tmp = NULL;
        switch ($this->_conf['url']['type']){
            case 0:
                $GLOBALS['_MOD'] = (empty($_GET['m']) || $_GET['m'] == '') ? $this->_conf['default_mod'] : $_GET['m'];
                $GLOBALS['_ACT'] = (empty($_GET['a']) || $_GET['a'] == '') ? $this->_conf['default_act'] : $_GET['a'];
                $GLOBALS['_RG'] = &$_GET;
                return;
                break;
            case 1:
                // http://reginx.com/?index/index.html
                $query = $_SERVER['QUERY_STRING'];
                // 兼容iis
                if(isset($_SERVER['HTTP_X_REWRITE_URL'])){
                    $query = explode('?', $_SERVER['HTTP_X_REWRITE_URL']);
                    $query = $query[1];
                }
                $tmp = $query != '' ? explode($this->_conf['url']['interval'], preg_replace('/' . preg_quote($this->_conf['url']['suf']) . '.*/i', '', $query)) : array();
                break;
            case 2:
                // http://reginx.com/index.php/index/index.html
                if(isset($_SERVER['PATH_INFO']) && !empty($_SERVER['PATH_INFO']) && $_SERVER['PATH_INFO'] != "/"){
                    // 兼容 nginx 模拟的 PATH_INFO
                    if(substr($_SERVER['PATH_INFO'], -1) == '/'){
                        $_SERVER['PATH_INFO'] = substr($_SERVER['PATH_INFO'], 0, -1);
                    }
                    // 去除第一个/,url后缀.然后分割
                    $tmp = explode($this->_conf['url']["interval"], str_replace($this->_conf['url']["suf"], '', substr($_SERVER['PATH_INFO'], 1)));
                }
                break;
        }

        $GLOBALS['_MOD'] = $this->_conf['default_mod'];
        if((!empty($tmp[0]) && !$tmp[0] == '' && preg_match('/^\w+$/i', $tmp[0]))){
            $GLOBALS['_MOD'] = array_shift($tmp);
        }

        $GLOBALS['_ACT'] = $this->_conf['default_act'];
        // 匿名Action , 兼容中文
        // if((!empty($tmp[0]) && !$tmp[0] == '' && preg_match('/^\w+$/i' ,
        // $tmp[0]))){
        if((!empty($tmp[0]) && !$tmp[0] == '')){
            $GLOBALS['_ACT'] = array_shift($tmp);
        }

        for($i = 0; $i < sizeof($tmp); $i += 2){
            $GLOBALS['_RP'][$tmp[$i]] = $tmp[$i + 1];
        }
    }

    /**
     * 创建文件夹
     *
     * @param String $dir
     */
    public static function makedir($dir){
        if(!is_dir($dir)){
            mkdir($dir, 0755) && file_put_contents($dir . '/index.html', ' ' , LOCK_EX);
        }
    }

    /**
     * url 构造器
     *
     * @example url("index-news-id-%d",2)
     *             http://reginx.com/index.php?a=index&m=news&id=10 [普通]
     *             http://reginx.com/index.php?index/news/id/10.html [伪静态]
     *             http://reginx.com/index.php/index/news/id/10.html [PHP_INFO]
     *
     * @param string $param
     * @return string
     */
    public static function url(){
        $ret = '';
        $conf = $GLOBALS['_APP']['url'];
        $def_mod = $GLOBALS['_APP']['default_mod'];
        // 获取 输入参数
        $params = func_get_args();
        // url 表达式
        $str = strtolower(array_shift($params));
        $str = str_replace('-' , '{#-#}' , $str);
        // 添加 默认 app 名称
        $pre = substr($GLOBALS['_APP']['app_dir'] == '/' ? '' : $GLOBALS['_APP']['app_dir'], 0, -1);
        $str = strpos($str, '@') === FALSE ? ($pre . '@' . $str) : $str;

        // 添加 默认 mod 名称
        $str = substr($str, -1) == '@' ? ($str . $def_mod) : $str;
        $match = array();
        // 提取数据
        preg_match('/^(?P<app>.*)\@(?P<ustr>[^\|]+)(?P<suf>\|(?:.+?))?$/i', $str, $match);
        // app
        $appstr = (isset($match['app']) && $match['app'] ? ($match['app'] . '/') : '');
        $urlsuf = (isset($match['suf']) && strpos($match['suf'] , 'false') !== false ) ? '' : $conf['suf'];
        $host   = (isset($match['suf']) && strpos($match['suf'] , 'nh')    !== false ) ? '/' : BASE_URL;
        // url 表达式
        $ustr = explode('{#-#}', vsprintf($match['ustr'], $params));
        $match = null;
        unset($match);
        // 拼接url字串
        switch (intval($conf['type'])){
            // 默认模式 , index.php?m=aa&a=222;
            case 0:
                $ret = '?';
                foreach($ustr as $k => $v){
                    // module && action
                    if($k < 2){
                        $ret .= $k === 0 ? ('m=' . $v) : ('&a=' . $v);
                    }else if($k % 2 == 0){
                        $ret .= '&' . $ustr[$k] . '=' . $ustr[$k + 1];
                    }
                }
                $ret = $host . $appstr . $ret;
                break;
            case 1:
                $ret = $host . $appstr . ($conf['rewrite'] ? '' : '?') . join($conf['interval'], $ustr) . $urlsuf;
                break;
            case 2:
                $ret = $host . $appstr . ($conf['rewrite'] ? '' : 'index.php/') . join($conf['interval'], $ustr) . $urlsuf;
                break;
        }
        return $ret;
    }

    /**
     * 获取 GPC 内容
     *
     * @param unknown_type $k
     * @param unknown_type $type
     * @return unknown
     */
    public static function getgpc($k, $type = 'GP'){
        $var = NULL;
        $key = explode(':', $k);
        switch (strtoupper($type)){
            // GET
            case 'G':
                $var = &$_GET;
                break;
            // POST
            case 'P':
                $var = &$_POST;
                break;
            // COOKIE
            case 'C':
                $var = &$_COOKIE;
                break;
            // REGINX ROUTE PARAM
            case 'R':
                $var = &$GLOBALS['_RP'];
                break;
            // DEFAULT
            default:
                $var = &$_POST;
                if(isset($_GET[$key[0]])){
                    $var = &$_GET;
                }
                break;
        }
        $ret = $var;
        foreach($key as $v){
            $ret = isset($ret[$v]) ? $ret[$v] : NULL;
        }
        return $ret;
    }

    /**
     * 是否存在GPCR值
     *
     * @param unknown_type $k
     * @param unknown_type $type
     * @return unknown
     */
    public static function hasgpc($k, $type = 'GP'){
        $var = NULL;
        $key = explode(':', $k);
        switch (strtoupper($type)){
            // GET
            case 'G':
                $var = &$_GET;
                break;
            // POST
            case 'P':
                $var = &$_POST;
                break;
            // COOKIE
            case 'C':
                $var = &$_COOKIE;
                break;
            // REGINX ROUTE PARAM
            case 'R':
                $var = &$GLOBALS['_RP'];
                break;
            // DEFAULT
            default:
                $var = &$_POST;
                if(isset($_GET[$k])){
                    $var = &$_GET;
                }
                break;
        }
        $ret = $var;
        foreach($key as $v){
            $ret = isset($ret[$v]) ? $ret[$v] : NULL;
        }
        return $ret !== null;
    }

    /**
     * 获取大小
     *
     * @param Mixed $val
     * @return Integer
     */
    public static function byteslen($val){
        $val = trim($val);
        $last = strtolower($val{strlen($val) - 1});
        switch ($last){
            case 'g':
                $val *= 1024;
            case 'm':
                $val *= 1024;
            case 'k':
                $val *= 1024;
        }
        return $val;
    }

    /**
     * 输出令牌
     */
    public static function token($get = FALSE){
        if($GLOBALS['_APP']['token']){
            $key = $GLOBALS['_APP']['token_var'];
            $sobj = sess_extra::getobj($GLOBALS['_APP']['sess']);
            $token = $sobj->get($key);
            if($token == NULL){
                $token = sha1($GLOBALS['_MISC']['STIME'] . $GLOBALS['_APP']['app_name']);
                $sobj->set($key, $token);
            }
            return $get ? $token : '<input type="hidden" name="' . $key . '" id="' . $key . '" value = "' . $token . '" />';
        }
        return NULL;
    }

    /**
     * 获取随机字串
     *
     * @param int $len
     * @return string
     */
    public static function randstr($len = 4){
        $ret = '';
        $randstr = '23456789abcdefghjkmnpqrstuvwxyABCDEFGHJKLMNPQRSTUVW';
        for($i = 0; $i < $len; $i++){
            $ret .= $randstr[mt_rand(0, strlen($randstr) - 1)];
        }
        return $ret;
    }

    /**
     * 获取当前 Url 的路由字串
     *
     * @param unknown_type $url
     * @return unknown
     */
    public static function geturl(){
        $temp = array();
        $temp[] = $GLOBALS['_MOD'];
        $temp[] = $GLOBALS['_ACT'];
        if(isset($GLOBALS['_RP']) && !empty($GLOBALS['_RP'])){
            foreach($GLOBALS['_RP'] as $k => $v){
                $temp[] = $k;
                $temp[] = $v;
            }
        }
        return ($GLOBALS['_APP']['app_dir'] == '/' ? '' : substr($GLOBALS['_APP']['app_dir'], 0, -1)) . '@' . implode('-', $temp);
    }

    /**
     * 清除模板缓存
     *
     * @param unknown_type $app
     */
    public static function cleartpl($app = ''){
        $tpldir  = realpath(DATA_PATH . 'temp/' . $app);
        if(is_dir($tpldir)){
            self::removeDir($tpldir, 1);
        }
    }
    
    /**
     * 清除运行库文件
     *
     */
    public static function clearrunfile(){
        $runfile = DATA_PATH . 'cache/~runtime.php';
        clearstatcache();
        if($ctype == 3 && file_exists($runfile)){
            unlink($runfile);
        }
    }
}// End Class
/**
 * 获取 对象
 *
 * @param string $class
 * @param boolean $single
 * @param array $extra
 * @return obj
 */
function OBJ($class, $single = TRUE, $extra = NULL){
    return core::getobj($class , $single , $extra);
}

/**
 * 语言
 *
 * @return string
 */
function LANG(){
    return $GLOBALS['_TPL']->lang(func_get_args());
}

/**
 * 错误输出
 *
 * @param unknown_type $msg
 * @param unknown_type $from
 * @param unknown_type $log
 * @param unknown_type $extra
 */
function ERR($msg, $from = 'Sys', $log = 0, $extra = ''){
    core::error($msg , $from , $log , $extra);
}

/**
 * 加载插件文件
 *
 * @param unknown_type $dir
 */
function PLU($dir){
    return plugin::load($dir);
}
?>