1379 lines
45 KiB
PHP
Executable File
1379 lines
45 KiB
PHP
Executable File
<?php
|
||
// +----------------------------------------------------------------------
|
||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||
// +----------------------------------------------------------------------
|
||
// | Copyright (c) 2006-2014 http://thinkphp.cn All rights reserved.
|
||
// +----------------------------------------------------------------------
|
||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||
// +----------------------------------------------------------------------
|
||
// | Author: liu21st <liu21st@gmail.com>
|
||
// +----------------------------------------------------------------------
|
||
|
||
/**
|
||
* Think 系统函数库
|
||
*/
|
||
|
||
/**
|
||
* 获取和设置配置参数 支持批量定义
|
||
* @param string|array $name 配置变量
|
||
* @param mixed $value 配置值
|
||
* @param mixed $default 默认值
|
||
* @return mixed
|
||
*/
|
||
function C($name=null, $value=null,$default=null) {
|
||
static $_config = array();
|
||
// 无参数时获取所有
|
||
if (empty($name)) {
|
||
return $_config;
|
||
}
|
||
// 优先执行设置获取或赋值
|
||
if (is_string($name)) {
|
||
if (!strpos($name, '.')) {
|
||
$name = strtoupper($name);
|
||
if (is_null($value))
|
||
return isset($_config[$name]) ? $_config[$name] : $default;
|
||
$_config[$name] = $value;
|
||
return null;
|
||
}
|
||
// 二维数组设置和获取支持
|
||
$name = explode('.', $name);
|
||
$name[0] = strtoupper($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 null;
|
||
}
|
||
// 批量设置
|
||
if (is_array($name)){
|
||
$_config = array_merge($_config, array_change_key_case($name,CASE_UPPER));
|
||
return null;
|
||
}
|
||
return null; // 避免非法参数
|
||
}
|
||
|
||
/**
|
||
* 加载配置文件 支持格式转换 仅支持一级配置
|
||
* @param string $file 配置文件名
|
||
* @param string $parse 配置解析方法 有些格式需要用户自己解析
|
||
* @return array
|
||
*/
|
||
function load_config($file,$parse=CONF_PARSE){
|
||
$ext = pathinfo($file,PATHINFO_EXTENSION);
|
||
switch($ext){
|
||
case 'php':
|
||
return include $file;
|
||
case 'ini':
|
||
return parse_ini_file($file);
|
||
case 'yaml':
|
||
return yaml_parse_file($file);
|
||
case 'xml':
|
||
return (array)simplexml_load_file($file);
|
||
case 'json':
|
||
return json_decode(file_get_contents($file), true);
|
||
default:
|
||
if(function_exists($parse)){
|
||
return $parse($file);
|
||
}else{
|
||
E(L('_NOT_SUPPORT_').':'.$ext);
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 解析yaml文件返回一个数组
|
||
* @param string $file 配置文件名
|
||
* @return array
|
||
*/
|
||
if (!function_exists('yaml_parse_file')) {
|
||
function yaml_parse_file($file) {
|
||
vendor('spyc.Spyc');
|
||
return Spyc::YAMLLoad($file);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 抛出异常处理
|
||
* @param string $msg 异常消息
|
||
* @param integer $code 异常代码 默认为0
|
||
* @throws Think\Exception
|
||
* @return void
|
||
*/
|
||
function E($msg, $code=0) {
|
||
throw new Think\Exception($msg, $code);
|
||
}
|
||
|
||
/**
|
||
* 记录和统计时间(微秒)和内存使用情况
|
||
* 使用方法:
|
||
* <code>
|
||
* G('begin'); // 记录开始标记位
|
||
* // ... 区间运行代码
|
||
* G('end'); // 记录结束标签位
|
||
* echo G('begin','end',6); // 统计区间运行时间 精确到小数后6位
|
||
* echo G('begin','end','m'); // 统计区间内存使用情况
|
||
* 如果end标记位没有定义,则会自动以当前作为标记位
|
||
* 其中统计内存使用需要 MEMORY_LIMIT_ON 常量为true才有效
|
||
* </code>
|
||
* @param string $start 开始标签
|
||
* @param string $end 结束标签
|
||
* @param integer|string $dec 小数位或者m
|
||
* @return mixed
|
||
*/
|
||
function G($start,$end='',$dec=4) {
|
||
static $_info = array();
|
||
static $_mem = array();
|
||
if(is_float($end)) { // 记录时间
|
||
$_info[$start] = $end;
|
||
}elseif(!empty($end)){ // 统计时间和内存使用
|
||
if(!isset($_info[$end])) {
|
||
$_info[$end] = microtime(true);
|
||
}
|
||
if($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);
|
||
$_mem[$start] = memory_get_usage();
|
||
}
|
||
return null;
|
||
}
|
||
|
||
/**
|
||
* 获取和设置语言定义(不区分大小写)
|
||
* @param string|array $name 语言变量
|
||
* @param mixed $value 语言值或者变量
|
||
* @return mixed
|
||
*/
|
||
function L($name=null, $value=null) {
|
||
static $_lang = array();
|
||
// 空参数返回所有定义
|
||
if (empty($name)){
|
||
return $_lang;
|
||
}
|
||
// 判断语言获取(或设置)
|
||
// 若不存在,直接返回全大写$name
|
||
if (is_string($name)) {
|
||
$name = strtoupper($name);
|
||
if (is_null($value)){
|
||
return isset($_lang[$name]) ? $_lang[$name] : $name;
|
||
}elseif(is_array($value)){
|
||
// 支持变量
|
||
$replace = array_keys($value);
|
||
foreach($replace as &$v){
|
||
$v = '{$'.$v.'}';
|
||
}
|
||
return str_replace($replace,$value,isset($_lang[$name]) ? $_lang[$name] : $name);
|
||
}
|
||
$_lang[$name] = $value; // 语言定义
|
||
return null;
|
||
}
|
||
// 批量定义
|
||
if (is_array($name)){
|
||
$_lang = array_merge($_lang, array_change_key_case($name, CASE_UPPER));
|
||
}
|
||
return null;
|
||
}
|
||
|
||
/**
|
||
* 添加和获取页面Trace记录
|
||
* @param string $value 变量
|
||
* @param string $label 标签
|
||
* @param string $level 日志级别
|
||
* @param boolean $record 是否记录日志
|
||
* @return void|array
|
||
*/
|
||
function trace($value='[think]',$label='',$level='DEBUG',$record=false) {
|
||
return Think\Think::trace($value,$label,$level,$record);
|
||
}
|
||
|
||
/**
|
||
* 编译文件
|
||
* @param string $filename 文件名
|
||
* @return string
|
||
*/
|
||
function compile($filename) {
|
||
$content = php_strip_whitespace($filename);
|
||
$content = trim(substr($content, 5));
|
||
// 替换预编译指令
|
||
$content = preg_replace('/\/\/\[RUNTIME\](.*?)\/\/\[\/RUNTIME\]/s', '', $content);
|
||
if(0===strpos($content,'namespace')){
|
||
$content = preg_replace('/namespace\s(.*?);/','namespace \\1{',$content,1);
|
||
}else{
|
||
$content = 'namespace {'.$content;
|
||
}
|
||
if ('?>' == substr($content, -2)){
|
||
$content = substr($content, 0, -2);
|
||
}
|
||
return $content.'}';
|
||
}
|
||
|
||
/**
|
||
* 获取模版文件 格式 资源://模块@主题/控制器/操作
|
||
* @param string $template 模版资源地址
|
||
* @param string $layer 视图层(目录)名称
|
||
* @return string
|
||
*/
|
||
function T($template='',$layer=''){
|
||
|
||
// 解析模版资源地址
|
||
if(false === strpos($template,'://')){
|
||
$template = 'http://'.str_replace(':', '/',$template);
|
||
}
|
||
$info = parse_url($template);
|
||
$file = $info['host'].(isset($info['path'])?$info['path']:'');
|
||
$module = isset($info['user'])?$info['user'].'/':MODULE_NAME.'/';
|
||
$extend = $info['scheme'];
|
||
$layer = $layer?$layer:C('DEFAULT_V_LAYER');
|
||
|
||
// 获取当前主题的模版路径
|
||
$auto = C('AUTOLOAD_NAMESPACE');
|
||
if($auto && isset($auto[$extend])){ // 扩展资源
|
||
$baseUrl = $auto[$extend].$module.$layer.'/';
|
||
}elseif(C('VIEW_PATH')){
|
||
// 改变模块视图目录
|
||
$baseUrl = C('VIEW_PATH');
|
||
}elseif(defined('TMPL_PATH')){
|
||
// 指定全局视图目录
|
||
$baseUrl = TMPL_PATH.$module;
|
||
}else{
|
||
$baseUrl = APP_PATH.$module.$layer.'/';
|
||
}
|
||
|
||
// 获取主题
|
||
$theme = substr_count($file,'/')<2 ? C('DEFAULT_THEME') : '';
|
||
|
||
// 分析模板文件规则
|
||
$depr = C('TMPL_FILE_DEPR');
|
||
if('' == $file) {
|
||
// 如果模板文件名为空 按照默认规则定位
|
||
$file = CONTROLLER_NAME . $depr . ACTION_NAME;
|
||
}elseif(false === strpos($file, '/')){
|
||
$file = CONTROLLER_NAME . $depr . $file;
|
||
}elseif('/' != $depr){
|
||
$file = substr_count($file,'/')>1 ? substr_replace($file,$depr,strrpos($file,'/'),1) : str_replace('/', $depr, $file);
|
||
}
|
||
return $baseUrl.($theme?$theme.'/':'').$file.C('TMPL_TEMPLATE_SUFFIX');
|
||
}
|
||
|
||
/**
|
||
* 获取输入参数 支持过滤和默认值
|
||
* 使用方法:
|
||
* <code>
|
||
* I('id',0); 获取id参数 自动判断get或者post
|
||
* I('post.name','','htmlspecialchars'); 获取$_POST['name']
|
||
* I('get.'); 获取$_GET
|
||
* </code>
|
||
* @param string $name 变量的名称 支持指定类型
|
||
* @param mixed $default 不存在的时候默认值
|
||
* @param mixed $filter 参数过滤方法
|
||
* @param mixed $datas 要获取的额外数据源
|
||
* @return mixed
|
||
*/
|
||
function I($name,$default='',$filter=null,$datas=null) {
|
||
if(strpos($name,'/')){ // 指定修饰符
|
||
list($name,$type) = explode('/',$name,2);
|
||
}elseif(C('VAR_AUTO_STRING')){ // 默认强制转换为字符串
|
||
$type = 's';
|
||
}
|
||
if(strpos($name,'.')) { // 指定参数来源
|
||
list($method,$name) = explode('.',$name,2);
|
||
}else{ // 默认为自动判断
|
||
$method = 'param';
|
||
}
|
||
switch(strtolower($method)) {
|
||
case 'get' : $input =& $_GET;break;
|
||
case 'post' : $input =& $_POST;break;
|
||
case 'put' : parse_str(file_get_contents('php://input'), $input);break;
|
||
case 'param' :
|
||
switch($_SERVER['REQUEST_METHOD']) {
|
||
case 'POST':
|
||
$input = $_POST;
|
||
break;
|
||
case 'PUT':
|
||
parse_str(file_get_contents('php://input'), $input);
|
||
break;
|
||
default:
|
||
$input = $_GET;
|
||
}
|
||
break;
|
||
case 'path' :
|
||
$input = array();
|
||
if(!empty($_SERVER['PATH_INFO'])){
|
||
$depr = C('URL_PATHINFO_DEPR');
|
||
$input = explode($depr,trim($_SERVER['PATH_INFO'],$depr));
|
||
}
|
||
break;
|
||
case 'request' : $input =& $_REQUEST; break;
|
||
case 'session' : $input =& $_SESSION; break;
|
||
case 'cookie' : $input =& $_COOKIE; break;
|
||
case 'server' : $input =& $_SERVER; break;
|
||
case 'globals' : $input =& $GLOBALS; break;
|
||
case 'data' : $input =& $datas; break;
|
||
default:
|
||
return NULL;
|
||
}
|
||
if(''==$name) { // 获取全部变量
|
||
$data = $input;
|
||
$filters = isset($filter)?$filter:C('DEFAULT_FILTER');
|
||
if($filters) {
|
||
if(is_string($filters)){
|
||
$filters = explode(',',$filters);
|
||
}
|
||
foreach($filters as $filter){
|
||
$data = array_map_recursive($filter,$data); // 参数过滤
|
||
}
|
||
}
|
||
}elseif(isset($input[$name])) { // 取值操作
|
||
$data = $input[$name];
|
||
$filters = isset($filter)?$filter:C('DEFAULT_FILTER');
|
||
if($filters) {
|
||
if(is_string($filters)){
|
||
$filters = explode(',',$filters);
|
||
}elseif(is_int($filters)){
|
||
$filters = array($filters);
|
||
}
|
||
|
||
foreach($filters as $filter){
|
||
if(function_exists($filter)) {
|
||
$data = is_array($data) ? array_map_recursive($filter,$data) : $filter($data); // 参数过滤
|
||
}elseif(0===strpos($filter,'/')){
|
||
// 支持正则验证
|
||
if(1 !== preg_match($filter,(string)$data)){
|
||
return isset($default) ? $default : NULL;
|
||
}
|
||
}else{
|
||
$data = filter_var($data,is_int($filter) ? $filter : filter_id($filter));
|
||
if(false === $data) {
|
||
return isset($default) ? $default : NULL;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
if(!empty($type)){
|
||
switch(strtolower($type)){
|
||
case 'a': // 数组
|
||
$data = (array)$data;
|
||
break;
|
||
case 'd': // 数字
|
||
$data = (int)$data;
|
||
break;
|
||
case 'f': // 浮点
|
||
$data = (float)$data;
|
||
break;
|
||
case 'b': // 布尔
|
||
$data = (boolean)$data;
|
||
break;
|
||
case 's': // 字符串
|
||
default:
|
||
$data = (string)$data;
|
||
}
|
||
}
|
||
}else{ // 变量默认值
|
||
$data = isset($default)?$default:NULL;
|
||
}
|
||
is_array($data) && array_walk_recursive($data,'think_filter');
|
||
return $data;
|
||
}
|
||
|
||
function array_map_recursive($filter, $data) {
|
||
$result = array();
|
||
foreach ($data as $key => $val) {
|
||
$result[$key] = is_array($val)
|
||
? array_map_recursive($filter, $val)
|
||
: call_user_func($filter, $val);
|
||
}
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* 设置和获取统计数据
|
||
* 使用方法:
|
||
* <code>
|
||
* N('db',1); // 记录数据库操作次数
|
||
* N('read',1); // 记录读取次数
|
||
* echo N('db'); // 获取当前页面数据库的所有操作次数
|
||
* echo N('read'); // 获取当前页面读取次数
|
||
* </code>
|
||
* @param string $key 标识位置
|
||
* @param integer $step 步进值
|
||
* @param boolean $save 是否保存结果
|
||
* @return mixed
|
||
*/
|
||
function N($key, $step=0,$save=false) {
|
||
static $_num = array();
|
||
if (!isset($_num[$key])) {
|
||
$_num[$key] = (false !== $save)? S('N_'.$key) : 0;
|
||
}
|
||
if (empty($step)){
|
||
return $_num[$key];
|
||
}else{
|
||
$_num[$key] = $_num[$key] + (int)$step;
|
||
}
|
||
if(false !== $save){ // 保存结果
|
||
S('N_'.$key,$_num[$key],$save);
|
||
}
|
||
return null;
|
||
}
|
||
|
||
/**
|
||
* 字符串命名风格转换
|
||
* type 0 将Java风格转换为C的风格 1 将C风格转换为Java的风格
|
||
* @param string $name 字符串
|
||
* @param integer $type 转换类型
|
||
* @return string
|
||
*/
|
||
function parse_name($name, $type=0) {
|
||
if ($type) {
|
||
return ucfirst(preg_replace_callback('/_([a-zA-Z])/', function($match){return strtoupper($match[1]);}, $name));
|
||
} else {
|
||
return strtolower(trim(preg_replace("/[A-Z]/", "_\\0", $name), "_"));
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 优化的require_once
|
||
* @param string $filename 文件地址
|
||
* @return boolean
|
||
*/
|
||
function require_cache($filename) {
|
||
static $_importFiles = array();
|
||
if (!isset($_importFiles[$filename])) {
|
||
if (file_exists_case($filename)) {
|
||
require $filename;
|
||
$_importFiles[$filename] = true;
|
||
} else {
|
||
$_importFiles[$filename] = false;
|
||
}
|
||
}
|
||
return $_importFiles[$filename];
|
||
}
|
||
|
||
/**
|
||
* 区分大小写的文件存在判断
|
||
* @param string $filename 文件地址
|
||
* @return boolean
|
||
*/
|
||
function file_exists_case($filename) {
|
||
if (is_file($filename)) {
|
||
if (IS_WIN && APP_DEBUG) {
|
||
if (basename(realpath($filename)) != basename($filename))
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* 导入所需的类库 同java的Import 本函数有缓存功能
|
||
* @param string $class 类库命名空间字符串
|
||
* @param string $baseUrl 起始路径
|
||
* @param string $ext 导入的文件扩展名
|
||
* @return boolean
|
||
*/
|
||
function import($class, $baseUrl = '', $ext=EXT) {
|
||
static $_file = array();
|
||
$class = str_replace(array('.', '#'), array('/', '.'), $class);
|
||
if (isset($_file[$class . $baseUrl]))
|
||
return true;
|
||
else
|
||
$_file[$class . $baseUrl] = true;
|
||
$class_strut = explode('/', $class);
|
||
if (empty($baseUrl)) {
|
||
if ('@' == $class_strut[0] || MODULE_NAME == $class_strut[0]) {
|
||
//加载当前模块的类库
|
||
$baseUrl = MODULE_PATH;
|
||
$class = substr_replace($class, '', 0, strlen($class_strut[0]) + 1);
|
||
}elseif ('Common' == $class_strut[0]) {
|
||
//加载公共模块的类库
|
||
$baseUrl = COMMON_PATH;
|
||
$class = substr($class, 7);
|
||
}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);
|
||
}
|
||
return null;
|
||
}
|
||
|
||
/**
|
||
* 基于命名空间方式导入函数库
|
||
* load('@.Util.Array')
|
||
* @param string $name 函数库命名空间字符串
|
||
* @param string $baseUrl 起始路径
|
||
* @param string $ext 导入的文件扩展名
|
||
* @return void
|
||
*/
|
||
function load($name, $baseUrl='', $ext='.php') {
|
||
$name = str_replace(array('.', '#'), array('/', '.'), $name);
|
||
if (empty($baseUrl)) {
|
||
if (0 === strpos($name, '@/')) {//加载当前模块函数库
|
||
$baseUrl = MODULE_PATH.'Common/';
|
||
$name = substr($name, 2);
|
||
} else { //加载其他模块函数库
|
||
$array = explode('/', $name);
|
||
$baseUrl = APP_PATH . array_shift($array).'/Common/';
|
||
$name = implode('/',$array);
|
||
}
|
||
}
|
||
if (substr($baseUrl, -1) != '/'){
|
||
$baseUrl .= '/';
|
||
}
|
||
require_cache($baseUrl . $name . $ext);
|
||
}
|
||
|
||
/**
|
||
* 快速导入第三方框架类库 所有第三方框架的类库文件统一放到 系统的Vendor目录下面
|
||
* @param string $class 类库
|
||