1
0
mirror of https://e.coding.net/circlecloud/MinecraftAccount.git synced 2026-02-14 10:49:19 +00:00

首次提交...

Signed-off-by: j502647092 <jtb1@163.com>
This commit is contained in:
j502647092
2015-11-01 22:25:03 +08:00
commit 2003fda7cb
409 changed files with 77938 additions and 0 deletions

View 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');
}
}
}

View 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();
}
}
}

View 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');
}
}
}
}

View 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;
}
}

View 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;
}
}

View 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);
}
}

View 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 tracewarn,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];
}
}
}

View 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;
}
}

View 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 ;
}
}

File diff suppressed because it is too large Load Diff

View 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;
}
}
}

View 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;
}
}

View 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;
}
}

View 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 )';
}
}

View 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;
}
}

View 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);
}
}

View 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, //调试默认如果为trueUPGRADE_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;
}
}

View 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');
}
}
}