lzj500 4 gadi atpakaļ
revīzija
f1db9412e2
100 mainītis faili ar 15274 papildinājumiem un 0 dzēšanām
  1. 5 0
      .buildpath
  2. 2 0
      .gitignore
  3. 8 0
      .htaccess
  4. 28 0
      .project
  5. 1 0
      Application/Index/Common/Common/index.html
  6. 4 0
      Application/Index/Common/Conf/config.php
  7. 1 0
      Application/Index/Common/Conf/index.html
  8. 1 0
      Application/Index/Common/index.html
  9. 4 0
      Application/Index/Home/Common/function.php
  10. 1 0
      Application/Index/Home/Common/index.html
  11. 25 0
      Application/Index/Home/Conf/config.php
  12. 1 0
      Application/Index/Home/Conf/index.html
  13. 53 0
      Application/Index/Home/Controller/IndexController.class.php
  14. 1 0
      Application/Index/Home/Controller/index.html
  15. 1 0
      Application/Index/Home/Model/index.html
  16. 25 0
      Application/Index/Home/View/Index/index.html
  17. 80 0
      Application/Index/Home/View/Index/table.html
  18. 4 0
      Application/Index/Home/View/Public/headCssJs.html
  19. 1 0
      Application/Index/Home/View/index.html
  20. 1 0
      Application/Index/Home/index.html
  21. 1 0
      Application/README.md
  22. 1 0
      Application/index.html
  23. 13 0
      Config/config.php
  24. 246 0
      Lib/commonFun.php
  25. 1 0
      Public/README.md
  26. 765 0
      Public/css/common_yckj.css
  27. 17 0
      Public/css/main.css
  28. 7 0
      Public/css/main.css.map
  29. 53 0
      Public/css/main.scss
  30. 2 0
      Public/js/jquery-1.8.3.min.js
  31. 2 0
      README.md
  32. 1550 0
      ThinkPHP/Common/functions.php
  33. 167 0
      ThinkPHP/Conf/convention.php
  34. 27 0
      ThinkPHP/Conf/debug.php
  35. 32 0
      ThinkPHP/LICENSE.txt
  36. 51 0
      ThinkPHP/Lang/en-us.php
  37. 51 0
      ThinkPHP/Lang/pt-br.php
  38. 51 0
      ThinkPHP/Lang/zh-cn.php
  39. 51 0
      ThinkPHP/Lang/zh-tw.php
  40. 24 0
      ThinkPHP/Library/Behavior/AgentCheckBehavior.class.php
  41. 42 0
      ThinkPHP/Library/Behavior/BorisBehavior.class.php
  42. 34 0
      ThinkPHP/Library/Behavior/BrowserCheckBehavior.class.php
  43. 87 0
      ThinkPHP/Library/Behavior/BuildLiteBehavior.class.php
  44. 194 0
      ThinkPHP/Library/Behavior/CheckActionRouteBehavior.class.php
  45. 77 0
      ThinkPHP/Library/Behavior/CheckLangBehavior.class.php
  46. 610 0
      ThinkPHP/Library/Behavior/ChromeShowPageTraceBehavior.class.php
  47. 47 0
      ThinkPHP/Library/Behavior/ContentReplaceBehavior.class.php
  48. 66 0
      ThinkPHP/Library/Behavior/CronRunBehavior.class.php
  49. 2079 0
      ThinkPHP/Library/Behavior/FireShowPageTraceBehavior.class.php
  50. 95 0
      ThinkPHP/Library/Behavior/ParseTemplateBehavior.class.php
  51. 117 0
      ThinkPHP/Library/Behavior/ReadHtmlCacheBehavior.class.php
  52. 41 0
      ThinkPHP/Library/Behavior/RobotCheckBehavior.class.php
  53. 119 0
      ThinkPHP/Library/Behavior/ShowPageTraceBehavior.class.php
  54. 69 0
      ThinkPHP/Library/Behavior/ShowRuntimeBehavior.class.php
  55. 54 0
      ThinkPHP/Library/Behavior/TokenBuildBehavior.class.php
  56. 117 0
      ThinkPHP/Library/Behavior/UpgradeNoticeBehavior.class.php
  57. 29 0
      ThinkPHP/Library/Behavior/WriteHtmlCacheBehavior.class.php
  58. 271 0
      ThinkPHP/Library/Org/Net/Http.class.php
  59. 233 0
      ThinkPHP/Library/Org/Net/IpLocation.class.php
  60. 240 0
      ThinkPHP/Library/Org/Util/ArrayList.class.php
  61. 200 0
      ThinkPHP/Library/Org/Util/CodeSwitch.class.php
  62. 569 0
      ThinkPHP/Library/Org/Util/Date.class.php
  63. 285 0
      ThinkPHP/Library/Org/Util/Rbac.class.php
  64. 51 0
      ThinkPHP/Library/Org/Util/Stack.class.php
  65. 248 0
      ThinkPHP/Library/Org/Util/String.class.php
  66. 211 0
      ThinkPHP/Library/Think/App.class.php
  67. 231 0
      ThinkPHP/Library/Think/Auth.class.php
  68. 24 0
      ThinkPHP/Library/Think/Behavior.class.php
  69. 165 0
      ThinkPHP/Library/Think/Build.class.php
  70. 127 0
      ThinkPHP/Library/Think/Cache.class.php
  71. 124 0
      ThinkPHP/Library/Think/Cache/Driver/Apachenote.class.php
  72. 86 0
      ThinkPHP/Library/Think/Cache/Driver/Apc.class.php
  73. 138 0
      ThinkPHP/Library/Think/Cache/Driver/Db.class.php
  74. 77 0
      ThinkPHP/Library/Think/Cache/Driver/Eaccelerator.class.php
  75. 181 0
      ThinkPHP/Library/Think/Cache/Driver/File.class.php
  76. 103 0
      ThinkPHP/Library/Think/Cache/Driver/Memcache.class.php
  77. 102 0
      ThinkPHP/Library/Think/Cache/Driver/Memcached.class.php
  78. 144 0
      ThinkPHP/Library/Think/Cache/Driver/Memcachesae.class.php
  79. 107 0
      ThinkPHP/Library/Think/Cache/Driver/Redis.class.php
  80. 186 0
      ThinkPHP/Library/Think/Cache/Driver/Shmop.class.php
  81. 119 0
      ThinkPHP/Library/Think/Cache/Driver/Sqlite.class.php
  82. 88 0
      ThinkPHP/Library/Think/Cache/Driver/Wincache.class.php
  83. 90 0
      ThinkPHP/Library/Think/Cache/Driver/Xcache.class.php
  84. 307 0
      ThinkPHP/Library/Think/Controller.class.php
  85. 61 0
      ThinkPHP/Library/Think/Controller/HproseController.class.php
  86. 39 0
      ThinkPHP/Library/Think/Controller/JsonRpcController.class.php
  87. 233 0
      ThinkPHP/Library/Think/Controller/RestController.class.php
  88. 56 0
      ThinkPHP/Library/Think/Controller/RpcController.class.php
  89. 42 0
      ThinkPHP/Library/Think/Controller/YarController.class.php
  90. 53 0
      ThinkPHP/Library/Think/Crypt.class.php
  91. 74 0
      ThinkPHP/Library/Think/Crypt/Driver/Base64.class.php
  92. 83 0
      ThinkPHP/Library/Think/Crypt/Driver/Crypt.class.php
  93. 241 0
      ThinkPHP/Library/Think/Crypt/Driver/Des.class.php
  94. 86 0
      ThinkPHP/Library/Think/Crypt/Driver/Think.class.php
  95. 116 0
      ThinkPHP/Library/Think/Crypt/Driver/Xxtea.class.php
  96. 137 0
      ThinkPHP/Library/Think/Db.class.php
  97. 1138 0
      ThinkPHP/Library/Think/Db/Driver.class.php
  98. 151 0
      ThinkPHP/Library/Think/Db/Driver/Firebird.class.php
  99. 821 0
      ThinkPHP/Library/Think/Db/Driver/Mongo.class.php
  100. 0 0
      ThinkPHP/Library/Think/Db/Driver/Mysql.class.php

+ 5 - 0
.buildpath

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<buildpath>
+	<buildpathentry kind="src" path=""/>
+	<buildpathentry kind="con" path="org.eclipse.php.core.LANGUAGE"/>
+</buildpath>

+ 2 - 0
.gitignore

@@ -0,0 +1,2 @@
+.svn
+/Application/Index/Runtime

+ 8 - 0
.htaccess

@@ -0,0 +1,8 @@
+<IfModule mod_rewrite.c>
+  Options +FollowSymlinks
+  RewriteEngine On
+
+  RewriteCond %{REQUEST_FILENAME} !-d
+  RewriteCond %{REQUEST_FILENAME} !-f
+  RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]
+</IfModule>

+ 28 - 0
.project

@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>dbkey</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.wst.validation.validationbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.dltk.core.scriptbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.wst.common.project.facet.core.builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+		<nature>org.eclipse.php.core.PHPNature</nature>
+	</natures>
+</projectDescription>

+ 1 - 0
Application/Index/Common/Common/index.html

@@ -0,0 +1 @@
+ 

+ 4 - 0
Application/Index/Common/Conf/config.php

@@ -0,0 +1,4 @@
+<?php
+return array(
+	//'配置项'=>'配置值'
+);

+ 1 - 0
Application/Index/Common/Conf/index.html

@@ -0,0 +1 @@
+ 

+ 1 - 0
Application/Index/Common/index.html

@@ -0,0 +1 @@
+ 

+ 4 - 0
Application/Index/Home/Common/function.php

@@ -0,0 +1,4 @@
+<?php
+
+require_once './Lib/commonFun.php';
+?>

+ 1 - 0
Application/Index/Home/Common/index.html

@@ -0,0 +1 @@
+ 

+ 25 - 0
Application/Index/Home/Conf/config.php

@@ -0,0 +1,25 @@
+<?php
+require_once  './Config/config.php';//引入共同配置
+$localConfig=array(
+		'SYS_NAME' => "丹霞山智能导游",	
+		'WX_AUTH_URL'=>'http://wxcms.zhijianun.com/wxapi/wxapi.php?m=Home&c=Auth&a=auth_userinfo',		
+		'WX_AUTH_BASE_URL'=>'http://wxcms.zhijianun.com/wxapi/wxapi.php?m=Home&c=Auth&a=auth_base',		
+		'WX_JSSDK_URL'=>'http://wxcms.zhijianun.com/wxapi/wxapi.php?m=Home&c=Jssdk&a=getJssdk',
+		'LOG_RECORD' => true, // 开启日志记录
+		//'SHOW_PAGE_Trace' =>true,//打开调试
+		'LOG_LEVEL'  =>'EMERG,ALERT,CRIT,ERR', // 只记录EMERG ALERT CRIT ERR 错误
+		
+		'PAGE_SIZE'=>15
+);
+//合并配置
+foreach ($localConfig as $k=>$v){
+	$config[$k]=$v;
+}
+
+unset($config['TMPL_ACTION_ERROR']);
+unset($config['TMPL_ACTION_SUCCESS']);
+/**
+ *Tools'TMPL_ACTION_ERROR' => 'Public:error', // 默认成功跳转对应的模板文件
+		'TMPL_ACTION_SUCCESS' => 'Public:success',
+ */
+return $config;

+ 1 - 0
Application/Index/Home/Conf/index.html

@@ -0,0 +1 @@
+ 

+ 53 - 0
Application/Index/Home/Controller/IndexController.class.php

@@ -0,0 +1,53 @@
+<?php
+
+namespace Home\Controller;
+
+use Think\Controller;
+
+class IndexController extends Controller {
+	public function index() {
+		$tables = M ( 'profiling' )->query ( "show databases" );
+		// print_r($tables);
+		$this->assign ( "tables", $tables );
+		$this->display ();
+	}
+	public function table() {
+		$t1 = microtime ( true );
+		header ( "Content-type: text/html; charset=utf-8" );
+		$table = request ( "table" );
+		$this->assign ( "table", $table );
+		$condition ['table_schema'] = $table;
+		$where = "table_schema='" . $table . "'";
+		$tables = M ( 'tables' )->where ( $where )->order ( "table_name asc" )->select ();	
+		// 第一种方式
+		$columns = M ( 'columns' )->where ( $where )->order ( "table_name asc,ordinal_position asc,column_name asc" )->select ();
+		// print_r($columns);
+		foreach ( $tables as $k => $v ) {
+			$i=0;
+			foreach ( $columns as $kk => $vv ) {
+				
+				if ($v ['table_name'] == $vv ['table_name']) {
+					$i++;
+					$tables [$k] ['column'] [$kk] = $vv;
+					$tables [$k] ['column'] [$kk]['index']=$i;
+					unset ( $columns [$kk] );
+				}
+			}
+		}
+// 		print_r($tables);
+		// 第二种方式
+		
+		// print_r($columns);
+// 		foreach ( $tables as $k => $v ) {
+			
+// 					$tables [$k] ['column'] =M ( 'columns' )->where (  "table_schema='" . $table . "' and table_name='".$v['table_name']."'" )->order ( "table_name asc,ordinal_position asc,column_name asc" )->select ();
+			
+// 		}
+		// print_r($tables);
+		$this->assign ( "tables", $tables );
+		
+		$this->display ();
+		$t2 = microtime(true);
+		echo '耗时'.round($t2-$t1,3).'秒';
+	}
+}

+ 1 - 0
Application/Index/Home/Controller/index.html

@@ -0,0 +1 @@
+ 

+ 1 - 0
Application/Index/Home/Model/index.html

@@ -0,0 +1 @@
+ 

+ 25 - 0
Application/Index/Home/View/Index/index.html

@@ -0,0 +1,25 @@
+<html>
+
+	<head>
+		<title>数据库列表</title>
+		<include file="Public:headCssJs" />
+	</head>
+
+	<body>
+		<div class="p15">
+			<h1>请选择数据库表</h1>
+
+			<table class="formtable">
+				<foreach name="tables" item="item">
+					<tr>
+						<td>
+							<a href="{:U('Index/table',array('table'=>$item['database']))}">
+							{$item.database}
+						</a></td>
+					</tr>
+				</foreach>
+			</table>
+		</div>
+	</body>
+
+</html>

+ 80 - 0
Application/Index/Home/View/Index/table.html

@@ -0,0 +1,80 @@
+<html>
+
+	<head>
+		<title>{$table}数据库字典</title>
+		<include file="Public:headCssJs" />
+	</head>
+
+	<body>
+
+		<div class="leftNav">
+			<ul>
+				<li>
+					<a href="{:U('Index/index')}">&lt;&lt;返回首页</a>
+				</li>
+				<foreach name="tables" item="tb" key="key0">
+					<li>
+						<a href="#{$tb.table_name}">{$key0+1}.{$tb.table_name}:{$tb.table_comment}</a>
+					</li>
+				</foreach>
+				<li>
+					<a href="#top">︽ 返回顶部</a>
+				</li>
+				
+			</ul>
+		</div>
+
+		<div class="rightBox">
+			<div class="p15">
+				<h1 class="tc fs18" id="top">{$table}数据库字典</h1>
+
+				<foreach name="tables" item="tb" key="key1">
+					<div class="p5 mt20" id="{$tb.table_name}">{$key1+1}.{$tb.table_name}:{$tb.table_comment}</div>
+					<table class="formtable">
+						<tr>
+							<th>序号</th>
+							<th>字段名</th>
+							<th>类型</th>
+							<th>主键</th>
+							<th>允许为空</th>
+							<th>默认值</th>
+							<th>自增长</th>
+							<th width="300">说明</th>
+
+						</tr>
+						
+						<foreach name="tb.column" item="item" key="key">
+							<tr>
+								<td>
+									{$item.index}
+								</td>
+								<td>
+									{$item.column_name}
+								</td>
+								<td>{$item.column_type}</td>
+								<td class="tc">{$item.column_key}</td>
+								<td class="tc">{$item.is_nullable}</td>
+								<td class="tc">{$item.column_default}</td>
+								<td class="tc">
+									<eq name="item.extra" value="auto_increment">是</eq>
+								</td>
+								<td><div class="w300">
+									{$item.column_comment}</div></td>
+							</tr>
+						</foreach>
+					</table>
+				</foreach>
+			</div>
+		</div>
+		<script>
+			$(function() {
+				$("#goto_box").mouseover(function() {
+					$(this).css("right", "0px");
+				}).mouseout(function() {
+					$(this).css("right", "-144px");
+				});
+			})
+		</script>
+	</body>
+
+</html>

+ 4 - 0
Application/Index/Home/View/Public/headCssJs.html

@@ -0,0 +1,4 @@
+
+<link href="__PUBLIC__/css/common_yckj.css"  rel="stylesheet" type="text/css" />
+<link href="__PUBLIC__/css/main.css"  rel="stylesheet" type="text/css" />
+<script src="__PUBLIC__/js/jquery-1.8.3.min.js"></script>

+ 1 - 0
Application/Index/Home/View/index.html

@@ -0,0 +1 @@
+ 

+ 1 - 0
Application/Index/Home/index.html

@@ -0,0 +1 @@
+ 

+ 1 - 0
Application/README.md

@@ -0,0 +1 @@
+项目目录

+ 1 - 0
Application/index.html

@@ -0,0 +1 @@
+ 

+ 13 - 0
Config/config.php

@@ -0,0 +1,13 @@
+<?php
+$config = array (
+		'PAGE_SIZE'=>15,
+		'DB_TYPE' => 'mysql', // 数据库类型
+		'DB_HOST' => '127.0.0.1', // 服务器地址
+		'DB_NAME' => 'information_schema', // 数据库名
+		'DB_USER' => 'root', // 用户名
+		'DB_PWD' => 'root', // 密码
+		'DB_PORT' => '3306', // 端口
+		'DB_PREFIX' => '', // 数据库表前缀
+		// 是否开启session
+		'SESSION_AUTO_START' => true 
+);

+ 246 - 0
Lib/commonFun.php

@@ -0,0 +1,246 @@
+<?php
+if (get_magic_quotes_gpc ()) {
+
+	function stripslashes_deep($value) {
+		$value = is_array ( $value ) ? array_map ( 'stripslashes_deep', $value ) : stripslashes ( $value );
+		return $value;
+	}
+	$_POST = array_map ( 'stripslashes_deep', $_POST );
+	$_GET = array_map ( 'stripslashes_deep', $_GET );
+	$_COOKIE = array_map ( 'stripslashes_deep', $_COOKIE );
+}
+
+/**
+ * 裁剪字符串
+ * @param unknown $str
+ * @param unknown $len
+ * @return string
+ */
+function  cutString($str,$len){
+	$str=strip_tags($str);
+	$strLen=strlen($str);
+	//$str=$strLen.$str;
+	if($strLen<=$len*3){
+		return $str;
+	}
+	return mb_substr($str,0,$len,'utf-8')."...";
+}
+
+/**
+ * 序列化
+ * @param unknown $obj
+ * @return string
+ */
+function my_serialize($obj) {
+	return base64_encode ( gzcompress ( serialize ( $obj ) ) );
+}
+
+// 反序列化
+/**
+ * 反序列化
+ * @param unknown $txt
+ * @return mixed
+ */
+function my_unserialize($txt) {
+	return unserialize ( gzuncompress ( base64_decode ( $txt ) ) );
+}
+
+/**
+ * 获取参数
+ *
+ * @param unknown $key
+ * @param unknown $df_value
+ */
+function request($key, $df_value = '') {
+	return isset ( $_REQUEST [$key] ) ? trim ( $_REQUEST [$key] ) : $df_value;
+}
+
+/**
+ * 获取参数,先get,后post,最后cookie
+ * @param unknown $key 参数名
+ * @return unknown|mixed|string
+ */
+function getParam($key){
+	//$str="oetCntxEFGHI22Ko4CDqQCoxjAB";
+	$val=request($key);
+	if(empty($val)){
+		$val=cookie($key);
+	}
+	return $val;
+}
+
+/**
+ * 输出图片。根据需求自动裁剪图片
+ *
+ * @param unknown $file
+ * @param number $width
+ * @param number $height
+ * @param string $def
+ * @return unknown|mixed 使用例子:<img src="{:img('/wyzxqy/Tools/Upload/../../Upload/image/20150529/20150529103500_39141.jpg',90,90)}" />
+ */
+function img($file, $width = 200, $height = 200, $def = '') {
+
+
+
+	if (preg_match ( '/^http:\/\//', $file )) {
+		// 如果是远程文件
+		return $file;
+	}
+
+	//获得文件扩展名
+	$temp_arr = explode(".", $file);
+	$file_ext = array_pop($temp_arr);
+	$file_ext = trim($file_ext);
+	$file_ext = strtolower($file_ext);
+
+	$baseFile = basename ( $file ); // 找到文件名
+	$basePath = str_replace ( $baseFile, "", $file ) . "temp/"; // 找到目录
+	$baseFile = str_replace ( ".", "", $baseFile ); // 替换掉“.”
+	$baseFile .= $width . "x" . $height . ".jpg";
+	$basePath = str_replace ( C ( 'VIR_DIR' ), ".", $basePath ); // 替换掉虚拟目录
+	if (! is_readable ( $basePath )) { // 判断文件夹是否存在,不存在就创建
+		is_file ( $basePath ) or mkdir ( $basePath, 0777 );
+	}
+	$baseFile = $basePath . $baseFile;
+	// trace ( $baseFile, "basefiel" );
+	$file = str_replace ( C ( 'VIR_DIR' ), ".", $file ); // 替换掉虚拟目录
+	if (! file_exists ( $file )) { // 判断原文件是否存在,不存在直接返回。
+		if (empty ( $def )) { // 如果没有默认图片
+			return $file;
+		} else {
+			// trace($def,"def");
+			return $def;
+		}
+	}
+
+	//后缀名
+	if($file_ext=="gif"){
+		return $file;
+	}
+	if (! file_exists ( $baseFile )) { // 判断文件是否存在
+		$image = new \Think\Image ();
+		$image->open ( $file ); // 生成一个缩放后填充大小的缩略图并保存
+		$image->thumb ( $width, $height, \Think\Image::IMAGE_THUMB_FILLED )->save ( $baseFile ); // 生成缩略图
+	}
+	$str2 = substr ( $baseFile, 0, 2 ); // 取前两个字符串
+	if ($str2 == "./") {
+		$baseFile = C ( 'VIR_DIR' ) . substr ( $baseFile, 1 ); // 取前两个字符串
+	}
+	return $baseFile;
+}
+
+
+
+
+/**
+ * 从摘要和内容中显示关键字
+ * @param unknown $descript
+ * @param unknown $content
+ * @param unknown $keyword
+ */
+function getDescKey($descript,$content,$keyword){
+	$startPre=80;//开始的位置
+	$len=160;//长度
+	//在摘要中找
+	$index=intval( stripos($descript,$keyword));
+	if($index>0){//如果摘要中就已经有关键字了。
+		$begin = $index - $startPre > 0 ? $index - $startPre : 0;
+		$descript = mb_strcut ( $descript, $begin, $len, "utf-8" ); // 视为字节流,utf-8下一个汉
+		return  showKeyword($keyword,$descript);
+	}
+	$content=strip_tags($content);
+	$index=intval( stripos($content,$keyword));
+	if($index>0){//如果正文中就已经有关键字了。
+		$begin=$index-$startPre>0?$index-$startPre:0;
+		$content= mb_strcut($content,$begin,$len,"utf-8");//视为字节流,utf-8下一个汉
+		return  showKeyword($keyword,$content);
+	}
+	return getDescript($descript,$content);//如果都没有关键字
+	//echo intval( stripos($str,'斯'));
+	//echo mb_strcut($str,4,10,"utf-8");//视为字节流,utf-8下一个汉
+}
+
+
+
+/**
+ * 跳转
+ *
+ * @param unknown $url
+ */
+function jumpUrl($url) {
+	if (! empty ( $url )) {
+		redirect ( $url );
+		exit ();
+	}
+}
+
+
+function simpleHtmlEncode($str){
+	$str = str_replace ( "\r\n", "<br/>", $str ); // \r\n
+	$str= str_replace ( "\r", "<br/>", $str ); // 替换"\r"
+	$str= str_replace ( "\n", "<br/>", $str ); // 替换"\n"
+	$str= str_replace ( " ", "&nbsp;", $str ); // 替换"\n"
+	return $str;
+}
+
+
+function simpleHtmlDecode($str){
+	$str=str_replace("<br/>","\r\n",$str);
+	$str=str_replace("&nbsp;"," ",$str);
+	return $str;
+}
+
+/**
+ * 显示关键字
+ * @param unknown $keyword
+ * @param unknown $content
+ * @return mixed
+ */
+function showKeyword($keyword,$content){
+	return str_replace($keyword,"<font class='red'>$keyword</font>",$content);
+}
+
+
+function  sendMail($mailto,$subject,$content){	
+	vendor("Mail.smtp");
+	$conditon['code']='email';
+	$result=M('config')->where($conditon)->find();
+	$model=unserialize($result['content']);
+	//使用163邮箱服务器
+	$smtpserver =$model['smtpserver'];// "smtp.qq.com";
+	//163邮箱服务器端口
+	$smtpserverport = 25;
+	//你的163服务器邮箱账号
+	$smtpusermail =$model['smtpusermail'];// "ycxxkj002@qq.com";
+	//收件人邮箱
+	$smtpemailto =$mailto;// "lzj500@qq.com";
+	//你的邮箱账号(去掉@163.com)
+	$smtpuser =$model['smtpuser'];// "2936890167";//SMTP服务器的用户帐号
+	//你的邮箱密码
+	$smtppass = $model['smtppass'];//"mail2015"; //SMTP服务器的用户密码
+	//邮件主题
+	$mailsubject = $subject;//"测试邮件发送";
+	//邮件内容
+	$mailbody =$content;// "<strong> PHP</strong>+<font style='color:red'>MySQL</font>+<a href='http://www.baidu.com'>点击跳转</a>";
+	//邮件格式(HTML/TXT),TXT为文本邮件
+	$mailtype = "HTML";
+	//这里面的一个true是表示使用身份验证,否则不使用身份验证.
+	$smtp = new \smtp($smtpserver,$smtpserverport,true,$smtpuser,$smtppass);
+	//是否显示发送的调试信息
+	$smtp->debug =false;// TRUE;
+	//$smtp->debug = TRUE;
+	//发送邮件
+	$res=$smtp->sendmail($smtpemailto, $smtpusermail, $mailsubject, $mailbody, $mailtype);
+	
+}
+
+function get_url() {
+	$sys_protocal = isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == '443' ? 'https://' : 'http://';
+	$php_self = $_SERVER['PHP_SELF'] ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME'];
+	$path_info = isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : '';
+	$relate_url = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : $php_self.(isset($_SERVER['QUERY_STRING']) ? '?'.$_SERVER['QUERY_STRING'] : $path_info);
+	return $sys_protocal.(isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '').$relate_url;
+}
+
+
+?>

+ 1 - 0
Public/README.md

@@ -0,0 +1 @@
+资源文件目录

+ 765 - 0
Public/css/common_yckj.css

@@ -0,0 +1,765 @@
+@charset "UTF-8";
+* { margin: 0; padding: 0; }
+
+a:hover { text-decoration: none; }
+
+.blank_s { height: 8px; }
+
+.blank_m { height: 16px; }
+
+.blank_l { height: 26px; }
+
+.bds { border: solid 1px #ccc !important; }
+
+.bdd { border: dashed 1px #ccc !important; }
+
+.bdd_t { border-top: dashed 1px #ccc !important; }
+
+.bdd_l { border-left: dashed 1px #ccc !important; }
+
+.bdd_r { border-right: dashed 1px #ccc !important; }
+
+.bdd_t { border-top: dashed 1px #ccc !important; }
+
+.bds_b { border-bottom: solid 1px #ccc !important; }
+
+.bds_t { border-top: solid 1px #ccc !important; }
+
+.bds_l { border-left: solid 1px #ccc !important; }
+
+.bds_r { border-right: solid 1px #ccc !important; }
+
+.bdd_b { border-bottom: dashed 1px #ccc !important; }
+
+.bdn { border: none !important; }
+
+.bdn_b { border-bottom: none !important; }
+
+.bdn_t { border-top: none !important; }
+
+.bdn_l { border-left: none !important; }
+
+.bg_white { background: #fff !important; }
+
+.bg_f5 { background: #F5F5F5 !important; }
+
+.bg_ff { background: #fff !important; }
+
+.bg_none { background: none  !important; }
+
+.cursor { cursor: pointer; }
+
+.cursor_none { cursor: default !important; }
+
+.dis_blk { display: block !important; }
+
+.dis_none { display: none !important; }
+
+.dis_inline { display: inline !important; }
+
+.dis_inb { display: inline-block !important; }
+
+.clear { clear: both; }
+
+.fl { float: left !important; }
+
+.fwb { font-weight: bold; }
+
+.white { color: #fff !important; }
+
+.red { color: #ff0000 !important; }
+
+.black { color: #000 !important; }
+
+.grey { color: grey !important; }
+
+.blue { color: blue !important; }
+
+.light-blue { color: #009CEB !important; }
+
+.bgc_grey { background: #ccc; }
+
+.fs12 { font-size: 12px !important; }
+
+.fs13 { font-size: 13px !important; }
+
+.fs14 { font-size: 14px !important; }
+
+.fs15 { font-size: 15px !important; }
+
+.fs16 { font-size: 16px !important; }
+
+.fs17 { font-size: 17px !important; }
+
+.fs18 { font-size: 18px !important; }
+
+.fs19 { font-size: 19px !important; }
+
+.fs20 { font-size: 20px !important; }
+
+.fs21 { font-size: 21px !important; }
+
+.fs22 { font-size: 22px !important; }
+
+.fs23 { font-size: 23px !important; }
+
+.fs24 { font-size: 24px !important; }
+
+.fs25 { font-size: 25px !important; }
+
+.fs26 { font-size: 26px !important; }
+
+.fs27 { font-size: 27px !important; }
+
+.fs28 { font-size: 28px !important; }
+
+.fs29 { font-size: 29px !important; }
+
+.fs30 { font-size: 30px !important; }
+
+.fs31 { font-size: 31px !important; }
+
+.fs32 { font-size: 32px !important; }
+
+.fs33 { font-size: 33px !important; }
+
+.fs34 { font-size: 34px !important; }
+
+.fs35 { font-size: 35px !important; }
+
+.fs36 { font-size: 36px !important; }
+
+.fs37 { font-size: 37px !important; }
+
+.fs38 { font-size: 38px !important; }
+
+.fs39 { font-size: 39px !important; }
+
+.fs40 { font-size: 40px !important; }
+
+.fs41 { font-size: 41px !important; }
+
+.fs42 { font-size: 42px !important; }
+
+.fs43 { font-size: 43px !important; }
+
+.fs44 { font-size: 44px !important; }
+
+.fs45 { font-size: 45px !important; }
+
+.fs46 { font-size: 46px !important; }
+
+.fs47 { font-size: 47px !important; }
+
+.fs48 { font-size: 48px !important; }
+
+.fs49 { font-size: 49px !important; }
+
+.fs50 { font-size: 50px !important; }
+
+.fr { float: right !important; }
+
+.h10 { height: 10px !important; }
+
+.h20 { height: 20px !important; }
+
+.h30 { height: 30px !important; }
+
+.h40 { height: 40px !important; }
+
+.h50 { height: 50px !important; }
+
+.h60 { height: 60px !important; }
+
+.h70 { height: 70px !important; }
+
+.h80 { height: 80px !important; }
+
+.h90 { height: 90px !important; }
+
+.h100 { height: 100px !important; }
+
+.h150 { height: 150px !important; }
+
+.h200 { height: 200px !important; }
+
+.h250 { height: 250px !important; }
+
+.h300 { height: 300px !important; }
+
+.h350 { height: 350px !important; }
+
+.h400 { height: 400px !important; }
+
+.h450 { height: 450px !important; }
+
+.h500 { height: 500px !important; }
+
+.h550 { height: 550px !important; }
+
+.h600 { height: 600px !important; }
+
+.h650 { height: 650px !important; }
+
+.h700 { height: 700px !important; }
+
+.mb0 { margin-bottom: 0px; }
+
+.mb5 { margin-bottom: 5px; }
+
+.mb10 { margin-bottom: 10px; }
+
+.mb15 { margin-bottom: 15px; }
+
+.mb20 { margin-bottom: 20px; }
+
+.mb25 { margin-bottom: 25px; }
+
+.mb30 { margin-bottom: 30px; }
+
+.mb35 { margin-bottom: 35px; }
+
+.mb40 { margin-bottom: 40px; }
+
+.mb45 { margin-bottom: 45px; }
+
+.mb50 { margin-bottom: 50px; }
+
+.mb55 { margin-bottom: 55px; }
+
+.mb60 { margin-bottom: 60px; }
+
+.mt0 { margin-top: 0px !important; }
+
+.mt5 { margin-top: 5px !important; }
+
+.mt10 { margin-top: 10px !important; }
+
+.mt15 { margin-top: 15px !important; }
+
+.mt20 { margin-top: 20px !important; }
+
+.mt25 { margin-top: 25px !important; }
+
+.mt30 { margin-top: 30px !important; }
+
+.mt35 { margin-top: 35px !important; }
+
+.mt40 { margin-top: 40px !important; }
+
+.mt45 { margin-top: 45px !important; }
+
+.mt50 { margin-top: 50px !important; }
+
+.mt55 { margin-top: 55px !important; }
+
+.mt60 { margin-top: 60px !important; }
+
+.ml0 { margin-left: 0px; }
+
+.ml5 { margin-left: 5px; }
+
+.ml10 { margin-left: 10px; }
+
+.ml15 { margin-left: 15px; }
+
+.ml20 { margin-left: 20px; }
+
+.ml25 { margin-left: 25px; }
+
+.ml30 { margin-left: 30px; }
+
+.ml35 { margin-left: 35px; }
+
+.ml40 { margin-left: 40px; }
+
+.ml45 { margin-left: 45px; }
+
+.ml50 { margin-left: 50px; }
+
+.ml55 { margin-left: 55px; }
+
+.ml60 { margin-left: 60px; }
+
+.mr0 { margin-right: 0px; }
+
+.mr5 { margin-right: 5px; }
+
+.mr10 { margin-right: 10px; }
+
+.mr15 { margin-right: 15px; }
+
+.mr20 { margin-right: 20px; }
+
+.mr25 { margin-right: 25px; }
+
+.mr30 { margin-right: 30px; }
+
+.mr35 { margin-right: 35px; }
+
+.mr40 { margin-right: 40px; }
+
+.mr45 { margin-right: 45px; }
+
+.mr50 { margin-right: 50px; }
+
+.mr55 { margin-right: 55px; }
+
+.mr60 { margin-right: 60px; }
+
+.m0 { margin: 0 !important; }
+
+.ma0 { margin: 0 auto; }
+
+.pb0 { padding-bottom: 0 !important; }
+
+.p0 { padding: 0px; }
+
+.p5 { padding: 5px; }
+
+.p10 { padding: 10px; }
+
+.p15 { padding: 15px; }
+
+.p20 { padding: 20px; }
+
+.p25 { padding: 25px; }
+
+.p30 { padding: 30px; }
+
+.p35 { padding: 35px; }
+
+.p40 { padding: 40px; }
+
+.p45 { padding: 45px; }
+
+.p50 { padding: 50px; }
+
+.p55 { padding: 55px; }
+
+.p60 { padding: 60px; }
+
+.pl0 { padding-left: 0px; }
+
+.pl5 { padding-left: 5px; }
+
+.pl10 { padding-left: 10px; }
+
+.pl15 { padding-left: 15px; }
+
+.pl20 { padding-left: 20px; }
+
+.pl25 { padding-left: 25px; }
+
+.pl30 { padding-left: 30px; }
+
+.pl35 { padding-left: 35px; }
+
+.pl40 { padding-left: 40px; }
+
+.pl45 { padding-left: 45px; }
+
+.pl50 { padding-left: 50px; }
+
+.pl55 { padding-left: 55px; }
+
+.pl60 { padding-left: 60px; }
+
+.pr0 { padding-right: 0px; }
+
+.pr5 { padding-right: 5px; }
+
+.pr10 { padding-right: 10px; }
+
+.pr15 { padding-right: 15px; }
+
+.pr20 { padding-right: 20px; }
+
+.pr25 { padding-right: 25px; }
+
+.pr30 { padding-right: 30px; }
+
+.pr35 { padding-right: 35px; }
+
+.pr40 { padding-right: 40px; }
+
+.pr45 { padding-right: 45px; }
+
+.pr50 { padding-right: 50px; }
+
+.pr55 { padding-right: 55px; }
+
+.pr60 { padding-right: 60px; }
+
+.pb0 { padding-bottom: 0px; }
+
+.pb5 { padding-bottom: 5px; }
+
+.pb10 { padding-bottom: 10px; }
+
+.pb15 { padding-bottom: 15px; }
+
+.pb20 { padding-bottom: 20px; }
+
+.pb25 { padding-bottom: 25px; }
+
+.pb30 { padding-bottom: 30px; }
+
+.pb35 { padding-bottom: 35px; }
+
+.pb40 { padding-bottom: 40px; }
+
+.pb45 { padding-bottom: 45px; }
+
+.pb50 { padding-bottom: 50px; }
+
+.pb55 { padding-bottom: 55px; }
+
+.pb60 { padding-bottom: 60px; }
+
+.pt0 { padding-top: 0px; }
+
+.pt5 { padding-top: 5px; }
+
+.pt10 { padding-top: 10px; }
+
+.pt15 { padding-top: 15px; }
+
+.pt20 { padding-top: 20px; }
+
+.pt25 { padding-top: 25px; }
+
+.pt30 { padding-top: 30px; }
+
+.pt35 { padding-top: 35px; }
+
+.pt40 { padding-top: 40px; }
+
+.pt45 { padding-top: 45px; }
+
+.pt50 { padding-top: 50px; }
+
+.pt55 { padding-top: 55px; }
+
+.pt60 { padding-top: 60px; }
+
+.pct1 { width: 1%; }
+
+.pct2 { width: 2%; }
+
+.pct3 { width: 3%; }
+
+.pct4 { width: 4%; }
+
+.pct5 { width: 5%; }
+
+.pct6 { width: 6%; }
+
+.pct7 { width: 7%; }
+
+.pct8 { width: 8%; }
+
+.pct9 { width: 9%; }
+
+.pct10 { width: 10%; }
+
+.pct11 { width: 11%; }
+
+.pct12 { width: 12%; }
+
+.pct13 { width: 13%; }
+
+.pct14 { width: 14%; }
+
+.pct15 { width: 15%; }
+
+.pct16 { width: 16%; }
+
+.pct17 { width: 17%; }
+
+.pct18 { width: 18%; }
+
+.pct19 { width: 19%; }
+
+.pct20 { width: 20%; }
+
+.pct21 { width: 21%; }
+
+.pct22 { width: 22%; }
+
+.pct23 { width: 23%; }
+
+.pct24 { width: 24%; }
+
+.pct25 { width: 25%; }
+
+.pct26 { width: 26%; }
+
+.pct27 { width: 27%; }
+
+.pct28 { width: 28%; }
+
+.pct29 { width: 29%; }
+
+.pct30 { width: 30%; }
+
+.pct31 { width: 31%; }
+
+.pct32 { width: 32%; }
+
+.pct33 { width: 33%; }
+
+.pct34 { width: 34%; }
+
+.pct35 { width: 35%; }
+
+.pct36 { width: 36%; }
+
+.pct37 { width: 37%; }
+
+.pct38 { width: 38%; }
+
+.pct39 { width: 39%; }
+
+.pct40 { width: 40%; }
+
+.pct41 { width: 41%; }
+
+.pct42 { width: 42%; }
+
+.pct43 { width: 43%; }
+
+.pct44 { width: 44%; }
+
+.pct45 { width: 45%; }
+
+.pct46 { width: 46%; }
+
+.pct47 { width: 47%; }
+
+.pct48 { width: 48%; }
+
+.pct49 { width: 49%; }
+
+.pct50 { width: 50%; }
+
+.pct51 { width: 51%; }
+
+.pct52 { width: 52%; }
+
+.pct53 { width: 53%; }
+
+.pct54 { width: 54%; }
+
+.pct55 { width: 55%; }
+
+.pct56 { width: 56%; }
+
+.pct57 { width: 57%; }
+
+.pct58 { width: 58%; }
+
+.pct59 { width: 59%; }
+
+.pct60 { width: 60%; }
+
+.pct61 { width: 61%; }
+
+.pct62 { width: 62%; }
+
+.pct63 { width: 63%; }
+
+.pct64 { width: 64%; }
+
+.pct65 { width: 65%; }
+
+.pct66 { width: 66%; }
+
+.pct67 { width: 67%; }
+
+.pct68 { width: 68%; }
+
+.pct69 { width: 69%; }
+
+.pct70 { width: 70%; }
+
+.pct71 { width: 71%; }
+
+.pct72 { width: 72%; }
+
+.pct73 { width: 73%; }
+
+.pct74 { width: 74%; }
+
+.pct75 { width: 75%; }
+
+.pct76 { width: 76%; }
+
+.pct77 { width: 77%; }
+
+.pct78 { width: 78%; }
+
+.pct79 { width: 79%; }
+
+.pct80 { width: 80%; }
+
+.pct81 { width: 81%; }
+
+.pct82 { width: 82%; }
+
+.pct83 { width: 83%; }
+
+.pct84 { width: 84%; }
+
+.pct85 { width: 85%; }
+
+.pct86 { width: 86%; }
+
+.pct87 { width: 87%; }
+
+.pct88 { width: 88%; }
+
+.pct89 { width: 89%; }
+
+.pct90 { width: 90%; }
+
+.pct91 { width: 91%; }
+
+.pct92 { width: 92%; }
+
+.pct93 { width: 93%; }
+
+.pct94 { width: 94%; }
+
+.pct95 { width: 95%; }
+
+.pct96 { width: 96%; }
+
+.pct97 { width: 97%; }
+
+.pct98 { width: 98%; }
+
+.pct99 { width: 99%; }
+
+.pct100 { width: 100%; }
+
+.nowrap { overflow: hidden; -o-text-overflow: ellipsis; /*兼容opera*/ text-overflow: ellipsis; /*这就是省略号喽*/ overflow: hidden; /*设置超过的隐藏*/ white-space: nowrap; /*设置不折行*/ }
+
+.pos_r { position: relative; }
+
+.pos_a { position: absolute; }
+
+.pos_f { position: fixed; }
+
+.tl { text-align: left !important; }
+
+.tr { text-align: right !important; }
+
+.tc { text-align: center !important; }
+
+.w0 { width: 0px; }
+
+.w20 { width: 20px; }
+
+.w40 { width: 40px; }
+
+.w60 { width: 60px; }
+
+.w80 { width: 80px; }
+
+.w100 { width: 100px; }
+
+.w120 { width: 120px; }
+
+.w140 { width: 140px; }
+
+.w160 { width: 160px; }
+
+.w180 { width: 180px; }
+
+.w200 { width: 200px; }
+
+.w220 { width: 220px; }
+
+.w240 { width: 240px; }
+
+.w260 { width: 260px; }
+
+.w280 { width: 280px; }
+
+.w300 { width: 300px; }
+
+.w320 { width: 320px; }
+
+.w340 { width: 340px; }
+
+.w360 { width: 360px; }
+
+.w380 { width: 380px; }
+
+.w400 { width: 400px; }
+
+.w420 { width: 420px; }
+
+.w440 { width: 440px; }
+
+.w460 { width: 460px; }
+
+.w480 { width: 480px; }
+
+.w500 { width: 500px; }
+
+.w520 { width: 520px; }
+
+.w540 { width: 540px; }
+
+.w560 { width: 560px; }
+
+.w580 { width: 580px; }
+
+.w600 { width: 600px; }
+
+.w620 { width: 620px; }
+
+.w640 { width: 640px; }
+
+.w660 { width: 660px; }
+
+.w680 { width: 680px; }
+
+.w700 { width: 700px; }
+
+.w720 { width: 720px; }
+
+.w740 { width: 740px; }
+
+.w760 { width: 760px; }
+
+.w780 { width: 780px; }
+
+.w800 { width: 800px; }
+
+/*==================loading=======================*/
+.spinner { width: 60px; height: 60px; background-color: #67CF22; margin: 10px auto; -webkit-animation: rotateplane 1.2s infinite ease-in-out; animation: rotateplane 1.2s infinite ease-in-out; }
+
+@-webkit-keyframes rotateplane { 0% { -webkit-transform: perspective(120px); }
+  50% { -webkit-transform: perspective(120px) rotateY(180deg); }
+  100% { -webkit-transform: perspective(120px) rotateY(180deg) rotateX(180deg); } }
+@keyframes rotateplane { 0% { transform: perspective(120px) rotateX(0deg) rotateY(0deg); -webkit-transform: perspective(120px) rotateX(0deg) rotateY(0deg); }
+  50% { transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg); -webkit-transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg); }
+  100% { transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg); -webkit-transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg); } }
+/*==================end loading===================*/
+/*from table*/
+table.formtable { width: 100%; font-family: verdana, arial, sans-serif; font-size: 11px; color: #333333; border-width: 1px; border-color: #ddd; border-collapse: collapse; }
+
+table.formtable th { border-width: 1px; padding: 8px; border-style: solid; border-color: #ddd; background-color: #dedede; }
+
+table.formtable td { border-width: 1px; padding: 8px; border-style: solid; border-color: #ddd; background-color: #ffffff; }
+
+table.tdcenter td { text-align: center; }
+
+table.formtable .ft_title { background: #f5f5f5; text-align: right; padding-right: 5px; width: 120px; }
+
+/*from table*/
+
+/*# sourceMappingURL=common_yckj.css.map */

+ 17 - 0
Public/css/main.css

@@ -0,0 +1,17 @@
+* { padding: 0; margin: 0; }
+
+.table_border { border: solid 1px #B4B4B4; border-collapse: collapse; }
+
+.table_border tr th { padding-left: 4px; height: 27px; border: solid 1px #B4B4B4; }
+
+.table_border tr td { height: 25px; padding: 4px; border: solid 1px #B4B4B4; }
+
+.goto_box { position: fixed; right: -144px; bottom: 10px; width: 150px; background: #fff; }
+
+.leftNav { box-sizing: border-box; padding: 10px; position: fixed; height: 100%; width: 250px; overflow: auto; background-color: #f0f0f0; padding-bottom: 20px; }
+.leftNav ul li { list-style: none; margin-top: 1px; padding: 5px; border-bottom: #ccc dashed 1px; }
+.leftNav ul li a { text-decoration: none; font-size: 14px; }
+
+.rightBox { margin-left: 270px; }
+
+/*# sourceMappingURL=main.css.map */

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 7 - 0
Public/css/main.css.map


+ 53 - 0
Public/css/main.scss

@@ -0,0 +1,53 @@
+*{
+    padding: 0;
+    margin: 0;
+}
+.table_border{  
+    border: solid 1px #B4B4B4;  
+    border-collapse: collapse; 
+}  
+.table_border tr th{   
+    padding-left:4px;  
+    height:27px;  
+    border: solid 1px #B4B4B4;  
+}  
+.table_border tr td{  
+    height:25px;  
+    padding:4px;  
+    border: solid 1px #B4B4B4;  
+}  
+.goto_box{
+    position: fixed;
+    right:-144px;
+    bottom: 10px;
+    width: 150px;    
+    background: #fff;    
+   
+}
+.leftNav{
+    box-sizing: border-box;
+    padding: 10px;
+    position: fixed;
+    height: 100%;
+    width: 250px;
+    overflow: auto;
+    background-color: #f0f0f0;
+    padding-bottom: 20px;  
+    ul{
+        li{
+            list-style: none;            
+            margin-top:1px;           
+            padding: 5px;
+            border-bottom: #ccc dashed 1px;
+            a{
+                text-decoration: none;                
+                font-size: 14px;
+            }
+            
+        }
+    }
+    
+}
+.rightBox{
+    margin-left: 270px;
+}

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 2 - 0
Public/js/jquery-1.8.3.min.js


+ 2 - 0
README.md

@@ -0,0 +1,2 @@
+#dbkey
+##yckj

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1550 - 0
ThinkPHP/Common/functions.php


+ 167 - 0
ThinkPHP/Conf/convention.php

@@ -0,0 +1,167 @@
+<?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>
+// +----------------------------------------------------------------------
+
+/**
+ * ThinkPHP惯例配置文件
+ * 该文件请不要修改,如果要覆盖惯例配置的值,可在应用配置文件中设定和惯例不符的配置项
+ * 配置名称大小写任意,系统会统一转换成小写
+ * 所有配置参数都可以在生效前动态改变
+ */
+defined('THINK_PATH') or exit();
+return  array(
+    /* 应用设定 */
+    'APP_USE_NAMESPACE'     =>  true,    // 应用类库是否使用命名空间
+    'APP_SUB_DOMAIN_DEPLOY' =>  false,   // 是否开启子域名部署
+    'APP_SUB_DOMAIN_RULES'  =>  array(), // 子域名部署规则
+    'APP_DOMAIN_SUFFIX'     =>  '', // 域名后缀 如果是com.cn net.cn 之类的后缀必须设置    
+    'ACTION_SUFFIX'         =>  '', // 操作方法后缀
+    'MULTI_MODULE'          =>  true, // 是否允许多模块 如果为false 则必须设置 DEFAULT_MODULE
+    'MODULE_DENY_LIST'      =>  array('Common','Runtime'),
+    'CONTROLLER_LEVEL'      =>  1,
+    'APP_AUTOLOAD_LAYER'    =>  'Controller,Model', // 自动加载的应用类库层 关闭APP_USE_NAMESPACE后有效
+    'APP_AUTOLOAD_PATH'     =>  '', // 自动加载的路径 关闭APP_USE_NAMESPACE后有效
+
+    /* Cookie设置 */
+    'COOKIE_EXPIRE'         =>  0,       // Cookie有效期
+    'COOKIE_DOMAIN'         =>  '',      // Cookie有效域名
+    'COOKIE_PATH'           =>  '/',     // Cookie路径
+    'COOKIE_PREFIX'         =>  '',      // Cookie前缀 避免冲突
+    'COOKIE_SECURE'         =>  false,   // Cookie安全传输
+    'COOKIE_HTTPONLY'       =>  '',      // Cookie httponly设置
+
+    /* 默认设定 */
+    'DEFAULT_M_LAYER'       =>  'Model', // 默认的模型层名称
+    'DEFAULT_C_LAYER'       =>  'Controller', // 默认的控制器层名称
+    'DEFAULT_V_LAYER'       =>  'View', // 默认的视图层名称
+    'DEFAULT_LANG'          =>  'zh-cn', // 默认语言
+    'DEFAULT_THEME'         =>  '',	// 默认模板主题名称
+    'DEFAULT_MODULE'        =>  'Home',  // 默认模块
+    'DEFAULT_CONTROLLER'    =>  'Index', // 默认控制器名称
+    'DEFAULT_ACTION'        =>  'index', // 默认操作名称
+    'DEFAULT_CHARSET'       =>  'utf-8', // 默认输出编码
+    'DEFAULT_TIMEZONE'      =>  'PRC',	// 默认时区
+    'DEFAULT_AJAX_RETURN'   =>  'JSON',  // 默认AJAX 数据返回格式,可选JSON XML ...
+    'DEFAULT_JSONP_HANDLER' =>  'jsonpReturn', // 默认JSONP格式返回的处理方法
+    'DEFAULT_FILTER'        =>  'htmlspecialchars', // 默认参数过滤方法 用于I函数...
+
+    /* 数据库设置 */
+    'DB_TYPE'               =>  '',     // 数据库类型
+    'DB_HOST'               =>  '', // 服务器地址
+    'DB_NAME'               =>  '',          // 数据库名
+    'DB_USER'               =>  '',      // 用户名
+    'DB_PWD'                =>  '',          // 密码
+    'DB_PORT'               =>  '',        // 端口
+    'DB_PREFIX'             =>  '',    // 数据库表前缀
+    'DB_PARAMS'          	=>  array(), // 数据库连接参数    
+    'DB_DEBUG'  			=>  TRUE, // 数据库调试模式 开启后可以记录SQL日志
+    'DB_FIELDS_CACHE'       =>  true,        // 启用字段缓存
+    'DB_CHARSET'            =>  'utf8',      // 数据库编码默认采用utf8
+    'DB_DEPLOY_TYPE'        =>  0, // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
+    'DB_RW_SEPARATE'        =>  false,       // 数据库读写是否分离 主从式有效
+    'DB_MASTER_NUM'         =>  1, // 读写分离后 主服务器数量
+    'DB_SLAVE_NO'           =>  '', // 指定从服务器序号
+
+    /* 数据缓存设置 */
+    'DATA_CACHE_TIME'       =>  0,      // 数据缓存有效期 0表示永久缓存
+    'DATA_CACHE_COMPRESS'   =>  false,   // 数据缓存是否压缩缓存
+    'DATA_CACHE_CHECK'      =>  false,   // 数据缓存是否校验缓存
+    'DATA_CACHE_PREFIX'     =>  '',     // 缓存前缀
+    'DATA_CACHE_TYPE'       =>  'File',  // 数据缓存类型,支持:File|Db|Apc|Memcache|Shmop|Sqlite|Xcache|Apachenote|Eaccelerator
+    'DATA_CACHE_PATH'       =>  TEMP_PATH,// 缓存路径设置 (仅对File方式缓存有效)
+    'DATA_CACHE_KEY'        =>  '',	// 缓存文件KEY (仅对File方式缓存有效)    
+    'DATA_CACHE_SUBDIR'     =>  false,    // 使用子目录缓存 (自动根据缓存标识的哈希创建子目录)
+    'DATA_PATH_LEVEL'       =>  1,        // 子目录缓存级别
+
+    /* 错误设置 */
+    'ERROR_MESSAGE'         =>  '页面错误!请稍后再试~',//错误显示信息,非调试模式有效
+    'ERROR_PAGE'            =>  '',	// 错误定向页面
+    'SHOW_ERROR_MSG'        =>  false,    // 显示错误信息
+    'TRACE_MAX_RECORD'      =>  100,    // 每个级别的错误信息 最大记录数
+
+    /* 日志设置 */
+    'LOG_RECORD'            =>  false,   // 默认不记录日志
+    'LOG_TYPE'              =>  'File', // 日志记录类型 默认为文件方式
+    'LOG_LEVEL'             =>  'EMERG,ALERT,CRIT,ERR',// 允许记录的日志级别
+    'LOG_FILE_SIZE'         =>  2097152,	// 日志文件大小限制
+    'LOG_EXCEPTION_RECORD'  =>  false,    // 是否记录异常信息日志
+
+    /* SESSION设置 */
+    'SESSION_AUTO_START'    =>  true,    // 是否自动开启Session
+    'SESSION_OPTIONS'       =>  array(), // session 配置数组 支持type name id path expire domain 等参数
+    'SESSION_TYPE'          =>  '', // session hander类型 默认无需设置 除非扩展了session hander驱动
+    'SESSION_PREFIX'        =>  '', // session 前缀
+    //'VAR_SESSION_ID'      =>  'session_id',     //sessionID的提交变量
+
+    /* 模板引擎设置 */
+    'TMPL_CONTENT_TYPE'     =>  'text/html', // 默认模板输出类型
+    'TMPL_ACTION_ERROR'     =>  THINK_PATH.'Tpl/dispatch_jump.tpl', // 默认错误跳转对应的模板文件
+    'TMPL_ACTION_SUCCESS'   =>  THINK_PATH.'Tpl/dispatch_jump.tpl', // 默认成功跳转对应的模板文件
+    'TMPL_EXCEPTION_FILE'   =>  THINK_PATH.'Tpl/think_exception.tpl',// 异常页面的模板文件
+    'TMPL_DETECT_THEME'     =>  false,       // 自动侦测模板主题
+    'TMPL_TEMPLATE_SUFFIX'  =>  '.html',     // 默认模板文件后缀
+    'TMPL_FILE_DEPR'        =>  '/', //模板文件CONTROLLER_NAME与ACTION_NAME之间的分割符
+    // 布局设置
+    'TMPL_ENGINE_TYPE'      =>  'Think',     // 默认模板引擎 以下设置仅对使用Think模板引擎有效
+    'TMPL_CACHFILE_SUFFIX'  =>  '.php',      // 默认模板缓存后缀
+    'TMPL_DENY_FUNC_LIST'   =>  'echo,exit',    // 模板引擎禁用函数
+    'TMPL_DENY_PHP'         =>  false, // 默认模板引擎是否禁用PHP原生代码
+    'TMPL_L_DELIM'          =>  '{',            // 模板引擎普通标签开始标记
+    'TMPL_R_DELIM'          =>  '}',            // 模板引擎普通标签结束标记
+    'TMPL_VAR_IDENTIFY'     =>  'array',     // 模板变量识别。留空自动判断,参数为'obj'则表示对象
+    'TMPL_STRIP_SPACE'      =>  true,       // 是否去除模板文件里面的html空格与换行
+    'TMPL_CACHE_ON'         =>  true,        // 是否开启模板编译缓存,设为false则每次都会重新编译
+    'TMPL_CACHE_PREFIX'     =>  '',         // 模板缓存前缀标识,可以动态改变
+    'TMPL_CACHE_TIME'       =>  0,         // 模板缓存有效期 0 为永久,(以数字为值,单位:秒)
+    'TMPL_LAYOUT_ITEM'      =>  '{__CONTENT__}', // 布局模板的内容替换标识
+    'LAYOUT_ON'             =>  false, // 是否启用布局
+    'LAYOUT_NAME'           =>  'layout', // 当前布局名称 默认为layout
+
+    // Think模板引擎标签库相关设定
+    'TAGLIB_BEGIN'          =>  '<',  // 标签库标签开始标记
+    'TAGLIB_END'            =>  '>',  // 标签库标签结束标记
+    'TAGLIB_LOAD'           =>  true, // 是否使用内置标签库之外的其它标签库,默认自动检测
+    'TAGLIB_BUILD_IN'       =>  'cx', // 内置标签库名称(标签使用不必指定标签库名称),以逗号分隔 注意解析顺序
+    'TAGLIB_PRE_LOAD'       =>  '',   // 需要额外加载的标签库(须指定标签库名称),多个以逗号分隔 
+    
+    /* URL设置 */
+    'URL_CASE_INSENSITIVE'  =>  true,   // 默认false 表示URL区分大小写 true则表示不区分大小写
+    'URL_MODEL'             =>  1,       // URL访问模式,可选参数0、1、2、3,代表以下四种模式:
+    // 0 (普通模式); 1 (PATHINFO 模式); 2 (REWRITE  模式); 3 (兼容模式)  默认为PATHINFO 模式
+    'URL_PATHINFO_DEPR'     =>  '/',	// PATHINFO模式下,各参数之间的分割符号
+    'URL_PATHINFO_FETCH'    =>  'ORIG_PATH_INFO,REDIRECT_PATH_INFO,REDIRECT_URL', // 用于兼容判断PATH_INFO 参数的SERVER替代变量列表
+    'URL_REQUEST_URI'       =>  'REQUEST_URI', // 获取当前页面地址的系统变量 默认为REQUEST_URI
+    'URL_HTML_SUFFIX'       =>  'html',  // URL伪静态后缀设置
+    'URL_DENY_SUFFIX'       =>  'ico|png|gif|jpg', // URL禁止访问的后缀设置
+    'URL_PARAMS_BIND'       =>  true, // URL变量绑定到Action方法参数
+    'URL_PARAMS_BIND_TYPE'  =>  0, // URL变量绑定的类型 0 按变量名绑定 1 按变量顺序绑定
+    'URL_PARAMS_FILTER'     =>  false, // URL变量绑定过滤
+    'URL_PARAMS_FILTER_TYPE'=>  '', // URL变量绑定过滤方法 如果为空 调用DEFAULT_FILTER
+    'URL_ROUTER_ON'         =>  false,   // 是否开启URL路由
+    'URL_ROUTE_RULES'       =>  array(), // 默认路由规则 针对模块
+    'URL_MAP_RULES'         =>  array(), // URL映射定义规则
+
+    /* 系统变量名称设置 */
+    'VAR_MODULE'            =>  'm',     // 默认模块获取变量
+    'VAR_ADDON'             =>  'addon',     // 默认的插件控制器命名空间变量
+    'VAR_CONTROLLER'        =>  'c',    // 默认控制器获取变量
+    'VAR_ACTION'            =>  'a',    // 默认操作获取变量
+    'VAR_AJAX_SUBMIT'       =>  'ajax',  // 默认的AJAX提交变量
+    'VAR_JSONP_HANDLER'     =>  'callback',
+    'VAR_PATHINFO'          =>  's',    // 兼容模式PATHINFO获取变量例如 ?s=/module/action/id/1 后面的参数取决于URL_PATHINFO_DEPR
+    'VAR_TEMPLATE'          =>  't',    // 默认模板切换变量
+    'VAR_AUTO_STRING'		=>	false,	// 输入变量是否自动强制转换为字符串 如果开启则数组变量需要手动传入变量修饰符获取变量
+
+    'HTTP_CACHE_CONTROL'    =>  'private',  // 网页缓存控制
+    'CHECK_APP_DIR'         =>  true,       // 是否检查应用目录是否创建
+    'FILE_UPLOAD_TYPE'      =>  'Local',    // 文件上传方式
+    'DATA_CRYPT_TYPE'       =>  'Think',    // 数据加密方式
+
+);

+ 27 - 0
ThinkPHP/Conf/debug.php

@@ -0,0 +1,27 @@
+<?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>
+// +----------------------------------------------------------------------
+
+/**
+ * ThinkPHP 默认的调试模式配置文件
+ */
+defined('THINK_PATH') or exit();
+// 调试模式下面默认设置 可以在应用配置目录下重新定义 debug.php 覆盖
+return  array(
+    'LOG_RECORD'            =>  true,  // 进行日志记录
+    'LOG_EXCEPTION_RECORD'  =>  true,    // 是否记录异常信息日志
+    'LOG_LEVEL'             =>  'EMERG,ALERT,CRIT,ERR,WARN,NOTIC,INFO,DEBUG,SQL',  // 允许记录的日志级别
+    'DB_FIELDS_CACHE'       =>  false, // 字段缓存信息
+    'DB_DEBUG'				=>  true, // 开启调试模式 记录SQL日志
+    'TMPL_CACHE_ON'         =>  false,        // 是否开启模板编译缓存,设为false则每次都会重新编译
+    'TMPL_STRIP_SPACE'      =>  false,       // 是否去除模板文件里面的html空格与换行
+    'SHOW_ERROR_MSG'        =>  true,    // 显示错误信息
+    'URL_CASE_INSENSITIVE'  =>  false,  // URL区分大小写
+);

+ 32 - 0
ThinkPHP/LICENSE.txt

@@ -0,0 +1,32 @@
+
+ThinkPHP遵循Apache2开源协议发布,并提供免费使用。
+版权所有Copyright © 2006-2014 by ThinkPHP (http://thinkphp.cn)
+All rights reserved。
+ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。
+
+Apache Licence是著名的非盈利开源组织Apache采用的协议。
+该协议和BSD类似,鼓励代码共享和尊重原作者的著作权,
+允许代码修改,再作为开源或商业软件发布。需要满足
+的条件: 
+1. 需要给代码的用户一份Apache Licence ;
+2. 如果你修改了代码,需要在被修改的文件中说明;
+3. 在延伸的代码中(修改和有源代码衍生的代码中)需要
+带有原来代码中的协议,商标,专利声明和其他原来作者规
+定需要包含的说明;
+4. 如果再发布的产品中包含一个Notice文件,则在Notice文
+件中需要带有本协议内容。你可以在Notice中增加自己的
+许可,但不可以表现为对Apache Licence构成更改。 
+具体的协议参考:http://www.apache.org/licenses/LICENSE-2.0
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.

+ 51 - 0
ThinkPHP/Lang/en-us.php

@@ -0,0 +1,51 @@
+<?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>
+// +----------------------------------------------------------------------
+
+/**
+ * ThinkPHP English language package
+ */
+return array(
+    /* core language package */ 
+    '_MODULE_NOT_EXIST_'     => "Module can't be loaded",
+    '_CONTROLLER_NOT_EXIST_' =>	"Controller can't be loaded",
+    '_ERROR_ACTION_'         => 'Illegal Action',
+    '_LANGUAGE_NOT_LOAD_'    => "Can't load language package",
+    '_TEMPLATE_NOT_EXIST_'   => "Template doesn't exist",
+    '_MODULE_'               => 'Module',
+    '_ACTION_'               => 'Action',
+    '_MODEL_NOT_EXIST_'      => "Model can't be loaded",
+    '_VALID_ACCESS_'         => 'No access',
+    '_XML_TAG_ERROR_'        => 'XML tag syntax errors',
+    '_DATA_TYPE_INVALID_'    => 'Illegal data objects!',
+    '_OPERATION_WRONG_'      => 'Operation error occurs',
+    '_NOT_LOAD_DB_'          => 'Unable to load the database',
+    '_NO_DB_DRIVER_'         => 'Unable to load database driver',
+    '_NOT_SUPPORT_DB_'       => 'The system is temporarily not support database',
+    '_NO_DB_CONFIG_'         => 'Not define the database configuration',
+    '_NOT_SUPPORT_'          => 'The system does not support',
+    '_CACHE_TYPE_INVALID_'   => 'Unable to load the cache type',
+    '_FILE_NOT_WRITABLE_'   => 'Directory (file) is not writable',
+    '_METHOD_NOT_EXIST_'     => 'The method you requested  does not exist!',
+    '_CLASS_NOT_EXIST_'      => 'Instantiating a class does not exist!',
+    '_CLASS_CONFLICT_'       => 'Class name conflicts',
+    '_TEMPLATE_ERROR_'       => 'Template Engine errors',
+    '_CACHE_WRITE_ERROR_'    => 'Cache file write failed!',
+    '_TAGLIB_NOT_EXIST_'     => 'Tag library is not defined',
+    '_OPERATION_FAIL_'       => 'Operation failed!',
+    '_OPERATION_SUCCESS_'    => 'Operation succeed!',
+    '_SELECT_NOT_EXIST_'     => 'Record does not exist!',
+    '_EXPRESS_ERROR_'        => 'Expression errors',
+    '_TOKEN_ERROR_'          => "Form's token errors",
+    '_RECORD_HAS_UPDATE_'    => 'Record has been updated',
+    '_NOT_ALLOW_PHP_'        => 'PHP codes are not allowed in the template',
+    '_PARAM_ERROR_'          => 'Parameter error or undefined',
+    '_ERROR_QUERY_EXPRESS_'  => 'Query express error',       
+);

+ 51 - 0
ThinkPHP/Lang/pt-br.php

@@ -0,0 +1,51 @@
+<?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: Daiane Azevedo <daianeaze16@gmail.com>
+// +----------------------------------------------------------------------
+
+/**
+ * ThinkPHP Portuguese language package
+ */
+return array(
+    /* core language package */ 
+    '_MODULE_NOT_EXIST_'     => "Módulo não pode ser carregado",
+    '_CONTROLLER_NOT_EXIST_' => "Controller não pode ser carregado",
+    '_ERROR_ACTION_'         => 'Ação ilegal',
+    '_LANGUAGE_NOT_LOAD_'    => "Não é possível carregar pacote da linguagem",
+    '_TEMPLATE_NOT_EXIST_'   => "Template não existe",
+    '_MODULE_'               => 'Módulo',
+    '_ACTION_'               => 'Ação',
+    '_MODEL_NOT_EXIST_'      => "Modelo não pode ser carregado",
+    '_VALID_ACCESS_'         => 'Sem acesso',
+    '_XML_TAG_ERROR_'        => 'Erro de sintaxe - XML tag',
+    '_DATA_TYPE_INVALID_'    => 'Tipos de dados ilegais!',
+    '_OPERATION_WRONG_'      => 'Erro na operação',
+    '_NOT_LOAD_DB_'          => 'Impossível carregar banco de dados',
+    '_NO_DB_DRIVER_'         => 'Impossível carregar driver do bando de dados',
+    '_NOT_SUPPORT_DB_'       => 'Temporariamente sem suporte ao banco',
+    '_NO_DB_CONFIG_'         => 'Não define a configuração do banco',
+    '_NOT_SUPPORT_'          => 'O sistema não suporta',
+    '_CACHE_TYPE_INVALID_'   => 'Impossível carregar o tipo de cache',
+    '_FILE_NOT_WRITABLE_'   => 'Diretório (arquivo) não pode ser escrito',
+    '_METHOD_NOT_EXIST_'     => 'O método solicitado não existe!',
+    '_CLASS_NOT_EXIST_'      => 'Não existe instância da classe',
+    '_CLASS_CONFLICT_'       => 'Conflitos com nome da classe',
+    '_TEMPLATE_ERROR_'       => 'Erros na contrução do template',
+    '_CACHE_WRITE_ERROR_'    => 'Escrita do arquivo de cache falhou!',
+    '_TAGLIB_NOT_EXIST_'     => 'Biblioteca da tag não foi definida',
+    '_OPERATION_FAIL_'       => 'Operação falhou!',
+    '_OPERATION_SUCCESS_'    => 'Operação bem sucessida!',
+    '_SELECT_NOT_EXIST_'     => 'Gravação não existe!',
+    '_EXPRESS_ERROR_'        => 'Erros de expressão',
+    '_TOKEN_ERROR_'          => 'Erro no token do formulário',
+    '_RECORD_HAS_UPDATE_'    => 'Gravação não foi atualizada',
+    '_NOT_ALLOW_PHP_'        => 'Código PHP não é permitido no template',
+    '_PARAM_ERROR_'          => 'Parâmetro errado ou indefinido',
+    '_ERROR_QUERY_EXPRESS_'  => 'Erros na expressão da query',       
+);

+ 51 - 0
ThinkPHP/Lang/zh-cn.php

@@ -0,0 +1,51 @@
+<?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>
+// +----------------------------------------------------------------------
+
+/**
+ * ThinkPHP 简体中文语言包
+ */
+return array(
+    /* 核心语言变量 */  
+    '_MODULE_NOT_EXIST_'     => '无法加载模块',
+    '_CONTROLLER_NOT_EXIST_' =>	'无法加载控制器',
+    '_ERROR_ACTION_'         => '非法操作',
+    '_LANGUAGE_NOT_LOAD_'    => '无法加载语言包',
+    '_TEMPLATE_NOT_EXIST_'   => '模板不存在',
+    '_MODULE_'               => '模块',
+    '_ACTION_'               => '操作',
+    '_MODEL_NOT_EXIST_'      => '模型不存在或者没有定义',
+    '_VALID_ACCESS_'         => '没有权限',
+    '_XML_TAG_ERROR_'        => 'XML标签语法错误',
+    '_DATA_TYPE_INVALID_'    => '非法数据对象!',
+    '_OPERATION_WRONG_'      => '操作出现错误',
+    '_NOT_LOAD_DB_'          => '无法加载数据库',
+    '_NO_DB_DRIVER_'         => '无法加载数据库驱动',
+    '_NOT_SUPPORT_DB_'       => '系统暂时不支持数据库',
+    '_NO_DB_CONFIG_'         => '没有定义数据库配置',
+    '_NOT_SUPPORT_'          => '系统不支持',
+    '_CACHE_TYPE_INVALID_'   => '无法加载缓存类型',
+    '_FILE_NOT_WRITABLE_'   => '目录(文件)不可写',
+    '_METHOD_NOT_EXIST_'     => '方法不存在!',
+    '_CLASS_NOT_EXIST_'      => '实例化一个不存在的类!',
+    '_CLASS_CONFLICT_'       => '类名冲突',
+    '_TEMPLATE_ERROR_'       => '模板引擎错误',
+    '_CACHE_WRITE_ERROR_'    => '缓存文件写入失败!',
+    '_TAGLIB_NOT_EXIST_'     => '标签库未定义',
+    '_OPERATION_FAIL_'       => '操作失败!',
+    '_OPERATION_SUCCESS_'    => '操作成功!',
+    '_SELECT_NOT_EXIST_'     => '记录不存在!',
+    '_EXPRESS_ERROR_'        => '表达式错误',
+    '_TOKEN_ERROR_'          => '表单令牌错误',
+    '_RECORD_HAS_UPDATE_'    => '记录已经更新',
+    '_NOT_ALLOW_PHP_'        => '模板禁用PHP代码',
+    '_PARAM_ERROR_'          => '参数错误或者未定义',
+    '_ERROR_QUERY_EXPRESS_'  => '错误的查询条件',
+);

+ 51 - 0
ThinkPHP/Lang/zh-tw.php

@@ -0,0 +1,51 @@
+<?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>
+// +----------------------------------------------------------------------
+
+/**
+ * ThinkPHP 繁体中文語言包
+ */
+return array(
+    /* 核心語言變數 */  
+    '_MODULE_NOT_EXIST_'     => '無法載入模組',
+    '_CONTROLLER_NOT_EXIST_' => '無法載入控制器',
+    '_ERROR_ACTION_'         => '非法操作',
+    '_LANGUAGE_NOT_LOAD_'    => '無法載入語言包',
+    '_TEMPLATE_NOT_EXIST_'   => '模板不存在',
+    '_MODULE_'               => '模組',
+    '_ACTION_'               => '操作',
+    '_MODEL_NOT_EXIST_'      => '模型不存在或者沒有定義',
+    '_VALID_ACCESS_'         => '沒有權限',
+    '_XML_TAG_ERROR_'        => 'XML標籤語法錯誤',
+    '_DATA_TYPE_INVALID_'    => '非法資料物件!',
+    '_OPERATION_WRONG_'      => '操作出現錯誤',
+    '_NOT_LOAD_DB_'          => '無法載入資料庫',
+    '_NO_DB_DRIVER_'         => '無法載入資料庫驅動',
+    '_NOT_SUPPORT_DB_'       => '系統暫時不支援資料庫',
+    '_NO_DB_CONFIG_'         => '沒有定義資料庫設定',
+    '_NOT_SUPPORT_'          => '系統不支援',
+    '_CACHE_TYPE_INVALID_'   => '無法載入快取類型',
+    '_FILE_NOT_WRITABLE_'   => '目錄(檔案)不可寫',
+    '_METHOD_NOT_EXIST_'     => '方法不存在!',
+    '_CLASS_NOT_EXIST_'      => '實例化一個不存在的類別!',
+    '_CLASS_CONFLICT_'       => '類別名稱衝突',
+    '_TEMPLATE_ERROR_'       => '模板引擎錯誤',
+    '_CACHE_WRITE_ERROR_'    => '快取檔案寫入失敗!',
+    '_TAGLIB_NOT_EXIST_'     => '標籤庫未定義',
+    '_OPERATION_FAIL_'       => '操作失敗!',
+    '_OPERATION_SUCCESS_'    => '操作成功!',
+    '_SELECT_NOT_EXIST_'     => '記錄不存在!',
+    '_EXPRESS_ERROR_'        => '運算式錯誤',
+    '_TOKEN_ERROR_'          => '表單權限錯誤',
+    '_RECORD_HAS_UPDATE_'    => '記錄已經更新',
+    '_NOT_ALLOW_PHP_'        => '模板禁用PHP代碼',
+    '_PARAM_ERROR_'          => '參數錯誤或者未定義',
+    '_ERROR_QUERY_EXPRESS_'  => '錯誤的查詢條件',    
+);

+ 24 - 0
ThinkPHP/Library/Behavior/AgentCheckBehavior.class.php

@@ -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 - 0
ThinkPHP/Library/Behavior/BorisBehavior.class.php

@@ -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 - 0
ThinkPHP/Library/Behavior/BrowserCheckBehavior.class.php

@@ -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 - 0
ThinkPHP/Library/Behavior/BuildLiteBehavior.class.php

@@ -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 - 0
ThinkPHP/Library/Behavior/CheckActionRouteBehavior.class.php

@@ -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 - 0
ThinkPHP/Library/Behavior/CheckLangBehavior.class.php

@@ -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 - 0
ThinkPHP/Library/Behavior/ChromeShowPageTraceBehavior.class.php

@@ -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 - 0
ThinkPHP/Library/Behavior/ContentReplaceBehavior.class.php

@@ -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__'      =>  __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 - 0
ThinkPHP/Library/Behavior/CronRunBehavior.class.php

@@ -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 ;
+    }
+}

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 2079 - 0
ThinkPHP/Library/Behavior/FireShowPageTraceBehavior.class.php


+ 95 - 0
ThinkPHP/Library/Behavior/ParseTemplateBehavior.class.php

@@ -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 - 0
ThinkPHP/Library/Behavior/ReadHtmlCacheBehavior.class.php

@@ -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 - 0
ThinkPHP/Library/Behavior/RobotCheckBehavior.class.php

@@ -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 - 0
ThinkPHP/Library/Behavior/ShowPageTraceBehavior.class.php

@@ -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 - 0
ThinkPHP/Library/Behavior/ShowRuntimeBehavior.class.php

@@ -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 - 0
ThinkPHP/Library/Behavior/TokenBuildBehavior.class.php

@@ -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 - 0
ThinkPHP/Library/Behavior/UpgradeNoticeBehavior.class.php

@@ -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 - 0
ThinkPHP/Library/Behavior/WriteHtmlCacheBehavior.class.php

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

+ 271 - 0
ThinkPHP/Library/Org/Net/Http.class.php

@@ -0,0 +1,271 @@
+<?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 Org\Net;
+/**
+ * Http 工具类
+ * 提供一系列的Http方法
+ * @author    liu21st <liu21st@gmail.com>
+ */
+class Http {
+
+    /**
+     * 采集远程文件
+     * @access public
+     * @param string $remote 远程文件名
+     * @param string $local 本地保存文件名
+     * @return mixed
+     */
+    static public function curlDownload($remote,$local) {
+        $cp = curl_init($remote);
+        $fp = fopen($local,"w");
+        curl_setopt($cp, CURLOPT_FILE, $fp);
+        curl_setopt($cp, CURLOPT_HEADER, 0);
+        curl_exec($cp);
+        curl_close($cp);
+        fclose($fp);
+    }
+
+   /**
+    * 使用 fsockopen 通过 HTTP 协议直接访问(采集)远程文件
+    * 如果主机或服务器没有开启 CURL 扩展可考虑使用
+    * fsockopen 比 CURL 稍慢,但性能稳定
+    * @static
+    * @access public
+    * @param string $url 远程URL
+    * @param array $conf 其他配置信息
+    *        int   limit 分段读取字符个数
+    *        string post  post的内容,字符串或数组,key=value&形式
+    *        string cookie 携带cookie访问,该参数是cookie内容
+    *        string ip    如果该参数传入,$url将不被使用,ip访问优先
+    *        int    timeout 采集超时时间
+    *        bool   block 是否阻塞访问,默认为true
+    * @return mixed
+    */
+    static public function fsockopenDownload($url, $conf = array()) {
+        $return = '';
+        if(!is_array($conf)) return $return;
+
+        $matches = parse_url($url);
+        !isset($matches['host']) 	&& $matches['host'] 	= '';
+        !isset($matches['path']) 	&& $matches['path'] 	= '';
+        !isset($matches['query']) 	&& $matches['query'] 	= '';
+        !isset($matches['port']) 	&& $matches['port'] 	= '';
+        $host = $matches['host'];
+        $path = $matches['path'] ? $matches['path'].($matches['query'] ? '?'.$matches['query'] : '') : '/';
+        $port = !empty($matches['port']) ? $matches['port'] : 80;
+
+        $conf_arr = array(
+            'limit'		=>	0,
+            'post'		=>	'',
+            'cookie'	=>	'',
+            'ip'		=>	'',
+            'timeout'	=>	15,
+            'block'		=>	TRUE,
+            );
+
+        foreach (array_merge($conf_arr, $conf) as $k=>$v) ${$k} = $v;
+
+        if($post) {
+            if(is_array($post))
+            {
+                $post = http_build_query($post);
+            }
+            $out  = "POST $path HTTP/1.0\r\n";
+            $out .= "Accept: */*\r\n";
+            //$out .= "Referer: $boardurl\r\n";
+            $out .= "Accept-Language: zh-cn\r\n";
+            $out .= "Content-Type: application/x-www-form-urlencoded\r\n";
+            $out .= "User-Agent: $_SERVER[HTTP_USER_AGENT]\r\n";
+            $out .= "Host: $host\r\n";
+            $out .= 'Content-Length: '.strlen($post)."\r\n";
+            $out .= "Connection: Close\r\n";
+            $out .= "Cache-Control: no-cache\r\n";
+            $out .= "Cookie: $cookie\r\n\r\n";
+            $out .= $post;
+        } else {
+            $out  = "GET $path HTTP/1.0\r\n";
+            $out .= "Accept: */*\r\n";
+            //$out .= "Referer: $boardurl\r\n";
+            $out .= "Accept-Language: zh-cn\r\n";
+            $out .= "User-Agent: $_SERVER[HTTP_USER_AGENT]\r\n";
+            $out .= "Host: $host\r\n";
+            $out .= "Connection: Close\r\n";
+            $out .= "Cookie: $cookie\r\n\r\n";
+        }
+        $fp = @fsockopen(($ip ? $ip : $host), $port, $errno, $errstr, $timeout);
+        if(!$fp) {
+            return '';
+        } else {
+            stream_set_blocking($fp, $block);
+            stream_set_timeout($fp, $timeout);
+            @fwrite($fp, $out);
+            $status = stream_get_meta_data($fp);
+            if(!$status['timed_out']) {
+                while (!feof($fp)) {
+                    if(($header = @fgets($fp)) && ($header == "\r\n" ||  $header == "\n")) {
+                        break;
+                    }
+                }
+
+                $stop = false;
+                while(!feof($fp) && !$stop) {
+                    $data = fread($fp, ($limit == 0 || $limit > 8192 ? 8192 : $limit));
+                    $return .= $data;
+                    if($limit) {
+                        $limit -= strlen($data);
+                        $stop = $limit <= 0;
+                    }
+                }
+            }
+            @fclose($fp);
+            return $return;
+        }
+    }
+
+    /**
+     * 下载文件
+     * 可以指定下载显示的文件名,并自动发送相应的Header信息
+     * 如果指定了content参数,则下载该参数的内容
+     * @static
+     * @access public
+     * @param string $filename 下载文件名
+     * @param string $showname 下载显示的文件名
+     * @param string $content  下载的内容
+     * @param integer $expire  下载内容浏览器缓存时间
+     * @return void
+     */
+    static public function download ($filename, $showname='',$content='',$expire=180) {
+        if(is_file($filename)) {
+            $length = filesize($filename);
+        }elseif(is_file(UPLOAD_PATH.$filename)) {
+            $filename = UPLOAD_PATH.$filename;
+            $length = filesize($filename);
+        }elseif($content != '') {
+            $length = strlen($content);
+        }else {
+            E($filename.L('下载文件不存在!'));
+        }
+        if(empty($showname)) {
+            $showname = $filename;
+        }
+        $showname = basename($showname);
+		if(!empty($filename)) {
+			$finfo 	= 	new \finfo(FILEINFO_MIME);
+			$type 	= 	$finfo->file($filename);			
+		}else{
+			$type	=	"application/octet-stream";
+		}
+        //发送Http Header信息 开始下载
+        header("Pragma: public");
+        header("Cache-control: max-age=".$expire);
+        //header('Cache-Control: no-store, no-cache, must-revalidate');
+        header("Expires: " . gmdate("D, d M Y H:i:s",time()+$expire) . "GMT");
+        header("Last-Modified: " . gmdate("D, d M Y H:i:s",time()) . "GMT");
+        header("Content-Disposition: attachment; filename=".$showname);
+        header("Content-Length: ".$length);
+        header("Content-type: ".$type);
+        header('Content-Encoding: none');
+        header("Content-Transfer-Encoding: binary" );
+        if($content == '' ) {
+            readfile($filename);
+        }else {
+        	echo($content);
+        }
+        exit();
+    }
+
+    /**
+     * 显示HTTP Header 信息
+     * @return string
+     */
+    static function getHeaderInfo($header='',$echo=true) {
+        ob_start();
+        $headers   	= getallheaders();
+        if(!empty($header)) {
+            $info 	= $headers[$header];
+            echo($header.':'.$info."\n"); ;
+        }else {
+            foreach($headers as $key=>$val) {
+                echo("$key:$val\n");
+            }
+        }
+        $output 	= ob_get_clean();
+        if ($echo) {
+            echo (nl2br($output));
+        }else {
+            return $output;
+        }
+
+    }
+
+    /**
+     * HTTP Protocol defined status codes
+     * @param int $num
+     */
+	static function sendHttpStatus($code) {
+		static $_status = array(
+			// Informational 1xx
+			100 => 'Continue',
+			101 => 'Switching Protocols',
+
+			// Success 2xx
+			200 => 'OK',
+			201 => 'Created',
+			202 => 'Accepted',
+			203 => 'Non-Authoritative Information',
+			204 => 'No Content',
+			205 => 'Reset Content',
+			206 => 'Partial Content',
+
+			// Redirection 3xx
+			300 => 'Multiple Choices',
+			301 => 'Moved Permanently',
+			302 => 'Found',  // 1.1
+			303 => 'See Other',
+			304 => 'Not Modified',
+			305 => 'Use Proxy',
+			// 306 is deprecated but reserved
+			307 => 'Temporary Redirect',
+
+			// Client Error 4xx
+			400 => 'Bad Request',
+			401 => 'Unauthorized',
+			402 => 'Payment Required',
+			403 => 'Forbidden',
+			404 => 'Not Found',
+			405 => 'Method Not Allowed',
+			406 => 'Not Acceptable',
+			407 => 'Proxy Authentication Required',
+			408 => 'Request Timeout',
+			409 => 'Conflict',
+			410 => 'Gone',
+			411 => 'Length Required',
+			412 => 'Precondition Failed',
+			413 => 'Request Entity Too Large',
+			414 => 'Request-URI Too Long',
+			415 => 'Unsupported Media Type',
+			416 => 'Requested Range Not Satisfiable',
+			417 => 'Expectation Failed',
+
+			// Server Error 5xx
+			500 => 'Internal Server Error',
+			501 => 'Not Implemented',
+			502 => 'Bad Gateway',
+			503 => 'Service Unavailable',
+			504 => 'Gateway Timeout',
+			505 => 'HTTP Version Not Supported',
+			509 => 'Bandwidth Limit Exceeded'
+		);
+		if(isset($_status[$code])) {
+			header('HTTP/1.1 '.$code.' '.$_status[$code]);
+		}
+	}
+}//类定义结束

+ 233 - 0
ThinkPHP/Library/Org/Net/IpLocation.class.php

@@ -0,0 +1,233 @@
+<?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 Org\Net;
+/**
+ *  IP 地理位置查询类 修改自 CoolCode.CN
+ *  由于使用UTF8编码 如果使用纯真IP地址库的话 需要对返回结果进行编码转换
+ * @author    liu21st <liu21st@gmail.com>
+ */
+class IpLocation {
+    /**
+     * QQWry.Dat文件指针
+     *
+     * @var resource
+     */
+    private $fp;
+
+    /**
+     * 第一条IP记录的偏移地址
+     *
+     * @var int
+     */
+    private $firstip;
+
+    /**
+     * 最后一条IP记录的偏移地址
+     *
+     * @var int
+     */
+    private $lastip;
+
+    /**
+     * IP记录的总条数(不包含版本信息记录)
+     *
+     * @var int
+     */
+    private $totalip;
+
+    /**
+     * 构造函数,打开 QQWry.Dat 文件并初始化类中的信息
+     *
+     * @param string $filename
+     * @return IpLocation
+     */
+    public function __construct($filename = "UTFWry.dat") {
+        $this->fp = 0;
+        if (($this->fp      = fopen(dirname(__FILE__).'/'.$filename, 'rb')) !== false) {
+            $this->firstip  = $this->getlong();
+            $this->lastip   = $this->getlong();
+            $this->totalip  = ($this->lastip - $this->firstip) / 7;
+        }
+    }
+
+    /**
+     * 返回读取的长整型数
+     *
+     * @access private
+     * @return int
+     */
+    private function getlong() {
+        //将读取的little-endian编码的4个字节转化为长整型数
+        $result = unpack('Vlong', fread($this->fp, 4));
+        return $result['long'];
+    }
+
+    /**
+     * 返回读取的3个字节的长整型数
+     *
+     * @access private
+     * @return int
+     */
+    private function getlong3() {
+        //将读取的little-endian编码的3个字节转化为长整型数
+        $result = unpack('Vlong', fread($this->fp, 3).chr(0));
+        return $result['long'];
+    }
+
+    /**
+     * 返回压缩后可进行比较的IP地址
+     *
+     * @access private
+     * @param string $ip
+     * @return string
+     */
+    private function packip($ip) {
+        // 将IP地址转化为长整型数,如果在PHP5中,IP地址错误,则返回False,
+        // 这时intval将Flase转化为整数-1,之后压缩成big-endian编码的字符串
+        return pack('N', intval(ip2long($ip)));
+    }
+
+    /**
+     * 返回读取的字符串
+     *
+     * @access private
+     * @param string $data
+     * @return string
+     */
+    private function getstring($data = "") {
+        $char = fread($this->fp, 1);
+        while (ord($char) > 0) {        // 字符串按照C格式保存,以\0结束
+            $data  .= $char;             // 将读取的字符连接到给定字符串之后
+            $char   = fread($this->fp, 1);
+        }
+        return $data;
+    }
+
+    /**
+     * 返回地区信息
+     *
+     * @access private
+     * @return string
+     */
+    private function getarea() {
+        $byte = fread($this->fp, 1);    // 标志字节
+        switch (ord($byte)) {
+            case 0:                     // 没有区域信息
+                $area = "";
+                break;
+            case 1:
+            case 2:                     // 标志字节为1或2,表示区域信息被重定向
+                fseek($this->fp, $this->getlong3());
+                $area = $this->getstring();
+                break;
+            default:                    // 否则,表示区域信息没有被重定向
+                $area = $this->getstring($byte);
+                break;
+        }
+        return $area;
+    }
+
+    /**
+     * 根据所给 IP 地址或域名返回所在地区信息
+     *
+     * @access public
+     * @param string $ip
+     * @return array
+     */
+    public function getlocation($ip='') {
+        if (!$this->fp) return null;            // 如果数据文件没有被正确打开,则直接返回空
+		if(empty($ip)) $ip = get_client_ip();
+        $location['ip'] = gethostbyname($ip);   // 将输入的域名转化为IP地址
+        $ip = $this->packip($location['ip']);   // 将输入的IP地址转化为可比较的IP地址
+                                                // 不合法的IP地址会被转化为255.255.255.255
+        // 对分搜索
+        $l = 0;                         // 搜索的下边界
+        $u = $this->totalip;            // 搜索的上边界
+        $findip = $this->lastip;        // 如果没有找到就返回最后一条IP记录(QQWry.Dat的版本信息)
+        while ($l <= $u) {              // 当上边界小于下边界时,查找失败
+            $i = floor(($l + $u) / 2);  // 计算近似中间记录
+            fseek($this->fp, $this->firstip + $i * 7);
+            $beginip = strrev(fread($this->fp, 4));     // 获取中间记录的开始IP地址
+            // strrev函数在这里的作用是将little-endian的压缩IP地址转化为big-endian的格式
+            // 以便用于比较,后面相同。
+            if ($ip < $beginip) {       // 用户的IP小于中间记录的开始IP地址时
+                $u = $i - 1;            // 将搜索的上边界修改为中间记录减一
+            }
+            else {
+                fseek($this->fp, $this->getlong3());
+                $endip = strrev(fread($this->fp, 4));   // 获取中间记录的结束IP地址
+                if ($ip > $endip) {     // 用户的IP大于中间记录的结束IP地址时
+                    $l = $i + 1;        // 将搜索的下边界修改为中间记录加一
+                }
+                else {                  // 用户的IP在中间记录的IP范围内时
+                    $findip = $this->firstip + $i * 7;
+                    break;              // 则表示找到结果,退出循环
+                }
+            }
+        }
+
+        //获取查找到的IP地理位置信息
+        fseek($this->fp, $findip);
+        $location['beginip'] = long2ip($this->getlong());   // 用户IP所在范围的开始地址
+        $offset = $this->getlong3();
+        fseek($this->fp, $offset);
+        $location['endip'] = long2ip($this->getlong());     // 用户IP所在范围的结束地址
+        $byte = fread($this->fp, 1);    // 标志字节
+        switch (ord($byte)) {
+            case 1:                     // 标志字节为1,表示国家和区域信息都被同时重定向
+                $countryOffset = $this->getlong3();         // 重定向地址
+                fseek($this->fp, $countryOffset);
+                $byte = fread($this->fp, 1);    // 标志字节
+                switch (ord($byte)) {
+                    case 2:             // 标志字节为2,表示国家信息又被重定向
+                        fseek($this->fp, $this->getlong3());
+                        $location['country']    = $this->getstring();
+                        fseek($this->fp, $countryOffset + 4);
+                        $location['area']       = $this->getarea();
+                        break;
+                    default:            // 否则,表示国家信息没有被重定向
+                        $location['country']    = $this->getstring($byte);
+                        $location['area']       = $this->getarea();
+                        break;
+                }
+                break;
+            case 2:                     // 标志字节为2,表示国家信息被重定向
+                fseek($this->fp, $this->getlong3());
+                $location['country']    = $this->getstring();
+                fseek($this->fp, $offset + 8);
+                $location['area']       = $this->getarea();
+                break;
+            default:                    // 否则,表示国家信息没有被重定向
+                $location['country']    = $this->getstring($byte);
+                $location['area']       = $this->getarea();
+                break;
+        }
+        if (trim($location['country']) == 'CZ88.NET') {  // CZ88.NET表示没有有效信息
+            $location['country'] = '未知';
+        }
+        if (trim($location['area']) == 'CZ88.NET') {
+            $location['area'] = '';
+        }
+        return $location;
+    }
+
+    /**
+     * 析构函数,用于在页面执行结束后自动关闭打开的文件。
+     *
+     */
+    public function __destruct() {
+        if ($this->fp) {
+            fclose($this->fp);
+        }
+        $this->fp = 0;
+    }
+
+}

+ 240 - 0
ThinkPHP/Library/Org/Util/ArrayList.class.php

@@ -0,0 +1,240 @@
+<?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 Org\Util;
+/**
+ * ArrayList实现类
+ * @category   Think
+ * @package  Think
+ * @subpackage  Util
+ * @author    liu21st <liu21st@gmail.com>
+ */
+class ArrayList implements \IteratorAggregate {
+
+    /**
+     * 集合元素
+     * @var array
+     * @access protected
+     */
+    protected $_elements = array();
+
+    /**
+     * 架构函数
+     * @access public
+     * @param string $elements  初始化数组元素
+     */
+    public function __construct($elements = array()) {
+        if (!empty($elements)) {
+            $this->_elements = $elements;
+        }
+    }
+
+    /**
+     * 若要获得迭代因子,通过getIterator方法实现
+     * @access public
+     * @return ArrayObject
+     */
+    public function getIterator() {
+        return new ArrayObject($this->_elements);
+    }
+
+    /**
+     * 增加元素
+     * @access public
+     * @param mixed $element  要添加的元素
+     * @return boolean
+     */
+    public function add($element) {
+        return (array_push($this->_elements, $element)) ? true : false;
+    }
+
+    //
+    public function unshift($element) {
+        return (array_unshift($this->_elements,$element))?true : false;
+    }
+
+    //
+    public function pop() {
+        return array_pop($this->_elements);
+    }
+
+    /**
+     * 增加元素列表
+     * @access public
+     * @param ArrayList $list  元素列表
+     * @return boolean
+     */
+    public function addAll($list) {
+        $before = $this->size();
+        foreach( $list as $element) {
+            $this->add($element);
+        }
+        $after = $this->size();
+        return ($before < $after);
+    }
+
+    /**
+     * 清除所有元素
+     * @access public
+     */
+    public function clear() {
+        $this->_elements = array();
+    }
+
+    /**
+     * 是否包含某个元素
+     * @access public
+     * @param mixed $element  查找元素
+     * @return string
+     */
+    public function contains($element) {
+        return (array_search($element, $this->_elements) !== false );
+    }
+
+    /**
+     * 根据索引取得元素
+     * @access public
+     * @param integer $index 索引
+     * @return mixed
+     */
+    public function get($index) {
+        return $this->_elements[$index];
+    }
+
+    /**
+     * 查找匹配元素,并返回第一个元素所在位置
+     * 注意 可能存在0的索引位置 因此要用===False来判断查找失败
+     * @access public
+     * @param mixed $element  查找元素
+     * @return integer
+     */
+    public function indexOf($element) {
+        return array_search($element, $this->_elements);
+    }
+
+    /**
+     * 判断元素是否为空
+     * @access public
+     * @return boolean
+     */
+    public function isEmpty() {
+        return empty($this->_elements);
+    }
+
+    /**
+     * 最后一个匹配的元素位置
+     * @access public
+     * @param mixed $element  查找元素
+     * @return integer
+     */
+    public function lastIndexOf($element) {
+        for ($i = (count($this->_elements) - 1); $i > 0; $i--) {
+            if ($element == $this->get($i)) { return $i; }
+        }
+    }
+
+    public function toJson() {
+        return json_encode($this->_elements);
+    }
+
+    /**
+     * 根据索引移除元素
+     * 返回被移除的元素
+     * @access public
+     * @param integer $index 索引
+     * @return mixed
+     */
+    public function remove($index) {
+        $element = $this->get($index);
+        if (!is_null($element)) { array_splice($this->_elements, $index, 1); }
+        return $element;
+    }
+
+    /**
+     * 移出一定范围的数组列表
+     * @access public
+     * @param integer $offset  开始移除位置
+     * @param integer $length  移除长度
+     */
+    public function removeRange($offset , $length) {
+        array_splice($this->_elements, $offset , $length);
+    }
+
+    /**
+     * 移出重复的值
+     * @access public
+     */
+    public function unique() {
+        $this->_elements = array_unique($this->_elements);
+    }
+
+    /**
+     * 取出一定范围的数组列表
+     * @access public
+     * @param integer $offset  开始位置
+     * @param integer $length  长度
+     */
+    public function range($offset,$length=null) {
+        return array_slice($this->_elements,$offset,$length);
+    }
+
+    /**
+     * 设置列表元素
+     * 返回修改之前的值
+     * @access public
+     * @param integer $index 索引
+     * @param mixed $element  元素
+     * @return mixed
+     */
+    public function set($index, $element) {
+        $previous = $this->get($index);
+        $this->_elements[$index] = $element;
+        return $previous;
+    }
+
+    /**
+     * 获取列表长度
+     * @access public
+     * @return integer
+     */
+    public function size() {
+        return count($this->_elements);
+    }
+
+    /**
+     * 转换成数组
+     * @access public
+     * @return array
+     */
+    public function toArray() {
+        return $this->_elements;
+    }
+
+    // 列表排序
+    public function ksort() {
+        ksort($this->_elements);
+    }
+
+    // 列表排序
+    public function asort() {
+        asort($this->_elements);
+    }
+
+    // 逆向排序
+    public function rsort() {
+        rsort($this->_elements);
+    }
+
+    // 自然排序
+    public function natsort() {
+        natsort($this->_elements);
+    }
+
+}

+ 200 - 0
ThinkPHP/Library/Org/Util/CodeSwitch.class.php

@@ -0,0 +1,200 @@
+<?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 Org\Util;
+class CodeSwitch {
+    // 错误信息
+    static private $error = array();
+    // 提示信息
+    static private $info = array();
+    // 记录错误
+    static private function error($msg) {
+        self::$error[]   =  $msg;
+    }
+    // 记录信息
+    static private function info($info) {
+        self::$info[]     = $info;
+    }
+	/**
+     * 编码转换函数,对整个文件进行编码转换
+	 * 支持以下转换
+	 * GB2312、UTF-8 WITH BOM转换为UTF-8
+	 * UTF-8、UTF-8 WITH BOM转换为GB2312
+     * @access public
+     * @param string $filename		文件名
+	 * @param string $out_charset	转换后的文件编码,与iconv使用的参数一致
+     * @return void
+     */
+	static function DetectAndSwitch($filename,$out_charset) {
+		$fpr = fopen($filename,"r");
+		$char1 = fread($fpr,1);
+		$char2 = fread($fpr,1);
+		$char3 = fread($fpr,1);
+
+		$originEncoding = "";
+
+		if($char1==chr(239) && $char2==chr(187) && $char3==chr(191))//UTF-8 WITH BOM
+			$originEncoding = "UTF-8 WITH BOM";
+		elseif($char1==chr(255) && $char2==chr(254))//UNICODE LE
+		{
+			self::error("不支持从UNICODE LE转换到UTF-8或GB编码");
+			fclose($fpr);
+			return;
+		}elseif($char1==chr(254) && $char2==chr(255)){//UNICODE BE
+			self::error("不支持从UNICODE BE转换到UTF-8或GB编码");
+			fclose($fpr);
+			return;
+		}else{//没有文件头,可能是GB或UTF-8
+			if(rewind($fpr)===false){//回到文件开始部分,准备逐字节读取判断编码
+				self::error($filename."文件指针后移失败");
+				fclose($fpr);
+				return;
+			}
+
+			while(!feof($fpr)){
+				$char = fread($fpr,1);
+				//对于英文,GB和UTF-8都是单字节的ASCII码小于128的值
+				if(ord($char)<128)
+					continue;
+
+				//对于汉字GB编码第一个字节是110*****第二个字节是10******(有特例,比如联字)
+				//UTF-8编码第一个字节是1110****第二个字节是10******第三个字节是10******
+				//按位与出来结果要跟上面非星号相同,所以应该先判断UTF-8
+				//因为使用GB的掩码按位与,UTF-8的111得出来的也是110,所以要先判断UTF-8
+				if((ord($char)&224)==224) {
+					//第一个字节判断通过
+					$char = fread($fpr,1);
+					if((ord($char)&128)==128) {
+						//第二个字节判断通过
+						$char = fread($fpr,1);
+						if((ord($char)&128)==128) {
+							$originEncoding = "UTF-8";
+							break;
+						}
+					}
+				}
+				if((ord($char)&192)==192) {
+					//第一个字节判断通过
+					$char = fread($fpr,1);
+					if((ord($char)&128)==128) {
+						//第二个字节判断通过
+						$originEncoding = "GB2312";
+						break;
+					}
+				}
+			}
+		}
+
+		if(strtoupper($out_charset)==$originEncoding) {
+			self::info("文件".$filename."转码检查完成,原始文件编码".$originEncoding);
+			fclose($fpr);
+		}else {
+			//文件需要转码
+			$originContent = "";
+
+			if($originEncoding == "UTF-8 WITH BOM") {
+				//跳过三个字节,把后面的内容复制一遍得到utf-8的内容
+				fseek($fpr,3);
+				$originContent = fread($fpr,filesize($filename)-3);
+				fclose($fpr);
+			}elseif(rewind($fpr)!=false){//不管是UTF-8还是GB2312,回到文件开始部分,读取内容
+				$originContent = fread($fpr,filesize($filename));
+				fclose($fpr);
+			}else{
+				self::error("文件编码不正确或指针后移失败");
+				fclose($fpr);
+				return;
+			}
+
+			//转码并保存文件
+			$content = iconv(str_replace(" WITH BOM","",$originEncoding),strtoupper($out_charset),$originContent);
+			$fpw = fopen($filename,"w");
+			fwrite($fpw,$content);
+			fclose($fpw);
+
+			if($originEncoding!="")
+				self::info("对文件".$filename."转码完成,原始文件编码".$originEncoding.",转换后文件编码".strtoupper($out_charset));
+			elseif($originEncoding=="")
+				self::info("文件".$filename."中没有出现中文,但是可以断定不是带BOM的UTF-8编码,没有进行编码转换,不影响使用");
+		}
+	}
+
+	/**
+     * 目录遍历函数
+     * @access public
+     * @param string $path		要遍历的目录名
+     * @param string $mode		遍历模式,一般取FILES,这样只返回带路径的文件名
+     * @param array $file_types		文件后缀过滤数组
+	 * @param int $maxdepth		遍历深度,-1表示遍历到最底层
+     * @return void
+     */
+	static function searchdir($path,$mode = "FULL",$file_types = array(".html",".php"),$maxdepth = -1,$d = 0) {
+	   if(substr($path,strlen($path)-1) != '/')
+		   $path .= '/';
+	   $dirlist = array();
+	   if($mode != "FILES")
+			$dirlist[] = $path;
+	   if($handle = @opendir($path)) {
+		   while(false !== ($file = readdir($handle)))
+		   {
+			   if($file != '.' && $file != '..')
+			   {
+				   $file = $path.$file ;
+				   if(!is_dir($file))
+				   {
+						if($mode != "DIRS")
+						{
+							$extension = "";
+							$extpos = strrpos($file, '.');
+							if($extpos!==false)
+								$extension = substr($file,$extpos,strlen($file)-$extpos);
+							$extension=strtolower($extension);
+							if(in_array($extension, $file_types))
+								$dirlist[] = $file;
+						}
+				   }
+				   elseif($d >= 0 && ($d < $maxdepth || $maxdepth < 0))
+				   {
+					   $result = self::searchdir($file.'/',$mode,$file_types,$maxdepth,$d + 1) ;
+					   $dirlist = array_merge($dirlist,$result);
+				   }
+			   }
+		   }
+		   closedir ( $handle ) ;
+	   }
+	   if($d == 0)
+		   natcasesort($dirlist);
+
+	   return($dirlist) ;
+	}
+
+	/**
+     * 对整个项目目录中的PHP和HTML文件行进编码转换
+     * @access public
+     * @param string $app		要遍历的项目路径
+     * @param string $mode		遍历模式,一般取FILES,这样只返回带路径的文件名
+     * @param array $file_types		文件后缀过滤数组
+     * @return void
+     */
+	static function CodingSwitch($app = "./",$charset='UTF-8',$mode = "FILES",$file_types = array(".html",".php")) {
+		self::info("注意: 程序使用的文件编码检测算法可能对某些特殊字符不适用");
+		$filearr = self::searchdir($app,$mode,$file_types);
+		foreach($filearr as $file)
+			self::DetectAndSwitch($file,$charset);
+	}
+
+    static public function getError() {
+        return self::$error;
+    }
+
+    static public function getInfo() {
+        return self::$info;
+    }
+}

+ 569 - 0
ThinkPHP/Library/Org/Util/Date.class.php

@@ -0,0 +1,569 @@
+<?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 Org\Util;
+/**
+ * 日期时间操作类
+ * @category   ORG
+ * @package  ORG
+ * @subpackage  Date
+ * @author    liu21st <liu21st@gmail.com>
+ * @version   $Id: Date.class.php 2662 2012-01-26 06:32:50Z liu21st $
+ */
+class Date {
+
+    /**
+     * 日期的时间戳
+     * @var integer
+     * @access protected
+     */
+     protected $date;
+
+    /**
+     * 时区
+     * @var integer
+     * @access protected
+     */
+     protected $timezone;
+
+    /**
+     * 年
+     * @var integer
+     * @access protected
+     */
+     protected $year;
+
+    /**
+     * 月
+     * @var integer
+     * @access protected
+     */
+     protected $month;
+
+    /**
+     * 日
+     * @var integer
+     * @access protected
+     */
+     protected $day;
+
+    /**
+     * 时
+     * @var integer
+     * @access protected
+     */
+     protected $hour;
+
+    /**
+     * 分
+     * @var integer
+     * @access protected
+     */
+     protected $minute;
+
+    /**
+     * 秒
+     * @var integer
+     * @access protected
+     */
+     protected $second;
+
+    /**
+     * 星期的数字表示
+     * @var integer
+     * @access protected
+     */
+     protected $weekday;
+
+    /**
+     * 星期的完整表示
+     * @var string
+     * @access protected
+     */
+     protected $cWeekday;
+
+    /**
+     * 一年中的天数 0-365
+     * @var integer
+     * @access protected
+     */
+     protected $yDay;
+
+    /**
+     * 月份的完整表示
+     * @var string
+     * @access protected
+     */
+     protected $cMonth;
+
+    /**
+     * 日期CDATE表示
+     * @var string
+     * @access protected
+     */
+     protected $CDATE;
+
+    /**
+     * 日期的YMD表示
+     * @var string
+     * @access protected
+     */
+     protected $YMD;
+
+    /**
+     * 时间的输出表示
+     * @var string
+     * @access protected
+     */
+     protected $CTIME;
+
+     // 星期的输出
+     protected $Week = array("日","一","二","三","四","五","六");
+
+    /**
+     * 架构函数
+     * 创建一个Date对象
+     * @param mixed $date  日期
+     * @static
+     * @access public
+     */
+    public function __construct($date='') {
+        //分析日期
+        $this->date =   $this->parse($date);
+        $this->setDate($this->date);
+    }
+
+    /**
+     * 日期分析
+     * 返回时间戳
+     * @static
+     * @access public
+     * @param mixed $date 日期
+     * @return string
+     */
+    public function parse($date) {
+        if (is_string($date)) {
+            if (($date == "") || strtotime($date) == -1) {
+                //为空默认取得当前时间戳
+                $tmpdate = time();
+            } else {
+                //把字符串转换成UNIX时间戳
+                $tmpdate = strtotime($date);
+            }
+        } elseif (is_null($date))  {
+            //为空默认取得当前时间戳
+            $tmpdate = time();
+
+        } elseif (is_numeric($date)) {
+            //数字格式直接转换为时间戳
+            $tmpdate = $date;
+
+        } else {
+            if (get_class($date) == "Date") {
+                //如果是Date对象
+                $tmpdate = $date->date;
+            } else {
+                //默认取当前时间戳
+                $tmpdate = time();
+            }
+        }
+        return $tmpdate;
+    }
+
+    /**
+     * 验证日期数据是否有效
+     * @access public
+     * @param mixed $date 日期数据
+     * @return string
+     */
+    public function valid($date) {
+
+    }
+
+    /**
+     * 日期参数设置
+     * @static
+     * @access public
+     * @param integer $date  日期时间戳
+     * @return void
+     */
+    public function setDate($date) {
+        $dateArray  =   getdate($date);
+        $this->date         =   $dateArray[0];            //时间戳
+        $this->second       =   $dateArray["seconds"];    //秒
+        $this->minute       =   $dateArray["minutes"];    //分
+        $this->hour         =   $dateArray["hours"];      //时
+        $this->day          =   $dateArray["mday"];       //日
+        $this->month        =   $dateArray["mon"];        //月
+        $this->year         =   $dateArray["year"];       //年
+
+        $this->weekday      =   $dateArray["wday"];       //星期 0~6
+        $this->cWeekday     =   '星期'.$this->Week[$this->weekday];//$dateArray["weekday"];    //星期完整表示
+        $this->yDay         =   $dateArray["yday"];       //一年中的天数 0-365
+        $this->cMonth       =   $dateArray["month"];      //月份的完整表示
+
+        $this->CDATE        =   $this->format("%Y-%m-%d");//日期表示
+        $this->YMD          =   $this->format("%Y%m%d");  //简单日期
+        $this->CTIME        =   $this->format("%H:%M:%S");//时间表示
+
+        return ;
+    }
+
+    /**
+     * 日期格式化
+     * 默认返回 1970-01-01 11:30:45 格式
+     * @access public
+     * @param string $format  格式化参数
+     * @return string
+     */
+    public function format($format = "%Y-%m-%d %H:%M:%S") {
+        return strftime($format, $this->date);
+    }
+
+    /**
+     * 是否为闰年
+     * @static
+     * @access public
+     * @return string
+     */
+    public function isLeapYear($year='') {
+        if(empty($year)) {
+            $year = $this->year;
+        }
+        return ((($year % 4) == 0) && (($year % 100) != 0) || (($year % 400) == 0));
+    }
+
+    /**
+     * 计算日期差
+     *
+     *  w - weeks
+     *  d - days
+     *  h - hours
+     *  m - minutes
+     *  s - seconds
+     * @static
+     * @access public
+     * @param mixed $date 要比较的日期
+     * @param string $elaps  比较跨度
+     * @return integer
+     */
+    public function dateDiff($date, $elaps = "d") {
+        $__DAYS_PER_WEEK__       = (7);
+        $__DAYS_PER_MONTH__       = (30);
+        $__DAYS_PER_YEAR__       = (365);
+        $__HOURS_IN_A_DAY__      = (24);
+        $__MINUTES_IN_A_DAY__    = (1440);
+        $__SECONDS_IN_A_DAY__    = (86400);
+        //计算天数差
+        $__DAYSELAPS = ($this->parse($date) - $this->date) / $__SECONDS_IN_A_DAY__ ;
+        switch ($elaps) {
+            case "y"://转换成年
+                $__DAYSELAPS =  $__DAYSELAPS / $__DAYS_PER_YEAR__;
+                break;
+            case "M"://转换成月
+                $__DAYSELAPS =  $__DAYSELAPS / $__DAYS_PER_MONTH__;
+                break;
+            case "w"://转换成星期
+                $__DAYSELAPS =  $__DAYSELAPS / $__DAYS_PER_WEEK__;
+                break;
+            case "h"://转换成小时
+                $__DAYSELAPS =  $__DAYSELAPS * $__HOURS_IN_A_DAY__;
+                break;
+            case "m"://转换成分钟
+                $__DAYSELAPS =  $__DAYSELAPS * $__MINUTES_IN_A_DAY__;
+                break;
+            case "s"://转换成秒
+                $__DAYSELAPS =  $__DAYSELAPS * $__SECONDS_IN_A_DAY__;
+                break;
+        }
+        return $__DAYSELAPS;
+    }
+
+    /**
+     * 人性化的计算日期差
+     * @static
+     * @access public
+     * @param mixed $time 要比较的时间
+     * @param mixed $precision 返回的精度
+     * @return string
+     */
+    public function timeDiff( $time ,$precision=false) {
+        if(!is_numeric($precision) && !is_bool($precision)) {
+            static $_diff = array('y'=>'年','M'=>'个月','d'=>'天','w'=>'周','s'=>'秒','h'=>'小时','m'=>'分钟');
+            return ceil($this->dateDiff($time,$precision)).$_diff[$precision].'前';
+        }
+        $diff = abs($this->parse($time) - $this->date);
+        static $chunks = array(array(31536000,'年'),array(2592000,'个月'),array(604800,'周'),array(86400,'天'),array(3600 ,'小时'),array(60,'分钟'),array(1,'秒'));
+        $count =0;
+        $since = '';
+        for($i=0;$i<count($chunks);$i++) {
+            if($diff>=$chunks[$i][0]) {
+                $num   =  floor($diff/$chunks[$i][0]);
+                $since .= sprintf('%d'.$chunks[$i][1],$num);
+                $diff =  (int)($diff-$chunks[$i][0]*$num);
+                $count++;
+                if(!$precision || $count>=$precision) {
+                    break;
+                }
+            }
+       }
+        return $since.'前';
+    }
+
+    /**
+     * 返回周的某一天 返回Date对象
+     * @access public
+     * @return Date
+     */
+    public function getDayOfWeek($n){
+        $week = array(0=>'sunday',1=>'monday',2=>'tuesday',3=>'wednesday',4=>'thursday',5=>'friday',6=>'saturday');
+        return (new Date($week[$n]));
+    }
+
+    /**
+     * 计算周的第一天 返回Date对象
+     * @access public
+     * @return Date
+     */
+    public function firstDayOfWeek() {
+        return $this->getDayOfWeek(1);
+    }
+
+    /**
+     * 计算月份的第一天 返回Date对象
+     * @access public
+     * @return Date
+     */
+    public function firstDayOfMonth() {
+        return (new Date(mktime(0, 0, 0,$this->month,1,$this->year )));
+    }
+
+    /**
+     * 计算年份的第一天 返回Date对象
+     * @access public
+     * @return Date
+     */
+    public function firstDayOfYear() {
+        return (new Date(mktime(0, 0, 0, 1, 1, $this->year)));
+    }
+
+    /**
+     * 计算周的最后一天 返回Date对象
+     * @access public
+     * @return Date
+     */
+    public function lastDayOfWeek() {
+        return $this->getDayOfWeek(0);
+    }
+
+    /**
+     * 计算月份的最后一天 返回Date对象
+     * @access public
+     * @return Date
+     */
+    public function lastDayOfMonth() {
+        return (new Date(mktime(0, 0, 0, $this->month + 1, 0, $this->year )));
+    }
+
+    /**
+     * 计算年份的最后一天 返回Date对象
+     * @access public
+     * @return Date
+     */
+    public function lastDayOfYear() {
+        return (new Date(mktime(0, 0, 0, 1, 0, $this->year + 1)));
+    }
+
+    /**
+     * 计算月份的最大天数
+     * @access public
+     * @return integer
+     */
+    public function maxDayOfMonth() {
+        $result = $this->dateDiff(strtotime($this->dateAdd(1,'m')),'d');
+        return $result;
+    }
+
+    /**
+     * 取得指定间隔日期
+     *
+     *    yyyy - 年
+     *    q    - 季度
+     *    m    - 月
+     *    y    - day of year
+     *    d    - 日
+     *    w    - 周
+     *    ww   - week of year
+     *    h    - 小时
+     *    n    - 分钟
+     *    s    - 秒
+     * @access public
+     * @param integer $number 间隔数目
+     * @param string $interval  比较类型
+     * @return Date
+     */
+    public function dateAdd($number = 0, $interval = "d") {
+        $hours =  $this->hour;
+        $minutes =  $this->minute;
+        $seconds =  $this->second;
+        $month =  $this->month;
+        $day =  $this->day;
+        $year =  $this->year;
+
+        switch ($interval) {
+            case "yyyy":
+                //---Add $number to year
+                $year += $number;
+                break;
+
+            case "q":
+                //---Add $number to quarter
+                $month += ($number*3);
+                break;
+
+            case "m":
+                //---Add $number to month
+                $month += $number;
+                break;
+
+            case "y":
+            case "d":
+            case "w":
+                //---Add $number to day of year, day, day of week
+                $day += $number;
+                break;
+
+            case "ww":
+                //---Add $number to week
+                $day += ($number*7);
+                break;
+
+            case "h":
+                //---Add $number to hours
+                $hours += $number;
+                break;
+
+            case "n":
+                //---Add $number to minutes
+                $minutes += $number;
+                break;
+
+            case "s":
+                //---Add $number to seconds
+                $seconds += $number;
+                break;
+        }
+
+        return (new Date(mktime($hours,
+                                $minutes,
+                                $seconds,
+                                $month,
+                                $day,
+                                $year)));
+
+    }
+
+    /**
+     * 日期数字转中文
+     * 用于日和月、周
+     * @static
+     * @access public
+     * @param integer $number 日期数字
+     * @return string
+     */
+    public function  numberToCh($number) {
+        $number = intval($number);
+        $array  = array('一','二','三','四','五','六','七','八','九','十');
+        $str = '';
+        if($number  ==0)  { $str .= "十" ;}
+        if($number  <  10){
+           $str .= $array[$number-1] ;
+        }
+        elseif($number  <  20  ){
+           $str .= "十".$array[$number-11];
+        }
+        elseif($number  <  30  ){
+           $str .= "二十".$array[$number-21];
+        }
+        else{
+           $str .= "三十".$array[$number-31];
+        }
+        return $str;
+    }
+
+    /**
+     * 年份数字转中文
+     * @static
+     * @access public
+     * @param integer $yearStr 年份数字
+     * @param boolean $flag 是否显示公元
+     * @return string
+     */
+    public function  yearToCh( $yearStr ,$flag=false ) {
+        $array = array('零','一','二','三','四','五','六','七','八','九');
+        $str = $flag? '公元' : '';
+        for($i=0;$i<4;$i++){
+            $str .= $array[substr($yearStr,$i,1)];
+        }
+        return $str;
+    }
+
+    /**
+     *  判断日期 所属 干支 生肖 星座
+     *  type 参数:XZ 星座 GZ 干支 SX 生肖
+     *
+     * @static
+     * @access public
+     * @param string $type  获取信息类型
+     * @return string
+     */
+    public function magicInfo($type) {
+        $result = '';
+        $m      =   $this->month;
+        $y      =   $this->year;
+        $d      =   $this->day;
+
+        switch ($type) {
+        case 'XZ'://星座
+            $XZDict = array('摩羯','宝瓶','双鱼','白羊','金牛','双子','巨蟹','狮子','处女','天秤','天蝎','射手');
+            $Zone   = array(1222,122,222,321,421,522,622,722,822,922,1022,1122,1222);
+            if((100*$m+$d)>=$Zone[0]||(100*$m+$d)<$Zone[1])
+                $i=0;
+            else
+                for($i=1;$i<12;$i++){
+                if((100*$m+$d)>=$Zone[$i]&&(100*$m+$d)<$Zone[$i+1])
+                  break;
+                }
+            $result = $XZDict[$i].'座';
+            break;
+
+        case 'GZ'://干支
+            $GZDict = array(
+                        array('甲','乙','丙','丁','戊','己','庚','辛','壬','癸'),
+                        array('子','丑','寅','卯','辰','巳','午','未','申','酉','戌','亥')
+                        );
+            $i= $y -1900+36 ;
+            $result = $GZDict[0][$i%10].$GZDict[1][$i%12];
+            break;
+
+        case 'SX'://生肖
+            $SXDict = array('鼠','牛','虎','兔','龙','蛇','马','羊','猴','鸡','狗','猪');
+            $result = $SXDict[($y-4)%12];
+            break;
+
+        }
+        return $result;
+    }
+
+    public function __toString() {
+        return $this->format();
+    }
+}

+ 285 - 0
ThinkPHP/Library/Org/Util/Rbac.class.php

@@ -0,0 +1,285 @@
+<?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 Org\Util;
+use Think\Db;
+/**
+ +------------------------------------------------------------------------------
+ * 基于角色的数据库方式验证类
+ +------------------------------------------------------------------------------
+ */
+// 配置文件增加设置
+// USER_AUTH_ON 是否需要认证
+// USER_AUTH_TYPE 认证类型
+// USER_AUTH_KEY 认证识别号
+// REQUIRE_AUTH_MODULE  需要认证模块
+// NOT_AUTH_MODULE 无需认证模块
+// USER_AUTH_GATEWAY 认证网关
+// RBAC_DB_DSN  数据库连接DSN
+// RBAC_ROLE_TABLE 角色表名称
+// RBAC_USER_TABLE 用户表名称
+// RBAC_ACCESS_TABLE 权限表名称
+// RBAC_NODE_TABLE 节点表名称
+/*
+-- --------------------------------------------------------
+CREATE TABLE IF NOT EXISTS `think_access` (
+  `role_id` smallint(6) unsigned NOT NULL,
+  `node_id` smallint(6) unsigned NOT NULL,
+  `level` tinyint(1) NOT NULL,
+  `module` varchar(50) DEFAULT NULL,
+  KEY `groupId` (`role_id`),
+  KEY `nodeId` (`node_id`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+CREATE TABLE IF NOT EXISTS `think_node` (
+  `id` smallint(6) unsigned NOT NULL AUTO_INCREMENT,
+  `name` varchar(20) NOT NULL,
+  `title` varchar(50) DEFAULT NULL,
+  `status` tinyint(1) DEFAULT '0',
+  `remark` varchar(255) DEFAULT NULL,
+  `sort` smallint(6) unsigned DEFAULT NULL,
+  `pid` smallint(6) unsigned NOT NULL,
+  `level` tinyint(1) unsigned NOT NULL,
+  PRIMARY KEY (`id`),
+  KEY `level` (`level`),
+  KEY `pid` (`pid`),
+  KEY `status` (`status`),
+  KEY `name` (`name`)
+) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
+
+CREATE TABLE IF NOT EXISTS `think_role` (
+  `id` smallint(6) unsigned NOT NULL AUTO_INCREMENT,
+  `name` varchar(20) NOT NULL,
+  `pid` smallint(6) DEFAULT NULL,
+  `status` tinyint(1) unsigned DEFAULT NULL,
+  `remark` varchar(255) DEFAULT NULL,
+  PRIMARY KEY (`id`),
+  KEY `pid` (`pid`),
+  KEY `status` (`status`)
+) ENGINE=MyISAM  DEFAULT CHARSET=utf8 ;
+
+CREATE TABLE IF NOT EXISTS `think_role_user` (
+  `role_id` mediumint(9) unsigned DEFAULT NULL,
+  `user_id` char(32) DEFAULT NULL,
+  KEY `group_id` (`role_id`),
+  KEY `user_id` (`user_id`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+*/
+class Rbac {
+    // 认证方法
+    static public function authenticate($map,$model='') {
+        if(empty($model)) $model =  C('USER_AUTH_MODEL');
+        //使用给定的Map进行认证
+        return M($model)->where($map)->find();
+    }
+
+    //用于检测用户权限的方法,并保存到Session中
+    static function saveAccessList($authId=null) {
+        if(null===$authId)   $authId = $_SESSION[C('USER_AUTH_KEY')];
+        // 如果使用普通权限模式,保存当前用户的访问权限列表
+        // 对管理员开发所有权限
+        if(C('USER_AUTH_TYPE') !=2 && !$_SESSION[C('ADMIN_AUTH_KEY')] )
+            $_SESSION['_ACCESS_LIST']	=	self::getAccessList($authId);
+        return ;
+    }
+
+	// 取得模块的所属记录访问权限列表 返回有权限的记录ID数组
+	static function getRecordAccessList($authId=null,$module='') {
+        if(null===$authId)   $authId = $_SESSION[C('USER_AUTH_KEY')];
+        if(empty($module))  $module	=	CONTROLLER_NAME;
+        //获取权限访问列表
+        $accessList = self::getModuleAccessList($authId,$module);
+        return $accessList;
+	}
+
+    //检查当前操作是否需要认证
+    static function checkAccess() {
+        //如果项目要求认证,并且当前模块需要认证,则进行权限认证
+        if( C('USER_AUTH_ON') ){
+			$_module	=	array();
+			$_action	=	array();
+            if("" != C('REQUIRE_AUTH_MODULE')) {
+                //需要认证的模块
+                $_module['yes'] = explode(',',strtoupper(C('REQUIRE_AUTH_MODULE')));
+            }else {
+                //无需认证的模块
+                $_module['no'] = explode(',',strtoupper(C('NOT_AUTH_MODULE')));
+            }
+            //检查当前模块是否需要认证
+            if((!empty($_module['no']) && !in_array(strtoupper(CONTROLLER_NAME),$_module['no'])) || (!empty($_module['yes']) && in_array(strtoupper(CONTROLLER_NAME),$_module['yes']))) {
+				if("" != C('REQUIRE_AUTH_ACTION')) {
+					//需要认证的操作
+					$_action['yes'] = explode(',',strtoupper(C('REQUIRE_AUTH_ACTION')));
+				}else {
+					//无需认证的操作
+					$_action['no'] = explode(',',strtoupper(C('NOT_AUTH_ACTION')));
+				}
+				//检查当前操作是否需要认证
+				if((!empty($_action['no']) && !in_array(strtoupper(ACTION_NAME),$_action['no'])) || (!empty($_action['yes']) && in_array(strtoupper(ACTION_NAME),$_action['yes']))) {
+					return true;
+				}else {
+					return false;
+				}
+            }else {
+                return false;
+            }
+        }
+        return false;
+    }
+
+	// 登录检查
+	static public function checkLogin() {
+        //检查当前操作是否需要认证
+        if(self::checkAccess()) {
+            //检查认证识别号
+            if(!$_SESSION[C('USER_AUTH_KEY')]) {
+                if(C('GUEST_AUTH_ON')) {
+                    // 开启游客授权访问
+                    if(!isset($_SESSION['_ACCESS_LIST']))
+                        // 保存游客权限
+                        self::saveAccessList(C('GUEST_AUTH_ID'));
+                }else{
+                    // 禁止游客访问跳转到认证网关
+                    redirect(PHP_FILE.C('USER_AUTH_GATEWAY'));
+                }
+            }
+        }
+        return true;
+	}
+
+    //权限认证的过滤器方法
+    static public function AccessDecision($appName=MODULE_NAME) {
+        //检查是否需要认证
+        if(self::checkAccess()) {
+            //存在认证识别号,则进行进一步的访问决策
+            $accessGuid   =   md5($appName.CONTROLLER_NAME.ACTION_NAME);
+            if(empty($_SESSION[C('ADMIN_AUTH_KEY')])) {
+                if(C('USER_AUTH_TYPE')==2) {
+                    //加强验证和即时验证模式 更加安全 后台权限修改可以即时生效
+                    //通过数据库进行访问检查
+                    $accessList = self::getAccessList($_SESSION[C('USER_AUTH_KEY')]);
+                }else {
+                    // 如果是管理员或者当前操作已经认证过,无需再次认证
+                    if( $_SESSION[$accessGuid]) {
+                        return true;
+                    }
+                    //登录验证模式,比较登录后保存的权限访问列表
+                    $accessList = $_SESSION['_ACCESS_LIST'];
+                }
+                //判断是否为组件化模式,如果是,验证其全模块名
+                if(!isset($accessList[strtoupper($appName)][strtoupper(CONTROLLER_NAME)][strtoupper(ACTION_NAME)])) {
+                    $_SESSION[$accessGuid]  =   false;
+                    return false;
+                }
+                else {
+                    $_SESSION[$accessGuid]	=	true;
+                }
+            }else{
+                //管理员无需认证
+				return true;
+			}
+        }
+        return true;
+    }
+
+    /**
+     +----------------------------------------------------------
+     * 取得当前认证号的所有权限列表
+     +----------------------------------------------------------
+     * @param integer $authId 用户ID
+     +----------------------------------------------------------
+     * @access public
+     +----------------------------------------------------------
+     */
+    static public function getAccessList($authId) {
+        // Db方式权限数据
+        $db     =   Db::getInstance(C('RBAC_DB_DSN'));
+        $table = array('role'=>C('RBAC_ROLE_TABLE'),'user'=>C('RBAC_USER_TABLE'),'access'=>C('RBAC_ACCESS_TABLE'),'node'=>C('RBAC_NODE_TABLE'));
+        $sql    =   "select node.id,node.name from ".
+                    $table['role']." as role,".
+                    $table['user']." as user,".
+                    $table['access']." as access ,".
+                    $table['node']." as node ".
+                    "where user.user_id='{$authId}' and user.role_id=role.id and ( access.role_id=role.id  or (access.role_id=role.pid and role.pid!=0 ) ) and role.status=1 and access.node_id=node.id and node.level=1 and node.status=1";
+        $apps =   $db->query($sql);
+        $access =  array();
+        foreach($apps as $key=>$app) {
+            $appId	=	$app['id'];
+            $appName	 =	 $app['name'];
+            // 读取项目的模块权限
+            $access[strtoupper($appName)]   =  array();
+            $sql    =   "select node.id,node.name from ".
+                    $table['role']." as role,".
+                    $table['user']." as user,".
+                    $table['access']." as access ,".
+                    $table['node']." as node ".
+                    "where user.user_id='{$authId}' and user.role_id=role.id and ( access.role_id=role.id  or (access.role_id=role.pid and role.pid!=0 ) ) and role.status=1 and access.node_id=node.id and node.level=2 and node.pid={$appId} and node.status=1";
+            $modules =   $db->query($sql);
+            // 判断是否存在公共模块的权限
+            $publicAction  = array();
+            foreach($modules as $key=>$module) {
+                $moduleId	 =	 $module['id'];
+                $moduleName = $module['name'];
+                if('PUBLIC'== strtoupper($moduleName)) {
+                $sql    =   "select node.id,node.name from ".
+                    $table['role']." as role,".
+                    $table['user']." as user,".
+                    $table['access']." as access ,".
+                    $table['node']." as node ".
+                    "where user.user_id='{$authId}' and user.role_id=role.id and ( access.role_id=role.id  or (access.role_id=role.pid and role.pid!=0 ) ) and role.status=1 and access.node_id=node.id and node.level=3 and node.pid={$moduleId} and node.status=1";
+                    $rs =   $db->query($sql);
+                    foreach ($rs as $a){
+                        $publicAction[$a['name']]	 =	 $a['id'];
+                    }
+                    unset($modules[$key]);
+                    break;
+                }
+            }
+            // 依次读取模块的操作权限
+            foreach($modules as $key=>$module) {
+                $moduleId	 =	 $module['id'];
+                $moduleName = $module['name'];
+                $sql    =   "select node.id,node.name from ".
+                    $table['role']." as role,".
+                    $table['user']." as user,".
+                    $table['access']." as access ,".
+                    $table['node']." as node ".
+                    "where user.user_id='{$authId}' and user.role_id=role.id and ( access.role_id=role.id  or (access.role_id=role.pid and role.pid!=0 ) ) and role.status=1 and access.node_id=node.id and node.level=3 and node.pid={$moduleId} and node.status=1";
+                $rs =   $db->query($sql);
+                $action = array();
+                foreach ($rs as $a){
+                    $action[$a['name']]	 =	 $a['id'];
+                }
+                // 和公共模块的操作权限合并
+                $action += $publicAction;
+                $access[strtoupper($appName)][strtoupper($moduleName)]   =  array_change_key_case($action,CASE_UPPER);
+            }
+        }
+        return $access;
+    }
+
+	// 读取模块所属的记录访问权限
+	static public function getModuleAccessList($authId,$module) {
+        // Db方式
+        $db     =   Db::getInstance(C('RBAC_DB_DSN'));
+        $table = array('role'=>C('RBAC_ROLE_TABLE'),'user'=>C('RBAC_USER_TABLE'),'access'=>C('RBAC_ACCESS_TABLE'));
+        $sql    =   "select access.node_id from ".
+                    $table['role']." as role,".
+                    $table['user']." as user,".
+                    $table['access']." as access ".
+                    "where user.user_id='{$authId}' and user.role_id=role.id and ( access.role_id=role.id  or (access.role_id=role.pid and role.pid!=0 ) ) and role.status=1 and  access.module='{$module}' and access.status=1";
+        $rs =   $db->query($sql);
+        $access	=	array();
+        foreach ($rs as $node){
+            $access[]	=	$node['node_id'];
+        }
+		return $access;
+	}
+}

+ 51 - 0
ThinkPHP/Library/Org/Util/Stack.class.php

@@ -0,0 +1,51 @@
+<?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 Org\Util;
+
+/**
+ * Stack实现类
+ * @category   ORG
+ * @package  ORG
+ * @subpackage  Util
+ * @author    liu21st <liu21st@gmail.com>
+ */
+class Stack extends ArrayList {
+
+    /**
+     * 架构函数
+     * @access public
+     * @param array $values  初始化数组元素
+     */
+    public function __construct($values = array()) {
+        parent::__construct($values);
+    }
+
+    /**
+     * 将堆栈的内部指针指向第一个单元
+     * @access public
+     * @return mixed
+     */
+    public function peek() {
+        return reset($this->toArray());
+    }
+
+    /**
+     * 元素进栈
+     * @access public
+     * @param mixed $value
+     * @return mixed
+     */
+    public function push($value) {
+        $this->add($value);
+        return $value;
+    }
+
+}

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 248 - 0
ThinkPHP/Library/Org/Util/String.class.php


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 211 - 0
ThinkPHP/Library/Think/App.class.php


+ 231 - 0
ThinkPHP/Library/Think/Auth.class.php

@@ -0,0 +1,231 @@
+<?php
+// +----------------------------------------------------------------------
+// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2011 http://thinkphp.cn All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+// +----------------------------------------------------------------------
+// | Author: luofei614 <weibo.com/luofei614> 
+// +----------------------------------------------------------------------
+namespace Think;
+/**
+ * 权限认证类
+ * 功能特性:
+ * 1,是对规则进行认证,不是对节点进行认证。用户可以把节点当作规则名称实现对节点进行认证。
+ *      $auth=new Auth();  $auth->check('规则名称','用户id')
+ * 2,可以同时对多条规则进行认证,并设置多条规则的关系(or或者and)
+ *      $auth=new Auth();  $auth->check('规则1,规则2','用户id','and') 
+ *      第三个参数为and时表示,用户需要同时具有规则1和规则2的权限。 当第三个参数为or时,表示用户值需要具备其中一个条件即可。默认为or
+ * 3,一个用户可以属于多个用户组(think_auth_group_access表 定义了用户所属用户组)。我们需要设置每个用户组拥有哪些规则(think_auth_group 定义了用户组权限)
+ * 
+ * 4,支持规则表达式。
+ *      在think_auth_rule 表中定义一条规则时,如果type为1, condition字段就可以定义规则表达式。 如定义{score}>5  and {score}<100  表示用户的分数在5-100之间时这条规则才会通过。
+ */
+
+//数据库
+/*
+-- ----------------------------
+-- think_auth_rule,规则表,
+-- id:主键,name:规则唯一标识, title:规则中文名称 status 状态:为1正常,为0禁用,condition:规则表达式,为空表示存在就验证,不为空表示按照条件验证
+-- ----------------------------
+ DROP TABLE IF EXISTS `think_auth_rule`;
+CREATE TABLE `think_auth_rule` (  
+    `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,  
+    `name` char(80) NOT NULL DEFAULT '',  
+    `title` char(20) NOT NULL DEFAULT '',  
+    `type` tinyint(1) NOT NULL DEFAULT '1',    
+    `status` tinyint(1) NOT NULL DEFAULT '1',  
+    `condition` char(100) NOT NULL DEFAULT '',  # 规则附件条件,满足附加条件的规则,才认为是有效的规则
+    PRIMARY KEY (`id`),  
+    UNIQUE KEY `name` (`name`)
+) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
+-- ----------------------------
+-- think_auth_group 用户组表, 
+-- id:主键, title:用户组中文名称, rules:用户组拥有的规则id, 多个规则","隔开,status 状态:为1正常,为0禁用
+-- ----------------------------
+ DROP TABLE IF EXISTS `think_auth_group`;
+CREATE TABLE `think_auth_group` ( 
+    `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT, 
+    `title` char(100) NOT NULL DEFAULT '', 
+    `status` tinyint(1) NOT NULL DEFAULT '1', 
+    `rules` char(80) NOT NULL DEFAULT '', 
+    PRIMARY KEY (`id`)
+) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
+-- ----------------------------
+-- think_auth_group_access 用户组明细表
+-- uid:用户id,group_id:用户组id
+-- ----------------------------
+DROP TABLE IF EXISTS `think_auth_group_access`;
+CREATE TABLE `think_auth_group_access` (  
+    `uid` mediumint(8) unsigned NOT NULL,  
+    `group_id` mediumint(8) unsigned NOT NULL, 
+    UNIQUE KEY `uid_group_id` (`uid`,`group_id`),  
+    KEY `uid` (`uid`), 
+    KEY `group_id` (`group_id`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+ */
+
+class Auth{
+
+    //默认配置
+    protected $_config = array(
+        'AUTH_ON'           => true,                      // 认证开关
+        'AUTH_TYPE'         => 1,                         // 认证方式,1为实时认证;2为登录认证。
+        'AUTH_GROUP'        => 'auth_group',        // 用户组数据表名
+        'AUTH_GROUP_ACCESS' => 'auth_group_access', // 用户-用户组关系表
+        'AUTH_RULE'         => 'auth_rule',         // 权限规则表
+        'AUTH_USER'         => 'member'             // 用户信息表
+    );
+
+    public function __construct() {
+        $prefix = C('DB_PREFIX');
+        $this->_config['AUTH_GROUP'] = $prefix.$this->_config['AUTH_GROUP'];
+        $this->_config['AUTH_RULE'] = $prefix.$this->_config['AUTH_RULE'];
+        $this->_config['AUTH_USER'] = $prefix.$this->_config['AUTH_USER'];
+        $this->_config['AUTH_GROUP_ACCESS'] = $prefix.$this->_config['AUTH_GROUP_ACCESS'];
+        if (C('AUTH_CONFIG')) {
+            //可设置配置项 AUTH_CONFIG, 此配置项为数组。
+            $this->_config = array_merge($this->_config, C('AUTH_CONFIG'));
+        }
+    }
+
+    /**
+      * 检查权限
+      * @param name string|array  需要验证的规则列表,支持逗号分隔的权限规则或索引数组
+      * @param uid  int           认证用户的id
+      * @param string mode        执行check的模式
+      * @param relation string    如果为 'or' 表示满足任一条规则即通过验证;如果为 'and'则表示需满足所有规则才能通过验证
+      * @return boolean           通过验证返回true;失败返回false
+     */
+    public function check($name, $uid, $type=1, $mode='url', $relation='or') {
+        if (!$this->_config['AUTH_ON'])
+            return true;
+        $authList = $this->getAuthList($uid,$type); //获取用户需要验证的所有有效规则列表
+        if (is_string($name)) {
+            $name = strtolower($name);
+            if (strpos($name, ',') !== false) {
+                $name = explode(',', $name);
+            } else {
+                $name = array($name);
+            }
+        }
+        $list = array(); //保存验证通过的规则名
+        if ($mode=='url') {
+            $REQUEST = unserialize( strtolower(serialize($_REQUEST)) );
+        }
+        foreach ( $authList as $auth ) {
+            $query = preg_replace('/^.+\?/U','',$auth);
+            if ($mode=='url' && $query!=$auth ) {
+                parse_str($query,$param); //解析规则中的param
+                $intersect = array_intersect_assoc($REQUEST,$param);
+                $auth = preg_replace('/\?.*$/U','',$auth);
+                if ( in_array($auth,$name) && $intersect==$param ) {  //如果节点相符且url参数满足
+                    $list[] = $auth ;
+                }
+            }else if (in_array($auth , $name)){
+                $list[] = $auth ;
+            }
+        }
+        if ($relation == 'or' and !empty($list)) {
+            return true;
+        }
+        $diff = array_diff($name, $list);
+        if ($relation == 'and' and empty($diff)) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * 根据用户id获取用户组,返回值为数组
+     * @param  uid int     用户id
+     * @return array       用户所属的用户组 array(
+     *     array('uid'=>'用户id','group_id'=>'用户组id','title'=>'用户组名称','rules'=>'用户组拥有的规则id,多个,号隔开'),
+     *     ...)   
+     */
+    public function getGroups($uid) {
+        static $groups = array();
+        if (isset($groups[$uid]))
+            return $groups[$uid];
+        $user_groups = M()
+            ->table($this->_config['AUTH_GROUP_ACCESS'] . ' a')
+            ->where("a.uid='$uid' and g.status='1'")
+            ->join($this->_config['AUTH_GROUP']." g on a.group_id=g.id")
+            ->field('uid,group_id,title,rules')->select();
+        $groups[$uid]=$user_groups?:array();
+        return $groups[$uid];
+    }
+
+    /**
+     * 获得权限列表
+     * @param integer $uid  用户id
+     * @param integer $type 
+     */
+    protected function getAuthList($uid,$type) {
+        static $_authList = array(); //保存用户验证通过的权限列表
+        $t = implode(',',(array)$type);
+        if (isset($_authList[$uid.$t])) {
+            return $_authList[$uid.$t];
+        }
+        if( $this->_config['AUTH_TYPE']==2 && isset($_SESSION['_AUTH_LIST_'.$uid.$t])){
+            return $_SESSION['_AUTH_LIST_'.$uid.$t];
+        }
+
+        //读取用户所属用户组
+        $groups = $this->getGroups($uid);
+        $ids = array();//保存用户所属用户组设置的所有权限规则id
+        foreach ($groups as $g) {
+            $ids = array_merge($ids, explode(',', trim($g['rules'], ',')));
+        }
+        $ids = array_unique($ids);
+        if (empty($ids)) {
+            $_authList[$uid.$t] = array();
+            return array();
+        }
+
+        $map=array(
+            'id'=>array('in',$ids),
+            'type'=>$type,
+            'status'=>1,
+        );
+        //读取用户组所有权限规则
+        $rules = M()->table($this->_config['AUTH_RULE'])->where($map)->field('condition,name')->select();
+
+        //循环规则,判断结果。
+        $authList = array();   //
+        foreach ($rules as $rule) {
+            if (!empty($rule['condition'])) { //根据condition进行验证
+                $user = $this->getUserInfo($uid);//获取用户信息,一维数组
+
+                $command = preg_replace('/\{(\w*?)\}/', '$user[\'\\1\']', $rule['condition']);
+                //dump($command);//debug
+                @(eval('$condition=(' . $command . ');'));
+                if ($condition) {
+                    $authList[] = strtolower($rule['name']);
+                }
+            } else {
+                //只要存在就记录
+                $authList[] = strtolower($rule['name']);
+            }
+        }
+        $_authList[$uid.$t] = $authList;
+        if($this->_config['AUTH_TYPE']==2){
+            //规则列表结果保存到session
+            $_SESSION['_AUTH_LIST_'.$uid.$t]=$authList;
+        }
+        return array_unique($authList);
+    }
+
+    /**
+     * 获得用户资料,根据自己的情况读取数据库
+     */
+    protected function getUserInfo($uid) {
+        static $userinfo=array();
+        if(!isset($userinfo[$uid])){
+             $userinfo[$uid]=M()->where(array('uid'=>$uid))->table($this->_config['AUTH_USER'])->find();
+        }
+        return $userinfo[$uid];
+    }
+
+}

+ 24 - 0
ThinkPHP/Library/Think/Behavior.class.php

@@ -0,0 +1,24 @@
+<?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 Think;
+/**
+ * ThinkPHP Behavior基础类
+ */
+abstract class Behavior {
+    /**
+     * 执行行为 run方法是Behavior唯一的接口
+     * @access public
+     * @param mixed $params  行为参数
+     * @return void
+     */
+    abstract public function run(&$params);
+
+}

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 165 - 0
ThinkPHP/Library/Think/Build.class.php


+ 127 - 0
ThinkPHP/Library/Think/Cache.class.php

@@ -0,0 +1,127 @@
+<?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 Think;
+/**
+ * 缓存管理类
+ */
+class Cache {
+
+    /**
+     * 操作句柄
+     * @var string
+     * @access protected
+     */
+    protected $handler    ;
+
+    /**
+     * 缓存连接参数
+     * @var integer
+     * @access protected
+     */
+    protected $options = array();
+
+    /**
+     * 连接缓存
+     * @access public
+     * @param string $type 缓存类型
+     * @param array $options  配置数组
+     * @return object
+     */
+    public function connect($type='',$options=array()) {
+        if(empty($type))  $type = C('DATA_CACHE_TYPE');
+        $class  =   strpos($type,'\\')? $type : 'Think\\Cache\\Driver\\'.ucwords(strtolower($type));            
+        if(class_exists($class))
+            $cache = new $class($options);
+        else
+            E(L('_CACHE_TYPE_INVALID_').':'.$type);
+        return $cache;
+    }
+
+    /**
+     * 取得缓存类实例
+     * @static
+     * @access public
+     * @return mixed
+     */
+    static function getInstance($type='',$options=array()) {
+		static $_instance	=	array();
+		$guid	=	$type.to_guid_string($options);
+		if(!isset($_instance[$guid])){
+			$obj	=	new Cache();
+			$_instance[$guid]	=	$obj->connect($type,$options);
+		}
+		return $_instance[$guid];
+    }
+
+    public function __get($name) {
+        return $this->get($name);
+    }
+
+    public function __set($name,$value) {
+        return $this->set($name,$value);
+    }
+
+    public function __unset($name) {
+        $this->rm($name);
+    }
+    public function setOptions($name,$value) {
+        $this->options[$name]   =   $value;
+    }
+
+    public function getOptions($name) {
+        return $this->options[$name];
+    }
+
+    /**
+     * 队列缓存
+     * @access protected
+     * @param string $key 队列名
+     * @return mixed
+     */
+    // 
+    protected function queue($key) {
+        static $_handler = array(
+            'file'  =>  array('F','F'),
+            'xcache'=>  array('xcache_get','xcache_set'),
+            'apc'   =>  array('apc_fetch','apc_store'),
+        );
+        $queue      =   isset($this->options['queue'])?$this->options['queue']:'file';
+        $fun        =   isset($_handler[$queue])?$_handler[$queue]:$_handler['file'];
+        $queue_name =   isset($this->options['queue_name'])?$this->options['queue_name']:'think_queue';
+        $value      =   $fun[0]($queue_name);
+        if(!$value) {
+            $value  =   array();
+        }
+        // 进列
+        if(false===array_search($key, $value))  array_push($value,$key);
+        if(count($value) > $this->options['length']) {
+            // 出列
+            $key =  array_shift($value);
+            // 删除缓存
+            $this->rm($key);
+             if(APP_DEBUG){
+                //调试模式下,记录出列次数
+                N($queue_name.'_out_times',1);
+            }
+        }
+        return $fun[1]($queue_name,$value);
+    }
+    
+    public function __call($method,$args){
+        //调用缓存类型自己的方法
+        if(method_exists($this->handler, $method)){
+           return call_user_func_array(array($this->handler,$method), $args);
+        }else{
+            E(__CLASS__.':'.$method.L('_METHOD_NOT_EXIST_'));
+            return;
+        }
+    }
+}

+ 124 - 0
ThinkPHP/Library/Think/Cache/Driver/Apachenote.class.php

@@ -0,0 +1,124 @@
+<?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 Think\Cache\Driver;
+use Think\Cache;
+defined('THINK_PATH') or exit();
+/**
+ * Apachenote缓存驱动
+ */
+class Apachenote extends Cache {
+
+    /**
+     * 架构函数
+     * @param array $options 缓存参数
+     * @access public
+     */
+    public function __construct($options=array()) {
+        if(!empty($options)) {
+            $this->options =  $options;
+        }
+        if(empty($options)) {
+            $options = array (
+                'host'        =>  '127.0.0.1',
+                'port'        =>  1042,
+                'timeout'     =>  10,
+            );
+        }
+        $this->options  =   $options;
+        $this->options['prefix']    =   isset($options['prefix'])?  $options['prefix']  :   C('DATA_CACHE_PREFIX');
+        $this->options['length']    =   isset($options['length'])?  $options['length']  :   0;
+        $this->handler = null;
+        $this->open();
+    }
+
+    /**
+     * 读取缓存
+     * @access public
+     * @param string $name 缓存变量名
+     * @return mixed
+     */
+     public function get($name) {
+         $this->open();
+         $name  =   $this->options['prefix'].$name;
+         $s     =   'F' . pack('N', strlen($name)) . $name;
+         fwrite($this->handler, $s);
+
+         for ($data = ''; !feof($this->handler);) {
+             $data .= fread($this->handler, 4096);
+         }
+        N('cache_read',1);
+         $this->close();
+         return $data === '' ? '' : unserialize($data);
+     }
+
+    /**
+     * 写入缓存
+     * @access public
+     * @param string $name 缓存变量名
+     * @param mixed $value  存储数据
+     * @return boolean
+     */
+    public function set($name, $value) {
+        N('cache_write',1);
+        $this->open();
+        $value  =   serialize($value);
+        $name   =   $this->options['prefix'].$name;        
+        $s      =   'S' . pack('NN', strlen($name), strlen($value)) . $name . $value;
+
+        fwrite($this->handler, $s);
+        $ret = fgets($this->handler);
+        $this->close();
+        if($ret === "OK\n") {
+            if($this->options['length']>0) {
+                // 记录缓存队列
+                $this->queue($name);
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * 删除缓存
+     * @access public
+     * @param string $name 缓存变量名
+     * @return boolean
+     */
+     public function rm($name) {
+        $this->open();
+        $name   =   $this->options['prefix'].$name;         
+        $s      =   'D' . pack('N', strlen($name)) . $name;
+        fwrite($this->handler, $s);
+        $ret    = fgets($this->handler);
+        $this->close();
+        return $ret === "OK\n";
+     }
+
+    /**
+     * 关闭缓存
+     * @access private
+     */
+     private function close() {
+         fclose($this->handler);
+         $this->handler = false;
+     }
+
+    /**
+     * 打开缓存
+     * @access private
+     */
+     private function open() {
+         if (!is_resource($this->handler)) {
+             $this->handler = fsockopen($this->options['host'], $this->options['port'], $_, $_, $this->options['timeout']);
+         }
+     }
+
+}

+ 86 - 0
ThinkPHP/Library/Think/Cache/Driver/Apc.class.php

@@ -0,0 +1,86 @@
+<?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 Think\Cache\Driver;
+use Think\Cache;
+defined('THINK_PATH') or exit();
+/**
+ * Apc缓存驱动
+ */
+class Apc extends Cache {
+
+    /**
+     * 架构函数
+     * @param array $options 缓存参数
+     * @access public
+     */
+    public function __construct($options=array()) {
+        if(!function_exists('apc_cache_info')) {
+            E(L('_NOT_SUPPORT_').':Apc');
+        }
+        $this->options['prefix']    =   isset($options['prefix'])?  $options['prefix']  :   C('DATA_CACHE_PREFIX');
+        $this->options['length']    =   isset($options['length'])?  $options['length']  :   0;        
+        $this->options['expire']    =   isset($options['expire'])?  $options['expire']  :   C('DATA_CACHE_TIME');
+    }
+
+    /**
+     * 读取缓存
+     * @access public
+     * @param string $name 缓存变量名
+     * @return mixed
+     */
+     public function get($name) {
+        N('cache_read',1);
+         return apc_fetch($this->options['prefix'].$name);
+     }
+
+    /**
+     * 写入缓存
+     * @access public
+     * @param string $name 缓存变量名
+     * @param mixed $value  存储数据
+     * @param integer $expire  有效时间(秒)
+     * @return boolean
+     */
+     public function set($name, $value, $expire = null) {
+        N('cache_write',1);
+        if(is_null($expire)) {
+            $expire  =  $this->options['expire'];
+        }
+        $name   =   $this->options['prefix'].$name;
+        if($result = apc_store($name, $value, $expire)) {
+            if($this->options['length']>0) {
+                // 记录缓存队列
+                $this->queue($name);
+            }
+        }
+        return $result;
+     }
+
+    /**
+     * 删除缓存
+     * @access public
+     * @param string $name 缓存变量名
+     * @return boolean
+     */
+     public function rm($name) {
+         return apc_delete($this->options['prefix'].$name);
+     }
+
+    /**
+     * 清除缓存
+     * @access public
+     * @return boolean
+     */
+    public function clear() {
+        return apc_clear_cache();
+    }
+
+}

+ 138 - 0
ThinkPHP/Library/Think/Cache/Driver/Db.class.php

@@ -0,0 +1,138 @@
+<?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 Think\Cache\Driver;
+use Think\Cache;
+defined('THINK_PATH') or exit();
+/**
+ * 数据库方式缓存驱动
+ *    CREATE TABLE think_cache (
+ *      cachekey varchar(255) NOT NULL,
+ *      expire int(11) NOT NULL,
+ *      data blob,
+ *      datacrc int(32),
+ *      UNIQUE KEY `cachekey` (`cachekey`)
+ *    );
+ */
+class Db extends Cache {
+
+    /**
+     * 架构函数
+     * @param array $options 缓存参数
+     * @access public
+     */
+    public function __construct($options=array()) {
+        if(empty($options)) {
+            $options = array (
+                'table'     =>  C('DATA_CACHE_TABLE'),
+            );
+        }
+        $this->options  =   $options;   
+        $this->options['prefix']    =   isset($options['prefix'])?  $options['prefix']  :   C('DATA_CACHE_PREFIX');
+        $this->options['length']    =   isset($options['length'])?  $options['length']  :   0;        
+        $this->options['expire']    =   isset($options['expire'])?  $options['expire']  :   C('DATA_CACHE_TIME');
+        $this->handler   = \Think\Db::getInstance();
+    }
+
+    /**
+     * 读取缓存
+     * @access public
+     * @param string $name 缓存变量名
+     * @return mixed
+     */
+    public function get($name) {
+        $name       =  $this->options['prefix'].addslashes($name);
+        N('cache_read',1);
+        $result     =  $this->handler->query('SELECT `data`,`datacrc` FROM `'.$this->options['table'].'` WHERE `cachekey`=\''.$name.'\' AND (`expire` =0 OR `expire`>'.time().') LIMIT 0,1');
+        if(false !== $result ) {
+            $result   =  $result[0];
+            if(C('DATA_CACHE_CHECK')) {//开启数据校验
+                if($result['datacrc'] != md5($result['data'])) {//校验错误
+                    return false;
+                }
+            }
+            $content   =  $result['data'];
+            if(C('DATA_CACHE_COMPRESS') && function_exists('gzcompress')) {
+                //启用数据压缩
+                $content   =   gzuncompress($content);
+            }
+            $content    =   unserialize($content);
+            return $content;
+        }
+        else {
+            return false;
+        }
+    }
+
+    /**
+     * 写入缓存
+     * @access public
+     * @param string $name 缓存变量名
+     * @param mixed $value  存储数据
+     * @param integer $expire  有效时间(秒)
+     * @return boolean
+     */
+    public function set($name, $value,$expire=null) {
+        $data   =  serialize($value);
+        $name   =  $this->options['prefix'].addslashes($name);
+        N('cache_write',1);
+        if( C('DATA_CACHE_COMPRESS') && function_exists('gzcompress')) {
+            //数据压缩
+            $data   =   gzcompress($data,3);
+        }
+        if(C('DATA_CACHE_CHECK')) {//开启数据校验
+            $crc  =  md5($data);
+        }else {
+            $crc  =  '';
+        }
+        if(is_null($expire)) {
+            $expire  =  $this->options['expire'];
+        }
+        $expire	    =   ($expire==0)?0: (time()+$expire) ;//缓存有效期为0表示永久缓存
+        $result     =   $this->handler->query('select `cachekey` from `'.$this->options['table'].'` where `cachekey`=\''.$name.'\' limit 0,1');
+        if(!empty($result) ) {
+        	//更新记录
+            $result  =  $this->handler->execute('UPDATE '.$this->options['table'].' SET data=\''.$data.'\' ,datacrc=\''.$crc.'\',expire='.$expire.' WHERE `cachekey`=\''.$name.'\'');
+        }else {
+        	//新增记录
+             $result  =  $this->handler->execute('INSERT INTO '.$this->options['table'].' (`cachekey`,`data`,`datacrc`,`expire`) VALUES (\''.$name.'\',\''.$data.'\',\''.$crc.'\','.$expire.')');
+        }
+        if($result) {
+            if($this->options['length']>0) {
+                // 记录缓存队列
+                $this->queue($name);
+            }
+            return true;
+        }else {
+            return false;
+        }
+    }
+
+    /**
+     * 删除缓存
+     * @access public
+     * @param string $name 缓存变量名
+     * @return boolean
+     */
+    public function rm($name) {
+        $name  =  $this->options['prefix'].addslashes($name);
+        return $this->handler->execute('DELETE FROM `'.$this->options['table'].'` WHERE `cachekey`=\''.$name.'\'');
+    }
+
+    /**
+     * 清除缓存
+     * @access public
+     * @return boolean
+     */
+    public function clear() {
+        return $this->handler->execute('TRUNCATE TABLE `'.$this->options['table'].'`');
+    }
+
+}

+ 77 - 0
ThinkPHP/Library/Think/Cache/Driver/Eaccelerator.class.php

@@ -0,0 +1,77 @@
+<?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 Think\Cache\Driver;
+use Think\Cache;
+defined('THINK_PATH') or exit();
+/**
+ * Eaccelerator缓存驱动
+ */
+class Eaccelerator extends Cache {
+
+    /**
+     * 架构函数
+     * @param array $options 缓存参数
+     * @access public
+     */
+    public function __construct($options=array()) {
+        $this->options['expire'] =  isset($options['expire'])?  $options['expire']  :   C('DATA_CACHE_TIME');
+        $this->options['prefix'] =  isset($options['prefix'])?  $options['prefix']  :   C('DATA_CACHE_PREFIX');        
+        $this->options['length'] =  isset($options['length'])?  $options['length']  :   0;
+    }
+
+    /**
+     * 读取缓存
+     * @access public
+     * @param string $name 缓存变量名
+     * @return mixed
+     */
+     public function get($name) {
+        N('cache_read',1);
+         return eaccelerator_get($this->options['prefix'].$name);
+     }
+
+    /**
+     * 写入缓存
+     * @access public
+     * @param string $name 缓存变量名
+     * @param mixed $value  存储数据
+     * @param integer $expire  有效时间(秒)
+     * @return boolean
+     */
+     public function set($name, $value, $expire = null) {
+        N('cache_write',1);
+        if(is_null($expire)) {
+            $expire  =  $this->options['expire'];
+        }
+        $name   =   $this->options['prefix'].$name;
+        eaccelerator_lock($name);
+        if(eaccelerator_put($name, $value, $expire)) {
+            if($this->options['length']>0) {
+                // 记录缓存队列
+                $this->queue($name);
+            }
+            return true;
+        }
+        return false;
+     }
+
+
+    /**
+     * 删除缓存
+     * @access public
+     * @param string $name 缓存变量名
+     * @return boolean
+     */
+     public function rm($name) {
+         return eaccelerator_rm($this->options['prefix'].$name);
+     }
+
+}

+ 181 - 0
ThinkPHP/Library/Think/Cache/Driver/File.class.php

@@ -0,0 +1,181 @@
+<?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 Think\Cache\Driver;
+use Think\Cache;
+defined('THINK_PATH') or exit();
+/**
+ * 文件类型缓存类
+ */
+class File extends Cache {
+
+    /**
+     * 架构函数
+     * @access public
+     */
+    public function __construct($options=array()) {
+        if(!empty($options)) {
+            $this->options =  $options;
+        }
+        $this->options['temp']      =   !empty($options['temp'])?   $options['temp']    :   C('DATA_CACHE_PATH');
+        $this->options['prefix']    =   isset($options['prefix'])?  $options['prefix']  :   C('DATA_CACHE_PREFIX');
+        $this->options['expire']    =   isset($options['expire'])?  $options['expire']  :   C('DATA_CACHE_TIME');
+        $this->options['length']    =   isset($options['length'])?  $options['length']  :   0;
+        if(substr($this->options['temp'], -1) != '/')    $this->options['temp'] .= '/';
+        $this->init();
+    }
+
+    /**
+     * 初始化检查
+     * @access private
+     * @return boolean
+     */
+    private function init() {
+        // 创建应用缓存目录
+        if (!is_dir($this->options['temp'])) {
+            mkdir($this->options['temp']);
+        }
+    }
+
+    /**
+     * 取得变量的存储文件名
+     * @access private
+     * @param string $name 缓存变量名
+     * @return string
+     */
+    private function filename($name) {
+        $name	=	md5(C('DATA_CACHE_KEY').$name);
+        if(C('DATA_CACHE_SUBDIR')) {
+            // 使用子目录
+            $dir   ='';
+            for($i=0;$i<C('DATA_PATH_LEVEL');$i++) {
+                $dir	.=	$name{$i}.'/';
+            }
+            if(!is_dir($this->options['temp'].$dir)) {
+                mkdir($this->options['temp'].$dir,0755,true);
+            }
+            $filename	=	$dir.$this->options['prefix'].$name.'.php';
+        }else{
+            $filename	=	$this->options['prefix'].$name.'.php';
+        }
+        return $this->options['temp'].$filename;
+    }
+
+    /**
+     * 读取缓存
+     * @access public
+     * @param string $name 缓存变量名
+     * @return mixed
+     */
+    public function get($name) {
+        $filename   =   $this->filename($name);
+        if (!is_file($filename)) {
+           return false;
+        }
+        N('cache_read',1);
+        $content    =   file_get_contents($filename);
+        if( false !== $content) {
+            $expire  =  (int)substr($content,8, 12);
+            if($expire != 0 && time() > filemtime($filename) + $expire) {
+                //缓存过期删除缓存文件
+                unlink($filename);
+                return false;
+            }
+            if(C('DATA_CACHE_CHECK')) {//开启数据校验
+                $check  =  substr($content,20, 32);
+                $content   =  substr($content,52, -3);
+                if($check != md5($content)) {//校验错误
+                    return false;
+                }
+            }else {
+            	$content   =  substr($content,20, -3);
+            }
+            if(C('DATA_CACHE_COMPRESS') && function_exists('gzcompress')) {
+                //启用数据压缩
+                $content   =   gzuncompress($content);
+            }
+            $content    =   unserialize($content);
+            return $content;
+        }
+        else {
+            return false;
+        }
+    }
+
+    /**
+     * 写入缓存
+     * @access public
+     * @param string $name 缓存变量名
+     * @param mixed $value  存储数据
+     * @param int $expire  有效时间 0为永久
+     * @return boolean
+     */
+    public function set($name,$value,$expire=null) {
+        N('cache_write',1);
+        if(is_null($expire)) {
+            $expire =  $this->options['expire'];
+        }
+        $filename   =   $this->filename($name);
+        $data   =   serialize($value);
+        if( C('DATA_CACHE_COMPRESS') && function_exists('gzcompress')) {
+            //数据压缩
+            $data   =   gzcompress($data,3);
+        }
+        if(C('DATA_CACHE_CHECK')) {//开启数据校验
+            $check  =  md5($data);
+        }else {
+            $check  =  '';
+        }
+        $data    = "<?php\n//".sprintf('%012d',$expire).$check.$data."\n?>";
+        $result  =   file_put_contents($filename,$data);
+        if($result) {
+            if($this->options['length']>0) {
+                // 记录缓存队列
+                $this->queue($name);
+            }
+            clearstatcache();
+            return true;
+        }else {
+            return false;
+        }
+    }
+
+    /**
+     * 删除缓存
+     * @access public
+     * @param string $name 缓存变量名
+     * @return boolean
+     */
+    public function rm($name) {
+        return unlink($this->filename($name));
+    }
+
+    /**
+     * 清除缓存
+     * @access public
+     * @param string $name 缓存变量名
+     * @return boolean
+     */
+    public function clear() {
+        $path   =  $this->options['temp'];
+        $files  =   scandir($path);
+        if($files){
+            foreach($files as $file){
+                if ($file != '.' && $file != '..' && is_dir($path.$file) ){
+                    array_map( 'unlink', glob( $path.$file.'/*.*' ) );
+                }elseif(is_file($path.$file)){
+                    unlink( $path . $file );
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+}

+ 103 - 0
ThinkPHP/Library/Think/Cache/Driver/Memcache.class.php

@@ -0,0 +1,103 @@
+<?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 Think\Cache\Driver;
+use Think\Cache;
+defined('THINK_PATH') or exit();
+/**
+ * Memcache缓存驱动
+ */
+class Memcache extends Cache {
+
+    /**
+     * 架构函数
+     * @param array $options 缓存参数
+     * @access public
+     */
+    function __construct($options=array()) {
+        if ( !extension_loaded('memcache') ) {
+            E(L('_NOT_SUPPORT_').':memcache');
+        }
+
+        $options = array_merge(array (
+            'host'        =>  C('MEMCACHE_HOST') ? : '127.0.0.1',
+            'port'        =>  C('MEMCACHE_PORT') ? : 11211,
+            'timeout'     =>  C('DATA_CACHE_TIMEOUT') ? : false,
+            'persistent'  =>  false,
+        ),$options);
+
+        $this->options      =   $options;
+        $this->options['expire'] =  isset($options['expire'])?  $options['expire']  :   C('DATA_CACHE_TIME');
+        $this->options['prefix'] =  isset($options['prefix'])?  $options['prefix']  :   C('DATA_CACHE_PREFIX');        
+        $this->options['length'] =  isset($options['length'])?  $options['length']  :   0;        
+        $func               =   $options['persistent'] ? 'pconnect' : 'connect';
+        $this->handler      =   new \Memcache;
+        $options['timeout'] === false ?
+            $this->handler->$func($options['host'], $options['port']) :
+            $this->handler->$func($options['host'], $options['port'], $options['timeout']);
+    }
+
+    /**
+     * 读取缓存
+     * @access public
+     * @param string $name 缓存变量名
+     * @return mixed
+     */
+    public function get($name) {
+        N('cache_read',1);
+        return $this->handler->get($this->options['prefix'].$name);
+    }
+
+    /**
+     * 写入缓存
+     * @access public
+     * @param string $name 缓存变量名
+     * @param mixed $value  存储数据
+     * @param integer $expire  有效时间(秒)
+     * @return boolean
+     */
+    public function set($name, $value, $expire = null) {
+        N('cache_write',1);
+        if(is_null($expire)) {
+            $expire  =  $this->options['expire'];
+        }
+        $name   =   $this->options['prefix'].$name;
+        if($this->handler->set($name, $value, 0, $expire)) {
+            if($this->options['length']>0) {
+                // 记录缓存队列
+                $this->queue($name);
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * 删除缓存
+     * @access public
+     * @param string $name 缓存变量名
+     * @return boolean
+     */
+    public function rm($name, $ttl = false) {
+        $name   =   $this->options['prefix'].$name;
+        return $ttl === false ?
+            $this->handler->delete($name) :
+            $this->handler->delete($name, $ttl);
+    }
+
+    /**
+     * 清除缓存
+     * @access public
+     * @return boolean
+     */
+    public function clear() {
+        return $this->handler->flush();
+    }
+}

+ 102 - 0
ThinkPHP/Library/Think/Cache/Driver/Memcached.class.php

@@ -0,0 +1,102 @@
+<?php
+// +----------------------------------------------------------------------
+// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2006-2013 http://thinkphp.cn All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+// +----------------------------------------------------------------------
+// | Author: 何辉 <runphp@qq.com>
+// +----------------------------------------------------------------------
+
+namespace Think\Cache\Driver;
+
+use Memcached as MemcachedResource;
+use Think\Cache;
+
+/**
+ * Memcached缓存驱动
+ */
+class Memcached extends Cache {
+
+    /**
+     *
+     * @param array $options
+     */
+    public function __construct($options = array()) {
+        if ( !extension_loaded('memcached') ) {
+            E(L('_NOT_SUPPORT_').':memcached');
+        }
+
+        $options = array_merge(array(
+            'servers'       =>  C('MEMCACHED_SERVER') ? : null,
+            'lib_options'   =>  C('MEMCACHED_LIB') ? : null
+        ), $options);
+
+        $this->options      =   $options;
+        $this->options['expire'] =  isset($options['expire'])?  $options['expire']  :   C('DATA_CACHE_TIME');
+        $this->options['prefix'] =  isset($options['prefix'])?  $options['prefix']  :   C('DATA_CACHE_PREFIX');
+        $this->options['length'] =  isset($options['length'])?  $options['length']  :   0;
+
+        $this->handler      =   new MemcachedResource;
+        $options['servers'] && $this->handler->addServers($options['servers']);
+        $options['lib_options'] && $this->handler->setOptions($options['lib_options']);
+    }
+
+    /**
+     * 读取缓存
+     * @access public
+     * @param string $name 缓存变量名
+     * @return mixed
+     */
+    public function get($name) {
+        N('cache_read',1);
+        return $this->handler->get($this->options['prefix'].$name);
+    }
+
+    /**
+     * 写入缓存
+     * @access public
+     * @param string $name 缓存变量名
+     * @param mixed $value  存储数据
+     * @param integer $expire  有效时间(秒)
+     * @return boolean
+     */
+    public function set($name, $value, $expire = null) {
+        N('cache_write',1);
+        if(is_null($expire)) {
+            $expire  =  $this->options['expire'];
+        }
+        $name   =   $this->options['prefix'].$name;
+        if($this->handler->set($name, $value, time() + $expire)) {
+            if($this->options['length']>0) {
+                // 记录缓存队列
+                $this->queue($name);
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * 删除缓存
+     * @access public
+     * @param string $name 缓存变量名
+     * @return boolean
+     */
+    public function rm($name, $ttl = false) {
+        $name   =   $this->options['prefix'].$name;
+        return $ttl === false ?
+        $this->handler->delete($name) :
+        $this->handler->delete($name, $ttl);
+    }
+
+    /**
+     * 清除缓存
+     * @access public
+     * @return boolean
+     */
+    public function clear() {
+        return $this->handler->flush();
+    }
+}

+ 144 - 0
ThinkPHP/Library/Think/Cache/Driver/Memcachesae.class.php

@@ -0,0 +1,144 @@
+<?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 Think\Cache\Driver;
+use Think\Cache;
+
+defined('THINK_PATH') or exit();
+/**
+ * Memcache缓存驱动
+ * @category   Extend
+ * @package  Extend
+ * @subpackage  Driver.Cache
+ * @author    liu21st <liu21st@gmail.com>
+ */
+class Memcachesae extends Cache {
+
+    /**
+     * 架构函数
+     * @param array $options 缓存参数
+     * @access public
+     */
+    function __construct($options=array()) {
+        $options = array_merge(array (
+            'host'        =>  C('MEMCACHE_HOST') ? : '127.0.0.1',
+            'port'        =>  C('MEMCACHE_PORT') ? : 11211,
+            'timeout'     =>  C('DATA_CACHE_TIMEOUT') ? : false,
+            'persistent'  =>  false,
+        ),$options);
+
+        $this->options      =   $options;
+        $this->options['expire'] =  isset($options['expire'])?  $options['expire']  :   C('DATA_CACHE_TIME');
+        $this->options['prefix'] =  isset($options['prefix'])?  $options['prefix']  :   C('DATA_CACHE_PREFIX');
+        $this->options['length'] =  isset($options['length'])?  $options['length']  :   0;
+         $this->handler      =  memcache_init();//[sae] 下实例化
+        //[sae] 下不用链接
+        $this->connected=true;
+    }
+
+    /**
+     * 是否连接
+     * @access private
+     * @return boolean
+     */
+    private function isConnected() {
+        return $this->connected;
+    }
+
+    /**
+     * 读取缓存
+     * @access public
+     * @param string $name 缓存变量名
+     * @return mixed
+     */
+    public function get($name) {
+        N('cache_read',1);
+        return $this->handler->get($_SERVER['HTTP_APPVERSION'].'/'.$this->options['prefix'].$name);
+    }
+
+    /**
+     * 写入缓存
+     * @access public
+     * @param string $name 缓存变量名
+     * @param mixed $value  存储数据
+     * @param integer $expire  有效时间(秒)
+     * @return boolean
+     */
+    public function set($name, $value, $expire = null) {
+        N('cache_write',1);
+        if(is_null($expire)) {
+            $expire  =  $this->options['expire'];
+        }
+        $name   =   $this->options['prefix'].$name;
+        if($this->handler->set($_SERVER['HTTP_APPVERSION'].'/'.$name, $value, 0, $expire)) {
+            if($this->options['length']>0) {
+                // 记录缓存队列
+                $this->queue($name);
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * 删除缓存
+     * @access public
+     * @param string $name 缓存变量名
+     * @return boolean
+     */
+    public function rm($name, $ttl = false) {
+        $name   =   $_SERVER['HTTP_APPVERSION'].'/'.$this->options['prefix'].$name;
+        return $ttl === false ?
+            $this->handler->delete($name) :
+            $this->handler->delete($name, $ttl);
+    }
+
+    /**
+     * 清除缓存
+     * @access public
+     * @return boolean
+     */
+    public function clear() {
+        return $this->handler->flush();
+    }
+
+    /**
+     * 队列缓存
+     * @access protected
+     * @param string $key 队列名
+     * @return mixed
+     */
+    //[sae] 下重写queque队列缓存方法
+    protected function queue($key) {
+        $queue_name=isset($this->options['queue_name'])?$this->options['queue_name']:'think_queue';
+        $value  =  F($queue_name);
+        if(!$value) {
+            $value   =  array();
+        }
+        // 进列
+        if(false===array_search($key, $value)) array_push($value,$key);
+        if(count($value) > $this->options['length']) {
+            // 出列
+            $key =  array_shift($value);
+            // 删除缓存
+            $this->rm($key);
+            if (APP_DEBUG) {
+                    //调试模式下记录出队次数
+                        $counter = Think::instance('SaeCounter');
+                        if ($counter->exists($queue_name.'_out_times'))
+                            $counter->incr($queue_name.'_out_times');
+                        else
+                            $counter->create($queue_name.'_out_times', 1);
+           }
+        }
+        return F($queue_name,$value);
+    }
+
+}

+ 107 - 0
ThinkPHP/Library/Think/Cache/Driver/Redis.class.php

@@ -0,0 +1,107 @@
+<?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 Think\Cache\Driver;
+use Think\Cache;
+defined('THINK_PATH') or exit();
+
+/**
+ * Redis缓存驱动 
+ * 要求安装phpredis扩展:https://github.com/nicolasff/phpredis
+ */
+class Redis extends Cache {
+	 /**
+	 * 架构函数
+     * @param array $options 缓存参数
+     * @access public
+     */
+    public function __construct($options=array()) {
+        if ( !extension_loaded('redis') ) {
+            E(L('_NOT_SUPPORT_').':redis');
+        }
+        $options = array_merge(array (
+            'host'          => C('REDIS_HOST') ? : '127.0.0.1',
+            'port'          => C('REDIS_PORT') ? : 6379,
+            'timeout'       => C('DATA_CACHE_TIMEOUT') ? : false,
+            'persistent'    => false,
+        ),$options);
+
+        $this->options =  $options;
+        $this->options['expire'] =  isset($options['expire'])?  $options['expire']  :   C('DATA_CACHE_TIME');
+        $this->options['prefix'] =  isset($options['prefix'])?  $options['prefix']  :   C('DATA_CACHE_PREFIX');        
+        $this->options['length'] =  isset($options['length'])?  $options['length']  :   0;        
+        $func = $options['persistent'] ? 'pconnect' : 'connect';
+        $this->handler  = new \Redis;
+        $options['timeout'] === false ?
+            $this->handler->$func($options['host'], $options['port']) :
+            $this->handler->$func($options['host'], $options['port'], $options['timeout']);
+    }
+
+    /**
+     * 读取缓存
+     * @access public
+     * @param string $name 缓存变量名
+     * @return mixed
+     */
+    public function get($name) {
+        N('cache_read',1);
+        $value = $this->handler->get($this->options['prefix'].$name);
+        $jsonData  = json_decode( $value, true );
+        return ($jsonData === NULL) ? $value : $jsonData;	//检测是否为JSON数据 true 返回JSON解析数组, false返回源数据
+    }
+
+    /**
+     * 写入缓存
+     * @access public
+     * @param string $name 缓存变量名
+     * @param mixed $value  存储数据
+     * @param integer $expire  有效时间(秒)
+     * @return boolean
+     */
+    public function set($name, $value, $expire = null) {
+        N('cache_write',1);
+        if(is_null($expire)) {
+            $expire  =  $this->options['expire'];
+        }
+        $name   =   $this->options['prefix'].$name;
+        //对数组/对象数据进行缓存处理,保证数据完整性
+        $value  =  (is_object($value) || is_array($value)) ? json_encode($value) : $value;
+        if(is_int($expire) && $expire) {
+            $result = $this->handler->setex($name, $expire, $value);
+        }else{
+            $result = $this->handler->set($name, $value);
+        }
+        if($result && $this->options['length']>0) {
+            // 记录缓存队列
+            $this->queue($name);
+        }
+        return $result;
+    }
+
+    /**
+     * 删除缓存
+     * @access public
+     * @param string $name 缓存变量名
+     * @return boolean
+     */
+    public function rm($name) {
+        return $this->handler->delete($this->options['prefix'].$name);
+    }
+
+    /**
+     * 清除缓存
+     * @access public
+     * @return boolean
+     */
+    public function clear() {
+        return $this->handler->flushDB();
+    }
+
+}

+ 186 - 0
ThinkPHP/Library/Think/Cache/Driver/Shmop.class.php

@@ -0,0 +1,186 @@
+<?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 Think\Cache\Driver;
+use Think\Cache;
+defined('THINK_PATH') or exit();
+/**
+ * Shmop缓存驱动 
+ */
+class Shmop extends Cache {
+
+    /**
+     * 架构函数
+     * @param array $options 缓存参数
+     * @access public
+     */
+    public function __construct($options=array()) {
+        if ( !extension_loaded('shmop') ) {
+            E(L('_NOT_SUPPORT_').':shmop');
+        }
+        if(!empty($options)){
+            $options = array(
+                'size'      => C('SHARE_MEM_SIZE'),
+                'temp'      => TEMP_PATH,
+                'project'   => 's',
+                'length'    =>  0,
+                );
+        }
+        $this->options = $options;
+        $this->options['prefix'] =  isset($options['prefix'])?  $options['prefix']  :   C('DATA_CACHE_PREFIX');        
+        $this->options['length'] =  isset($options['length'])?  $options['length']  :   0;        
+        $this->handler = $this->_ftok($this->options['project']);
+    }
+
+    /**
+     * 读取缓存
+     * @access public
+     * @param string $name 缓存变量名
+     * @return mixed
+     */
+    public function get($name = false) {
+        N('cache_read',1);
+        $id = shmop_open($this->handler, 'c', 0600, 0);
+        if ($id !== false) {
+            $ret = unserialize(shmop_read($id, 0, shmop_size($id)));
+            shmop_close($id);
+
+            if ($name === false) {
+                return $ret;
+            }
+            $name   =   $this->options['prefix'].$name;
+            if(isset($ret[$name])) {
+                $content   =  $ret[$name];
+                if(C('DATA_CACHE_COMPRESS') && function_exists('gzcompress')) {
+                    //启用数据压缩
+                    $content   =   gzuncompress($content);
+                }
+                return $content;
+            }else {
+                return null;
+            }
+        }else {
+            return false;
+        }
+    }
+
+    /**
+     * 写入缓存
+     * @access public
+     * @param string $name 缓存变量名
+     * @param mixed $value  存储数据
+     * @return boolean
+     */
+    public function set($name, $value) {
+        N('cache_write',1);
+        $lh = $this->_lock();
+        $val = $this->get();
+        if (!is_array($val)) $val = array();
+        if( C('DATA_CACHE_COMPRESS') && function_exists('gzcompress')) {
+            //数据压缩
+            $value   =   gzcompress($value,3);
+        }
+        $name   =   $this->options['prefix'].$name;
+        $val[$name] = $value;
+        $val = serialize($val);
+        if($this->_write($val, $lh)) {
+            if($this->options['length']>0) {
+                // 记录缓存队列
+                $this->queue($name);
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * 删除缓存
+     * @access public
+     * @param string $name 缓存变量名
+     * @return boolean
+     */
+    public function rm($name) {
+        $lh = $this->_lock();
+        $val = $this->get();
+        if (!is_array($val)) $val = array();
+        $name   =   $this->options['prefix'].$name;
+        unset($val[$name]);
+        $val = serialize($val);
+        return $this->_write($val, $lh);
+    }
+
+    /**
+     * 生成IPC key
+     * @access private
+     * @param string $project 项目标识名
+     * @return integer
+     */
+    private function _ftok($project) {
+        if (function_exists('ftok'))   return ftok(__FILE__, $project);
+        if(strtoupper(PHP_OS) == 'WINNT'){
+            $s = stat(__FILE__);
+            return sprintf("%u", (($s['ino'] & 0xffff) | (($s['dev'] & 0xff) << 16) |
+            (($project & 0xff) << 24)));
+        }else {
+            $filename = __FILE__ . (string) $project;
+            for($key = array(); sizeof($key) < strlen($filename); $key[] = ord(substr($filename, sizeof($key), 1)));
+            return dechex(array_sum($key));
+        }
+    }
+
+    /**
+     * 写入操作
+     * @access private
+     * @param string $name 缓存变量名
+     * @return integer|boolean
+     */
+    private function _write(&$val, &$lh) {
+        $id  = shmop_open($this->handler, 'c', 0600, $this->options['size']);
+        if ($id) {
+           $ret = shmop_write($id, $val, 0) == strlen($val);
+           shmop_close($id);
+           $this->_unlock($lh);
+           return $ret;
+        }
+        $this->_unlock($lh);
+        return false;
+    }
+
+    /**
+     * 共享锁定
+     * @access private
+     * @param string $name 缓存变量名
+     * @return boolean
+     */
+    private function _lock() {
+        if (function_exists('sem_get')) {
+            $fp = sem_get($this->handler, 1, 0600, 1);
+            sem_acquire ($fp);
+        } else {
+            $fp = fopen($this->options['temp'].$this->options['prefix'].md5($this->handler), 'w');
+            flock($fp, LOCK_EX);
+        }
+        return $fp;
+    }
+
+    /**
+     * 解除共享锁定
+     * @access private
+     * @param string $name 缓存变量名
+     * @return boolean
+     */
+    private function _unlock(&$fp) {
+        if (function_exists('sem_release')) {
+            sem_release($fp);
+        } else {
+            fclose($fp);
+        }
+    }
+}

+ 119 - 0
ThinkPHP/Library/Think/Cache/Driver/Sqlite.class.php

@@ -0,0 +1,119 @@
+<?php
+// +----------------------------------------------------------------------
+// | ThinkPHP [ WE CAN DO IT JUST THINK ]
+// +----------------------------------------------------------------------
+// | 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 Think\Cache\Driver;
+use Think\Cache;
+defined('THINK_PATH') or exit();
+/**
+ * Sqlite缓存驱动
+ */
+class Sqlite extends Cache {
+
+    /**
+     * 架构函数
+     * @param array $options 缓存参数
+     * @access public
+     */
+    public function __construct($options=array()) {
+        if ( !extension_loaded('sqlite') ) {
+            E(L('_NOT_SUPPORT_').':sqlite');
+        }
+        if(empty($options)) {
+            $options = array (
+                'db'        =>  ':memory:',
+                'table'     =>  'sharedmemory',
+            );
+        }
+        $this->options  =   $options;      
+        $this->options['prefix']    =   isset($options['prefix'])?  $options['prefix']  :   C('DATA_CACHE_PREFIX');
+        $this->options['length']    =   isset($options['length'])?  $options['length']  :   0;        
+        $this->options['expire']    =   isset($options['expire'])?  $options['expire']  :   C('DATA_CACHE_TIME');
+        
+        $func = $this->options['persistent'] ? 'sqlite_popen' : 'sqlite_open';
+        $this->handler      = $func($this->options['db']);
+    }
+
+    /**
+     * 读取缓存
+     * @access public
+     * @param string $name 缓存变量名
+     * @return mixed
+     */
+    public function get($name) {
+        N('cache_read',1);
+		$name   = $this->options['prefix'].sqlite_escape_string($name);
+        $sql    = 'SELECT value FROM '.$this->options['table'].' WHERE var=\''.$name.'\' AND (expire=0 OR expire >'.time().') LIMIT 1';
+        $result = sqlite_query($this->handler, $sql);
+        if (sqlite_num_rows($result)) {
+            $content   =  sqlite_fetch_single($result);
+            if(C('DATA_CACHE_COMPRESS') && function_exists('gzcompress')) {
+                //启用数据压缩
+                $content   =   gzuncompress($content);
+            }
+            return unserialize($content);
+        }
+        return false;
+    }
+
+    /**
+     * 写入缓存
+     * @access public
+     * @param string $name 缓存变量名
+     * @param mixed $value  存储数据
+     * @param integer $expire  有效时间(秒)
+     * @return boolean
+     */
+    public function set($name, $value,$expire=null) {
+        N('cache_write',1);
+        $name  = $this->options['prefix'].sqlite_escape_string($name);
+        $value = sqlite_escape_string(serialize($value));
+        if(is_null($expire)) {
+            $expire  =  $this->options['expire'];
+        }
+        $expire	=	($expire==0)?0: (time()+$expire) ;//缓存有效期为0表示永久缓存
+        if( C('DATA_CACHE_COMPRESS') && function_exists('gzcompress')) {
+            //数据压缩
+            $value   =   gzcompress($value,3);
+        }
+        $sql  = 'REPLACE INTO '.$this->options['table'].' (var, value,expire) VALUES (\''.$name.'\', \''.$value.'\', \''.$expire.'\')';
+        if(sqlite_query($this->handler, $sql)){
+            if($this->options['length']>0) {
+                // 记录缓存队列
+                $this->queue($name);
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * 删除缓存
+     * @access public
+     * @param string $name 缓存变量名
+     * @return boolean
+     */
+    public function rm($name) {
+        $name  = $this->options['prefix'].sqlite_escape_string($name);
+        $sql  = 'DELETE FROM '.$this->options['table'].' WHERE var=\''.$name.'\'';
+        sqlite_query($this->handler, $sql);
+        return true;
+    }
+
+    /**
+     * 清除缓存
+     * @access public
+     * @return boolean
+     */
+    public function clear() {
+        $sql  = 'DELETE FROM '.$this->options['table'];
+        sqlite_query($this->handler, $sql);
+        return ;
+    }
+}

+ 88 - 0
ThinkPHP/Library/Think/Cache/Driver/Wincache.class.php

@@ -0,0 +1,88 @@
+<?php
+// +----------------------------------------------------------------------
+// | ThinkPHP [ WE CAN DO IT JUST THINK ]
+// +----------------------------------------------------------------------
+// | 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 Think\Cache\Driver;
+use Think\Cache;
+defined('THINK_PATH') or exit();
+/**
+ * Wincache缓存驱动
+ */
+class Wincache extends Cache {
+
+    /**
+     * 架构函数
+     * @param array $options 缓存参数
+     * @access public
+     */
+    public function __construct($options=array()) {
+        if ( !function_exists('wincache_ucache_info') ) {
+            E(L('_NOT_SUPPORT_').':WinCache');
+        }
+        $this->options['expire']    =   isset($options['expire'])?  $options['expire']  :   C('DATA_CACHE_TIME');
+        $this->options['prefix']    =   isset($options['prefix'])?  $options['prefix']  :   C('DATA_CACHE_PREFIX');
+        $this->options['length']    =   isset($options['length'])?  $options['length']  :   0;
+    }
+
+    /**
+     * 读取缓存
+     * @access public
+     * @param string $name 缓存变量名
+     * @return mixed
+     */
+    public function get($name) {
+        N('cache_read',1);
+        $name   =   $this->options['prefix'].$name;
+        return wincache_ucache_exists($name)? wincache_ucache_get($name) : false;
+    }
+
+    /**
+     * 写入缓存
+     * @access public
+     * @param string $name 缓存变量名
+     * @param mixed $value  存储数据
+     * @param integer $expire  有效时间(秒)
+     * @return boolean
+     */
+    public function set($name, $value,$expire=null) {
+        N('cache_write',1);
+        if(is_null($expire)) {
+            $expire  =  $this->options['expire'];
+        }
+        $name   =   $this->options['prefix'].$name;
+        if(wincache_ucache_set($name, $value, $expire)) {
+            if($this->options['length']>0) {
+                // 记录缓存队列
+                $this->queue($name);
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * 删除缓存
+     * @access public
+     * @param string $name 缓存变量名
+     * @return boolean
+     */
+    public function rm($name) {
+        return wincache_ucache_delete($this->options['prefix'].$name);
+    }
+
+    /**
+     * 清除缓存
+     * @access public
+     * @return boolean
+     */
+    public function clear() {
+        return wincache_ucache_clear();
+    }    
+
+}

+ 90 - 0
ThinkPHP/Library/Think/Cache/Driver/Xcache.class.php

@@ -0,0 +1,90 @@
+<?php
+// +----------------------------------------------------------------------
+// | ThinkPHP [ WE CAN DO IT JUST THINK ]
+// +----------------------------------------------------------------------
+// | 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 Think\Cache\Driver;
+use Think\Cache;
+defined('THINK_PATH') or exit();
+/**
+ * Xcache缓存驱动
+ */
+class Xcache extends Cache {
+
+    /**
+     * 架构函数
+     * @param array $options 缓存参数
+     * @access public
+     */
+    public function __construct($options=array()) {
+        if ( !function_exists('xcache_info') ) {
+            E(L('_NOT_SUPPORT_').':Xcache');
+        }
+        $this->options['expire']    =   isset($options['expire'])?$options['expire']:C('DATA_CACHE_TIME');
+        $this->options['prefix']    =   isset($options['prefix'])?$options['prefix']:C('DATA_CACHE_PREFIX');
+        $this->options['length']    =   isset($options['length'])?$options['length']:0;
+    }
+
+    /**
+     * 读取缓存
+     * @access public
+     * @param string $name 缓存变量名
+     * @return mixed
+     */
+    public function get($name) {
+        N('cache_read',1);
+        $name   =   $this->options['prefix'].$name;
+        if (xcache_isset($name)) {
+            return xcache_get($name);
+        }
+        return false;
+    }
+
+    /**
+     * 写入缓存
+     * @access public
+     * @param string $name 缓存变量名
+     * @param mixed $value  存储数据
+     * @param integer $expire  有效时间(秒)
+     * @return boolean
+     */
+    public function set($name, $value,$expire=null) {
+        N('cache_write',1);
+        if(is_null($expire)) {
+            $expire = $this->options['expire'] ;
+        }
+        $name   =   $this->options['prefix'].$name;
+        if(xcache_set($name, $value, $expire)) {
+            if($this->options['length']>0) {
+                // 记录缓存队列
+                $this->queue($name);
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * 删除缓存
+     * @access public
+     * @param string $name 缓存变量名
+     * @return boolean
+     */
+    public function rm($name) {
+        return xcache_unset($this->options['prefix'].$name);
+    }
+
+    /**
+     * 清除缓存
+     * @access public
+     * @return boolean
+     */
+    public function clear() {
+        return xcache_clear_cache(1, -1);
+    }
+}

+ 307 - 0
ThinkPHP/Library/Think/Controller.class.php

@@ -0,0 +1,307 @@
+<?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 Think;
+/**
+ * ThinkPHP 控制器基类 抽象类
+ */
+abstract class Controller {
+
+    /**
+     * 视图实例对象
+     * @var view
+     * @access protected
+     */    
+    protected $view     =  null;
+
+    /**
+     * 控制器参数
+     * @var config
+     * @access protected
+     */      
+    protected $config   =   array();
+
+   /**
+     * 架构函数 取得模板对象实例
+     * @access public
+     */
+    public function __construct() {
+        Hook::listen('action_begin',$this->config);
+        //实例化视图类
+        $this->view     = Think::instance('Think\View');
+        //控制器初始化
+        if(method_exists($this,'_initialize'))
+            $this->_initialize();
+    }
+
+    /**
+     * 模板显示 调用内置的模板引擎显示方法,
+     * @access protected
+     * @param string $templateFile 指定要调用的模板文件
+     * 默认为空 由系统自动定位模板文件
+     * @param string $charset 输出编码
+     * @param string $contentType 输出类型
+     * @param string $content 输出内容
+     * @param string $prefix 模板缓存前缀
+     * @return void
+     */
+    protected function display($templateFile='',$charset='',$contentType='',$content='',$prefix='') {
+        $this->view->display($templateFile,$charset,$contentType,$content,$prefix);
+    }
+
+    /**
+     * 输出内容文本可以包括Html 并支持内容解析
+     * @access protected
+     * @param string $content 输出内容
+     * @param string $charset 模板输出字符集
+     * @param string $contentType 输出类型
+     * @param string $prefix 模板缓存前缀
+     * @return mixed
+     */
+    protected function show($content,$charset='',$contentType='',$prefix='') {
+        $this->view->display('',$charset,$contentType,$content,$prefix);
+    }
+
+    /**
+     *  获取输出页面内容
+     * 调用内置的模板引擎fetch方法,
+     * @access protected
+     * @param string $templateFile 指定要调用的模板文件
+     * 默认为空 由系统自动定位模板文件
+     * @param string $content 模板输出内容
+     * @param string $prefix 模板缓存前缀* 
+     * @return string
+     */
+    protected function fetch($templateFile='',$content='',$prefix='') {
+        return $this->view->fetch($templateFile,$content,$prefix);
+    }
+
+    /**
+     *  创建静态页面
+     * @access protected
+     * @htmlfile 生成的静态文件名称
+     * @htmlpath 生成的静态文件路径
+     * @param string $templateFile 指定要调用的模板文件
+     * 默认为空 由系统自动定位模板文件
+     * @return string
+     */
+    protected function buildHtml($htmlfile='',$htmlpath='',$templateFile='') {
+        $content    =   $this->fetch($templateFile);
+        $htmlpath   =   !empty($htmlpath)?$htmlpath:HTML_PATH;
+        $htmlfile   =   $htmlpath.$htmlfile.C('HTML_FILE_SUFFIX');
+        Storage::put($htmlfile,$content,'html');
+        return $content;
+    }
+
+    /**
+     * 模板主题设置
+     * @access protected
+     * @param string $theme 模版主题
+     * @return Action
+     */
+    protected function theme($theme){
+        $this->view->theme($theme);
+        return $this;
+    }
+
+    /**
+     * 模板变量赋值
+     * @access protected
+     * @param mixed $name 要显示的模板变量
+     * @param mixed $value 变量的值
+     * @return Action
+     */
+    protected function assign($name,$value='') {
+        $this->view->assign($name,$value);
+        return $this;
+    }
+
+    public function __set($name,$value) {
+        $this->assign($name,$value);
+    }
+
+    /**
+     * 取得模板显示变量的值
+     * @access protected
+     * @param string $name 模板显示变量
+     * @return mixed
+     */
+    public function get($name='') {
+        return $this->view->get($name);      
+    }
+
+    public function __get($name) {
+        return $this->get($name);
+    }
+
+    /**
+     * 检测模板变量的值
+     * @access public
+     * @param string $name 名称
+     * @return boolean
+     */
+    public function __isset($name) {
+        return $this->get($name);
+    }
+
+    /**
+     * 魔术方法 有不存在的操作的时候执行
+     * @access public
+     * @param string $method 方法名
+     * @param array $args 参数
+     * @return mixed
+     */
+    public function __call($method,$args) {
+        if( 0 === strcasecmp($method,ACTION_NAME.C('ACTION_SUFFIX'))) {
+            if(method_exists($this,'_empty')) {
+                // 如果定义了_empty操作 则调用
+                $this->_empty($method,$args);
+            }elseif(file_exists_case($this->view->parseTemplate())){
+                // 检查是否存在默认模版 如果有直接输出模版
+                $this->display();
+            }else{
+                E(L('_ERROR_ACTION_').':'.ACTION_NAME);
+            }
+        }else{
+            E(__CLASS__.':'.$method.L('_METHOD_NOT_EXIST_'));
+            return;
+        }
+    }
+
+    /**
+     * 操作错误跳转的快捷方法
+     * @access protected
+     * @param string $message 错误信息
+     * @param string $jumpUrl 页面跳转地址
+     * @param mixed $ajax 是否为Ajax方式 当数字时指定跳转时间
+     * @return void
+     */
+    protected function error($message='',$jumpUrl='',$ajax=false) {
+        $this->dispatchJump($message,0,$jumpUrl,$ajax);
+    }
+
+    /**
+     * 操作成功跳转的快捷方法
+     * @access protected
+     * @param string $message 提示信息
+     * @param string $jumpUrl 页面跳转地址
+     * @param mixed $ajax 是否为Ajax方式 当数字时指定跳转时间
+     * @return void
+     */
+    protected function success($message='',$jumpUrl='',$ajax=false) {
+        $this->dispatchJump($message,1,$jumpUrl,$ajax);
+    }
+
+    /**
+     * Ajax方式返回数据到客户端
+     * @access protected
+     * @param mixed $data 要返回的数据
+     * @param String $type AJAX返回数据格式
+     * @param int $json_option 传递给json_encode的option参数
+     * @return void
+     */
+    protected function ajaxReturn($data,$type='',$json_option=0) {
+        if(empty($type)) $type  =   C('DEFAULT_AJAX_RETURN');
+        switch (strtoupper($type)){
+            case 'JSON' :
+                // 返回JSON数据格式到客户端 包含状态信息
+                header('Content-Type:application/json; charset=utf-8');
+                exit(json_encode($data,$json_option));
+            case 'XML'  :
+                // 返回xml格式数据
+                header('Content-Type:text/xml; charset=utf-8');
+                exit(xml_encode($data));
+            case 'JSONP':
+                // 返回JSON数据格式到客户端 包含状态信息
+                header('Content-Type:application/json; charset=utf-8');
+                $handler  =   isset($_GET[C('VAR_JSONP_HANDLER')]) ? $_GET[C('VAR_JSONP_HANDLER')] : C('DEFAULT_JSONP_HANDLER');
+                exit($handler.'('.json_encode($data,$json_option).');');  
+            case 'EVAL' :
+                // 返回可执行的js脚本
+                header('Content-Type:text/html; charset=utf-8');
+                exit($data);            
+            default     :
+                // 用于扩展其他返回格式数据
+                Hook::listen('ajax_return',$data);
+        }
+    }
+
+    /**
+     * Action跳转(URL重定向) 支持指定模块和延时跳转
+     * @access protected
+     * @param string $url 跳转的URL表达式
+     * @param array $params 其它URL参数
+     * @param integer $delay 延时跳转的时间 单位为秒
+     * @param string $msg 跳转提示信息
+     * @return void
+     */
+    protected function redirect($url,$params=array(),$delay=0,$msg='') {
+        $url    =   U($url,$params);
+        redirect($url,$delay,$msg);
+    }
+
+    /**
+     * 默认跳转操作 支持错误导向和正确跳转
+     * 调用模板显示 默认为public目录下面的success页面
+     * 提示页面为可配置 支持模板标签
+     * @param string $message 提示信息
+     * @param Boolean $status 状态
+     * @param string $jumpUrl 页面跳转地址
+     * @param mixed $ajax 是否为Ajax方式 当数字时指定跳转时间
+     * @access private
+     * @return void
+     */
+    private function dispatchJump($message,$status=1,$jumpUrl='',$ajax=false) {
+        if(true === $ajax || IS_AJAX) {// AJAX提交
+            $data           =   is_array($ajax)?$ajax:array();
+            $data['info']   =   $message;
+            $data['status'] =   $status;
+            $data['url']    =   $jumpUrl;
+            $this->ajaxReturn($data);
+        }
+        if(is_int($ajax)) $this->assign('waitSecond',$ajax);
+        if(!empty($jumpUrl)) $this->assign('jumpUrl',$jumpUrl);
+        // 提示标题
+        $this->assign('msgTitle',$status? L('_OPERATION_SUCCESS_') : L('_OPERATION_FAIL_'));
+        //如果设置了关闭窗口,则提示完毕后自动关闭窗口
+        if($this->get('closeWin'))    $this->assign('jumpUrl','javascript:window.close();');
+        $this->assign('status',$status);   // 状态
+        //保证输出不受静态缓存影响
+        C('HTML_CACHE_ON',false);
+        if($status) { //发送成功信息
+            $this->assign('message',$message);// 提示信息
+            // 成功操作后默认停留1秒
+            if(!isset($this->waitSecond))    $this->assign('waitSecond','1');
+            // 默认操作成功自动返回操作前页面
+            if(!isset($this->jumpUrl)) $this->assign("jumpUrl",$_SERVER["HTTP_REFERER"]);
+            $this->display(C('TMPL_ACTION_SUCCESS'));
+        }else{
+            $this->assign('error',$message);// 提示信息
+            //发生错误时候默认停留3秒
+            if(!isset($this->waitSecond))    $this->assign('waitSecond','3');
+            // 默认发生错误的话自动返回上页
+            if(!isset($this->jumpUrl)) $this->assign('jumpUrl',"javascript:history.back(-1);");
+            $this->display(C('TMPL_ACTION_ERROR'));
+            // 中止执行  避免出错后继续执行
+            exit ;
+        }
+    }
+
+   /**
+     * 析构方法
+     * @access public
+     */
+    public function __destruct() {
+        // 执行后续操作
+        Hook::listen('action_end');
+    }
+}
+// 设置控制器别名 便于升级
+class_alias('Think\Controller','Think\Action');

+ 61 - 0
ThinkPHP/Library/Think/Controller/HproseController.class.php

@@ -0,0 +1,61 @@
+<?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 Think\Controller;
+/**
+ * ThinkPHP Hprose控制器类
+ */
+class HproseController {
+
+    protected $allowMethodList  =   '';
+    protected $crossDomain      =   false;
+    protected $P3P              =   false;
+    protected $get              =   true;
+    protected $debug            =   false;
+
+   /**
+     * 架构函数
+     * @access public
+     */
+    public function __construct() {
+        //控制器初始化
+        if(method_exists($this,'_initialize'))
+            $this->_initialize();
+        //导入类库
+        Vendor('Hprose.HproseHttpServer');
+        //实例化HproseHttpServer
+        $server     =   new \HproseHttpServer();
+        if($this->allowMethodList){
+            $methods    =   $this->allowMethodList;
+        }else{
+            $methods    =   get_class_methods($this);
+            $methods    =   array_diff($methods,array('__construct','__call','_initialize'));   
+        }
+        $server->addMethods($methods,$this);
+        if(APP_DEBUG || $this->debug ) {
+            $server->setDebugEnabled(true);
+        }
+        // Hprose设置
+        $server->setCrossDomainEnabled($this->crossDomain);
+        $server->setP3PEnabled($this->P3P);
+        $server->setGetEnabled($this->get);
+        // 启动server
+        $server->start();
+    }
+
+    /**
+     * 魔术方法 有不存在的操作的时候执行
+     * @access public
+     * @param string $method 方法名
+     * @param array $args 参数
+     * @return mixed
+     */
+    public function __call($method,$args){}
+}

+ 39 - 0
ThinkPHP/Library/Think/Controller/JsonRpcController.class.php

@@ -0,0 +1,39 @@
+<?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 Think\Controller;
+/**
+ * ThinkPHP JsonRPC控制器类
+ */
+class JsonRpcController {
+
+   /**
+     * 架构函数
+     * @access public
+     */
+    public function __construct() {
+        //控制器初始化
+        if(method_exists($this,'_initialize'))
+            $this->_initialize();
+        //导入类库
+        Vendor('jsonRPC.jsonRPCServer');
+        // 启动server
+        \jsonRPCServer::handle($this);
+    }
+
+    /**
+     * 魔术方法 有不存在的操作的时候执行
+     * @access public
+     * @param string $method 方法名
+     * @param array $args 参数
+     * @return mixed
+     */
+    public function __call($method,$args){}
+}

+ 233 - 0
ThinkPHP/Library/Think/Controller/RestController.class.php

@@ -0,0 +1,233 @@
+<?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 Think\Controller;
+use Think\Controller;
+/**
+ * ThinkPHP REST控制器类
+ */
+class RestController extends Controller {
+    // 当前请求类型
+    protected   $_method        =   ''; 
+    // 当前请求的资源类型
+    protected   $_type          =   ''; 
+    // REST允许的请求类型列表
+    protected   $allowMethod    =   array('get','post','put','delete'); 
+    // REST默认请求类型
+    protected   $defaultMethod  =   'get';
+    // REST允许请求的资源类型列表
+    protected   $allowType      =   array('html','xml','json','rss'); 
+    // 默认的资源类型
+    protected   $defaultType    =   'html';
+    // REST允许输出的资源类型列表
+    protected   $allowOutputType=   array(  
+                    'xml' => 'application/xml',
+                    'json' => 'application/json',
+                    'html' => 'text/html',
+                );
+
+   /**
+     * 架构函数
+     * @access public
+     */
+    public function __construct() {
+        // 资源类型检测
+        if(''==__EXT__) { // 自动检测资源类型
+            $this->_type   =  $this->getAcceptType();
+        }elseif(!in_array(__EXT__,$this->allowType)) {
+            // 资源类型非法 则用默认资源类型访问
+            $this->_type   =  $this->defaultType;
+        }else{
+            $this->_type   =  __EXT__ ;
+        }
+
+        // 请求方式检测
+        $method  =  strtolower(REQUEST_METHOD);
+        if(!in_array($method,$this->allowMethod)) {
+            // 请求方式非法 则用默认请求方法
+            $method = $this->defaultMethod;
+        }
+        $this->_method = $method;
+        
+        parent::__construct();
+    }
+
+    /**
+     * 魔术方法 有不存在的操作的时候执行
+     * @access public
+     * @param string $method 方法名
+     * @param array $args 参数
+     * @return mixed
+     */
+    public function __call($method,$args) {
+        if( 0 === strcasecmp($method,ACTION_NAME.C('ACTION_SUFFIX'))) {
+            if(method_exists($this,$method.'_'.$this->_method.'_'.$this->_type)) { // RESTFul方法支持
+                $fun  =  $method.'_'.$this->_method.'_'.$this->_type;
+                $this->$fun();
+            }elseif($this->_method == $this->defaultMethod && method_exists($this,$method.'_'.$this->_type) ){
+                $fun  =  $method.'_'.$this->_type;
+                $this->$fun();
+            }elseif($this->_type == $this->defaultType && method_exists($this,$method.'_'.$this->_method) ){
+                $fun  =  $method.'_'.$this->_method;
+                $this->$fun();
+            }elseif(method_exists($this,'_empty')) {
+                // 如果定义了_empty操作 则调用
+                $this->_empty($method,$args);
+            }elseif(file_exists_case($this->view->parseTemplate())){
+                // 检查是否存在默认模版 如果有直接输出模版
+                $this->display();
+            }else{
+                E(L('_ERROR_ACTION_').':'.ACTION_NAME);
+            }
+        }
+    }
+
+    /**
+     * 获取当前请求的Accept头信息
+     * @return string
+     */
+    protected function getAcceptType(){
+        $type = array(
+            'xml'   =>  'application/xml,text/xml,application/x-xml',
+            'json'  =>  'application/json,text/x-json,application/jsonrequest,text/json',
+            'js'    =>  'text/javascript,application/javascript,application/x-javascript',
+            'css'   =>  'text/css',
+            'rss'   =>  'application/rss+xml',
+            'yaml'  =>  'application/x-yaml,text/yaml',
+            'atom'  =>  'application/atom+xml',
+            'pdf'   =>  'application/pdf',
+            'text'  =>  'text/plain',
+            'png'   =>  'image/png',
+            'jpg'   =>  'image/jpg,image/jpeg,image/pjpeg',
+            'gif'   =>  'image/gif',
+            'csv'   =>  'text/csv',
+            'html'  =>  'text/html,application/xhtml+xml,*/*'
+        );
+        
+        foreach($type as $key=>$val){
+            $array   =  explode(',',$val);
+            foreach($array as $k=>$v){
+                if(stristr($_SERVER['HTTP_ACCEPT'], $v)) {
+                    return $key;
+                }
+            }
+        }
+        return false;
+    }
+
+    // 发送Http状态信息
+    protected function sendHttpStatus($code) {
+        static $_status = array(
+            // Informational 1xx
+            100 => 'Continue',
+            101 => 'Switching Protocols',
+            // Success 2xx
+            200 => 'OK',
+            201 => 'Created',
+            202 => 'Accepted',
+            203 => 'Non-Authoritative Information',
+            204 => 'No Content',
+            205 => 'Reset Content',
+            206 => 'Partial Content',
+            // Redirection 3xx
+            300 => 'Multiple Choices',
+            301 => 'Moved Permanently',
+            302 => 'Moved Temporarily ',  // 1.1
+            303 => 'See Other',
+            304 => 'Not Modified',
+            305 => 'Use Proxy',
+            // 306 is deprecated but reserved
+            307 => 'Temporary Redirect',
+            // Client Error 4xx
+            400 => 'Bad Request',
+            401 => 'Unauthorized',
+            402 => 'Payment Required',
+            403 => 'Forbidden',
+            404 => 'Not Found',
+            405 => 'Method Not Allowed',
+            406 => 'Not Acceptable',
+            407 => 'Proxy Authentication Required',
+            408 => 'Request Timeout',
+            409 => 'Conflict',
+            410 => 'Gone',
+            411 => 'Length Required',
+            412 => 'Precondition Failed',
+            413 => 'Request Entity Too Large',
+            414 => 'Request-URI Too Long',
+            415 => 'Unsupported Media Type',
+            416 => 'Requested Range Not Satisfiable',
+            417 => 'Expectation Failed',
+            // Server Error 5xx
+            500 => 'Internal Server Error',
+            501 => 'Not Implemented',
+            502 => 'Bad Gateway',
+            503 => 'Service Unavailable',
+            504 => 'Gateway Timeout',
+            505 => 'HTTP Version Not Supported',
+            509 => 'Bandwidth Limit Exceeded'
+        );
+        if(isset($_status[$code])) {
+            header('HTTP/1.1 '.$code.' '.$_status[$code]);
+            // 确保FastCGI模式下正常
+            header('Status:'.$code.' '.$_status[$code]);
+        }
+    }
+
+    /**
+     * 编码数据
+     * @access protected
+     * @param mixed $data 要返回的数据
+     * @param String $type 返回类型 JSON XML
+     * @return string
+     */
+    protected function encodeData($data,$type='') {
+        if(empty($data))  return '';
+        if('json' == $type) {
+            // 返回JSON数据格式到客户端 包含状态信息
+            $data = json_encode($data);
+        }elseif('xml' == $type){
+            // 返回xml格式数据
+            $data = xml_encode($data);
+        }elseif('php'==$type){
+            $data = serialize($data);
+        }// 默认直接输出
+        $this->setContentType($type);
+        //header('Content-Length: ' . strlen($data));
+        return $data;
+    }
+
+    /**
+     * 设置页面输出的CONTENT_TYPE和编码
+     * @access public
+     * @param string $type content_type 类型对应的扩展名
+     * @param string $charset 页面输出编码
+     * @return void
+     */
+    public function setContentType($type, $charset=''){
+        if(headers_sent()) return;
+        if(empty($charset))  $charset = C('DEFAULT_CHARSET');
+        $type = strtolower($type);
+        if(isset($this->allowOutputType[$type])) //过滤content_type
+            header('Content-Type: '.$this->allowOutputType[$type].'; charset='.$charset);
+    }
+
+    /**
+     * 输出返回数据
+     * @access protected
+     * @param mixed $data 要返回的数据
+     * @param String $type 返回类型 JSON XML
+     * @param integer $code HTTP状态
+     * @return void
+     */
+    protected function response($data,$type='',$code=200) {
+        $this->sendHttpStatus($code);
+        exit($this->encodeData($data,strtolower($type)));
+    }
+}

+ 56 - 0
ThinkPHP/Library/Think/Controller/RpcController.class.php

@@ -0,0 +1,56 @@
+<?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 Think\Controller;
+/**
+ * ThinkPHP RPC控制器类
+ */
+class RpcController {
+
+    protected $allowMethodList  =   '';
+    protected $debug            =   false;
+
+   /**
+     * 架构函数
+     * @access public
+     */
+    public function __construct() {
+        //控制器初始化
+        if(method_exists($this,'_initialize'))
+            $this->_initialize();
+        //导入类库
+        Vendor('phpRPC.phprpc_server');
+        //实例化phprpc
+        $server     =   new \PHPRPC_Server();
+        if($this->allowMethodList){
+            $methods    =   $this->allowMethodList;
+        }else{
+            $methods    =   get_class_methods($this);
+            $methods    =   array_diff($methods,array('__construct','__call','_initialize'));   
+        }
+        $server->add($methods,$this);
+
+        if(APP_DEBUG || $this->debug ) {
+            $server->setDebugMode(true);
+        }
+        $server->setEnableGZIP(true);
+        $server->start();
+        echo $server->comment();
+    }
+
+    /**
+     * 魔术方法 有不存在的操作的时候执行
+     * @access public
+     * @param string $method 方法名
+     * @param array $args 参数
+     * @return mixed
+     */
+    public function __call($method,$args){}
+}

+ 42 - 0
ThinkPHP/Library/Think/Controller/YarController.class.php

@@ -0,0 +1,42 @@
+<?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 Think\Controller;
+/**
+ * ThinkPHP Yar控制器类
+ */
+class YarController {
+
+   /**
+     * 架构函数
+     * @access public
+     */
+    public function __construct() {
+        //控制器初始化
+        if(method_exists($this,'_initialize'))
+            $this->_initialize();
+        //判断扩展是否存在
+        if(!extension_loaded('yar'))
+            E(L('_NOT_SUPPORT_').':yar');
+        //实例化Yar_Server
+        $server     =   new \Yar_Server($this);
+        // 启动server
+        $server->handle();
+    }
+
+    /**
+     * 魔术方法 有不存在的操作的时候执行
+     * @access public
+     * @param string $method 方法名
+     * @param array $args 参数
+     * @return mixed
+     */
+    public function __call($method,$args){}
+}

+ 53 - 0
ThinkPHP/Library/Think/Crypt.class.php

@@ -0,0 +1,53 @@
+<?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 Think;
+/**
+ * 加密解密类
+ */
+class Crypt {
+
+    private static $handler    =   '';
+
+    public static function init($type=''){
+        $type   =   $type?:C('DATA_CRYPT_TYPE');
+        $class  =   strpos($type,'\\')? $type: 'Think\\Crypt\\Driver\\'. ucwords(strtolower($type));
+        self::$handler  =    $class;
+    }
+
+    /**
+     * 加密字符串
+     * @param string $str 字符串
+     * @param string $key 加密key
+     * @param integer $expire 有效期(秒) 0 为永久有效
+     * @return string
+     */
+    public static function encrypt($data,$key,$expire=0){
+        if(empty(self::$handler)){
+            self::init();
+        }
+        $class  =   self::$handler; 
+        return $class::encrypt($data,$key,$expire);
+    }
+
+    /**
+     * 解密字符串
+     * @param string $str 字符串
+     * @param string $key 加密key
+     * @return string
+     */
+    public static function decrypt($data,$key){
+        if(empty(self::$handler)){
+            self::init();
+        }
+        $class  =   self::$handler;         
+        return $class::decrypt($data,$key);
+    }
+}

+ 74 - 0
ThinkPHP/Library/Think/Crypt/Driver/Base64.class.php

@@ -0,0 +1,74 @@
+<?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 Think\Crypt\Driver;
+/**
+ * Base64 加密实现类
+ */
+class Base64 {
+
+    /**
+     * 加密字符串
+     * @param string $str 字符串
+     * @param string $key 加密key
+     * @param integer $expire 有效期(秒)     
+     * @return string
+     */
+    public static function encrypt($data,$key,$expire=0) {
+        $expire = sprintf('%010d', $expire ? $expire + time():0);
+        $key    =   md5($key);
+        $data   =   base64_encode($expire.$data);
+        $x=0;
+		$len = strlen($data);
+		$l = strlen($key);
+        for ($i=0;$i< $len;$i++) {
+            if ($x== $l) $x=0;
+            $char   .=substr($key,$x,1);
+            $x++;
+        }
+
+        for ($i=0;$i< $len;$i++) {
+            $str    .=chr(ord(substr($data,$i,1))+(ord(substr($char,$i,1)))%256);
+        }
+        return $str;
+    }
+
+    /**
+     * 解密字符串
+     * @param string $str 字符串
+     * @param string $key 加密key
+     * @return string
+     */
+    public static function decrypt($data,$key) {
+        $key    =   md5($key);
+        $x=0;
+        $len = strlen($data);
+        $l = strlen($key);
+        for ($i=0;$i< $len;$i++) {
+            if ($x== $l) $x=0;
+            $char   .=substr($key,$x,1);
+            $x++;
+        }
+        for ($i=0;$i< $len;$i++) {
+            if (ord(substr($data,$i,1))<ord(substr($char,$i,1))) {
+                $str    .=chr((ord(substr($data,$i,1))+256)-ord(substr($char,$i,1)));
+            }else{
+                $str    .=chr(ord(substr($data,$i,1))-ord(substr($char,$i,1)));
+            }
+        }
+        $data = base64_decode($str);
+        $expire = substr($data,0,10);
+        if($expire > 0 && $expire < time()) {
+            return '';
+        }
+        $data   = substr($data,10);
+        return $data;
+    }
+}

+ 83 - 0
ThinkPHP/Library/Think/Crypt/Driver/Crypt.class.php

@@ -0,0 +1,83 @@
+<?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 Think\Crypt\Driver;
+/**
+ * Crypt 加密实现类
+ * @category   ORG
+ * @package  ORG
+ * @subpackage  Crypt
+ * @author    liu21st <liu21st@gmail.com>
+ */
+class Crypt {
+
+    /**
+     * 加密字符串
+     * @param string $str 字符串
+     * @param string $key 加密key
+     * @param integer $expire 有效期(秒)     
+     * @return string
+     */
+    public static function encrypt($str,$key,$expire=0){
+        $expire = sprintf('%010d', $expire ? $expire + time():0);
+        $r = md5($key);
+        $c=0;
+        $v = "";
+        $str    =   $expire.$str;
+		$len = strlen($str);
+		$l = strlen($r);
+        for ($i=0;$i<$len;$i++){
+         if ($c== $l) $c=0;
+         $v.= substr($r,$c,1) .
+             (substr($str,$i,1) ^ substr($r,$c,1));
+         $c++;
+        }
+        return self::ed($v,$key);
+    }
+
+    /**
+     * 解密字符串
+     * @param string $str 字符串
+     * @param string $key 加密key
+     * @return string
+     */
+    public static function decrypt($str,$key) {
+        $str = self::ed($str,$key);
+        $v = "";
+		$len = strlen($str);
+        for ($i=0;$i<$len;$i++){
+         $md5 = substr($str,$i,1);
+         $i++;
+         $v.= (substr($str,$i,1) ^ $md5);
+        }
+        $data   =    $v;
+        $expire = substr($data,0,10);
+        if($expire > 0 && $expire < time()) {
+            return '';
+        }
+        $data   = substr($data,10);
+        return $data;
+    }
+
+
+   function ed($str,$key) {
+      $r = md5($key);
+      $c=0;
+      $v = "";
+	  $len = strlen($str);
+	  $l = strlen($r);
+      for ($i=0;$i<$len;$i++) {
+         if ($c==$l) $c=0;
+         $v.= substr($str,$i,1) ^ substr($r,$c,1);
+         $c++;
+      }
+      return $v;
+   }
+}

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 241 - 0
ThinkPHP/Library/Think/Crypt/Driver/Des.class.php


+ 86 - 0
ThinkPHP/Library/Think/Crypt/Driver/Think.class.php

@@ -0,0 +1,86 @@
+<?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 Think\Crypt\Driver;
+/**
+ * Base64 加密实现类
+ */
+class Think {
+
+    /**
+     * 加密字符串
+     * @param string $str 字符串
+     * @param string $key 加密key
+     * @param integer $expire 有效期(秒)     
+     * @return string
+     */
+    public static function encrypt($data,$key,$expire=0) {
+        $expire = sprintf('%010d', $expire ? $expire + time():0);
+        $key  = md5($key);
+        $data = base64_encode($expire.$data);
+        $x    = 0;
+        $len  = strlen($data);
+        $l    = strlen($key);
+        $char = $str    =   '';
+
+        for ($i = 0; $i < $len; $i++) {
+            if ($x == $l) $x = 0;
+            $char .= substr($key, $x, 1);
+            $x++;
+        }
+
+        for ($i = 0; $i < $len; $i++) {
+            $str .= chr(ord(substr($data, $i, 1)) + (ord(substr($char, $i, 1)))%256);
+        }
+        return str_replace(array('+','/','='),array('-','_',''),base64_encode($str));
+    }
+
+    /**
+     * 解密字符串
+     * @param string $str 字符串
+     * @param string $key 加密key
+     * @return string
+     */
+    public static function decrypt($data,$key) {
+        $key    = md5($key);
+        $data   = str_replace(array('-','_'),array('+','/'),$data);
+        $mod4   = strlen($data) % 4;
+        if ($mod4) {
+           $data .= substr('====', $mod4);
+        }
+        $data   = base64_decode($data);
+
+        $x      = 0;
+        $len    = strlen($data);
+        $l      = strlen($key);
+        $char   = $str = '';
+
+        for ($i = 0; $i < $len; $i++) {
+            if ($x == $l) $x = 0;
+            $char .= substr($key, $x, 1);
+            $x++;
+        }
+
+        for ($i = 0; $i < $len; $i++) {
+            if (ord(substr($data, $i, 1))<ord(substr($char, $i, 1))) {
+                $str .= chr((ord(substr($data, $i, 1)) + 256) - ord(substr($char, $i, 1)));
+            }else{
+                $str .= chr(ord(substr($data, $i, 1)) - ord(substr($char, $i, 1)));
+            }
+        }
+        $data   = base64_decode($str);
+        $expire = substr($data,0,10);
+        if($expire > 0 && $expire < time()) {
+            return '';
+        }
+        $data   = substr($data,10);
+        return $data;
+    }
+}

+ 116 - 0
ThinkPHP/Library/Think/Crypt/Driver/Xxtea.class.php

@@ -0,0 +1,116 @@
+<?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 Think\Crypt\Driver;
+/**
+ * Xxtea 加密实现类
+ */
+class Xxtea {
+
+    /**
+     * 加密字符串
+     * @param string $str 字符串
+     * @param string $key 加密key
+     * @param integer $expire 有效期(秒)     
+     * @return string
+     */
+    public static function encrypt($str, $key,$expire=0) {
+        $expire = sprintf('%010d', $expire ? $expire + time():0);
+        $str    =   $expire.$str;
+        $v = self::str2long($str, true);
+        $k = self::str2long($key, false);
+        $n = count($v) - 1;
+
+        $z = $v[$n];
+        $y = $v[0];
+        $delta = 0x9E3779B9;
+        $q = floor(6 + 52 / ($n + 1));
+        $sum = 0;
+        while (0 < $q--) {
+            $sum = self::int32($sum + $delta);
+            $e = $sum >> 2 & 3;
+            for ($p = 0; $p < $n; $p++) {
+                $y = $v[$p + 1];
+                $mx = self::int32((($z >> 5 & 0x07ffffff) ^ $y << 2) + (($y >> 3 & 0x1fffffff) ^ $z << 4)) ^ self::int32(($sum ^ $y) + ($k[$p & 3 ^ $e] ^ $z));
+                $z = $v[$p] = self::int32($v[$p] + $mx);
+            }
+            $y = $v[0];
+            $mx = self::int32((($z >> 5 & 0x07ffffff) ^ $y << 2) + (($y >> 3 & 0x1fffffff) ^ $z << 4)) ^ self::int32(($sum ^ $y) + ($k[$p & 3 ^ $e] ^ $z));
+            $z = $v[$n] = self::int32($v[$n] + $mx);
+        }
+        return self::long2str($v, false);
+    }
+
+    /**
+     * 解密字符串
+     * @param string $str 字符串
+     * @param string $key 加密key
+     * @return string
+     */
+    public static function decrypt($str, $key) {
+        $v = self::str2long($str, false);
+        $k = self::str2long($key, false);
+        $n = count($v) - 1;
+
+        $z = $v[$n];
+        $y = $v[0];
+        $delta = 0x9E3779B9;
+        $q = floor(6 + 52 / ($n + 1));
+        $sum = self::int32($q * $delta);
+        while ($sum != 0) {
+            $e = $sum >> 2 & 3;
+            for ($p = $n; $p > 0; $p--) {
+                $z = $v[$p - 1];
+                $mx = self::int32((($z >> 5 & 0x07ffffff) ^ $y << 2) + (($y >> 3 & 0x1fffffff) ^ $z << 4)) ^ self::int32(($sum ^ $y) + ($k[$p & 3 ^ $e] ^ $z));
+                $y = $v[$p] = self::int32($v[$p] - $mx);
+            }
+            $z = $v[$n];
+            $mx = self::int32((($z >> 5 & 0x07ffffff) ^ $y << 2) + (($y >> 3 & 0x1fffffff) ^ $z << 4)) ^ self::int32(($sum ^ $y) + ($k[$p & 3 ^ $e] ^ $z));
+            $y = $v[0] = self::int32($v[0] - $mx);
+            $sum = self::int32($sum - $delta);
+        }
+        $data   = self::long2str($v, true);
+        $expire = substr($data,0,10);
+        if($expire > 0 && $expire < time()) {
+            return '';
+        }
+        $data   = substr($data,10);
+        return $data;
+    }
+
+    private static function long2str($v, $w) {
+        $len = count($v);
+        $s = array();
+        for ($i = 0; $i < $len; $i++) {
+            $s[$i] = pack("V", $v[$i]);
+        }
+        if ($w) {
+            return substr(join('', $s), 0, $v[$len - 1]);
+        }else{
+            return join('', $s);
+        }
+    }
+
+    private static function str2long($s, $w) {
+        $v = unpack("V*", $s. str_repeat("\0", (4 - strlen($s) % 4) & 3));
+        $v = array_values($v);
+        if ($w) {
+            $v[count($v)] = strlen($s);
+        }
+        return $v;
+    }
+
+    private static function int32($n) {
+        while ($n >= 2147483648) $n -= 4294967296;
+        while ($n <= -2147483649) $n += 4294967296;
+        return (int)$n;
+    }
+
+}

+ 137 - 0
ThinkPHP/Library/Think/Db.class.php

@@ -0,0 +1,137 @@
+<?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 Think;
+
+/**
+ * ThinkPHP 数据库中间层实现类
+ */
+class Db {
+
+    static private  $instance   =  array();     //  数据库连接实例
+    static private  $_instance  =  null;   //  当前数据库连接实例
+
+    /**
+     * 取得数据库类实例
+     * @static
+     * @access public
+     * @param mixed $config 连接配置
+     * @return Object 返回数据库驱动类
+     */
+    static public function getInstance($config=array()) {
+        $md5    =   md5(serialize($config));
+        if(!isset(self::$instance[$md5])) {
+            // 解析连接参数 支持数组和字符串
+            $options    =   self::parseConfig($config);
+            // 兼容mysqli
+            if('mysqli' == $options['type']) $options['type']   =   'mysql';
+            // 如果采用lite方式 仅支持原生SQL 包括query和execute方法
+            $class  =   $options['lite']?  'Think\Db\Lite' :   'Think\\Db\\Driver\\'.ucwords(strtolower($options['type']));
+            if(class_exists($class)){
+                self::$instance[$md5]   =   new $class($options);
+            }else{
+                // 类没有定义
+                E(L('_NO_DB_DRIVER_').': ' . $class);
+            }
+        }
+        self::$_instance    =   self::$instance[$md5];
+        return self::$_instance;
+    }
+
+    /**
+     * 数据库连接参数解析
+     * @static
+     * @access private
+     * @param mixed $config
+     * @return array
+     */
+    static private function parseConfig($config){
+        if(!empty($config)){
+            if(is_string($config)) {
+                return self::parseDsn($config);
+            }
+            $config =   array_change_key_case($config);
+            $config = array (
+                'type'          =>  $config['db_type'],
+                'username'      =>  $config['db_user'],
+                'password'      =>  $config['db_pwd'],
+                'hostname'      =>  $config['db_host'],
+                'hostport'      =>  $config['db_port'],
+                'database'      =>  $config['db_name'],
+                'dsn'           =>  isset($config['db_dsn'])?$config['db_dsn']:null,
+                'params'        =>  isset($config['db_params'])?$config['db_params']:null,
+                'charset'       =>  isset($config['db_charset'])?$config['db_charset']:'utf8',
+                'deploy'        =>  isset($config['db_deploy_type'])?$config['db_deploy_type']:0,
+                'rw_separate'   =>  isset($config['db_rw_separate'])?$config['db_rw_separate']:false,
+                'master_num'    =>  isset($config['db_master_num'])?$config['db_master_num']:1,
+                'slave_no'      =>  isset($config['db_slave_no'])?$config['db_slave_no']:'',
+                'debug'         =>  isset($config['db_debug'])?$config['db_debug']:APP_DEBUG,
+                'lite'          =>  isset($config['db_lite'])?$config['db_lite']:false,
+            );
+        }else {
+            $config = array (
+                'type'          =>  C('DB_TYPE'),
+                'username'      =>  C('DB_USER'),
+                'password'      =>  C('DB_PWD'),
+                'hostname'      =>  C('DB_HOST'),
+                'hostport'      =>  C('DB_PORT'),
+                'database'      =>  C('DB_NAME'),
+                'dsn'           =>  C('DB_DSN'),
+                'params'        =>  C('DB_PARAMS'),
+                'charset'       =>  C('DB_CHARSET'),
+                'deploy'        =>  C('DB_DEPLOY_TYPE'),
+                'rw_separate'   =>  C('DB_RW_SEPARATE'),
+                'master_num'    =>  C('DB_MASTER_NUM'),
+                'slave_no'      =>  C('DB_SLAVE_NO'),
+                'debug'         =>  C('DB_DEBUG',null,APP_DEBUG),
+                'lite'          =>  C('DB_LITE'),
+            );
+        }
+        return $config;
+    }
+
+    /**
+     * DSN解析
+     * 格式: mysql://username:passwd@localhost:3306/DbName?param1=val1&param2=val2#utf8
+     * @static
+     * @access private
+     * @param string $dsnStr
+     * @return array
+     */
+    static private function parseDsn($dsnStr) {
+        if( empty($dsnStr) ){return false;}
+        $info = parse_url($dsnStr);
+        if(!$info) {
+            return false;
+        }
+        $dsn = array(
+            'type'      =>  $info['scheme'],
+            'username'  =>  isset($info['user']) ? $info['user'] : '',
+            'password'  =>  isset($info['pass']) ? $info['pass'] : '',
+            'hostname'  =>  isset($info['host']) ? $info['host'] : '',
+            'hostport'  =>  isset($info['port']) ? $info['port'] : '',
+            'database'  =>  isset($info['path']) ? substr($info['path'],1) : '',
+            'charset'   =>  isset($info['fragment'])?$info['fragment']:'utf8',
+        );
+        
+        if(isset($info['query'])) {
+            parse_str($info['query'],$dsn['params']);
+        }else{
+            $dsn['params']  =   array();
+        }
+        return $dsn;
+     }
+
+    // 调用驱动类的方法
+    static public function __callStatic($method, $params){
+        return call_user_func_array(array(self::$_instance, $method), $params);
+    }
+}

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1138 - 0
ThinkPHP/Library/Think/Db/Driver.class.php


+ 151 - 0
ThinkPHP/Library/Think/Db/Driver/Firebird.class.php

@@ -0,0 +1,151 @@
+<?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 Think\Db\Driver;
+use Think\Db\Driver;
+
+/**
+ * Firebird数据库驱动 
+ */
+class Firebird extends Driver{
+    protected $selectSql  =     'SELECT %LIMIT% %DISTINCT% %FIELD% FROM %TABLE%%JOIN%%WHERE%%GROUP%%HAVING%%ORDER%';
+
+    /**
+     * 解析pdo连接的dsn信息
+     * @access public
+     * @param array $config 连接信息
+     * @return string
+     */
+    protected function parseDsn($config){
+       $dsn  =   'firebird:dbname='.$config['hostname'].'/'.($config['hostport']?:3050).':'.$config['database'];
+       return $dsn;
+    }
+    
+    /**
+     * 执行语句
+     * @access public
+     * @param string $str  sql指令
+     * @param boolean $fetchSql  不执行只是获取SQL
+     * @return mixed
+     */
+    public function execute($str,$fetchSql=false) {
+        $this->initConnect(true);
+        if ( !$this->_linkID ) return false;
+        $this->queryStr = $str;
+        if(!empty($this->bind)){
+            $that   =   $this;
+            $this->queryStr =   strtr($this->queryStr,array_map(function($val) use($that){ return '\''.$that->escapeString($val).'\''; },$this->bind));
+        }
+        if($fetchSql){
+            return $this->queryStr;
+        }
+        //释放前次的查询结果
+        if ( !empty($this->PDOStatement) ) $this->free();
+        $this->executeTimes++;
+        N('db_write',1); // 兼容代码
+        // 记录开始执行时间
+        $this->debug(true);
+        $this->PDOStatement =   $this->_linkID->prepare($str);
+        if(false === $this->PDOStatement) {
+            E($this->error());
+        }
+        foreach ($this->bind as $key => $val) {
+            if(is_array($val)){
+                $this->PDOStatement->bindValue($key, $val[0], $val[1]);
+            }else{
+                $this->PDOStatement->bindValue($key, $val);
+            }
+        }
+        $this->bind =   array();
+        $result =   $this->PDOStatement->execute();
+        $this->debug(false);
+        if ( false === $result) {
+            $this->error();
+            return false;
+        } else {
+            $this->numRows = $this->PDOStatement->rowCount();
+            return $this->numRows;
+        }
+    }
+    
+    /**
+     * 取得数据表的字段信息
+     * @access public
+     */
+    public function getFields($tableName) {
+        $this->initConnect(true);
+        list($tableName) = explode(' ', $tableName);
+        $sql='SELECT RF.RDB$FIELD_NAME AS FIELD,RF.RDB$DEFAULT_VALUE AS DEFAULT1,RF.RDB$NULL_FLAG AS NULL1,TRIM(T.RDB$TYPE_NAME) || \'(\' || F.RDB$FIELD_LENGTH || \')\' as TYPE FROM RDB$RELATION_FIELDS RF LEFT JOIN RDB$FIELDS F ON (F.RDB$FIELD_NAME = RF.RDB$FIELD_SOURCE) LEFT JOIN RDB$TYPES T ON (T.RDB$TYPE = F.RDB$FIELD_TYPE) WHERE RDB$RELATION_NAME=UPPER(\''.$tableName.'\') AND T.RDB$FIELD_NAME = \'RDB$FIELD_TYPE\' ORDER By RDB$FIELD_POSITION';
+        $result = $this->query($sql);
+        $info   =   array();
+        if($result){
+            foreach($result as $key => $val){
+                $info[trim($val['field'])] = array(
+                    'name'    => trim($val['field']),
+                    'type'    => $val['type'],
+                    'notnull' => (bool) ($val['null1'] ==1), // 1表示不为Null
+                    'default' => $val['default1'],
+                    'primary' => false,
+                    'autoinc' => false,
+                );
+            }
+        }
+        //获取主键
+        $sql='select b.rdb$field_name as field_name from rdb$relation_constraints a join rdb$index_segments b on a.rdb$index_name=b.rdb$index_name where a.rdb$constraint_type=\'PRIMARY KEY\' and a.rdb$relation_name=UPPER(\''.$tableName.'\')';
+        $rs_temp = $this->query($sql);
+        foreach($rs_temp as $row) {
+            $info[trim($row['field_name'])]['primary']= true;
+        }
+        return $info;
+    }
+    
+    /**
+     * 取得数据库的表信息
+     * @access public
+     */
+    public function getTables($dbName='') {
+        $sql='SELECT DISTINCT RDB$RELATION_NAME FROM RDB$RELATION_FIELDS WHERE RDB$SYSTEM_FLAG=0';
+        $result   =  $this->query($sql);
+        $info   =   array();
+        foreach ($result as $key => $val) {
+            $info[$key] = trim(current($val));
+        }
+        return $info;
+    }
+    
+    /**
+     * SQL指令安全过滤
+     * @access public
+     * @param string $str  SQL指令
+     * @return string
+     */
+    public function escapeString($str) {
+        return str_replace("'", "''", $str);
+    }
+
+    /**
+     * limit
+     * @access public
+     * @param $limit limit表达式
+     * @return string
+     */
+    public function parseLimit($limit) {
+        $limitStr    = '';
+        if(!empty($limit)) {
+            $limit  =   explode(',',$limit);
+            if(count($limit)>1) {
+                 $limitStr = ' FIRST '.$limit[1].' SKIP '.$limit[0].' ';
+            }else{
+              $limitStr = ' FIRST '.$limit[0].' ';
+            }
+        }
+        return $limitStr;
+    }
+}

+ 821 - 0
ThinkPHP/Library/Think/Db/Driver/Mongo.class.php

@@ -0,0 +1,821 @@
+<?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 Think\Db\Driver;
+use Think\Db\Driver;
+
+/**
+ * Mongo数据库驱动
+ */
+class Mongo extends Driver {
+
+    protected $_mongo           =   null; // MongoDb Object
+    protected $_collection      =   null; // MongoCollection Object
+    protected $_dbName          =   ''; // dbName
+    protected $_collectionName  =   ''; // collectionName
+    protected $_cursor          =   null; // MongoCursor Object
+    protected $comparison       =   array('neq'=>'ne','ne'=>'ne','gt'=>'gt','egt'=>'gte','gte'=>'gte','lt'=>'lt','elt'=>'lte','lte'=>'lte','in'=>'in','not in'=>'nin','nin'=>'nin');
+
+    /**
+     * 架构函数 读取数据库配置信息
+     * @access public
+     * @param array $config 数据库配置数组
+     */
+    public function __construct($config=''){
+        if ( !class_exists('mongoClient') ) {
+            E(L('_NOT_SUPPORT_').':Mongo');
+        }
+        if(!empty($config)) {
+            $this->config           =   array_merge($this->config,$config);
+            if(empty($this->config['params'])){
+                $this->config['params'] =   array();
+            }            
+        }
+    }
+
+    /**
+     * 连接数据库方法
+     * @access public
+     */
+    public function connect($config='',$linkNum=0) {
+        if ( !isset($this->linkID[$linkNum]) ) {
+            if(empty($config))  $config =   $this->config;
+            $host = 'mongodb://'.($config['username']?"{$config['username']}":'').($config['password']?":{$config['password']}@":'').$config['hostname'].($config['hostport']?":{$config['hostport']}":'').'/'.($config['database']?"{$config['database']}":'');
+            try{
+                $this->linkID[$linkNum] = new \mongoClient( $host,$this->config['params']);
+            }catch (\MongoConnectionException $e){
+                E($e->getmessage());
+            }
+        }
+        return $this->linkID[$linkNum];
+    }
+
+    /**
+     * 切换当前操作的Db和Collection
+     * @access public
+     * @param string $collection  collection
+     * @param string $db  db
+     * @param boolean $master 是否主服务器
+     * @return void
+     */
+    public function switchCollection($collection,$db='',$master=true){
+        // 当前没有连接 则首先进行数据库连接
+        if ( !$this->_linkID ) $this->initConnect($master);
+        try{
+            if(!empty($db)) { // 传人Db则切换数据库
+                // 当前MongoDb对象
+                $this->_dbName  =  $db;
+                $this->_mongo = $this->_linkID->selectDb($db);
+            }
+            // 当前MongoCollection对象
+            if($this->config['debug']) {
+                $this->queryStr   =  $this->_dbName.'.getCollection('.$collection.')';
+            }
+            if($this->_collectionName != $collection) {
+                $this->queryTimes++;
+                N('db_query',1); // 兼容代码                
+                $this->debug(true);
+                $this->_collection =  $this->_mongo->selectCollection($collection);
+                $this->debug(false);
+                $this->_collectionName  = $collection; // 记录当前Collection名称
+            }
+        }catch (MongoException $e){
+            E($e->getMessage());
+        }
+    }
+
+    /**
+     * 释放查询结果
+     * @access public
+     */
+    public function free() {
+        $this->_cursor = null;
+    }
+
+    /**
+     * 执行命令
+     * @access public
+     * @param array $command  指令
+     * @return array
+     */
+    public function command($command=array(), $options=array()) {
+        $cache  =  isset($options['cache'])?$options['cache']:false;
+        if($cache) { // 查询缓存检测
+            $key =  is_string($cache['key'])?$cache['key']:md5(serialize($command));
+            $value   =  S($key,'','',$cache['type']);
+            if(false !== $value) {
+                return $value;
+            }
+        }
+        N('db_write',1); // 兼容代码
+        $this->executeTimes++;
+        try{
+            if($this->config['debug']) {
+                $this->queryStr   =  $this->_dbName.'.'.$this->_collectionName.'.runCommand(';
+                $this->queryStr  .=  json_encode($command);
+                $this->queryStr  .=  ')';
+            }
+            $this->debug(true);
+            $result   = $this->_mongo->command($command);
+            $this->debug(false);
+            
+            if($cache && $result['ok']) { // 查询缓存写入
+                S($key,$result,$cache['expire'],$cache['type']);
+            }
+            return $result;
+        } catch (\MongoCursorException $e) {
+            E($e->getMessage());
+        }
+    }
+
+    /**
+     * 执行语句
+     * @access public
+     * @param string $code  sql指令
+     * @param array $args  参数
+     * @return mixed
+     */
+    public function execute($code,$args=array()) {
+        $this->executeTimes++;
+        N('db_write',1); // 兼容代码
+        $this->debug(true);
+        $this->queryStr = 'execute:'.$code;
+        $result   = $this->_mongo->execute($code,$args);
+        $this->debug(false);
+        if($result['ok']) {
+            return $result['retval'];
+        }else{
+            E($result['errmsg']);
+        }
+    }
+
+    /**
+     * 关闭数据库
+     * @access public
+     */
+    public function close() {
+        if($this->_linkID) {
+            $this->_linkID->close();
+            $this->_linkID = null;
+            $this->_mongo = null;
+            $this->_collection =  null;
+            $this->_cursor = null;
+        }
+    }
+
+    /**
+     * 数据库错误信息
+     * @access public
+     * @return string
+     */
+    public function error() {
+        $this->error = $this->_mongo->lastError();
+        trace($this->error,'','ERR');
+        return $this->error;
+    }
+
+    /**
+     * 插入记录
+     * @access public
+     * @param mixed $data 数据
+     * @param array $options 参数表达式
+     * @param boolean $replace 是否replace
+     * @return false | integer
+     */
+    public function insert($data,$options=array(),$replace=false) {
+        if(isset($options['table'])) {
+            $this->switchCollection($options['table']);
+        }
+        $this->model  =   $options['model'];
+        $this->executeTimes++;
+        N('db_write',1); // 兼容代码        
+        if($this->config['debug']) {
+            $this->queryStr   =  $this->_dbName.'.'.$this->_collectionName.'.insert(';
+            $this->queryStr   .= $data?json_encode($data):'{}';
+            $this->queryStr   .= ')';
+        }
+        try{
+            $this->debug(true);
+            $result =  $replace?   $this->_collection->save($data):  $this->_collection->insert($data);
+            $this->debug(false);
+            if($result) {
+               $_id    = $data['_id'];
+                if(is_object($_id)) {
+                    $_id = $_id->__toString();
+                }
+               $this->lastInsID    = $_id;
+            }
+            return $result;
+        } catch (\MongoCursorException $e) {
+            E($e->getMessage());
+        }
+    }
+
+    /**
+     * 插入多条记录
+     * @access public
+     * @param array $dataList 数据
+     * @param array $options 参数表达式
+     * @return bool
+     */
+    public function insertAll($dataList,$options=array()) {
+        if(isset($options['table'])) {
+            $this->switchCollection($options['table']);
+        }
+        $this->model  =   $options['model'];
+        $this->executeTimes++;
+        N('db_write',1); // 兼容代码        
+        try{
+            $this->debug(true);
+            $result =  $this->_collection->batchInsert($dataList);
+            $this->debug(false);
+            return $result;
+        } catch (\MongoCursorException $e) {
+            E($e->getMessage());
+        }
+    }
+
+    /**
+     * 生成下一条记录ID 用于自增非MongoId主键
+     * @access public
+     * @param string $pk 主键名
+     * @return integer
+     */
+    public function getMongoNextId($pk) {
+        if($this->config['debug']) {
+            $this->queryStr   =  $this->_dbName.'.'.$this->_collectionName.'.find({},{'.$pk.':1}).sort({'.$pk.':-1}).limit(1)';
+        }
+        try{
+            $this->debug(true);
+            $result   =  $this->_collection->find(array(),array($pk=>1))->sort(array($pk=>-1))->limit(1);
+            $this->debug(false);
+        } catch (\MongoCursorException $e) {
+            E($e->getMessage());
+        }
+        $data = $result->getNext();
+        return isset($data[$pk])?$data[$pk]+1:1;
+    }
+
+    /**
+     * 更新记录
+     * @access public
+     * @param mixed $data 数据
+     * @param array $options 表达式
+     * @return bool
+     */
+    public function update($data,$options) {
+        if(isset($options['table'])) {
+            $this->switchCollection($options['table']);
+        }
+        $this->executeTimes++;
+        N('db_write',1); // 兼容代码        
+        $this->model  =   $options['model'];
+        $query   = $this->parseWhere(isset($options['where'])?$options['where']:array());
+        $set  =  $this->parseSet($data);
+        if($this->config['debug']) {
+            $this->queryStr   =  $this->_dbName.'.'.$this->_collectionName.'.update(';
+            $this->queryStr   .= $query?json_encode($query):'{}';
+            $this->queryStr   .=  ','.json_encode($set).')';
+        }
+        try{
+            $this->debug(true);
+            if(isset($options['limit']) && $options['limit'] == 1) {
+                $multiple   =   array("multiple" => false);
+            }else{
+                $multiple   =   array("multiple" => true);
+            }
+            $result   = $this->_collection->update($query,$set,$multiple);
+            $this->debug(false);
+            return $result;
+        } catch (\MongoCursorException $e) {
+            E($e->getMessage());
+        }
+    }
+
+    /**
+     * 删除记录
+     * @access public
+     * @param array $options 表达式
+     * @return false | integer
+     */
+    public function delete($options=array()) {
+        if(isset($options['table'])) {
+            $this->switchCollection($options['table']);
+        }
+        $query   = $this->parseWhere(isset($options['where'])?$options['where']:array());
+        $this->model  =   $options['model'];
+        $this->executeTimes++;
+        N('db_write',1); // 兼容代码        
+        if($this->config['debug']) {
+            $this->queryStr   =  $this->_dbName.'.'.$this->_collectionName.'.remove('.json_encode($query).')';
+        }
+        try{
+            $this->debug(true);
+            $result   = $this->_collection->remove($query);
+            $this->debug(false);
+            return $result;
+        } catch (\MongoCursorException $e) {
+            E($e->getMessage());
+        }
+    }
+
+    /**
+     * 清空记录
+     * @access public
+     * @param array $options 表达式
+     * @return false | integer
+     */
+    public function clear($options=array()){
+        if(isset($options['table'])) {
+            $this->switchCollection($options['table']);
+        }
+        $this->model  =   $options['model'];
+        $this->executeTimes++;
+        N('db_write',1); // 兼容代码        
+        if($this->config['debug']) {
+            $this->queryStr   =  $this->_dbName.'.'.$this->_collectionName.'.remove({})';
+        }
+        try{
+            $this->debug(true);
+            $result   =  $this->_collection->drop();
+            $this->debug(false);
+            return $result;
+        } catch (\MongoCursorException $e) {
+            E($e->getMessage());
+        }
+    }
+
+    /**
+     * 查找记录
+     * @access public
+     * @param array $options 表达式
+     * @return iterator
+     */
+    public function select($options=array()) {
+        if(isset($options['table'])) {
+            $this->switchCollection($options['table'],'',false);
+        }
+        $this->model  =   $options['model'];
+        $this->queryTimes++;
+        N('db_query',1); // 兼容代码        
+        $query  =  $this->parseWhere(isset($options['where'])?$options['where']:array());
+        $field  =  $this->parseField(isset($options['field'])?$options['field']:array());
+        try{
+            if($this->config['debug']) {
+                $this->queryStr   =  $this->_dbName.'.'.$this->_collectionName.'.find(';
+                $this->queryStr  .=  $query? json_encode($query):'{}';
+                if(is_array($field) && count($field)) {
+                    foreach ($field as $f=>$v)
+                        $_field_array[$f] = $v ? 1 : 0;
+
+                    $this->queryStr  .=  $field? ', '.json_encode($_field_array):', {}';
+                }
+                $this->queryStr  .=  ')';
+            }
+            $this->debug(true);
+            $_cursor   = $this->_collection->find($query,$field);
+            if(!empty($options['order'])) {
+                $order   =  $this->parseOrder($options['order']);
+                if($this->config['debug']) {
+                    $this->queryStr .= '.sort('.json_encode($order).')';
+                }
+                $_cursor =  $_cursor->sort($order);
+            }
+            if(isset($options['page'])) { // 根据页数计算limit
+                list($page,$length)   =   $options['page'];
+                $page    =  $page>0 ? $page : 1;
+                $length  =  $length>0 ? $length : (is_numeric($options['limit'])?$options['limit']:20);
+                $offset  =  $length*((int)$page-1);
+                $options['limit'] =  $offset.','.$length;
+            }
+            if(isset($options['limit'])) {
+                list($offset,$length) =  $this->parseLimit($options['limit']);
+                if(!empty($offset)) {
+                    if($this->config['debug']) {
+                        $this->queryStr .= '.skip('.intval($offset).')';
+                    }
+                    $_cursor =  $_cursor->skip(intval($offset));
+                }
+                if($this->config['debug']) {
+                    $this->queryStr .= '.limit('.intval($length).')';
+                }
+                $_cursor =  $_cursor->limit(intval($length));
+            }
+            $this->debug(false);
+            $this->_cursor =  $_cursor;
+            $resultSet  =  iterator_to_array($_cursor);
+            return $resultSet;
+        } catch (\MongoCursorException $e) {
+            E($e->getMessage());
+        }
+    }
+
+    /**
+     * 查找某个记录
+     * @access public
+     * @param array $options 表达式
+     * @return array
+     */
+    public function find($options=array()){
+        $options['limit'] = 1;
+        $find = $this->select($options);
+        return array_shift($find);
+    }
+
+    /**
+     * 统计记录数
+     * @access public
+     * @param array $options 表达式
+     * @return iterator
+     */
+    public function count($options=array()){
+        if(isset($options['table'])) {
+            $this->switchCollection($options['table'],'',false);
+        }
+        $this->model  =   $options['model'];
+        $this->queryTimes++;
+        N('db_query',1); // 兼容代码        
+        $query  =  $this->parseWhere(isset($options['where'])?$options['where']:array());
+        if($this->config['debug']) {
+            $this->queryStr   =  $this->_dbName.'.'.$this->_collectionName;
+            $this->queryStr   .= $query?'.find('.json_encode($query).')':'';
+            $this->queryStr   .= '.count()';
+        }
+        try{
+            $this->debug(true);
+            $count   = $this->_collection->count($query);
+            $this->debug(false);
+            return $count;
+        } catch (\MongoCursorException $e) {
+            E($e->getMessage());
+        }
+    }
+
+    public function group($keys,$initial,$reduce,$options=array()){
+        if(isset($options['table']) && $this->_collectionName != $options['table']) {
+            $this->switchCollection($options['table'],'',false);
+        }
+        
+        $cache  =  isset($options['cache'])?$options['cache']:false;
+        if($cache) {
+            $key    =  is_string($cache['key'])?$cache['key']:md5(serialize($options));
+            $value  =  S($key,'','',$cache['type']);
+            if(false !== $value) {
+                return $value;
+            }
+        }
+        
+        $this->model  =   $options['model'];
+        $this->queryTimes++;
+        N('db_query',1); // 兼容代码        
+        $query  =  $this->parseWhere(isset($options['where'])?$options['where']:array());
+        
+        if($this->config['debug']) {
+            $this->queryStr   =  $this->_dbName.'.'.$this->_collectionName.'.group({key:'.json_encode($keys).',cond:'.
+            json_encode($options['condition']) . ',reduce:' .
+            json_encode($reduce).',initial:'.
+            json_encode($initial).'})';
+        }
+        try{
+            $this->debug(true);
+            $option = array('condition'=>$options['condition'], 'finalize'=>$options['finalize'], 'maxTimeMS'=>$options['maxTimeMS']);
+            $group = $this->_collection->group($keys,$initial,$reduce,$options);
+            $this->debug(false);
+            
+            if($cache && $group['ok'])
+                S($key,$group,$cache['expire'],$cache['type']);
+            
+            return $group;
+        } catch (\MongoCursorException $e) {
+            E($e->getMessage());
+        }
+    }
+
+    /**
+     * 取得数据表的字段信息
+     * @access public
+     * @return array
+     */
+    public function getFields($collection=''){
+        if(!empty($collection) && $collection != $this->_collectionName) {
+            $this->switchCollection($collection,'',false);
+        }
+        $this->queryTimes++;
+        N('db_query',1); // 兼容代码        
+        if($this->config['debug']) {
+            $this->queryStr   =  $this->_dbName.'.'.$this->_collectionName.'.findOne()';
+        }
+        try{
+            $this->debug(true);
+            $result   =  $this->_collection->findOne();
+            $this->debug(false);
+        } catch (\MongoCursorException $e) {
+            E($e->getMessage());
+        }
+        if($result) { // 存在数据则分析字段
+            $info =  array();
+            foreach ($result as $key=>$val){
+                $info[$key] =  array(
+                    'name'  =>  $key,
+                    'type'  =>  getType($val),
+                );
+            }
+            return $info;
+        }
+        // 暂时没有数据 返回false
+        return false;
+    }
+
+    /**
+     * 取得当前数据库的collection信息
+     * @access public
+     */
+    public function getTables(){
+        if($this->config['debug']) {
+            $this->queryStr   =  $this->_dbName.'.getCollenctionNames()';
+        }
+        $this->queryTimes++;
+        N('db_query',1); // 兼容代码        
+        $this->debug(true);
+        $list   = $this->_mongo->listCollections();
+        $this->debug(false);
+        $info =  array();
+        foreach ($list as $collection){
+            $info[]   =  $collection->getName();
+        }
+        return $info;
+    }
+
+    /**
+     * 取得当前数据库的对象
+     * @access public
+     * @return object mongoClient
+     */
+    public function getDB(){
+        return $this->_mongo;
+    }
+    
+    /**
+     * 取得当前集合的对象
+     * @access public
+     * @return object MongoCollection
+     */
+    public function getCollection(){
+        return $this->_collection;
+    }
+
+    /**
+     * set分析
+     * @access protected
+     * @param array $data
+     * @return string
+     */
+    protected function parseSet($data) {
+        $result   =  array();
+        foreach ($data as $key=>$val){
+            if(is_array($val)) {
+                switch($val[0]) {
+                    case 'inc':
+                        $result['$inc'][$key]  =  (int)$val[1];
+                        break;
+                    case 'set':
+                    case 'unset':
+                    case 'push':
+                    case 'pushall':
+                    case 'addtoset':
+                    case 'pop':
+                    case 'pull':
+                    case 'pullall':
+                        $result['$'.$val[0]][$key] = $val[1];
+                        break;
+                    default:
+                        $result['$set'][$key] =  $val;
+                }
+            }else{
+                $result['$set'][$key]    = $val;
+            }
+        }
+        return $result;
+    }
+
+    /**
+     * order分析
+     * @access protected
+     * @param mixed $order
+     * @return array
+     */
+    protected function parseOrder($order) {
+        if(is_string($order)) {
+            $array   =  explode(',',$order);
+            $order   =  array();
+            foreach ($array as $key=>$val){
+                $arr  =  explode(' ',trim($val));
+                if(isset($arr[1])) {
+                    $arr[1]  =  $arr[1]=='asc'?1:-1;
+                }else{
+                    $arr[1]  =  1;
+                }
+                $order[$arr[0]]    = $arr[1];
+            }
+        }
+        return $order;
+    }
+
+    /**
+     * limit分析
+     * @access protected
+     * @param mixed $limit
+     * @return array
+     */
+    protected function parseLimit($limit) {
+        if(strpos($limit,',')) {
+            $array  =  explode(',',$limit);
+        }else{
+            $array   =  array(0,$limit);
+        }
+        return $array;
+    }
+
+    /**
+     * field分析
+     * @access protected
+     * @param mixed $fields
+     * @return array
+     */
+    public function parseField($fields){
+        if(empty($fields)) {
+            $fields    = array();
+        }
+        if(is_string($fields)) {
+            $_fields    = explode(',',$fields);
+            $fields     = array();
+            foreach ($_fields as $f)
+                $fields[$f] = true;
+        }elseif(is_array($fields)) {
+            $_fields    = $fields;
+            $fields     = array();
+            foreach ($_fields as $f=>$v) {
+                if(is_numeric($f))
+                    $fields[$v] = true;
+                else
+                    $fields[$f] = $v ? true : false;
+            }
+        }
+        return $fields;
+    }
+
+    /**
+     * where分析
+     * @access protected
+     * @param mixed $where
+     * @return array
+     */
+    public function parseWhere($where){
+        $query   = array();
+        $return     = array();
+        $_logic     = '$and';
+        if(isset($where['_logic'])){
+            $where['_logic']    = strtolower($where['_logic']);
+            $_logic             = in_array($where['_logic'], array('or','xor','nor', 'and'))?'$'.$where['_logic']:$_logic;
+            unset($where['_logic']);
+        }
+        foreach ($where as $key=>$val){
+            if('_id' != $key && 0===strpos($key,'_')) {
+                // 解析特殊条件表达式
+                $parse   = $this->parseThinkWhere($key,$val);
+                $query   = array_merge($query,$parse);
+            }else{
+                // 查询字段的安全过滤
+                if(!preg_match('/^[A-Z_\|\&\-.a-z0-9]+$/',trim($key))){
+                    E(L('_ERROR_QUERY_').':'.$key);
+                }
+                $key = trim($key);
+                if(strpos($key,'|')) {
+                    $array   =  explode('|',$key);
+                    $str   = array();
+                    foreach ($array as $k){
+                        $str[]   = $this->parseWhereItem($k,$val);
+                    }
+                    $query['$or'] =    $str;
+                }elseif(strpos($key,'&')){
+                    $array   =  explode('&',$key);
+                    $str   = array();
+                    foreach ($array as $k){
+                        $str[]   = $this->parseWhereItem($k,$val);
+                    }
+                    $query   = array_merge($query,$str);
+                }else{
+                    $str   = $this->parseWhereItem($key,$val);
+                    $query   = array_merge($query,$str);
+                }
+            }
+        }
+        if($_logic == '$and')
+            return $query;
+        
+        foreach($query as $key=>$val)
+            $return[$_logic][]  = array($key=>$val);
+
+        return $return;
+    }
+
+    /**
+     * 特殊条件分析
+     * @access protected
+     * @param string $key
+     * @param mixed $val
+     * @return string
+     */
+    protected function parseThinkWhere($key,$val) {
+        $query   = array();
+        $_logic = array('or','xor','nor', 'and');
+        
+        switch($key) {
+            case '_query': // 字符串模式查询条件
+                parse_str($val,$query);
+                if(isset($query['_logic']) && strtolower($query['_logic']) == 'or' ) {
+                    unset($query['_logic']);
+                    $query['$or']   =  $query;
+                }
+                break;
+            case '_complex': // 子查询模式查询条件
+                $__logic = strtolower($val['_logic']);
+                if(isset($val['_logic']) && in_array($__logic, $_logic) ) {
+                    unset($val['_logic']);
+                    $query['$'.$__logic]   =  $val;
+                }
+                break;
+            case '_string':// MongoCode查询
+                $query['$where']  = new \MongoCode($val);
+                break;
+        }
+        //兼容 MongoClient OR条件查询方法
+        if(isset($query['$or']) && !is_array(current($query['$or']))) {
+            $val = array();
+            foreach ($query['$or'] as $k=>$v)
+                $val[] = array($k=>$v);
+            $query['$or'] = $val;
+        }
+        return $query;
+    }
+
+    /**
+     * where子单元分析
+     * @access protected
+     * @param string $key
+     * @param mixed $val
+     * @return array
+     */
+    protected function parseWhereItem($key,$val) {
+        $query   = array();
+        if(is_array($val)) {
+            if(is_string($val[0])) {
+                $con  =  strtolower($val[0]);
+                if(in_array($con,array('neq','ne','gt','egt','gte','lt','lte','elt'))) { // 比较运算
+                    $k = '$'.$this->comparison[$con];
+                    $query[$key]  =  array($k=>$val[1]);
+                }elseif('like'== $con){ // 模糊查询 采用正则方式
+                    $query[$key]  =  new \MongoRegex("/".$val[1]."/");  
+                }elseif('mod'==$con){ // mod 查询
+                    $query[$key]   =  array('$mod'=>$val[1]);
+                }elseif('regex'==$con){ // 正则查询
+                    $query[$key]  =  new \MongoRegex($val[1]);
+                }elseif(in_array($con,array('in','nin','not in'))){ // IN NIN 运算
+                    $data = is_string($val[1])? explode(',',$val[1]):$val[1];
+                    $k = '$'.$this->comparison[$con];
+                    $query[$key]  =  array($k=>$data);
+                }elseif('all'==$con){ // 满足所有指定条件
+                    $data = is_string($val[1])? explode(',',$val[1]):$val[1];
+                    $query[$key]  =  array('$all'=>$data);
+                }elseif('between'==$con){ // BETWEEN运算
+                    $data = is_string($val[1])? explode(',',$val[1]):$val[1];
+                    $query[$key]  =  array('$gte'=>$data[0],'$lte'=>$data[1]);
+                }elseif('not between'==$con){
+                    $data = is_string($val[1])? explode(',',$val[1]):$val[1];
+                    $query[$key]  =  array('$lt'=>$data[0],'$gt'=>$data[1]);
+                }elseif('exp'==$con){ // 表达式查询
+                    $query['$where']  = new \MongoCode($val[1]);
+                }elseif('exists'==$con){ // 字段是否存在
+                    $query[$key]  = array('$exists'=>(bool)$val[1]);
+                }elseif('size'==$con){ // 限制属性大小
+                    $query[$key]  = array('$size'=>intval($val[1]));
+                }elseif('type'==$con){ // 限制字段类型 1 浮点型 2 字符型 3 对象或者MongoDBRef 5 MongoBinData 7 MongoId 8 布尔型 9 MongoDate 10 NULL 15 MongoCode 16 32位整型 17 MongoTimestamp 18 MongoInt64 如果是数组的话判断元素的类型
+                    $query[$key]  = array('$type'=>intval($val[1]));
+                }else{
+                    $query[$key]  =  $val;
+                }
+                return $query;
+            }
+        }
+        $query[$key]  =  $val;
+        return $query;
+    }
+}

+ 0 - 0
ThinkPHP/Library/Think/Db/Driver/Mysql.class.php


Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels