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();}
}
}
* 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();}
}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.