mirror of
https://e.coding.net/circlecloud/MinecraftAccount.git
synced 2026-02-14 10:49:19 +00:00
24
ThinkPHP/Library/Behavior/AgentCheckBehavior.class.php
Normal file
24
ThinkPHP/Library/Behavior/AgentCheckBehavior.class.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2009 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace Behavior;
|
||||
/**
|
||||
* 行为扩展:代理检测
|
||||
*/
|
||||
class AgentCheckBehavior {
|
||||
public function run(&$params) {
|
||||
// 代理访问检测
|
||||
$limitProxyVisit = C('LIMIT_PROXY_VISIT',null,true);
|
||||
if($limitProxyVisit && ($_SERVER['HTTP_X_FORWARDED_FOR'] || $_SERVER['HTTP_VIA'] || $_SERVER['HTTP_PROXY_CONNECTION'] || $_SERVER['HTTP_USER_AGENT_VIA'])) {
|
||||
// 禁止代理访问
|
||||
exit('Access Denied');
|
||||
}
|
||||
}
|
||||
}
|
||||
42
ThinkPHP/Library/Behavior/BorisBehavior.class.php
Normal file
42
ThinkPHP/Library/Behavior/BorisBehavior.class.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2009 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace Behavior;
|
||||
use Think\Think;
|
||||
/**
|
||||
* Boris行为扩展
|
||||
*/
|
||||
class BorisBehavior {
|
||||
public function run(&$params) {
|
||||
if(IS_CLI){
|
||||
if(!function_exists('pcntl_signal'))
|
||||
E("pcntl_signal not working.\nRepl mode based on Linux OS or PHP for OS X(http://php-osx.liip.ch/)\n");
|
||||
Think::addMap(array(
|
||||
'Boris\Boris' => VENDOR_PATH . 'Boris/Boris.php',
|
||||
'Boris\Config' => VENDOR_PATH . 'Boris/Config.php',
|
||||
'Boris\CLIOptionsHandler' => VENDOR_PATH . 'Boris/CLIOptionsHandler.php',
|
||||
'Boris\ColoredInspector' => VENDOR_PATH . 'Boris/ColoredInspector.php',
|
||||
'Boris\DumpInspector' => VENDOR_PATH . 'Boris/DumpInspector.php',
|
||||
'Boris\EvalWorker' => VENDOR_PATH . 'Boris/EvalWorker.php',
|
||||
'Boris\ExportInspector' => VENDOR_PATH . 'Boris/ExportInspector.php',
|
||||
'Boris\Inspector' => VENDOR_PATH . 'Boris/Inspector.php',
|
||||
'Boris\ReadlineClient' => VENDOR_PATH . 'Boris/ReadlineClient.php',
|
||||
'Boris\ShallowParser' => VENDOR_PATH . 'Boris/ShallowParser.php',
|
||||
));
|
||||
$boris = new \Boris\Boris(">>> ");
|
||||
$config = new \Boris\Config();
|
||||
$config->apply($boris, true);
|
||||
$options = new \Boris\CLIOptionsHandler();
|
||||
$options->handle($boris);
|
||||
$boris->onStart(sprintf("echo 'REPL MODE FOR THINKPHP \nTHINKPHP_VERSION: %s, PHP_VERSION: %s, BORIS_VERSION: %s\n';", THINK_VERSION, PHP_VERSION, $boris::VERSION));
|
||||
$boris->start();
|
||||
}
|
||||
}
|
||||
}
|
||||
34
ThinkPHP/Library/Behavior/BrowserCheckBehavior.class.php
Normal file
34
ThinkPHP/Library/Behavior/BrowserCheckBehavior.class.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2009 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace Behavior;
|
||||
/**
|
||||
* 浏览器防刷新检测
|
||||
*/
|
||||
class BrowserCheckBehavior {
|
||||
public function run(&$params) {
|
||||
if($_SERVER['REQUEST_METHOD'] == 'GET') {
|
||||
// 启用页面防刷新机制
|
||||
$guid = md5($_SERVER['PHP_SELF']);
|
||||
// 浏览器防刷新的时间间隔(秒) 默认为10
|
||||
$refleshTime = C('LIMIT_REFLESH_TIMES',null,10);
|
||||
// 检查页面刷新间隔
|
||||
if(cookie('_last_visit_time_'.$guid) && cookie('_last_visit_time_'.$guid)>time()-$refleshTime) {
|
||||
// 页面刷新读取浏览器缓存
|
||||
header('HTTP/1.1 304 Not Modified');
|
||||
exit;
|
||||
}else{
|
||||
// 缓存当前地址访问时间
|
||||
cookie('_last_visit_time_'.$guid, $_SERVER['REQUEST_TIME']);
|
||||
//header('Last-Modified:'.(date('D,d M Y H:i:s',$_SERVER['REQUEST_TIME']-C('LIMIT_REFLESH_TIMES'))).' GMT');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
87
ThinkPHP/Library/Behavior/BuildLiteBehavior.class.php
Normal file
87
ThinkPHP/Library/Behavior/BuildLiteBehavior.class.php
Normal file
@@ -0,0 +1,87 @@
|
||||
<?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>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace Behavior;
|
||||
// 创建Lite运行文件
|
||||
// 可以替换框架入口文件运行
|
||||
// 建议绑定位置app_init
|
||||
class BuildLiteBehavior {
|
||||
public function run(&$params) {
|
||||
if(!defined('BUILD_LITE_FILE')) return ;
|
||||
$litefile = C('RUNTIME_LITE_FILE',null,RUNTIME_PATH.'lite.php');
|
||||
if(is_file($litefile)) return;
|
||||
|
||||
$defs = get_defined_constants(TRUE);
|
||||
$content = 'namespace {$GLOBALS[\'_beginTime\'] = microtime(TRUE);';
|
||||
if(MEMORY_LIMIT_ON) {
|
||||
$content .= '$GLOBALS[\'_startUseMems\'] = memory_get_usage();';
|
||||
}
|
||||
|
||||
// 生成数组定义
|
||||
unset($defs['user']['BUILD_LITE_FILE']);
|
||||
$content .= $this->buildArrayDefine($defs['user']).'}';
|
||||
|
||||
// 读取编译列表文件
|
||||
$filelist = is_file(CONF_PATH.'lite.php')?
|
||||
include CONF_PATH.'lite.php':
|
||||
array(
|
||||
THINK_PATH.'Common/functions.php',
|
||||
COMMON_PATH.'Common/function.php',
|
||||
CORE_PATH . 'Think'.EXT,
|
||||
CORE_PATH . 'Hook'.EXT,
|
||||
CORE_PATH . 'App'.EXT,
|
||||
CORE_PATH . 'Dispatcher'.EXT,
|
||||
CORE_PATH . 'Log'.EXT,
|
||||
CORE_PATH . 'Log/Driver/File'.EXT,
|
||||
CORE_PATH . 'Route'.EXT,
|
||||
CORE_PATH . 'Controller'.EXT,
|
||||
CORE_PATH . 'View'.EXT,
|
||||
CORE_PATH . 'Storage'.EXT,
|
||||
CORE_PATH . 'Storage/Driver/File'.EXT,
|
||||
CORE_PATH . 'Exception'.EXT,
|
||||
BEHAVIOR_PATH . 'ParseTemplateBehavior'.EXT,
|
||||
BEHAVIOR_PATH . 'ContentReplaceBehavior'.EXT,
|
||||
);
|
||||
|
||||
// 编译文件
|
||||
foreach ($filelist as $file){
|
||||
if(is_file($file)) {
|
||||
$content .= compile($file);
|
||||
}
|
||||
}
|
||||
|
||||
// 处理Think类的start方法
|
||||
$content = preg_replace('/\$runtimefile = RUNTIME_PATH(.+?)(if\(APP_STATUS)/','\2',$content,1);
|
||||
$content .= "\nnamespace { Think\Think::addMap(".var_export(\Think\Think::getMap(),true).");";
|
||||
$content .= "\nL(".var_export(L(),true).");\nC(".var_export(C(),true).');Think\Hook::import('.var_export(\Think\Hook::get(),true).');Think\Think::start();}';
|
||||
|
||||
// 生成运行Lite文件
|
||||
file_put_contents($litefile,strip_whitespace('<?php '.$content));
|
||||
}
|
||||
|
||||
// 根据数组生成常量定义
|
||||
private function buildArrayDefine($array) {
|
||||
$content = "\n";
|
||||
foreach ($array as $key => $val) {
|
||||
$key = strtoupper($key);
|
||||
$content .= 'defined(\'' . $key . '\') or ';
|
||||
if (is_int($val) || is_float($val)) {
|
||||
$content .= "define('" . $key . "'," . $val . ');';
|
||||
} elseif (is_bool($val)) {
|
||||
$val = ($val) ? 'true' : 'false';
|
||||
$content .= "define('" . $key . "'," . $val . ');';
|
||||
} elseif (is_string($val)) {
|
||||
$content .= "define('" . $key . "','" . addslashes($val) . "');";
|
||||
}
|
||||
$content .= "\n";
|
||||
}
|
||||
return $content;
|
||||
}
|
||||
}
|
||||
194
ThinkPHP/Library/Behavior/CheckActionRouteBehavior.class.php
Normal file
194
ThinkPHP/Library/Behavior/CheckActionRouteBehavior.class.php
Normal file
@@ -0,0 +1,194 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2012 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace Behavior;
|
||||
/**
|
||||
* 系统行为扩展:操作路由检测
|
||||
*/
|
||||
class CheckActionRouteBehavior {
|
||||
|
||||
// 行为扩展的执行入口必须是run
|
||||
public function run(&$config){
|
||||
// 优先检测是否存在PATH_INFO
|
||||
$regx = trim($_SERVER['PATH_INFO'],'/');
|
||||
if(empty($regx)) return ;
|
||||
// 路由定义文件优先于config中的配置定义
|
||||
// 路由处理
|
||||
$routes = $config['routes'];
|
||||
if(!empty($routes)) {
|
||||
$depr = C('URL_PATHINFO_DEPR');
|
||||
// 分隔符替换 确保路由定义使用统一的分隔符
|
||||
$regx = str_replace($depr,'/',$regx);
|
||||
$regx = substr_replace($regx,'',0,strlen(__URL__));
|
||||
foreach ($routes as $rule=>$route){
|
||||
if(0===strpos($rule,'/') && preg_match($rule,$regx,$matches)) { // 正则路由
|
||||
return C('ACTION_NAME',$this->parseRegex($matches,$route,$regx));
|
||||
}else{ // 规则路由
|
||||
$len1 = substr_count($regx,'/');
|
||||
$len2 = substr_count($rule,'/');
|
||||
if($len1>=$len2) {
|
||||
if('$' == substr($rule,-1,1)) {// 完整匹配
|
||||
if($len1 != $len2) {
|
||||
continue;
|
||||
}else{
|
||||
$rule = substr($rule,0,-1);
|
||||
}
|
||||
}
|
||||
$match = $this->checkUrlMatch($regx,$rule);
|
||||
if($match) return C('ACTION_NAME',$this->parseRule($rule,$route,$regx));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 检测URL和规则路由是否匹配
|
||||
private function checkUrlMatch($regx,$rule) {
|
||||
$m1 = explode('/',$regx);
|
||||
$m2 = explode('/',$rule);
|
||||
$match = true; // 是否匹配
|
||||
foreach ($m2 as $key=>$val){
|
||||
if(':' == substr($val,0,1)) {// 动态变量
|
||||
if(strpos($val,'\\')) {
|
||||
$type = substr($val,-1);
|
||||
if('d'==$type && !is_numeric($m1[$key])) {
|
||||
$match = false;
|
||||
break;
|
||||
}
|
||||
}elseif(strpos($val,'^')){
|
||||
$array = explode('|',substr(strstr($val,'^'),1));
|
||||
if(in_array($m1[$key],$array)) {
|
||||
$match = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}elseif(0 !== strcasecmp($val,$m1[$key])){
|
||||
$match = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $match;
|
||||
}
|
||||
|
||||
// 解析规范的路由地址
|
||||
// 地址格式 操作?参数1=值1&参数2=值2...
|
||||
private function parseUrl($url) {
|
||||
$var = array();
|
||||
if(false !== strpos($url,'?')) { // 操作?参数1=值1&参数2=值2...
|
||||
$info = parse_url($url);
|
||||
$path = $info['path'];
|
||||
parse_str($info['query'],$var);
|
||||
}else{ // 操作
|
||||
$path = $url;
|
||||
}
|
||||
$var[C('VAR_ACTION')] = $path;
|
||||
return $var;
|
||||
}
|
||||
|
||||
// 解析规则路由
|
||||
// '路由规则'=>'操作?额外参数1=值1&额外参数2=值2...'
|
||||
// '路由规则'=>array('操作','额外参数1=值1&额外参数2=值2...')
|
||||
// '路由规则'=>'外部地址'
|
||||
// '路由规则'=>array('外部地址','重定向代码')
|
||||
// 路由规则中 :开头 表示动态变量
|
||||
// 外部地址中可以用动态变量 采用 :1 :2 的方式
|
||||
// 'news/:month/:day/:id'=>array('News/read?cate=1','status=1'),
|
||||
// 'new/:id'=>array('/new.php?id=:1',301), 重定向
|
||||
private function parseRule($rule,$route,$regx) {
|
||||
// 获取路由地址规则
|
||||
$url = is_array($route)?$route[0]:$route;
|
||||
// 获取URL地址中的参数
|
||||
$paths = explode('/',$regx);
|
||||
// 解析路由规则
|
||||
$matches = array();
|
||||
$rule = explode('/',$rule);
|
||||
foreach ($rule as $item){
|
||||
if(0===strpos($item,':')) { // 动态变量获取
|
||||
if($pos = strpos($item,'^') ) {
|
||||
$var = substr($item,1,$pos-1);
|
||||
}elseif(strpos($item,'\\')){
|
||||
$var = substr($item,1,-2);
|
||||
}else{
|
||||
$var = substr($item,1);
|
||||
}
|
||||
$matches[$var] = array_shift($paths);
|
||||
}else{ // 过滤URL中的静态变量
|
||||
array_shift($paths);
|
||||
}
|
||||
}
|
||||
if(0=== strpos($url,'/') || 0===strpos($url,'http')) { // 路由重定向跳转
|
||||
if(strpos($url,':')) { // 传递动态参数
|
||||
$values = array_values($matches);
|
||||
$url = preg_replace('/:(\d+)/e','$values[\\1-1]',$url);
|
||||
}
|
||||
header("Location: $url", true,(is_array($route) && isset($route[1]))?$route[1]:301);
|
||||
exit;
|
||||
}else{
|
||||
// 解析路由地址
|
||||
$var = $this->parseUrl($url);
|
||||
// 解析路由地址里面的动态参数
|
||||
$values = array_values($matches);
|
||||
foreach ($var as $key=>$val){
|
||||
if(0===strpos($val,':')) {
|
||||
$var[$key] = $values[substr($val,1)-1];
|
||||
}
|
||||
}
|
||||
$var = array_merge($matches,$var);
|
||||
// 解析剩余的URL参数
|
||||
if($paths) {
|
||||
preg_replace('@(\w+)\/([^\/]+)@e', '$var[strtolower(\'\\1\')]=strip_tags(\'\\2\');', implode('/',$paths));
|
||||
}
|
||||
// 解析路由自动传入参数
|
||||
if(is_array($route) && isset($route[1])) {
|
||||
parse_str($route[1],$params);
|
||||
$var = array_merge($var,$params);
|
||||
}
|
||||
$action = $var[C('VAR_ACTION')];
|
||||
unset($var[C('VAR_ACTION')]);
|
||||
$_GET = array_merge($var,$_GET);
|
||||
return $action;
|
||||
}
|
||||
}
|
||||
|
||||
// 解析正则路由
|
||||
// '路由正则'=>'[分组/模块/操作]?参数1=值1&参数2=值2...'
|
||||
// '路由正则'=>array('[分组/模块/操作]?参数1=值1&参数2=值2...','额外参数1=值1&额外参数2=值2...')
|
||||
// '路由正则'=>'外部地址'
|
||||
// '路由正则'=>array('外部地址','重定向代码')
|
||||
// 参数值和外部地址中可以用动态变量 采用 :1 :2 的方式
|
||||
// '/new\/(\d+)\/(\d+)/'=>array('News/read?id=:1&page=:2&cate=1','status=1'),
|
||||
// '/new\/(\d+)/'=>array('/new.php?id=:1&page=:2&status=1','301'), 重定向
|
||||
private function parseRegex($matches,$route,$regx) {
|
||||
// 获取路由地址规则
|
||||
$url = is_array($route)?$route[0]:$route;
|
||||
$url = preg_replace('/:(\d+)/e','$matches[\\1]',$url);
|
||||
if(0=== strpos($url,'/') || 0===strpos($url,'http')) { // 路由重定向跳转
|
||||
header("Location: $url", true,(is_array($route) && isset($route[1]))?$route[1]:301);
|
||||
exit;
|
||||
}else{
|
||||
// 解析路由地址
|
||||
$var = $this->parseUrl($url);
|
||||
// 解析剩余的URL参数
|
||||
$regx = substr_replace($regx,'',0,strlen($matches[0]));
|
||||
if($regx) {
|
||||
preg_replace('@(\w+)\/([^,\/]+)@e', '$var[strtolower(\'\\1\')]=strip_tags(\'\\2\');', $regx);
|
||||
}
|
||||
// 解析路由自动传入参数
|
||||
if(is_array($route) && isset($route[1])) {
|
||||
parse_str($route[1],$params);
|
||||
$var = array_merge($var,$params);
|
||||
}
|
||||
$action = $var[C('VAR_ACTION')];
|
||||
unset($var[C('VAR_ACTION')]);
|
||||
$_GET = array_merge($var,$_GET);
|
||||
}
|
||||
return $action;
|
||||
}
|
||||
}
|
||||
77
ThinkPHP/Library/Behavior/CheckLangBehavior.class.php
Normal file
77
ThinkPHP/Library/Behavior/CheckLangBehavior.class.php
Normal file
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2012 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace Behavior;
|
||||
/**
|
||||
* 语言检测 并自动加载语言包
|
||||
*/
|
||||
class CheckLangBehavior {
|
||||
|
||||
// 行为扩展的执行入口必须是run
|
||||
public function run(&$params){
|
||||
// 检测语言
|
||||
$this->checkLanguage();
|
||||
}
|
||||
|
||||
/**
|
||||
* 语言检查
|
||||
* 检查浏览器支持语言,并自动加载语言包
|
||||
* @access private
|
||||
* @return void
|
||||
*/
|
||||
private function checkLanguage() {
|
||||
// 不开启语言包功能,仅仅加载框架语言文件直接返回
|
||||
if (!C('LANG_SWITCH_ON',null,false)){
|
||||
return;
|
||||
}
|
||||
$langSet = C('DEFAULT_LANG');
|
||||
$varLang = C('VAR_LANGUAGE',null,'l');
|
||||
$langList = C('LANG_LIST',null,'zh-cn');
|
||||
// 启用了语言包功能
|
||||
// 根据是否启用自动侦测设置获取语言选择
|
||||
if (C('LANG_AUTO_DETECT',null,true)){
|
||||
if(isset($_GET[$varLang])){
|
||||
$langSet = $_GET[$varLang];// url中设置了语言变量
|
||||
cookie('think_language',$langSet,3600);
|
||||
}elseif(cookie('think_language')){// 获取上次用户的选择
|
||||
$langSet = cookie('think_language');
|
||||
}elseif(isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])){// 自动侦测浏览器语言
|
||||
preg_match('/^([a-z\d\-]+)/i', $_SERVER['HTTP_ACCEPT_LANGUAGE'], $matches);
|
||||
$langSet = $matches[1];
|
||||
cookie('think_language',$langSet,3600);
|
||||
}
|
||||
if(false === stripos($langList,$langSet)) { // 非法语言参数
|
||||
$langSet = C('DEFAULT_LANG');
|
||||
}
|
||||
}
|
||||
// 定义当前语言
|
||||
define('LANG_SET',strtolower($langSet));
|
||||
|
||||
// 读取框架语言包
|
||||
$file = THINK_PATH.'Lang/'.LANG_SET.'.php';
|
||||
if(LANG_SET != C('DEFAULT_LANG') && is_file($file))
|
||||
L(include $file);
|
||||
|
||||
// 读取应用公共语言包
|
||||
$file = LANG_PATH.LANG_SET.'.php';
|
||||
if(is_file($file))
|
||||
L(include $file);
|
||||
|
||||
// 读取模块语言包
|
||||
$file = MODULE_PATH.'Lang/'.LANG_SET.'.php';
|
||||
if(is_file($file))
|
||||
L(include $file);
|
||||
|
||||
// 读取当前控制器语言包
|
||||
$file = MODULE_PATH.'Lang/'.LANG_SET.'/'.strtolower(CONTROLLER_NAME).'.php';
|
||||
if (is_file($file))
|
||||
L(include $file);
|
||||
}
|
||||
}
|
||||
610
ThinkPHP/Library/Behavior/ChromeShowPageTraceBehavior.class.php
Normal file
610
ThinkPHP/Library/Behavior/ChromeShowPageTraceBehavior.class.php
Normal file
@@ -0,0 +1,610 @@
|
||||
<?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: luofei614 <weibo.com/luofei614>
|
||||
// +----------------------------------------------------------------------
|
||||
// $Id$
|
||||
|
||||
/**
|
||||
* 将Trace信息输出到chrome浏览器的控制器,从而不影响ajax效果和页面的布局。
|
||||
* 使用前,你需要先安装 chrome log 这个插件: http://craig.is/writing/chrome-logger。
|
||||
* 定义应用的tags.php文件 Application/Common/Conf/tags.php,
|
||||
* <code>
|
||||
* <?php return array(
|
||||
* 'app_end'=>array(
|
||||
* 'Behavior\ChromeShowPageTrace'
|
||||
* )
|
||||
* );
|
||||
* </code>
|
||||
* 如果trace信息没有正常输出,请查看您的日志。
|
||||
* 这是通过http headers和chrome通信,所以要保证在输出trace信息之前不能有
|
||||
* headers输出,你可以在入口文件第一行加入代码 ob_start(); 或者配置output_buffering
|
||||
*
|
||||
*/
|
||||
namespace Behavior;
|
||||
use Think\Log;
|
||||
|
||||
/**
|
||||
* 系统行为扩展 页面Trace显示输出
|
||||
*/
|
||||
class ChromeShowPageTraceBehavior {
|
||||
|
||||
protected $tracePageTabs = array('BASE'=>'基本','FILE'=>'文件','INFO'=>'流程','ERR|NOTIC'=>'错误','SQL'=>'SQL','DEBUG'=>'调试');
|
||||
|
||||
// 行为扩展的执行入口必须是run
|
||||
public function run(&$params){
|
||||
if(C('SHOW_PAGE_TRACE')) $this->showTrace();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 显示页面Trace信息
|
||||
* @access private
|
||||
*/
|
||||
private function showTrace() {
|
||||
// 系统默认显示信息
|
||||
$files = get_included_files();
|
||||
$info = array();
|
||||
foreach ($files as $key=>$file){
|
||||
$info[] = $file.' ( '.number_format(filesize($file)/1024,2).' KB )';
|
||||
}
|
||||
$trace = array();
|
||||
$base = array(
|
||||
'请求信息' => date('Y-m-d H:i:s',$_SERVER['REQUEST_TIME']).' '.$_SERVER['SERVER_PROTOCOL'].' '.$_SERVER['REQUEST_METHOD'].' : '.__SELF__,
|
||||
'运行时间' => $this->showTime(),
|
||||
'吞吐率' => number_format(1/G('beginTime','viewEndTime'),2).'req/s',
|
||||
'内存开销' => MEMORY_LIMIT_ON?number_format((memory_get_usage() - $GLOBALS['_startUseMems'])/1024,2).' kb':'不支持',
|
||||
'查询信息' => N('db_query').' queries '.N('db_write').' writes ',
|
||||
'文件加载' => count(get_included_files()),
|
||||
'缓存信息' => N('cache_read').' gets '.N('cache_write').' writes ',
|
||||
'配置加载' => count(c()),
|
||||
'会话信息' => 'SESSION_ID='.session_id(),
|
||||
);
|
||||
// 读取应用定义的Trace文件
|
||||
$traceFile = COMMON_PATH.'Conf/trace.php';
|
||||
if(is_file($traceFile)) {
|
||||
$base = array_merge($base,include $traceFile);
|
||||
}
|
||||
|
||||
$debug = trace();
|
||||
$tabs = C('TRACE_PAGE_TABS',null,$this->tracePageTabs);
|
||||
foreach ($tabs as $name=>$title){
|
||||
switch(strtoupper($name)) {
|
||||
case 'BASE':// 基本信息
|
||||
$trace[$title] = $base;
|
||||
break;
|
||||
case 'FILE': // 文件信息
|
||||
$trace[$title] = $info;
|
||||
break;
|
||||
default:// 调试信息
|
||||
$name = strtoupper($name);
|
||||
if(strpos($name,'|')) {// 多组信息
|
||||
$array = explode('|',$name);
|
||||
$result = array();
|
||||
foreach($array as $name){
|
||||
$result += isset($debug[$name])?$debug[$name]:array();
|
||||
}
|
||||
$trace[$title] = $result;
|
||||
}else{
|
||||
$trace[$title] = isset($debug[$name])?$debug[$name]:'';
|
||||
}
|
||||
}
|
||||
}
|
||||
chrome_debug('TRACE信息:'.__SELF__,'group');
|
||||
//输出日志
|
||||
foreach($trace as $title=>$log){
|
||||
'错误'==$title?chrome_debug($title,'group'):chrome_debug($title,'groupCollapsed');
|
||||
foreach($log as $i=>$logstr){
|
||||
chrome_debug($i.'.'.$logstr,'log');
|
||||
}
|
||||
chrome_debug('','groupEnd');
|
||||
}
|
||||
chrome_debug('','groupEnd');
|
||||
if($save = C('PAGE_TRACE_SAVE')) { // 保存页面Trace日志
|
||||
if(is_array($save)) {// 选择选项卡保存
|
||||
$tabs = C('TRACE_PAGE_TABS',null,$this->tracePageTabs);
|
||||
$array = array();
|
||||
foreach ($save as $tab){
|
||||
$array[] = $tabs[$tab];
|
||||
}
|
||||
}
|
||||
$content = date('[ c ]').' '.get_client_ip().' '.$_SERVER['REQUEST_URI']."\r\n";
|
||||
foreach ($trace as $key=>$val){
|
||||
if(!isset($array) || in_array($key,$array)) {
|
||||
$content .= '[ '.$key." ]\r\n";
|
||||
if(is_array($val)) {
|
||||
foreach ($val as $k=>$v){
|
||||
$content .= (!is_numeric($k)?$k.':':'').print_r($v,true)."\r\n";
|
||||
}
|
||||
}else{
|
||||
$content .= print_r($val,true)."\r\n";
|
||||
}
|
||||
$content .= "\r\n";
|
||||
}
|
||||
}
|
||||
error_log(str_replace('<br/>',"\r\n",$content), 3,LOG_PATH.date('y_m_d').'_trace.log');
|
||||
}
|
||||
unset($files,$info,$base);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取运行时间
|
||||
*/
|
||||
private function showTime() {
|
||||
// 显示运行时间
|
||||
G('beginTime',$GLOBALS['_beginTime']);
|
||||
G('viewEndTime');
|
||||
// 显示详细运行时间
|
||||
return G('beginTime','viewEndTime').'s ( Load:'.G('beginTime','loadTime').'s Init:'.G('loadTime','initTime').'s Exec:'.G('initTime','viewStartTime').'s Template:'.G('viewStartTime','viewEndTime').'s )';
|
||||
}
|
||||
}
|
||||
if(!function_exists('chrome_debug')){
|
||||
//ChromePhp 输出trace的函数
|
||||
function chrome_debug($msg,$type='trace',$trace_level=1){
|
||||
if('trace'==$type){
|
||||
ChromePhp::groupCollapsed($msg);
|
||||
$traces=debug_backtrace(false);
|
||||
$traces=array_reverse($traces);
|
||||
$max=count($traces)-$trace_level;
|
||||
for($i=0;$i<$max;$i++){
|
||||
$trace=$traces[$i];
|
||||
$fun=isset($trace['class'])?$trace['class'].'::'.$trace['function']:$trace['function'];
|
||||
$file=isset($trace['file'])?$trace['file']:'unknown file';
|
||||
$line=isset($trace['line'])?$trace['line']:'unknown line';
|
||||
$trace_msg='#'.$i.' '.$fun.' called at ['.$file.':'.$line.']';
|
||||
if(!empty($trace['args'])){
|
||||
ChromePhp::groupCollapsed($trace_msg);
|
||||
ChromePhp::log($trace['args']);
|
||||
ChromePhp::groupEnd();
|
||||
}else{
|
||||
ChromePhp::log($trace_msg);
|
||||
}
|
||||
}
|
||||
ChromePhp::groupEnd();
|
||||
}else{
|
||||
if(method_exists('Behavior\ChromePhp',$type)){
|
||||
//支持type trace,warn,log,error,group, groupCollapsed, groupEnd等
|
||||
call_user_func(array('Behavior\ChromePhp',$type),$msg);
|
||||
}else{
|
||||
//如果type不为trace,warn,log等,则为log的标签
|
||||
call_user_func_array(array('Behavior\ChromePhp','log'),func_get_args());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Server Side Chrome PHP debugger class
|
||||
*
|
||||
* @package ChromePhp
|
||||
* @author Craig Campbell <iamcraigcampbell@gmail.com>
|
||||
*/
|
||||
class ChromePhp{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
const VERSION = '4.1.0';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
const HEADER_NAME = 'X-ChromeLogger-Data';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
const BACKTRACE_LEVEL = 'backtrace_level';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
const LOG = 'log';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
const WARN = 'warn';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
const ERROR = 'error';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
const GROUP = 'group';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
const INFO = 'info';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
const GROUP_END = 'groupEnd';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
const GROUP_COLLAPSED = 'groupCollapsed';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
const TABLE = 'table';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $_php_version;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $_timestamp;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_json = array(
|
||||
'version' => self::VERSION,
|
||||
'columns' => array('log', 'backtrace', 'type'),
|
||||
'rows' => array()
|
||||
);
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_backtraces = array();
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $_error_triggered = false;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_settings = array(
|
||||
self::BACKTRACE_LEVEL => 1
|
||||
);
|
||||
|
||||
/**
|
||||
* @var ChromePhp
|
||||
*/
|
||||
protected static $_instance;
|
||||
|
||||
/**
|
||||
* Prevent recursion when working with objects referring to each other
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_processed = array();
|
||||
|
||||
/**
|
||||
* constructor
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
$this->_php_version = phpversion();
|
||||
$this->_timestamp = $this->_php_version >= 5.1 ? $_SERVER['REQUEST_TIME'] : time();
|
||||
$this->_json['request_uri'] = $_SERVER['REQUEST_URI'];
|
||||
}
|
||||
|
||||
/**
|
||||
* gets instance of this class
|
||||
*
|
||||
* @return ChromePhp
|
||||
*/
|
||||
public static function getInstance()
|
||||
{
|
||||
if (self::$_instance === null) {
|
||||
self::$_instance = new self();
|
||||
}
|
||||
return self::$_instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* logs a variable to the console
|
||||
*
|
||||
* @param mixed $data,... unlimited OPTIONAL number of additional logs [...]
|
||||
* @return void
|
||||
*/
|
||||
public static function log()
|
||||
{
|
||||
$args = func_get_args();
|
||||
return self::_log('', $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* logs a warning to the console
|
||||
*
|
||||
* @param mixed $data,... unlimited OPTIONAL number of additional logs [...]
|
||||
* @return void
|
||||
*/
|
||||
public static function warn()
|
||||
{
|
||||
$args = func_get_args();
|
||||
return self::_log(self::WARN, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* logs an error to the console
|
||||
*
|
||||
* @param mixed $data,... unlimited OPTIONAL number of additional logs [...]
|
||||
* @return void
|
||||
*/
|
||||
public static function error()
|
||||
{
|
||||
$args = func_get_args();
|
||||
return self::_log(self::ERROR, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* sends a group log
|
||||
*
|
||||
* @param string value
|
||||
*/
|
||||
public static function group()
|
||||
{
|
||||
$args = func_get_args();
|
||||
return self::_log(self::GROUP, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* sends an info log
|
||||
*
|
||||
* @param mixed $data,... unlimited OPTIONAL number of additional logs [...]
|
||||
* @return void
|
||||
*/
|
||||
public static function info()
|
||||
{
|
||||
$args = func_get_args();
|
||||
return self::_log(self::INFO, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* sends a collapsed group log
|
||||
*
|
||||
* @param string value
|
||||
*/
|
||||
public static function groupCollapsed()
|
||||
{
|
||||
$args = func_get_args();
|
||||
return self::_log(self::GROUP_COLLAPSED, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* ends a group log
|
||||
*
|
||||
* @param string value
|
||||
*/
|
||||
public static function groupEnd()
|
||||
{
|
||||
$args = func_get_args();
|
||||
return self::_log(self::GROUP_END, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* sends a table log
|
||||
*
|
||||
* @param string value
|
||||
*/
|
||||
public static function table()
|
||||
{
|
||||
$args = func_get_args();
|
||||
return self::_log(self::TABLE, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* internal logging call
|
||||
*
|
||||
* @param string $type
|
||||
* @return void
|
||||
*/
|
||||
protected static function _log($type, array $args)
|
||||
{
|
||||
// nothing passed in, don't do anything
|
||||
if (count($args) == 0 && $type != self::GROUP_END) {
|
||||
return;
|
||||
}
|
||||
|
||||
$logger = self::getInstance();
|
||||
|
||||
$logger->_processed = array();
|
||||
|
||||
$logs = array();
|
||||
foreach ($args as $arg) {
|
||||
$logs[] = $logger->_convert($arg);
|
||||
}
|
||||
|
||||
$backtrace = debug_backtrace(false);
|
||||
$level = $logger->getSetting(self::BACKTRACE_LEVEL);
|
||||
|
||||
$backtrace_message = 'unknown';
|
||||
if (isset($backtrace[$level]['file']) && isset($backtrace[$level]['line'])) {
|
||||
$backtrace_message = $backtrace[$level]['file'] . ' : ' . $backtrace[$level]['line'];
|
||||
}
|
||||
|
||||
$logger->_addRow($logs, $backtrace_message, $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* converts an object to a better format for logging
|
||||
*
|
||||
* @param Object
|
||||
* @return array
|
||||
*/
|
||||
protected function _convert($object)
|
||||
{
|
||||
// if this isn't an object then just return it
|
||||
if (!is_object($object)) {
|
||||
return $object;
|
||||
}
|
||||
|
||||
//Mark this object as processed so we don't convert it twice and it
|
||||
//Also avoid recursion when objects refer to each other
|
||||
$this->_processed[] = $object;
|
||||
|
||||
$object_as_array = array();
|
||||
|
||||
// first add the class name
|
||||
$object_as_array['___class_name'] = get_class($object);
|
||||
|
||||
// loop through object vars
|
||||
$object_vars = get_object_vars($object);
|
||||
foreach ($object_vars as $key => $value) {
|
||||
|
||||
// same instance as parent object
|
||||
if ($value === $object || in_array($value, $this->_processed, true)) {
|
||||
$value = 'recursion - parent object [' . get_class($value) . ']';
|
||||
}
|
||||
$object_as_array[$key] = $this->_convert($value);
|
||||
}
|
||||
|
||||
$reflection = new ReflectionClass($object);
|
||||
|
||||
// loop through the properties and add those
|
||||
foreach ($reflection->getProperties() as $property) {
|
||||
|
||||
// if one of these properties was already added above then ignore it
|
||||
if (array_key_exists($property->getName(), $object_vars)) {
|
||||
continue;
|
||||
}
|
||||
$type = $this->_getPropertyKey($property);
|
||||
|
||||
if ($this->_php_version >= 5.3) {
|
||||
$property->setAccessible(true);
|
||||
}
|
||||
|
||||
try {
|
||||
$value = $property->getValue($object);
|
||||
} catch (ReflectionException $e) {
|
||||
$value = 'only PHP 5.3 can access private/protected properties';
|
||||
}
|
||||
|
||||
// same instance as parent object
|
||||
if ($value === $object || in_array($value, $this->_processed, true)) {
|
||||
$value = 'recursion - parent object [' . get_class($value) . ']';
|
||||
}
|
||||
|
||||
$object_as_array[$type] = $this->_convert($value);
|
||||
}
|
||||
return $object_as_array;
|
||||
}
|
||||
|
||||
/**
|
||||
* takes a reflection property and returns a nicely formatted key of the property name
|
||||
*
|
||||
* @param ReflectionProperty
|
||||
* @return string
|
||||
*/
|
||||
protected function _getPropertyKey(ReflectionProperty $property)
|
||||
{
|
||||
$static = $property->isStatic() ? ' static' : '';
|
||||
if ($property->isPublic()) {
|
||||
return 'public' . $static . ' ' . $property->getName();
|
||||
}
|
||||
|
||||
if ($property->isProtected()) {
|
||||
return 'protected' . $static . ' ' . $property->getName();
|
||||
}
|
||||
|
||||
if ($property->isPrivate()) {
|
||||
return 'private' . $static . ' ' . $property->getName();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* adds a value to the data array
|
||||
*
|
||||
* @var mixed
|
||||
* @return void
|
||||
*/
|
||||
protected function _addRow(array $logs, $backtrace, $type)
|
||||
{
|
||||
// if this is logged on the same line for example in a loop, set it to null to save space
|
||||
if (in_array($backtrace, $this->_backtraces)) {
|
||||
$backtrace = null;
|
||||
}
|
||||
|
||||
// for group, groupEnd, and groupCollapsed
|
||||
// take out the backtrace since it is not useful
|
||||
if ($type == self::GROUP || $type == self::GROUP_END || $type == self::GROUP_COLLAPSED) {
|
||||
$backtrace = null;
|
||||
}
|
||||
|
||||
if ($backtrace !== null) {
|
||||
$this->_backtraces[] = $backtrace;
|
||||
}
|
||||
|
||||
$row = array($logs, $backtrace, $type);
|
||||
|
||||
$this->_json['rows'][] = $row;
|
||||
$this->_writeHeader($this->_json);
|
||||
}
|
||||
|
||||
protected function _writeHeader($data)
|
||||
{
|
||||
header(self::HEADER_NAME . ': ' . $this->_encode($data));
|
||||
}
|
||||
|
||||
/**
|
||||
* encodes the data to be sent along with the request
|
||||
*
|
||||
* @param array $data
|
||||
* @return string
|
||||
*/
|
||||
protected function _encode($data)
|
||||
{
|
||||
return base64_encode(utf8_encode(json_encode($data)));
|
||||
}
|
||||
|
||||
/**
|
||||
* adds a setting
|
||||
*
|
||||
* @param string key
|
||||
* @param mixed value
|
||||
* @return void
|
||||
*/
|
||||
public function addSetting($key, $value)
|
||||
{
|
||||
$this->_settings[$key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* add ability to set multiple settings in one call
|
||||
*
|
||||
* @param array $settings
|
||||
* @return void
|
||||
*/
|
||||
public function addSettings(array $settings)
|
||||
{
|
||||
foreach ($settings as $key => $value) {
|
||||
$this->addSetting($key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gets a setting
|
||||
*
|
||||
* @param string key
|
||||
* @return mixed
|
||||
*/
|
||||
public function getSetting($key)
|
||||
{
|
||||
if (!isset($this->_settings[$key])) {
|
||||
return null;
|
||||
}
|
||||
return $this->_settings[$key];
|
||||
}
|
||||
}
|
||||
}
|
||||
47
ThinkPHP/Library/Behavior/ContentReplaceBehavior.class.php
Normal file
47
ThinkPHP/Library/Behavior/ContentReplaceBehavior.class.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?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>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace Behavior;
|
||||
/**
|
||||
* 系统行为扩展:模板内容输出替换
|
||||
*/
|
||||
class ContentReplaceBehavior {
|
||||
|
||||
// 行为扩展的执行入口必须是run
|
||||
public function run(&$content){
|
||||
$content = $this->templateContentReplace($content);
|
||||
}
|
||||
|
||||
/**
|
||||
* 模板内容替换
|
||||
* @access protected
|
||||
* @param string $content 模板内容
|
||||
* @return string
|
||||
*/
|
||||
protected function templateContentReplace($content) {
|
||||
// 系统默认的特殊变量替换
|
||||
$replace = array(
|
||||
'__ROOT__' => __ROOT__, // 当前网站地址
|
||||
'__APP__' => __APP__, // 当前应用地址
|
||||
'__MODULE__' => __MODULE__,
|
||||
'__ACTION__' => __ACTION__, // 当前操作地址
|
||||
'__SELF__' => htmlentities(__SELF__), // 当前页面地址
|
||||
'__CONTROLLER__'=> __CONTROLLER__,
|
||||
'__URL__' => __CONTROLLER__,
|
||||
'__PUBLIC__' => __ROOT__.'/Public',// 站点公共目录
|
||||
);
|
||||
// 允许用户自定义模板的字符串替换
|
||||
if(is_array(C('TMPL_PARSE_STRING')) )
|
||||
$replace = array_merge($replace,C('TMPL_PARSE_STRING'));
|
||||
$content = str_replace(array_keys($replace),array_values($replace),$content);
|
||||
return $content;
|
||||
}
|
||||
|
||||
}
|
||||
66
ThinkPHP/Library/Behavior/CronRunBehavior.class.php
Normal file
66
ThinkPHP/Library/Behavior/CronRunBehavior.class.php
Normal file
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2009 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace Behavior;
|
||||
/**
|
||||
* 自动执行任务
|
||||
*/
|
||||
class CronRunBehavior {
|
||||
|
||||
public function run(&$params) {
|
||||
// 锁定自动执行
|
||||
$lockfile = RUNTIME_PATH.'cron.lock';
|
||||
if(is_writable($lockfile) && filemtime($lockfile) > $_SERVER['REQUEST_TIME'] - C('CRON_MAX_TIME',null,60)) {
|
||||
return ;
|
||||
} else {
|
||||
touch($lockfile);
|
||||
}
|
||||
set_time_limit(1000);
|
||||
ignore_user_abort(true);
|
||||
|
||||
// 载入cron配置文件
|
||||
// 格式 return array(
|
||||
// 'cronname'=>array('filename',intervals,nextruntime),...
|
||||
// );
|
||||
if(is_file(RUNTIME_PATH.'~crons.php')) {
|
||||
$crons = include RUNTIME_PATH.'~crons.php';
|
||||
}elseif(is_file(COMMON_PATH.'Conf/crons.php')){
|
||||
$crons = include COMMON_PATH.'Conf/crons.php';
|
||||
}
|
||||
if(isset($crons) && is_array($crons)) {
|
||||
$update = false;
|
||||
$log = array();
|
||||
foreach ($crons as $key=>$cron){
|
||||
if(empty($cron[2]) || $_SERVER['REQUEST_TIME']>=$cron[2]) {
|
||||
// 到达时间 执行cron文件
|
||||
G('cronStart');
|
||||
include COMMON_PATH.'Cron/'.$cron[0].'.php';
|
||||
G('cronEnd');
|
||||
$_useTime = G('cronStart','cronEnd', 6);
|
||||
// 更新cron记录
|
||||
$cron[2] = $_SERVER['REQUEST_TIME']+$cron[1];
|
||||
$crons[$key] = $cron;
|
||||
$log[] = "Cron:$key Runat ".date('Y-m-d H:i:s')." Use $_useTime s\n";
|
||||
$update = true;
|
||||
}
|
||||
}
|
||||
if($update) {
|
||||
// 记录Cron执行日志
|
||||
\Think\Log::write(implode('',$log));
|
||||
// 更新cron文件
|
||||
$content = "<?php\nreturn ".var_export($crons,true).";\n?>";
|
||||
file_put_contents(RUNTIME_PATH.'~crons.php',$content);
|
||||
}
|
||||
}
|
||||
// 解除锁定
|
||||
unlink($lockfile);
|
||||
return ;
|
||||
}
|
||||
}
|
||||
2079
ThinkPHP/Library/Behavior/FireShowPageTraceBehavior.class.php
Normal file
2079
ThinkPHP/Library/Behavior/FireShowPageTraceBehavior.class.php
Normal file
File diff suppressed because it is too large
Load Diff
95
ThinkPHP/Library/Behavior/ParseTemplateBehavior.class.php
Normal file
95
ThinkPHP/Library/Behavior/ParseTemplateBehavior.class.php
Normal file
@@ -0,0 +1,95 @@
|
||||
<?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>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace Behavior;
|
||||
use Think\Storage;
|
||||
use Think\Think;
|
||||
/**
|
||||
* 系统行为扩展:模板解析
|
||||
*/
|
||||
class ParseTemplateBehavior {
|
||||
|
||||
// 行为扩展的执行入口必须是run
|
||||
public function run(&$_data){
|
||||
$engine = strtolower(C('TMPL_ENGINE_TYPE'));
|
||||
$_content = empty($_data['content'])?$_data['file']:$_data['content'];
|
||||
$_data['prefix'] = !empty($_data['prefix'])?$_data['prefix']:C('TMPL_CACHE_PREFIX');
|
||||
if('think'==$engine){ // 采用Think模板引擎
|
||||
if((!empty($_data['content']) && $this->checkContentCache($_data['content'],$_data['prefix']))
|
||||
|| $this->checkCache($_data['file'],$_data['prefix'])) { // 缓存有效
|
||||
//载入模版缓存文件
|
||||
Storage::load(C('CACHE_PATH').$_data['prefix'].md5($_content).C('TMPL_CACHFILE_SUFFIX'),$_data['var']);
|
||||
}else{
|
||||
$tpl = Think::instance('Think\\Template');
|
||||
// 编译并加载模板文件
|
||||
$tpl->fetch($_content,$_data['var'],$_data['prefix']);
|
||||
}
|
||||
}else{
|
||||
// 调用第三方模板引擎解析和输出
|
||||
if(strpos($engine,'\\')){
|
||||
$class = $engine;
|
||||
}else{
|
||||
$class = 'Think\\Template\\Driver\\'.ucwords($engine);
|
||||
}
|
||||
if(class_exists($class)) {
|
||||
$tpl = new $class;
|
||||
$tpl->fetch($_content,$_data['var']);
|
||||
}else { // 类没有定义
|
||||
E(L('_NOT_SUPPORT_').': ' . $class);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查缓存文件是否有效
|
||||
* 如果无效则需要重新编译
|
||||
* @access public
|
||||
* @param string $tmplTemplateFile 模板文件名
|
||||
* @return boolean
|
||||
*/
|
||||
protected function checkCache($tmplTemplateFile,$prefix='') {
|
||||
if (!C('TMPL_CACHE_ON')) // 优先对配置设定检测
|
||||
return false;
|
||||
$tmplCacheFile = C('CACHE_PATH').$prefix.md5($tmplTemplateFile).C('TMPL_CACHFILE_SUFFIX');
|
||||
if(!Storage::has($tmplCacheFile)){
|
||||
return false;
|
||||
}elseif (filemtime($tmplTemplateFile) > Storage::get($tmplCacheFile,'mtime')) {
|
||||
// 模板文件如果有更新则缓存需要更新
|
||||
return false;
|
||||
}elseif (C('TMPL_CACHE_TIME') != 0 && time() > Storage::get($tmplCacheFile,'mtime')+C('TMPL_CACHE_TIME')) {
|
||||
// 缓存是否在有效期
|
||||
return false;
|
||||
}
|
||||
// 开启布局模板
|
||||
if(C('LAYOUT_ON')) {
|
||||
$layoutFile = THEME_PATH.C('LAYOUT_NAME').C('TMPL_TEMPLATE_SUFFIX');
|
||||
if(filemtime($layoutFile) > Storage::get($tmplCacheFile,'mtime')) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// 缓存有效
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查缓存内容是否有效
|
||||
* 如果无效则需要重新编译
|
||||
* @access public
|
||||
* @param string $tmplContent 模板内容
|
||||
* @return boolean
|
||||
*/
|
||||
protected function checkContentCache($tmplContent,$prefix='') {
|
||||
if(Storage::has(C('CACHE_PATH').$prefix.md5($tmplContent).C('TMPL_CACHFILE_SUFFIX'))){
|
||||
return true;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
117
ThinkPHP/Library/Behavior/ReadHtmlCacheBehavior.class.php
Normal file
117
ThinkPHP/Library/Behavior/ReadHtmlCacheBehavior.class.php
Normal file
@@ -0,0 +1,117 @@
|
||||
<?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>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace Behavior;
|
||||
use Think\Storage;
|
||||
/**
|
||||
* 系统行为扩展:静态缓存读取
|
||||
*/
|
||||
class ReadHtmlCacheBehavior {
|
||||
// 行为扩展的执行入口必须是run
|
||||
public function run(&$params){
|
||||
// 开启静态缓存
|
||||
if(IS_GET && C('HTML_CACHE_ON')) {
|
||||
$cacheTime = $this->requireHtmlCache();
|
||||
if( false !== $cacheTime && $this->checkHTMLCache(HTML_FILE_NAME,$cacheTime)) { //静态页面有效
|
||||
// 读取静态页面输出
|
||||
echo Storage::read(HTML_FILE_NAME,'html');
|
||||
exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 判断是否需要静态缓存
|
||||
static private function requireHtmlCache() {
|
||||
// 分析当前的静态规则
|
||||
$htmls = C('HTML_CACHE_RULES'); // 读取静态规则
|
||||
if(!empty($htmls)) {
|
||||
$htmls = array_change_key_case($htmls);
|
||||
// 静态规则文件定义格式 actionName=>array('静态规则','缓存时间','附加规则')
|
||||
// 'read'=>array('{id},{name}',60,'md5') 必须保证静态规则的唯一性 和 可判断性
|
||||
// 检测静态规则
|
||||
$controllerName = strtolower(CONTROLLER_NAME);
|
||||
$actionName = strtolower(ACTION_NAME);
|
||||
if(isset($htmls[$controllerName.':'.$actionName])) {
|
||||
$html = $htmls[$controllerName.':'.$actionName]; // 某个控制器的操作的静态规则
|
||||
}elseif(isset($htmls[$controllerName.':'])){// 某个控制器的静态规则
|
||||
$html = $htmls[$controllerName.':'];
|
||||
}elseif(isset($htmls[$actionName])){
|
||||
$html = $htmls[$actionName]; // 所有操作的静态规则
|
||||
}elseif(isset($htmls['*'])){
|
||||
$html = $htmls['*']; // 全局静态规则
|
||||
}
|
||||
if(!empty($html)) {
|
||||
// 解读静态规则
|
||||
$rule = is_array($html)?$html[0]:$html;
|
||||
// 以$_开头的系统变量
|
||||
$callback = function($match){
|
||||
switch($match[1]){
|
||||
case '_GET': $var = $_GET[$match[2]]; break;
|
||||
case '_POST': $var = $_POST[$match[2]]; break;
|
||||
case '_REQUEST': $var = $_REQUEST[$match[2]]; break;
|
||||
case '_SERVER': $var = $_SERVER[$match[2]]; break;
|
||||
case '_SESSION': $var = $_SESSION[$match[2]]; break;
|
||||
case '_COOKIE': $var = $_COOKIE[$match[2]]; break;
|
||||
}
|
||||
return (count($match) == 4) ? $match[3]($var) : $var;
|
||||
};
|
||||
$rule = preg_replace_callback('/{\$(_\w+)\.(\w+)(?:\|(\w+))?}/', $callback, $rule);
|
||||
// {ID|FUN} GET变量的简写
|
||||
$rule = preg_replace_callback('/{(\w+)\|(\w+)}/', function($match){return $match[2]($_GET[$match[1]]);}, $rule);
|
||||
$rule = preg_replace_callback('/{(\w+)}/', function($match){return $_GET[$match[1]];}, $rule);
|
||||
// 特殊系统变量
|
||||
$rule = str_ireplace(
|
||||
array('{:controller}','{:action}','{:module}'),
|
||||
array(CONTROLLER_NAME,ACTION_NAME,MODULE_NAME),
|
||||
$rule);
|
||||
// {|FUN} 单独使用函数
|
||||
$rule = preg_replace_callback('/{|(\w+)}/', function($match){return $match[1]();},$rule);
|
||||
$cacheTime = C('HTML_CACHE_TIME',null,60);
|
||||
if(is_array($html)){
|
||||
if(!empty($html[2])) $rule = $html[2]($rule); // 应用附加函数
|
||||
$cacheTime = isset($html[1])?$html[1]:$cacheTime; // 缓存有效期
|
||||
}else{
|
||||
$cacheTime = $cacheTime;
|
||||
}
|
||||
|
||||
// 当前缓存文件
|
||||
define('HTML_FILE_NAME',HTML_PATH . $rule.C('HTML_FILE_SUFFIX',null,'.html'));
|
||||
return $cacheTime;
|
||||
}
|
||||
}
|
||||
// 无需缓存
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查静态HTML文件是否有效
|
||||
* 如果无效需要重新更新
|
||||
* @access public
|
||||
* @param string $cacheFile 静态文件名
|
||||
* @param integer $cacheTime 缓存有效期
|
||||
* @return boolean
|
||||
*/
|
||||
static public function checkHTMLCache($cacheFile='',$cacheTime='') {
|
||||
if(!is_file($cacheFile) && 'sae' != APP_MODE ){
|
||||
return false;
|
||||
}elseif (filemtime(\Think\Think::instance('Think\View')->parseTemplate()) > Storage::get($cacheFile,'mtime','html')) {
|
||||
// 模板文件如果更新静态文件需要更新
|
||||
return false;
|
||||
}elseif(!is_numeric($cacheTime) && function_exists($cacheTime)){
|
||||
return $cacheTime($cacheFile);
|
||||
}elseif ($cacheTime != 0 && NOW_TIME > Storage::get($cacheFile,'mtime','html')+$cacheTime) {
|
||||
// 文件是否在有效期
|
||||
return false;
|
||||
}
|
||||
//静态文件有效
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
41
ThinkPHP/Library/Behavior/RobotCheckBehavior.class.php
Normal file
41
ThinkPHP/Library/Behavior/RobotCheckBehavior.class.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2009 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace Behavior;
|
||||
/**
|
||||
* 机器人检测
|
||||
* @author liu21st <liu21st@gmail.com>
|
||||
*/
|
||||
class RobotCheckBehavior {
|
||||
|
||||
public function run(&$params) {
|
||||
// 机器人访问检测
|
||||
if(C('LIMIT_ROBOT_VISIT',null,true) && self::isRobot()) {
|
||||
// 禁止机器人访问
|
||||
exit('Access Denied');
|
||||
}
|
||||
}
|
||||
|
||||
static private function isRobot() {
|
||||
static $_robot = null;
|
||||
if(is_null($_robot)) {
|
||||
$spiders = 'Bot|Crawl|Spider|slurp|sohu-search|lycos|robozilla';
|
||||
$browsers = 'MSIE|Netscape|Opera|Konqueror|Mozilla';
|
||||
if(preg_match("/($browsers)/", $_SERVER['HTTP_USER_AGENT'])) {
|
||||
$_robot = false ;
|
||||
} elseif(preg_match("/($spiders)/", $_SERVER['HTTP_USER_AGENT'])) {
|
||||
$_robot = true;
|
||||
} else {
|
||||
$_robot = false;
|
||||
}
|
||||
}
|
||||
return $_robot;
|
||||
}
|
||||
}
|
||||
119
ThinkPHP/Library/Behavior/ShowPageTraceBehavior.class.php
Normal file
119
ThinkPHP/Library/Behavior/ShowPageTraceBehavior.class.php
Normal file
@@ -0,0 +1,119 @@
|
||||
<?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>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace Behavior;
|
||||
use Think\Log;
|
||||
/**
|
||||
* 系统行为扩展:页面Trace显示输出
|
||||
*/
|
||||
class ShowPageTraceBehavior {
|
||||
protected $tracePageTabs = array('BASE'=>'基本','FILE'=>'文件','INFO'=>'流程','ERR|NOTIC'=>'错误','SQL'=>'SQL','DEBUG'=>'调试');
|
||||
|
||||
// 行为扩展的执行入口必须是run
|
||||
public function run(&$params){
|
||||
if(!IS_AJAX && !IS_CLI && C('SHOW_PAGE_TRACE')) {
|
||||
echo $this->showTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示页面Trace信息
|
||||
* @access private
|
||||
*/
|
||||
private function showTrace() {
|
||||
// 系统默认显示信息
|
||||
$files = get_included_files();
|
||||
$info = array();
|
||||
foreach ($files as $key=>$file){
|
||||
$info[] = $file.' ( '.number_format(filesize($file)/1024,2).' KB )';
|
||||
}
|
||||
$trace = array();
|
||||
$base = array(
|
||||
'请求信息' => date('Y-m-d H:i:s',$_SERVER['REQUEST_TIME']).' '.$_SERVER['SERVER_PROTOCOL'].' '.$_SERVER['REQUEST_METHOD'].' : '.__SELF__,
|
||||
'运行时间' => $this->showTime(),
|
||||
'吞吐率' => number_format(1/G('beginTime','viewEndTime'),2).'req/s',
|
||||
'内存开销' => MEMORY_LIMIT_ON?number_format((memory_get_usage() - $GLOBALS['_startUseMems'])/1024,2).' kb':'不支持',
|
||||
'查询信息' => N('db_query').' queries '.N('db_write').' writes ',
|
||||
'文件加载' => count(get_included_files()),
|
||||
'缓存信息' => N('cache_read').' gets '.N('cache_write').' writes ',
|
||||
'配置加载' => count(C()),
|
||||
'会话信息' => 'SESSION_ID='.session_id(),
|
||||
);
|
||||
// 读取应用定义的Trace文件
|
||||
$traceFile = COMMON_PATH.'Conf/trace.php';
|
||||
if(is_file($traceFile)) {
|
||||
$base = array_merge($base,include $traceFile);
|
||||
}
|
||||
$debug = trace();
|
||||
$tabs = C('TRACE_PAGE_TABS',null,$this->tracePageTabs);
|
||||
foreach ($tabs as $name=>$title){
|
||||
switch(strtoupper($name)) {
|
||||
case 'BASE':// 基本信息
|
||||
$trace[$title] = $base;
|
||||
break;
|
||||
case 'FILE': // 文件信息
|
||||
$trace[$title] = $info;
|
||||
break;
|
||||
default:// 调试信息
|
||||
$name = strtoupper($name);
|
||||
if(strpos($name,'|')) {// 多组信息
|
||||
$names = explode('|',$name);
|
||||
$result = array();
|
||||
foreach($names as $name){
|
||||
$result += isset($debug[$name])?$debug[$name]:array();
|
||||
}
|
||||
$trace[$title] = $result;
|
||||
}else{
|
||||
$trace[$title] = isset($debug[$name])?$debug[$name]:'';
|
||||
}
|
||||
}
|
||||
}
|
||||
if($save = C('PAGE_TRACE_SAVE')) { // 保存页面Trace日志
|
||||
if(is_array($save)) {// 选择选项卡保存
|
||||
$tabs = C('TRACE_PAGE_TABS',null,$this->tracePageTabs);
|
||||
$array = array();
|
||||
foreach ($save as $tab){
|
||||
$array[] = $tabs[$tab];
|
||||
}
|
||||
}
|
||||
$content = date('[ c ]').' '.get_client_ip().' '.$_SERVER['REQUEST_URI']."\r\n";
|
||||
foreach ($trace as $key=>$val){
|
||||
if(!isset($array) || in_array_case($key,$array)) {
|
||||
$content .= '[ '.$key." ]\r\n";
|
||||
if(is_array($val)) {
|
||||
foreach ($val as $k=>$v){
|
||||
$content .= (!is_numeric($k)?$k.':':'').print_r($v,true)."\r\n";
|
||||
}
|
||||
}else{
|
||||
$content .= print_r($val,true)."\r\n";
|
||||
}
|
||||
$content .= "\r\n";
|
||||
}
|
||||
}
|
||||
error_log(str_replace('<br/>',"\r\n",$content), 3,C('LOG_PATH').date('y_m_d').'_trace.log');
|
||||
}
|
||||
unset($files,$info,$base);
|
||||
// 调用Trace页面模板
|
||||
ob_start();
|
||||
include C('TMPL_TRACE_FILE')?C('TMPL_TRACE_FILE'):THINK_PATH.'Tpl/page_trace.tpl';
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取运行时间
|
||||
*/
|
||||
private function showTime() {
|
||||
// 显示运行时间
|
||||
G('beginTime',$GLOBALS['_beginTime']);
|
||||
G('viewEndTime');
|
||||
// 显示详细运行时间
|
||||
return G('beginTime','viewEndTime').'s ( Load:'.G('beginTime','loadTime').'s Init:'.G('loadTime','initTime').'s Exec:'.G('initTime','viewStartTime').'s Template:'.G('viewStartTime','viewEndTime').'s )';
|
||||
}
|
||||
}
|
||||
69
ThinkPHP/Library/Behavior/ShowRuntimeBehavior.class.php
Normal file
69
ThinkPHP/Library/Behavior/ShowRuntimeBehavior.class.php
Normal file
@@ -0,0 +1,69 @@
|
||||
<?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>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace Behavior;
|
||||
/**
|
||||
* 系统行为扩展:运行时间信息显示
|
||||
*/
|
||||
class ShowRuntimeBehavior {
|
||||
|
||||
// 行为扩展的执行入口必须是run
|
||||
public function run(&$content){
|
||||
if(C('SHOW_RUN_TIME')){
|
||||
if(false !== strpos($content,'{__NORUNTIME__}')) {
|
||||
$content = str_replace('{__NORUNTIME__}','',$content);
|
||||
}else{
|
||||
$runtime = $this->showTime();
|
||||
if(strpos($content,'{__RUNTIME__}'))
|
||||
$content = str_replace('{__RUNTIME__}',$runtime,$content);
|
||||
else
|
||||
$content .= $runtime;
|
||||
}
|
||||
}else{
|
||||
$content = str_replace(array('{__NORUNTIME__}','{__RUNTIME__}'),'',$content);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示运行时间、数据库操作、缓存次数、内存使用信息
|
||||
* @access private
|
||||
* @return string
|
||||
*/
|
||||
private function showTime() {
|
||||
// 显示运行时间
|
||||
G('beginTime',$GLOBALS['_beginTime']);
|
||||
G('viewEndTime');
|
||||
$showTime = 'Process: '.G('beginTime','viewEndTime').'s ';
|
||||
if(C('SHOW_ADV_TIME')) {
|
||||
// 显示详细运行时间
|
||||
$showTime .= '( Load:'.G('beginTime','loadTime').'s Init:'.G('loadTime','initTime').'s Exec:'.G('initTime','viewStartTime').'s Template:'.G('viewStartTime','viewEndTime').'s )';
|
||||
}
|
||||
if(C('SHOW_DB_TIMES') ) {
|
||||
// 显示数据库操作次数
|
||||
$showTime .= ' | DB :'.N('db_query').' queries '.N('db_write').' writes ';
|
||||
}
|
||||
if(C('SHOW_CACHE_TIMES') ) {
|
||||
// 显示缓存读写次数
|
||||
$showTime .= ' | Cache :'.N('cache_read').' gets '.N('cache_write').' writes ';
|
||||
}
|
||||
if(MEMORY_LIMIT_ON && C('SHOW_USE_MEM')) {
|
||||
// 显示内存开销
|
||||
$showTime .= ' | UseMem:'. number_format((memory_get_usage() - $GLOBALS['_startUseMems'])/1024).' kb';
|
||||
}
|
||||
if(C('SHOW_LOAD_FILE')) {
|
||||
$showTime .= ' | LoadFile:'.count(get_included_files());
|
||||
}
|
||||
if(C('SHOW_FUN_TIMES')) {
|
||||
$fun = get_defined_functions();
|
||||
$showTime .= ' | CallFun:'.count($fun['user']).','.count($fun['internal']);
|
||||
}
|
||||
return $showTime;
|
||||
}
|
||||
}
|
||||
54
ThinkPHP/Library/Behavior/TokenBuildBehavior.class.php
Normal file
54
ThinkPHP/Library/Behavior/TokenBuildBehavior.class.php
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | TOPThink [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2010 http://topthink.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace Behavior;
|
||||
/**
|
||||
* 系统行为扩展:表单令牌生成
|
||||
*/
|
||||
class TokenBuildBehavior {
|
||||
|
||||
public function run(&$content){
|
||||
if(C('TOKEN_ON')) {
|
||||
list($tokenName,$tokenKey,$tokenValue)=$this->getToken();
|
||||
$input_token = '<input type="hidden" name="'.$tokenName.'" value="'.$tokenKey.'_'.$tokenValue.'" />';
|
||||
$meta_token = '<meta name="'.$tokenName.'" content="'.$tokenKey.'_'.$tokenValue.'" />';
|
||||
if(strpos($content,'{__TOKEN__}')) {
|
||||
// 指定表单令牌隐藏域位置
|
||||
$content = str_replace('{__TOKEN__}',$input_token,$content);
|
||||
}elseif(preg_match('/<\/form(\s*)>/is',$content,$match)) {
|
||||
// 智能生成表单令牌隐藏域
|
||||
$content = str_replace($match[0],$input_token.$match[0],$content);
|
||||
}
|
||||
$content = str_ireplace('</head>',$meta_token.'</head>',$content);
|
||||
}else{
|
||||
$content = str_replace('{__TOKEN__}','',$content);
|
||||
}
|
||||
}
|
||||
|
||||
//获得token
|
||||
private function getToken(){
|
||||
$tokenName = C('TOKEN_NAME',null,'__hash__');
|
||||
$tokenType = C('TOKEN_TYPE',null,'md5');
|
||||
if(!isset($_SESSION[$tokenName])) {
|
||||
$_SESSION[$tokenName] = array();
|
||||
}
|
||||
// 标识当前页面唯一性
|
||||
$tokenKey = md5($_SERVER['REQUEST_URI']);
|
||||
if(isset($_SESSION[$tokenName][$tokenKey])) {// 相同页面不重复生成session
|
||||
$tokenValue = $_SESSION[$tokenName][$tokenKey];
|
||||
}else{
|
||||
$tokenValue = is_callable($tokenType) ? $tokenType(microtime(true)) : md5(microtime(true));
|
||||
$_SESSION[$tokenName][$tokenKey] = $tokenValue;
|
||||
if(IS_AJAX && C('TOKEN_RESET',null,true))
|
||||
header($tokenName.': '.$tokenKey.'_'.$tokenValue); //ajax需要获得这个header并替换页面中meta中的token值
|
||||
}
|
||||
return array($tokenName,$tokenKey,$tokenValue);
|
||||
}
|
||||
}
|
||||
117
ThinkPHP/Library/Behavior/UpgradeNoticeBehavior.class.php
Normal file
117
ThinkPHP/Library/Behavior/UpgradeNoticeBehavior.class.php
Normal file
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// | Copyright (c) 2006-2012 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: luofei614<www.3g4k.com>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace Behavior;
|
||||
/**
|
||||
* 升级短信通知, 如果有ThinkPHP新版升级,或者重要的更新,会发送短信通知你。
|
||||
* 需要使用SAE的短信服务。请先找一个SAE的应用开通短信服务。
|
||||
* 使用步骤如下:
|
||||
* 1,在项目的Conf目录下建立tags.php配置文件,内容如下:
|
||||
* <code>
|
||||
* <?php
|
||||
* return array(
|
||||
* 'app_init' => array('UpgradeNotice')
|
||||
* );
|
||||
* </code>
|
||||
*
|
||||
* 2,将此文件放在应用的Lib/Behavior文件夹下。
|
||||
*注:在SAE上面使用时,以上两步可以省略
|
||||
* 3,在config.php中配置:
|
||||
* 'UPGRADE_NOTICE_ON'=>true,//开启短信升级提醒功能
|
||||
* 'UPGRADE_NOTICE_AKEY'=>'your akey',//SAE应用的AKEY,如果在SAE上使用可以不填
|
||||
* 'UPGRADE_NOTICE_SKEY'=>'your skey',//SAE应用的SKEY,如果在SAE上使用可以不填
|
||||
*'UPGRADE_NOTICE_MOBILE'=>'136456789',//接受短信的手机号
|
||||
*'UPGRADE_NOTICE_CHECK_INTERVAL' => 604800,//检测频率,单位秒,默认是一周
|
||||
*'UPGRADE_CURRENT_VERSION'=>'0',//升级后的版本号,会在短信中告诉你填写什么
|
||||
*UPGRADE_NOTICE_DEBUG=>true, //调试默认,如果为true,UPGRADE_NOTICE_CHECK_INTERVAL配置不起作用,每次都会进行版本检查,此时用于调试,调试完毕后请设置次配置为false
|
||||
*
|
||||
*/
|
||||
|
||||
class UpgradeNoticeBehavior {
|
||||
|
||||
protected $header_ = '';
|
||||
protected $httpCode_;
|
||||
protected $httpDesc_;
|
||||
protected $accesskey_;
|
||||
protected $secretkey_;
|
||||
public function run(&$params) {
|
||||
if (C('UPGRADE_NOTICE_ON') && (!S('think_upgrade_interval') || C('UPGRADE_NOTICE_DEBUG'))) {
|
||||
if(IS_SAE && C('UPGRADE_NOTICE_QUEUE') && !isset($_POST['think_upgrade_queque'])){
|
||||
$queue=new SaeTaskQueue(C('UPGRADE_NOTICE_QUEUE'));
|
||||
$queue->addTask('http://'.$_SERVER['HTTP_HOST'].__APP__,'think_upgrade_queque=1');
|
||||
if(!$queue->push()){
|
||||
trace('升级提醒队列执行失败,错误原因:'.$queue->errmsg(), '升级通知出错', 'NOTIC', true);
|
||||
}
|
||||
return ;
|
||||
}
|
||||
$akey = C('UPGRADE_NOTICE_AKEY',null,'');
|
||||
$skey = C('UPGRADE_NOTICE_SKEY',null,'');
|
||||
$this->accesskey_ = $akey ? $akey : (defined('SAE_ACCESSKEY') ? SAE_ACCESSKEY : '');
|
||||
$this->secretkey_ = $skey ? $skey : (defined('SAE_SECRETKEY') ? SAE_SECRETKEY : '');
|
||||
$current_version = C('UPGRADE_CURRENT_VERSION',null,0);
|
||||
//读取接口
|
||||
$info = $this->send('http://sinaclouds.sinaapp.com/thinkapi/upgrade.php?v=' . $current_version);
|
||||
if ($info['version'] != $current_version) {
|
||||
if($this->send_sms($info['msg'])) trace($info['msg'], '升级通知成功', 'NOTIC', true); //发送升级短信
|
||||
}
|
||||
S('think_upgrade_interval', true, C('UPGRADE_NOTICE_CHECK_INTERVAL',null,604800));
|
||||
}
|
||||
}
|
||||
private function send_sms($msg) {
|
||||
$timestamp=time();
|
||||
$url = 'http://inno.smsinter.sina.com.cn/sae_sms_service/sendsms.php'; //发送短信的接口地址
|
||||
$content = "FetchUrl" . $url . "TimeStamp" . $timestamp . "AccessKey" . $this->accesskey_;
|
||||
$signature = (base64_encode(hash_hmac('sha256', $content, $this->secretkey_, true)));
|
||||
$headers = array(
|
||||
"FetchUrl: $url",
|
||||
"AccessKey: ".$this->accesskey_,
|
||||
"TimeStamp: " . $timestamp,
|
||||
"Signature: $signature"
|
||||
);
|
||||
$data = array(
|
||||
'mobile' => C('UPGRADE_NOTICE_MOBILE',null,'') ,
|
||||
'msg' => $msg,
|
||||
'encoding' => 'UTF-8'
|
||||
);
|
||||
if(!$ret = $this->send('http://g.apibus.io', $data, $headers)){
|
||||
return false;
|
||||
}
|
||||
if (isset($ret['ApiBusError'])) {
|
||||
trace('errno:' . $ret['ApiBusError']['errcode'] . ',errmsg:' . $ret['ApiBusError']['errdesc'], '升级通知出错', 'NOTIC', true);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
private function send($url, $params = array() , $headers = array()) {
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
if (!empty($params)) {
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
|
||||
}
|
||||
if (!empty($headers)) curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
$txt = curl_exec($ch);
|
||||
if (curl_errno($ch)) {
|
||||
trace(curl_error($ch) , '升级通知出错', 'NOTIC', true);
|
||||
|
||||
return false;
|
||||
}
|
||||
curl_close($ch);
|
||||
$ret = json_decode($txt, true);
|
||||
if (!$ret) {
|
||||
trace('接口[' . $url . ']返回格式不正确', '升级通知出错', 'NOTIC', true);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
29
ThinkPHP/Library/Behavior/WriteHtmlCacheBehavior.class.php
Normal file
29
ThinkPHP/Library/Behavior/WriteHtmlCacheBehavior.class.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?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>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace Behavior;
|
||||
use Think\Storage;
|
||||
/**
|
||||
* 系统行为扩展:静态缓存写入
|
||||
*/
|
||||
class WriteHtmlCacheBehavior {
|
||||
|
||||
// 行为扩展的执行入口必须是run
|
||||
public function run(&$content) {
|
||||
//2014-11-28 修改 如果有HTTP 4xx 3xx 5xx 头部,禁止存储
|
||||
//2014-12-1 修改 对注入的网址 防止生成,例如 /game/lst/SortType/hot/-e8-90-8c-e5-85-94-e7-88-b1-e6-b6-88-e9-99-a4/-e8-bf-9b-e5-87-bb-e7-9a-84-e9-83-a8-e8-90-bd/-e9-a3-8e-e4-ba-91-e5-a4-a9-e4-b8-8b/index.shtml
|
||||
if (C('HTML_CACHE_ON') && defined('HTML_FILE_NAME')
|
||||
&& !preg_match('/Status.*[345]{1}\d{2}/i', implode(' ', headers_list()))
|
||||
&& !preg_match('/(-[a-z0-9]{2}){3,}/i',HTML_FILE_NAME)) {
|
||||
//静态文件写入
|
||||
Storage::put(HTML_FILE_NAME, $content, 'html');
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user