From 5f95d62cf2f978609d44c8072ee399aa64a6c2e3 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Sun, 14 Dec 2014 10:16:38 +0800 Subject: [PATCH 001/166] =?UTF-8?q?I=E5=87=BD=E6=95=B0=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E4=BF=AE=E9=A5=B0=E7=AC=A6=E5=8A=9F=E8=83=BD=E5=92=8C=E6=AD=A3?= =?UTF-8?q?=E5=88=99=E6=A3=80=E6=B5=8B=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Common/functions.php | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/ThinkPHP/Common/functions.php b/ThinkPHP/Common/functions.php index 7c3e697b6..6ac4961a4 100644 --- a/ThinkPHP/Common/functions.php +++ b/ThinkPHP/Common/functions.php @@ -269,6 +269,9 @@ function T($template='',$layer=''){ * @return mixed */ function I($name,$default='',$filter=null,$datas=null) { + if(strpos($name,'/')){ // 指定修饰符 + list($name,$type) = explode('/',$name,2); + } if(strpos($name,'.')) { // 指定参数来源 list($method,$name) = explode('.',$name,2); }else{ // 默认为自动判断 @@ -329,15 +332,39 @@ function I($name,$default='',$filter=null,$datas=null) { foreach($filters as $filter){ if(function_exists($filter)) { - $data = is_array($data)?array_map_recursive($filter,$data):$filter($data); // 参数过滤 + $data = is_array($data) ? array_map_recursive($filter,$data) : filter($data); // 参数过滤 + }elseif(0===strpos($filter,'/')){ + // 支持正则验证 + if(1 !== preg_match($filter,(string)$data)){ + return isset($default) ? $default : NULL; + } }else{ - $data = filter_var($data,is_int($filter)?$filter:filter_id($filter)); + $data = filter_var($data,is_int($filter) ? $filter : filter_id($filter)); if(false === $data) { - return isset($default)?$default:NULL; + return isset($default) ? $default : NULL; } } } } + if(!empty($type)){ + switch(strtolower($type)){ + case 's': // 字符串 + $data = (string)$data; + break; + case 'a': // 数组 + $data = (array)$data; + break; + case 'd': // 数字 + $data = (int)$data; + break; + case 'f': // 浮点 + $data = (float)$data; + break; + case 'b': // 布尔 + $data = (boolean)$data; + break; + } + } }else{ // 变量默认值 $data = isset($default)?$default:NULL; } From 1d9aa58e4ea7fb01503341eba3f46b3115e88da3 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Sun, 14 Dec 2014 11:21:10 +0800 Subject: [PATCH 002/166] =?UTF-8?q?=E6=A8=A1=E5=9E=8B=E7=B1=BB=5FparseOpti?= =?UTF-8?q?ons=E4=B8=AD=E7=9A=84=E6=A3=80=E6=B5=8B=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=E8=B0=83=E6=95=B4=E5=9B=9E=E5=8E=9F=E6=9D=A5=20=E9=81=BF?= =?UTF-8?q?=E5=85=8D=E4=BD=BF=E7=94=A8=E5=90=8C=E5=90=8D=E6=95=B0=E7=BB=84?= =?UTF-8?q?=E8=A1=A8=E5=8D=95=E6=95=B0=E6=8D=AE=E7=9A=84=E6=97=B6=E5=80=99?= =?UTF-8?q?=E8=A2=AB=E8=BD=AC=E6=8D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Model.class.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ThinkPHP/Library/Think/Model.class.php b/ThinkPHP/Library/Think/Model.class.php index 63193df24..a8e02dbe1 100644 --- a/ThinkPHP/Library/Think/Model.class.php +++ b/ThinkPHP/Library/Think/Model.class.php @@ -656,9 +656,7 @@ protected function _parseOptions($options=array()) { if(in_array($key,$fields,true)){ if(is_scalar($val)) { $this->_parseType($options['where'],$key); - }elseif(is_array($val) && isset($_REQUEST[$key]) && is_array($_REQUEST[$key])){ - $options['where'][$key] = (string)$val; - } + } }elseif(!is_numeric($key) && '_' != substr($key,0,1) && false === strpos($key,'.') && false === strpos($key,'(') && false === strpos($key,'|') && false === strpos($key,'&')){ if(!empty($this->options['strict'])){ E(L('_ERROR_QUERY_EXPRESS_').':['.$key.'=>'.$val.']'); From 2641c80ec47efd7692d9e9b19af71fe4dcff3f33 Mon Sep 17 00:00:00 2001 From: Wilson Liu Date: Mon, 15 Dec 2014 00:21:15 +0800 Subject: [PATCH 003/166] Update Think.class.php MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 89行加个\更规范点 --- ThinkPHP/Library/Think/Think.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ThinkPHP/Library/Think/Think.class.php b/ThinkPHP/Library/Think/Think.class.php index f7ef3b7c4..3bd18643e 100644 --- a/ThinkPHP/Library/Think/Think.class.php +++ b/ThinkPHP/Library/Think/Think.class.php @@ -86,7 +86,7 @@ static public function start() { L(include THINK_PATH.'Lang/'.strtolower(C('DEFAULT_LANG')).'.php'); if(!APP_DEBUG){ - $content .= "\nnamespace { Think\Think::addMap(".var_export(self::$_map,true).");"; + $content .= "\nnamespace { Think\\Think::addMap(".var_export(self::$_map,true).");"; $content .= "\nL(".var_export(L(),true).");\nC(".var_export(C(),true).');Think\Hook::import('.var_export(Hook::get(),true).');}'; Storage::put($runtimefile,strip_whitespace(' Date: Mon, 15 Dec 2014 09:38:00 +0800 Subject: [PATCH 004/166] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E4=B8=80=E5=A4=84?= =?UTF-8?q?=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Common/functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ThinkPHP/Common/functions.php b/ThinkPHP/Common/functions.php index 6ac4961a4..d65563773 100644 --- a/ThinkPHP/Common/functions.php +++ b/ThinkPHP/Common/functions.php @@ -332,7 +332,7 @@ function I($name,$default='',$filter=null,$datas=null) { foreach($filters as $filter){ if(function_exists($filter)) { - $data = is_array($data) ? array_map_recursive($filter,$data) : filter($data); // 参数过滤 + $data = is_array($data) ? array_map_recursive($filter,$data) : $filter($data); // 参数过滤 }elseif(0===strpos($filter,'/')){ // 支持正则验证 if(1 !== preg_match($filter,(string)$data)){ From 7b0195345bc7a3713099eadcee9d052b7e246d43 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Thu, 18 Dec 2014 16:48:48 +0800 Subject: [PATCH 005/166] =?UTF-8?q?=E6=94=B9=E8=BF=9Bsession=E5=87=BD?= =?UTF-8?q?=E6=95=B0=E5=AF=B9=E5=A4=9A=E7=BB=B4=E8=B5=8B=E5=80=BC=E7=9A=84?= =?UTF-8?q?=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Common/functions.php | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/ThinkPHP/Common/functions.php b/ThinkPHP/Common/functions.php index d65563773..9485caa8a 100644 --- a/ThinkPHP/Common/functions.php +++ b/ThinkPHP/Common/functions.php @@ -1288,14 +1288,20 @@ function session($name='',$value='') { } } }else{ // 设置session - if($prefix){ - if (!isset($_SESSION[$prefix])) { - $_SESSION[$prefix] = array(); - } - $_SESSION[$prefix][$name] = $value; - }else{ - $_SESSION[$name] = $value; - } + if(strpos($name,'.')){ + list($name1,$name2) = explode('.',$name); + if($prefix){ + $_SESSION[$prefix][$name1][$name2] = $value; + }else{ + $_SESSION[$name1][$name2] = $value; + } + }else{ + if($prefix){ + $_SESSION[$prefix][$name] = $value; + }else{ + $_SESSION[$name] = $value; + } + } } return null; } From b70ebb6b7a48fadbd34e4ebd7506a30c25a7c3c6 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Thu, 18 Dec 2014 22:54:57 +0800 Subject: [PATCH 006/166] =?UTF-8?q?=E6=94=B9=E8=BF=9B=E6=A8=A1=E6=9D=BF?= =?UTF-8?q?=E5=BC=95=E6=93=8E=E8=A7=A3=E6=9E=90=E7=9A=84=E4=B8=80=E5=A4=84?= =?UTF-8?q?BUG?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Template.class.php | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/ThinkPHP/Library/Think/Template.class.php b/ThinkPHP/Library/Think/Template.class.php index 90d3d8734..b8c7a964f 100644 --- a/ThinkPHP/Library/Think/Template.class.php +++ b/ThinkPHP/Library/Think/Template.class.php @@ -180,8 +180,8 @@ public function parse($content) { foreach ($tagLibs as $tag){ $this->parseTagLib($tag,$content,true); } - //解析普通模板标签 {tagName} - $content = preg_replace_callback('/('.$this->config['tmpl_begin'].')([^\d\s'.$this->config['tmpl_begin'].$this->config['tmpl_end'].'].+?)('.$this->config['tmpl_end'].')/is', array($this, 'parseTag'),$content); + //解析普通模板标签 {$tagName} + $content = preg_replace_callback('/('.$this->config['tmpl_begin'].')([^\d\w\s'.$this->config['tmpl_begin'].$this->config['tmpl_end'].'].+?)('.$this->config['tmpl_end'].')/is', array($this, 'parseTag'),$content); return $content; } @@ -462,10 +462,6 @@ public function parseTag($tagStr){ //if (MAGIC_QUOTES_GPC) { $tagStr = stripslashes($tagStr); //} - //还原非模板标签 - if(preg_match('/^[\s|\d]/is',$tagStr)) - //过滤空格和数字打头的标签 - return C('TMPL_L_DELIM') . $tagStr .C('TMPL_R_DELIM'); $flag = substr($tagStr,0,1); $flag2 = substr($tagStr,1,1); $name = substr($tagStr,1); From fabca592a4426afe68a574a7949f3f24775cd41b Mon Sep 17 00:00:00 2001 From: thinkphp Date: Fri, 19 Dec 2014 10:43:43 +0800 Subject: [PATCH 007/166] =?UTF-8?q?=E6=94=B9=E8=BF=9BDb=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Common/functions.php | 2 +- ThinkPHP/Library/Think/Db/Driver.class.php | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/ThinkPHP/Common/functions.php b/ThinkPHP/Common/functions.php index 9485caa8a..2cb295cd2 100644 --- a/ThinkPHP/Common/functions.php +++ b/ThinkPHP/Common/functions.php @@ -1505,7 +1505,7 @@ function think_filter(&$value){ // TODO 其他安全过滤 // 过滤查询特殊字符 - if(preg_match('/^(EXP|NEQ|GT|EGT|LT|ELT|OR|LIKE|NOTLIKE|BETWEEN|IN)$/i',$value)){ + if(preg_match('/^(EXP|NEQ|GT|EGT|LT|ELT|OR|LIKE|NOTLIKE|NOTBETWEEN|BETWEEN|NOTIN|IN)$/i',$value)){ $value .= ' '; } } diff --git a/ThinkPHP/Library/Think/Db/Driver.class.php b/ThinkPHP/Library/Think/Db/Driver.class.php index 978de821d..fb0729d60 100644 --- a/ThinkPHP/Library/Think/Db/Driver.class.php +++ b/ThinkPHP/Library/Think/Db/Driver.class.php @@ -55,7 +55,7 @@ abstract class Driver { 'db_like_fields' => '', ); // 数据库表达式 - protected $comparison = array('eq'=>'=','neq'=>'<>','gt'=>'>','egt'=>'>=','lt'=>'<','elt'=>'<=','notlike'=>'NOT LIKE','like'=>'LIKE','in'=>'IN','notin'=>'NOT IN'); + protected $exp = array('eq'=>'=','neq'=>'<>','gt'=>'>','egt'=>'>=','lt'=>'<','elt'=>'<=','notlike'=>'NOT LIKE','like'=>'LIKE','in'=>'IN','notin'=>'NOT IN','between'=>'BETWEEN','notbetween'=>'NOT BETWEEN'); // 查询表达式 protected $selectSql = 'SELECT%DISTINCT% %FIELD% FROM %TABLE%%FORCE%%JOIN%%WHERE%%GROUP%%HAVING%%ORDER%%LIMIT% %UNION%%LOCK%%COMMENT%'; // 查询次数 @@ -532,39 +532,39 @@ protected function parseWhereItem($key,$val) { $whereStr = ''; if(is_array($val)) { if(is_string($val[0])) { + $exp = $this->exp[strtolower($val[0])]; if(preg_match('/^(EQ|NEQ|GT|EGT|LT|ELT)$/i',$val[0])) { // 比较运算 - $whereStr .= $key.' '.$this->comparison[strtolower($val[0])].' '.$this->parseValue($val[1]); + $whereStr .= $key.' '.$exp.' '.$this->parseValue($val[1]); }elseif(preg_match('/^(NOTLIKE|LIKE)$/i',$val[0])){// 模糊查找 if(is_array($val[1])) { $likeLogic = isset($val[2])?strtoupper($val[2]):'OR'; if(in_array($likeLogic,array('AND','OR','XOR'))){ - $likeStr = $this->comparison[strtolower($val[0])]; $like = array(); foreach ($val[1] as $item){ - $like[] = $key.' '.$likeStr.' '.$this->parseValue($item); + $like[] = $key.' '.$exp.' '.$this->parseValue($item); } $whereStr .= '('.implode(' '.$likeLogic.' ',$like).')'; } }else{ - $whereStr .= $key.' '.$this->comparison[strtolower($val[0])].' '.$this->parseValue($val[1]); + $whereStr .= $key.' '.$exp.' '.$this->parseValue($val[1]); } }elseif('bind'==strtolower($val[0])){ // 使用表达式 $whereStr .= $key.' = :'.$val[1]; }elseif('exp'==strtolower($val[0])){ // 使用表达式 $whereStr .= $key.' '.$val[1]; - }elseif(preg_match('/IN/i',$val[0])){ // IN 运算 + }elseif(preg_match('/^(NOTIN|IN)$/i',$val[0])){ // IN 运算 if(isset($val[2]) && 'exp'==$val[2]) { - $whereStr .= $key.' '.strtoupper($val[0]).' '.$val[1]; + $whereStr .= $key.' '.$exp.' '.$val[1]; }else{ if(is_string($val[1])) { $val[1] = explode(',',$val[1]); } $zone = implode(',',$this->parseValue($val[1])); - $whereStr .= $key.' '.strtoupper($val[0]).' ('.$zone.')'; + $whereStr .= $key.' '.$exp.' ('.$zone.')'; } - }elseif(preg_match('/BETWEEN/i',$val[0])){ // BETWEEN运算 + }elseif(preg_match('/^(NOTBETWEEN|BETWEEN)$/i',$val[0])){ // BETWEEN运算 $data = is_string($val[1])? explode(',',$val[1]):$val[1]; - $whereStr .= $key.' '.strtoupper($val[0]).' '.$this->parseValue($data[0]).' AND '.$this->parseValue($data[1]); + $whereStr .= $key.' '.$exp.' '.$this->parseValue($data[0]).' AND '.$this->parseValue($data[1]); }else{ E(L('_EXPRESS_ERROR_').':'.$val[0]); } From 5bcde4cdaa63a7dbe53ad0fb6809910c268f4e78 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Fri, 19 Dec 2014 11:02:40 +0800 Subject: [PATCH 008/166] =?UTF-8?q?=E6=94=B9=E8=BF=9BDb\Driver=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Db/Driver.class.php | 26 +++++++++++----------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/ThinkPHP/Library/Think/Db/Driver.class.php b/ThinkPHP/Library/Think/Db/Driver.class.php index fb0729d60..0b3c6599d 100644 --- a/ThinkPHP/Library/Think/Db/Driver.class.php +++ b/ThinkPHP/Library/Think/Db/Driver.class.php @@ -532,39 +532,39 @@ protected function parseWhereItem($key,$val) { $whereStr = ''; if(is_array($val)) { if(is_string($val[0])) { - $exp = $this->exp[strtolower($val[0])]; - if(preg_match('/^(EQ|NEQ|GT|EGT|LT|ELT)$/i',$val[0])) { // 比较运算 - $whereStr .= $key.' '.$exp.' '.$this->parseValue($val[1]); - }elseif(preg_match('/^(NOTLIKE|LIKE)$/i',$val[0])){// 模糊查找 + $exp = strtolower($val[0]); + if(preg_match('/^(eq|neq|gt|egt|lt|elt)$/',$exp)) { // 比较运算 + $whereStr .= $key.' '.$this->exp[$exp].' '.$this->parseValue($val[1]); + }elseif(preg_match('/^(notlike|like)$/',$exp)){// 模糊查找 if(is_array($val[1])) { $likeLogic = isset($val[2])?strtoupper($val[2]):'OR'; if(in_array($likeLogic,array('AND','OR','XOR'))){ $like = array(); foreach ($val[1] as $item){ - $like[] = $key.' '.$exp.' '.$this->parseValue($item); + $like[] = $key.' '.$this->exp[$exp].' '.$this->parseValue($item); } $whereStr .= '('.implode(' '.$likeLogic.' ',$like).')'; } }else{ - $whereStr .= $key.' '.$exp.' '.$this->parseValue($val[1]); + $whereStr .= $key.' '.$this->exp[$exp].' '.$this->parseValue($val[1]); } - }elseif('bind'==strtolower($val[0])){ // 使用表达式 + }elseif('bind' == $exp ){ // 使用表达式 $whereStr .= $key.' = :'.$val[1]; - }elseif('exp'==strtolower($val[0])){ // 使用表达式 + }elseif('exp' == $exp ){ // 使用表达式 $whereStr .= $key.' '.$val[1]; - }elseif(preg_match('/^(NOTIN|IN)$/i',$val[0])){ // IN 运算 + }elseif(preg_match('/^(notin|in)$/',$exp)){ // IN 运算 if(isset($val[2]) && 'exp'==$val[2]) { - $whereStr .= $key.' '.$exp.' '.$val[1]; + $whereStr .= $key.' '.$this->exp[$exp].' '.$val[1]; }else{ if(is_string($val[1])) { $val[1] = explode(',',$val[1]); } $zone = implode(',',$this->parseValue($val[1])); - $whereStr .= $key.' '.$exp.' ('.$zone.')'; + $whereStr .= $key.' '.$this->exp[$exp].' ('.$zone.')'; } - }elseif(preg_match('/^(NOTBETWEEN|BETWEEN)$/i',$val[0])){ // BETWEEN运算 + }elseif(preg_match('/^(notbetween|between)$/',$exp)){ // BETWEEN运算 $data = is_string($val[1])? explode(',',$val[1]):$val[1]; - $whereStr .= $key.' '.$exp.' '.$this->parseValue($data[0]).' AND '.$this->parseValue($data[1]); + $whereStr .= $key.' '.$this->exp[$exp].' '.$this->parseValue($data[0]).' AND '.$this->parseValue($data[1]); }else{ E(L('_EXPRESS_ERROR_').':'.$val[0]); } From 3e2bd35f4f73cdb83c439d5f689c4bae9f90279b Mon Sep 17 00:00:00 2001 From: huangdijia Date: Fri, 19 Dec 2014 11:30:12 +0800 Subject: [PATCH 009/166] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=BF=AB=E6=8D=B7?= =?UTF-8?q?=E8=B0=83=E7=94=A8=E6=96=B9=E5=BC=8F=20cache(10)=20=E7=AD=89?= =?UTF-8?q?=E5=90=8C=E4=BA=8E=20cache(true,=2010)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Model.class.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ThinkPHP/Library/Think/Model.class.php b/ThinkPHP/Library/Think/Model.class.php index a8e02dbe1..40298e76e 100644 --- a/ThinkPHP/Library/Think/Model.class.php +++ b/ThinkPHP/Library/Think/Model.class.php @@ -1694,6 +1694,11 @@ public function union($union,$all=false) { * @return Model */ public function cache($key=true,$expire=null,$type=''){ + // 增加快捷调用方式 cache(10) 等同于 cache(true, 10) + if(is_numeric($key) && is_null($expire)){ + $expire = $key; + $key = true; + } if(false !== $key) $this->options['cache'] = array('key'=>$key,'expire'=>$expire,'type'=>$type); return $this; From 234f045cf95a8792eedbcec2bd8b554da56ad2aa Mon Sep 17 00:00:00 2001 From: thinkphp Date: Fri, 19 Dec 2014 15:19:12 +0800 Subject: [PATCH 010/166] =?UTF-8?q?=E6=94=B9=E8=BF=9Bthink=5Ffilter?= =?UTF-8?q?=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Common/functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ThinkPHP/Common/functions.php b/ThinkPHP/Common/functions.php index 2cb295cd2..58d022be0 100644 --- a/ThinkPHP/Common/functions.php +++ b/ThinkPHP/Common/functions.php @@ -1505,7 +1505,7 @@ function think_filter(&$value){ // TODO 其他安全过滤 // 过滤查询特殊字符 - if(preg_match('/^(EXP|NEQ|GT|EGT|LT|ELT|OR|LIKE|NOTLIKE|NOTBETWEEN|BETWEEN|NOTIN|IN)$/i',$value)){ + if(preg_match('/^(EXP|NEQ|GT|EGT|LT|ELT|OR|XOR|LIKE|NOTLIKE|NOTBETWEEN|BETWEEN|NOTIN|IN)$/i',$value)){ $value .= ' '; } } From 504062bae918049cdbcc02139ef244fd278ce412 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Sun, 21 Dec 2014 21:43:22 +0800 Subject: [PATCH 011/166] =?UTF-8?q?=E8=A1=A8=E8=BE=BE=E5=BC=8F=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E6=94=AF=E6=8C=81=20not=20in/notin=20=20=E5=92=8C=20n?= =?UTF-8?q?ot=20between/notbetween=20=E4=BE=BF=E4=BA=8E=E5=85=BC=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Common/functions.php | 2 +- ThinkPHP/Library/Think/Db/Driver.class.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ThinkPHP/Common/functions.php b/ThinkPHP/Common/functions.php index 58d022be0..f1faf823c 100644 --- a/ThinkPHP/Common/functions.php +++ b/ThinkPHP/Common/functions.php @@ -1505,7 +1505,7 @@ function think_filter(&$value){ // TODO 其他安全过滤 // 过滤查询特殊字符 - if(preg_match('/^(EXP|NEQ|GT|EGT|LT|ELT|OR|XOR|LIKE|NOTLIKE|NOTBETWEEN|BETWEEN|NOTIN|IN)$/i',$value)){ + if(preg_match('/^(EXP|NEQ|GT|EGT|LT|ELT|OR|XOR|LIKE|NOTLIKE|NOT BETWEEN|NOTBETWEEN|BETWEEN|NOTIN|NOT IN|IN)$/i',$value)){ $value .= ' '; } } diff --git a/ThinkPHP/Library/Think/Db/Driver.class.php b/ThinkPHP/Library/Think/Db/Driver.class.php index 0b3c6599d..392cdd271 100644 --- a/ThinkPHP/Library/Think/Db/Driver.class.php +++ b/ThinkPHP/Library/Think/Db/Driver.class.php @@ -55,7 +55,7 @@ abstract class Driver { 'db_like_fields' => '', ); // 数据库表达式 - protected $exp = array('eq'=>'=','neq'=>'<>','gt'=>'>','egt'=>'>=','lt'=>'<','elt'=>'<=','notlike'=>'NOT LIKE','like'=>'LIKE','in'=>'IN','notin'=>'NOT IN','between'=>'BETWEEN','notbetween'=>'NOT BETWEEN'); + protected $exp = array('eq'=>'=','neq'=>'<>','gt'=>'>','egt'=>'>=','lt'=>'<','elt'=>'<=','notlike'=>'NOT LIKE','like'=>'LIKE','in'=>'IN','notin'=>'NOT IN','not in'=>'NOT IN','between'=>'BETWEEN','not between'=>'NOT BETWEEN','notbetween'=>'NOT BETWEEN'); // 查询表达式 protected $selectSql = 'SELECT%DISTINCT% %FIELD% FROM %TABLE%%FORCE%%JOIN%%WHERE%%GROUP%%HAVING%%ORDER%%LIMIT% %UNION%%LOCK%%COMMENT%'; // 查询次数 @@ -552,7 +552,7 @@ protected function parseWhereItem($key,$val) { $whereStr .= $key.' = :'.$val[1]; }elseif('exp' == $exp ){ // 使用表达式 $whereStr .= $key.' '.$val[1]; - }elseif(preg_match('/^(notin|in)$/',$exp)){ // IN 运算 + }elseif(preg_match('/^(notin|not in|in)$/',$exp)){ // IN 运算 if(isset($val[2]) && 'exp'==$val[2]) { $whereStr .= $key.' '.$this->exp[$exp].' '.$val[1]; }else{ @@ -562,7 +562,7 @@ protected function parseWhereItem($key,$val) { $zone = implode(',',$this->parseValue($val[1])); $whereStr .= $key.' '.$this->exp[$exp].' ('.$zone.')'; } - }elseif(preg_match('/^(notbetween|between)$/',$exp)){ // BETWEEN运算 + }elseif(preg_match('/^(notbetween|not between|between)$/',$exp)){ // BETWEEN运算 $data = is_string($val[1])? explode(',',$val[1]):$val[1]; $whereStr .= $key.' '.$this->exp[$exp].' '.$this->parseValue($data[0]).' AND '.$this->parseValue($data[1]); }else{ From e21c7c8ba91e02d8b50dc29b8e8a954f311a98a6 Mon Sep 17 00:00:00 2001 From: huangdijia Date: Mon, 22 Dec 2014 16:48:51 +0800 Subject: [PATCH 012/166] =?UTF-8?q?=E5=A2=9E=E5=8A=A0ON=20DUPLICATE=20KEY?= =?UTF-8?q?=20UPDATE=E6=94=AF=E6=8C=81=EF=BC=8C=E7=9B=AE=E5=89=8D=E5=8F=AA?= =?UTF-8?q?=E6=94=AF=E6=8C=81mysql?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 使用方式 add($data='',$options=array(),$replace=false) 其中add方法增加$replace参数(是否添加数据时允许覆盖),true表示REPLACE方式覆盖,array表示ON DUPLICATE KEY UPDATE方式更新,默认为false 快捷方式: add($data, array(), 'field1,field2') 或 add($data, array(), array('field1','field2')) 解析后 ON DUPLICATE KEY UPDATE field1=VALUES(field1), field2=VALUES(field2) 增强方式,支持传值及表达式 add($data, array(), array('field1'=>'value1','field2'=>array('value', 'value2'), 'field3'=>array('exp', 'field3+1'))) 解析后 ON DUPLICATE KEY UPDATE field1='value1', field2='value2', field3=(field3+1) --- ThinkPHP/Library/Think/Db/Driver.class.php | 46 +++++++++++++++++++++- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/ThinkPHP/Library/Think/Db/Driver.class.php b/ThinkPHP/Library/Think/Db/Driver.class.php index 392cdd271..c88cbbd33 100644 --- a/ThinkPHP/Library/Think/Db/Driver.class.php +++ b/ThinkPHP/Library/Think/Db/Driver.class.php @@ -761,6 +761,46 @@ protected function parseForce($index) { return sprintf(" FORCE INDEX ( %s ) ", $index); } + /** + * ON DUPLICATE KEY UPDATE 分析 + * @access protected + * @param mixed $duplicate + * @return string + */ + protected function parseDuplicate($duplicate){ + // 只支持mysql + if($this->config['type']!='mysql') return ''; + // 布尔值或空则返回空字符串 + if(is_bool($duplicate) || empty($duplicate)) return ''; + // field1,field2 转数组 + if(is_string($duplicate)) $duplicate = explode(',', $duplicate); + // 对象转数组 + if(is_object($duplicate)) $duplicate = get_class_vars($duplicate); + $updates = array(); + foreach((array) $duplicate as $key=>$val){ + if(is_numeric($key)){ // array('field1', 'field2', 'field3') 解析为 ON DUPLICATE KEY UPDATE field1=VALUES(field1), field2=VALUES(field2), field3=VALUES(field3) + $updates[] = $this->parseKey($val)."=VALUES(".$this->parseKey($val).")"; + }else{ + if(is_scalar($val)) // 兼容标量传值方式 + $val = array('value', $val); + if(!isset($val[1])) continue; + switch($val[0]){ + case 'exp': // 表达式 + $updates[] = $this->parseKey($key)."=($val[1])"; + break; + case 'value': // 值 + default: + $name = count($this->bind); + $updates[] = $this->parseKey($key)."=:".$name; + $this->bindParam($name, $val[1]); + break; + } + } + } + if(empty($updates)) return ''; + return " ON DUPLICATE KEY UPDATE ".join(', ', $updates); + } + /** * 插入记录 * @access public @@ -788,8 +828,10 @@ public function insert($data,$options=array(),$replace=false) { } } } - $sql = ($replace?'REPLACE':'INSERT').' INTO '.$this->parseTable($options['table']).' ('.implode(',', $fields).') VALUES ('.implode(',', $values).')'; - $sql .= $this->parseComment(!empty($options['comment'])?$options['comment']:''); + // 兼容数字传入方式 + $replace= (is_numeric($replace) && $replace>0)?true:$replace; + $sql = (true===$replace?'REPLACE':'INSERT').' INTO '.$this->parseTable($options['table']).' ('.implode(',', $fields).') VALUES ('.implode(',', $values).')'.$this->parseDuplicate($replace); + $sql .= $this->parseComment(!empty($options['comment'])?$options['comment']:''); return $this->execute($sql,!empty($options['fetch_sql']) ? true : false); } From dfd6dd34ecaa994626ada15c17dc3c0502fef32a Mon Sep 17 00:00:00 2001 From: huangdijia Date: Tue, 23 Dec 2014 08:50:43 +0800 Subject: [PATCH 013/166] =?UTF-8?q?ON=20DUPLICATE=20KEY=20UPDATE=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E7=A7=BB=E8=87=B3MySQL=E9=A9=B1=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Db/Driver.class.php | 32 +--------------- .../Library/Think/Db/Driver/Mysql.class.php | 38 +++++++++++++++++++ 2 files changed, 39 insertions(+), 31 deletions(-) diff --git a/ThinkPHP/Library/Think/Db/Driver.class.php b/ThinkPHP/Library/Think/Db/Driver.class.php index c88cbbd33..1b0b2777f 100644 --- a/ThinkPHP/Library/Think/Db/Driver.class.php +++ b/ThinkPHP/Library/Think/Db/Driver.class.php @@ -768,37 +768,7 @@ protected function parseForce($index) { * @return string */ protected function parseDuplicate($duplicate){ - // 只支持mysql - if($this->config['type']!='mysql') return ''; - // 布尔值或空则返回空字符串 - if(is_bool($duplicate) || empty($duplicate)) return ''; - // field1,field2 转数组 - if(is_string($duplicate)) $duplicate = explode(',', $duplicate); - // 对象转数组 - if(is_object($duplicate)) $duplicate = get_class_vars($duplicate); - $updates = array(); - foreach((array) $duplicate as $key=>$val){ - if(is_numeric($key)){ // array('field1', 'field2', 'field3') 解析为 ON DUPLICATE KEY UPDATE field1=VALUES(field1), field2=VALUES(field2), field3=VALUES(field3) - $updates[] = $this->parseKey($val)."=VALUES(".$this->parseKey($val).")"; - }else{ - if(is_scalar($val)) // 兼容标量传值方式 - $val = array('value', $val); - if(!isset($val[1])) continue; - switch($val[0]){ - case 'exp': // 表达式 - $updates[] = $this->parseKey($key)."=($val[1])"; - break; - case 'value': // 值 - default: - $name = count($this->bind); - $updates[] = $this->parseKey($key)."=:".$name; - $this->bindParam($name, $val[1]); - break; - } - } - } - if(empty($updates)) return ''; - return " ON DUPLICATE KEY UPDATE ".join(', ', $updates); + return ''; } /** diff --git a/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php b/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php index 5f196b0f9..653e5fbb0 100644 --- a/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php +++ b/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php @@ -130,4 +130,42 @@ public function insertAll($dataSet,$options=array(),$replace=false) { $sql .= $this->parseComment(!empty($options['comment'])?$options['comment']:''); return $this->execute($sql,!empty($options['fetch_sql']) ? true : false); } + + /** + * ON DUPLICATE KEY UPDATE 分析 + * @access protected + * @param mixed $duplicate + * @return string + */ + protected function parseDuplicate($duplicate){ + // 布尔值或空则返回空字符串 + if(is_bool($duplicate) || empty($duplicate)) return ''; + // field1,field2 转数组 + if(is_string($duplicate)) $duplicate = explode(',', $duplicate); + // 对象转数组 + if(is_object($duplicate)) $duplicate = get_class_vars($duplicate); + $updates = array(); + foreach((array) $duplicate as $key=>$val){ + if(is_numeric($key)){ // array('field1', 'field2', 'field3') 解析为 ON DUPLICATE KEY UPDATE field1=VALUES(field1), field2=VALUES(field2), field3=VALUES(field3) + $updates[] = $this->parseKey($val)."=VALUES(".$this->parseKey($val).")"; + }else{ + if(is_scalar($val)) // 兼容标量传值方式 + $val = array('value', $val); + if(!isset($val[1])) continue; + switch($val[0]){ + case 'exp': // 表达式 + $updates[] = $this->parseKey($key)."=($val[1])"; + break; + case 'value': // 值 + default: + $name = count($this->bind); + $updates[] = $this->parseKey($key)."=:".$name; + $this->bindParam($name, $val[1]); + break; + } + } + } + if(empty($updates)) return ''; + return " ON DUPLICATE KEY UPDATE ".join(', ', $updates); + } } From c9d7769e37632bd66cdc36b6e7cd46f1d634fc77 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Tue, 23 Dec 2014 09:00:42 +0800 Subject: [PATCH 014/166] =?UTF-8?q?=E6=94=B9=E8=BF=9B=20=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E8=A1=A8=E8=87=AA=E5=8A=A8=E8=AF=86=E5=88=AB=E8=A7=84=E5=88=99?= =?UTF-8?q?=E6=AD=A3=E5=88=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Model.class.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ThinkPHP/Library/Think/Model.class.php b/ThinkPHP/Library/Think/Model.class.php index 40298e76e..2170e43b5 100644 --- a/ThinkPHP/Library/Think/Model.class.php +++ b/ThinkPHP/Library/Think/Model.class.php @@ -1394,7 +1394,7 @@ protected function parseSql($sql,$parse) { }else{ $sql = strtr($sql,array('__TABLE__'=>$this->getTableName(),'__PREFIX__'=>$this->tablePrefix)); $prefix = $this->tablePrefix; - $sql = preg_replace_callback("/__([A-Z_-]+)__/sU", function($match) use($prefix){ return $prefix.strtolower($match[1]);}, $sql); + $sql = preg_replace_callback("/__([A-Z0-9_-]+)__/sU", function($match) use($prefix){ return $prefix.strtolower($match[1]);}, $sql); } $this->db->setModel($this->name); return $sql; @@ -1604,7 +1604,7 @@ public function table($table) { $this->options['table'] = $table; }elseif(!empty($table)) { //将__TABLE_NAME__替换成带前缀的表名 - $table = preg_replace_callback("/__([A-Z_-]+)__/sU", function($match) use($prefix){ return $prefix.strtolower($match[1]);}, $table); + $table = preg_replace_callback("/__([A-Z0-9_-]+)__/sU", function($match) use($prefix){ return $prefix.strtolower($match[1]);}, $table); $this->options['table'] = $table; } return $this; @@ -1622,7 +1622,7 @@ public function using($using){ $this->options['using'] = $using; }elseif(!empty($using)) { //将__TABLE_NAME__替换成带前缀的表名 - $using = preg_replace_callback("/__([A-Z_-]+)__/sU", function($match) use($prefix){ return $prefix.strtolower($match[1]);}, $using); + $using = preg_replace_callback("/__([A-Z0-9_-]+)__/sU", function($match) use($prefix){ return $prefix.strtolower($match[1]);}, $using); $this->options['using'] = $using; } return $this; @@ -1639,13 +1639,13 @@ public function join($join,$type='INNER') { $prefix = $this->tablePrefix; if(is_array($join)) { foreach ($join as $key=>&$_join){ - $_join = preg_replace_callback("/__([A-Z_-]+)__/sU", function($match) use($prefix){ return $prefix.strtolower($match[1]);}, $_join); + $_join = preg_replace_callback("/__([A-Z0-9_-]+)__/sU", function($match) use($prefix){ return $prefix.strtolower($match[1]);}, $_join); $_join = false !== stripos($_join,'JOIN')? $_join : $type.' JOIN ' .$_join; } $this->options['join'] = $join; }elseif(!empty($join)) { //将__TABLE_NAME__字符串替换成带前缀的表名 - $join = preg_replace_callback("/__([A-Z_-]+)__/sU", function($match) use($prefix){ return $prefix.strtolower($match[1]);}, $join); + $join = preg_replace_callback("/__([A-Z0-9_-]+)__/sU", function($match) use($prefix){ return $prefix.strtolower($match[1]);}, $join); $this->options['join'][] = false !== stripos($join,'JOIN')? $join : $type.' JOIN '.$join; } return $this; @@ -1670,7 +1670,7 @@ public function union($union,$all=false) { if(is_string($union) ) { $prefix = $this->tablePrefix; //将__TABLE_NAME__字符串替换成带前缀的表名 - $options = preg_replace_callback("/__([A-Z_-]+)__/sU", function($match) use($prefix){ return $prefix.strtolower($match[1]);}, $union); + $options = preg_replace_callback("/__([A-Z0-9_-]+)__/sU", function($match) use($prefix){ return $prefix.strtolower($match[1]);}, $union); }elseif(is_array($union)){ if(isset($union[0])) { $this->options['union'] = array_merge($this->options['union'],$union); From 9840c1b8b67b5f1a1f578a417ac352d18c6c27f3 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Tue, 23 Dec 2014 22:33:22 +0800 Subject: [PATCH 015/166] =?UTF-8?q?=E6=94=B9=E8=BF=9B=E6=97=A5=E5=BF=97?= =?UTF-8?q?=E7=9B=AE=E5=BD=95=E8=AE=BE=E7=BD=AE=20=E9=81=BF=E5=85=8D?= =?UTF-8?q?=E5=9C=A8=E8=8E=B7=E5=8F=96=E6=A8=A1=E5=9D=97=E4=B9=8B=E5=89=8D?= =?UTF-8?q?=E5=87=BA=E7=8E=B0=E5=BC=82=E5=B8=B8=E5=90=8E=E6=97=A5=E5=BF=97?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E5=86=99=E9=94=99=E4=BD=8D=E7=BD=AE=E7=9A=84?= =?UTF-8?q?=E6=83=85=E5=86=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/App.class.php | 5 +++-- ThinkPHP/Library/Think/Dispatcher.class.php | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ThinkPHP/Library/Think/App.class.php b/ThinkPHP/Library/Think/App.class.php index 26a852507..dfe9271aa 100644 --- a/ThinkPHP/Library/Think/App.class.php +++ b/ThinkPHP/Library/Think/App.class.php @@ -23,6 +23,9 @@ static public function init() { // 加载动态应用公共文件和配置 load_ext_file(COMMON_PATH); + // 日志目录转换为绝对路径 默认情况下存储到公共模块下面 + C('LOG_PATH', realpath(LOG_PATH).'/Common/'); + // 定义当前请求的系统常量 define('NOW_TIME', $_SERVER['REQUEST_TIME']); define('REQUEST_METHOD',$_SERVER['REQUEST_METHOD']); @@ -46,8 +49,6 @@ static public function init() { define('IS_AJAX', ((isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') || !empty($_POST[C('VAR_AJAX_SUBMIT')]) || !empty($_GET[C('VAR_AJAX_SUBMIT')])) ? true : false); - // 日志目录转换为绝对路径 - C('LOG_PATH', realpath(LOG_PATH).'/'.MODULE_NAME.'/'); // TMPL_EXCEPTION_FILE 改为绝对地址 C('TMPL_EXCEPTION_FILE',realpath(C('TMPL_EXCEPTION_FILE'))); return ; diff --git a/ThinkPHP/Library/Think/Dispatcher.class.php b/ThinkPHP/Library/Think/Dispatcher.class.php index a3c3b9178..72ac8faac 100644 --- a/ThinkPHP/Library/Think/Dispatcher.class.php +++ b/ThinkPHP/Library/Think/Dispatcher.class.php @@ -145,6 +145,8 @@ static public function dispatch() { define('MODULE_PATH', APP_PATH.MODULE_NAME.'/'); // 定义当前模块的模版缓存路径 C('CACHE_PATH',CACHE_PATH.MODULE_NAME.'/'); + // 定义当前模块的日志目录 + C('LOG_PATH', realpath(LOG_PATH).'/'.MODULE_NAME.'/'); // 模块检测 Hook::listen('module_check'); From b8e547721592860cbe4510fd62923ad2249977c8 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Wed, 24 Dec 2014 09:41:48 +0800 Subject: [PATCH 016/166] =?UTF-8?q?=E7=89=88=E6=9C=AC=E5=8F=B7=E6=9B=B4?= =?UTF-8?q?=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/ThinkPHP.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ThinkPHP/ThinkPHP.php b/ThinkPHP/ThinkPHP.php index dbc4820e3..291c7bc9d 100644 --- a/ThinkPHP/ThinkPHP.php +++ b/ThinkPHP/ThinkPHP.php @@ -20,7 +20,7 @@ if(MEMORY_LIMIT_ON) $GLOBALS['_startUseMems'] = memory_get_usage(); // 版本信息 -const THINK_VERSION = '3.2.3beta'; +const THINK_VERSION = '3.2.3'; // URL 模式定义 const URL_COMMON = 0; //普通模式 From 5c91368afa96563e45fa258ff8e880c9d47a1da2 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Wed, 24 Dec 2014 10:20:43 +0800 Subject: [PATCH 017/166] =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Build.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ThinkPHP/Library/Think/Build.class.php b/ThinkPHP/Library/Think/Build.class.php index 2b504def1..627e7abf5 100644 --- a/ThinkPHP/Library/Think/Build.class.php +++ b/ThinkPHP/Library/Think/Build.class.php @@ -19,7 +19,7 @@ class Build { use Think\Controller; class [CONTROLLER]Controller extends Controller { public function index(){ - $this->show(\'

:)

欢迎使用 ThinkPHP


[ 您现在访问的是[MODULE]模块的[CONTROLLER]控制器 ]
\',\'utf-8\'); + $this->show(\'

:)

欢迎使用 ThinkPHP


版本 V{$Think.version}
\',\'utf-8\'); } }'; From 748f848b94f4865ba6ddcc6aee89929c0631508f Mon Sep 17 00:00:00 2001 From: thinkphp Date: Wed, 24 Dec 2014 14:25:02 +0800 Subject: [PATCH 018/166] =?UTF-8?q?API=E6=A8=A1=E5=BC=8F=E5=AE=89=E5=85=A8?= =?UTF-8?q?=E8=BF=87=E6=BB=A4=E6=94=B9=E8=BF=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Mode/Api/App.class.php | 8 ++++ ThinkPHP/Mode/Api/functions.php | 67 +++++++++++++++++++++++++++++---- 2 files changed, 68 insertions(+), 7 deletions(-) diff --git a/ThinkPHP/Mode/Api/App.class.php b/ThinkPHP/Mode/Api/App.class.php index 3072403e4..92fd3ec3a 100644 --- a/ThinkPHP/Mode/Api/App.class.php +++ b/ThinkPHP/Mode/Api/App.class.php @@ -32,6 +32,13 @@ static public function init() { // URL调度 Dispatcher::dispatch(); + if(C('REQUEST_VARS_FILTER')){ + // 全局安全过滤 + array_walk_recursive($_GET, 'think_filter'); + array_walk_recursive($_POST, 'think_filter'); + array_walk_recursive($_REQUEST, 'think_filter'); + } + // 日志目录转换为绝对路径 C('LOG_PATH',realpath(LOG_PATH).'/'); // TMPL_EXCEPTION_FILE 改为绝对地址 @@ -99,6 +106,7 @@ static public function exec() { E(L('_PARAM_ERROR_').':'.$name); } } + array_walk_recursive($args,'think_filter'); $method->invokeArgs($module,$args); }else{ $method->invoke($module); diff --git a/ThinkPHP/Mode/Api/functions.php b/ThinkPHP/Mode/Api/functions.php index cdcd48323..04a8e6978 100644 --- a/ThinkPHP/Mode/Api/functions.php +++ b/ThinkPHP/Mode/Api/functions.php @@ -195,9 +195,13 @@ function compile($filename) { * @param string $name 变量的名称 支持指定类型 * @param mixed $default 不存在的时候默认值 * @param mixed $filter 参数过滤方法 + * @param mixed $datas 要获取的额外数据源 * @return mixed */ -function I($name,$default='',$filter=null) { +function I($name,$default='',$filter=null,$datas=null) { + if(strpos($name,'/')){ // 指定修饰符 + list($name,$type) = explode('/',$name,2); + } if(strpos($name,'.')) { // 指定参数来源 list($method,$name) = explode('.',$name,2); }else{ // 默认为自动判断 @@ -219,19 +223,29 @@ function I($name,$default='',$filter=null) { $input = $_GET; } break; + case 'path' : + $input = array(); + if(!empty($_SERVER['PATH_INFO'])){ + $depr = C('URL_PATHINFO_DEPR'); + $input = explode($depr,trim($_SERVER['PATH_INFO'],$depr)); + } + break; case 'request' : $input =& $_REQUEST; break; case 'session' : $input =& $_SESSION; break; case 'cookie' : $input =& $_COOKIE; break; case 'server' : $input =& $_SERVER; break; case 'globals' : $input =& $GLOBALS; break; + case 'data' : $input =& $datas; break; default: return NULL; } - if(empty($name)) { // 获取全部变量 + if(''==$name) { // 获取全部变量 $data = $input; $filters = isset($filter)?$filter:C('DEFAULT_FILTER'); if($filters) { - $filters = explode(',',$filters); + if(is_string($filters)){ + $filters = explode(',',$filters); + } foreach($filters as $filter){ $data = array_map_recursive($filter,$data); // 参数过滤 } @@ -240,21 +254,51 @@ function I($name,$default='',$filter=null) { $data = $input[$name]; $filters = isset($filter)?$filter:C('DEFAULT_FILTER'); if($filters) { - $filters = explode(',',$filters); + if(is_string($filters)){ + $filters = explode(',',$filters); + }elseif(is_int($filters)){ + $filters = array($filters); + } + foreach($filters as $filter){ if(function_exists($filter)) { - $data = is_array($data)?array_map_recursive($filter,$data):$filter($data); // 参数过滤 + $data = is_array($data) ? array_map_recursive($filter,$data) : $filter($data); // 参数过滤 + }elseif(0===strpos($filter,'/')){ + // 支持正则验证 + if(1 !== preg_match($filter,(string)$data)){ + return isset($default) ? $default : NULL; + } }else{ - $data = filter_var($data,is_int($filter)?$filter:filter_id($filter)); + $data = filter_var($data,is_int($filter) ? $filter : filter_id($filter)); if(false === $data) { - return isset($default)?$default:NULL; + return isset($default) ? $default : NULL; } } } } + if(!empty($type)){ + switch(strtolower($type)){ + case 's': // 字符串 + $data = (string)$data; + break; + case 'a': // 数组 + $data = (array)$data; + break; + case 'd': // 数字 + $data = (int)$data; + break; + case 'f': // 浮点 + $data = (float)$data; + break; + case 'b': // 布尔 + $data = (boolean)$data; + break; + } + } }else{ // 变量默认值 $data = isset($default)?$default:NULL; } + is_array($data) && array_walk_recursive($data,'think_filter'); return $data; } @@ -1054,3 +1098,12 @@ function send_http_status($code) { function in_array_case($value,$array){ return in_array(strtolower($value),array_map('strtolower',$array)); } + +function think_filter(&$value){ + // TODO 其他安全过滤 + + // 过滤查询特殊字符 + if(preg_match('/^(EXP|NEQ|GT|EGT|LT|ELT|OR|XOR|LIKE|NOTLIKE|NOT BETWEEN|NOTBETWEEN|BETWEEN|NOTIN|NOT IN|IN)$/i',$value)){ + $value .= ' '; + } +} \ No newline at end of file From b4b5954af08b54e2a611603532c4c18ca14fb71a Mon Sep 17 00:00:00 2001 From: thinkphp Date: Wed, 24 Dec 2014 15:58:53 +0800 Subject: [PATCH 019/166] =?UTF-8?q?=E5=88=A0=E9=99=A4=E4=B8=80=E4=BA=9B?= =?UTF-8?q?=E6=97=A0=E7=94=A8=E7=9A=84=E9=85=8D=E7=BD=AE=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Conf/convention.php | 7 +------ ThinkPHP/Conf/debug.php | 2 +- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/ThinkPHP/Conf/convention.php b/ThinkPHP/Conf/convention.php index 6c5ed8f20..499e65dba 100644 --- a/ThinkPHP/Conf/convention.php +++ b/ThinkPHP/Conf/convention.php @@ -60,18 +60,13 @@ 'DB_PWD' => '', // 密码 'DB_PORT' => '', // 端口 'DB_PREFIX' => '', // 数据库表前缀 - 'DB_FIELDTYPE_CHECK' => false, // 是否进行字段类型检查 + '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' => '', // 指定从服务器序号 - 'DB_SQL_BUILD_CACHE' => false, // 数据库查询的SQL创建缓存 - 'DB_SQL_BUILD_QUEUE' => 'file', // SQL缓存队列的缓存方式 支持 file xcache和apc - 'DB_SQL_BUILD_LENGTH' => 20, // SQL缓存的队列长度 - 'DB_SQL_LOG' => false, // SQL执行日志记录 - 'DB_BIND_PARAM' => false, // 数据库写入数据自动参数绑定 /* 数据缓存设置 */ 'DATA_CACHE_TIME' => 0, // 数据缓存有效期 0表示永久缓存 diff --git a/ThinkPHP/Conf/debug.php b/ThinkPHP/Conf/debug.php index f71c0e204..06674b925 100644 --- a/ThinkPHP/Conf/debug.php +++ b/ThinkPHP/Conf/debug.php @@ -19,7 +19,7 @@ 'LOG_EXCEPTION_RECORD' => true, // 是否记录异常信息日志 'LOG_LEVEL' => 'EMERG,ALERT,CRIT,ERR,WARN,NOTIC,INFO,DEBUG,SQL', // 允许记录的日志级别 'DB_FIELDS_CACHE' => false, // 字段缓存信息 - 'DB_SQL_LOG' => true, // 记录SQL信息 + 'DB_DEBUG' => true, // 开启调试模式 记录SQL日志 'TMPL_CACHE_ON' => false, // 是否开启模板编译缓存,设为false则每次都会重新编译 'TMPL_STRIP_SPACE' => false, // 是否去除模板文件里面的html空格与换行 'SHOW_ERROR_MSG' => true, // 显示错误信息 From 8acd408cb12e597156171c5b82d00469ada121c8 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Wed, 24 Dec 2014 21:17:08 +0800 Subject: [PATCH 020/166] =?UTF-8?q?=E5=A2=9E=E5=8A=A0DATA=5FCACHE=5FKEY?= =?UTF-8?q?=E5=8F=82=E6=95=B0=20=E7=94=A8=E4=BA=8E=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E6=96=B9=E5=BC=8F=E7=9A=84=E7=BC=93=E5=AD=98=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=90=8D=E8=A7=84=E5=88=99=E5=93=88=E5=B8=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Conf/convention.php | 2 ++ ThinkPHP/Library/Think/Cache/Driver/File.class.php | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ThinkPHP/Conf/convention.php b/ThinkPHP/Conf/convention.php index 499e65dba..8b7c32d7f 100644 --- a/ThinkPHP/Conf/convention.php +++ b/ThinkPHP/Conf/convention.php @@ -60,6 +60,7 @@ 'DB_PWD' => '', // 密码 'DB_PORT' => '', // 端口 'DB_PREFIX' => '', // 数据库表前缀 + 'DB_PARAMS' => array(), // 数据库连接参数 'DB_DEBUG' => TRUE, // 数据库调试模式 开启后可以记录SQL日志 'DB_FIELDS_CACHE' => true, // 启用字段缓存 'DB_CHARSET' => 'utf8', // 数据库编码默认采用utf8 @@ -75,6 +76,7 @@ '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, // 子目录缓存级别 diff --git a/ThinkPHP/Library/Think/Cache/Driver/File.class.php b/ThinkPHP/Library/Think/Cache/Driver/File.class.php index eb33c1932..c5c64efc1 100644 --- a/ThinkPHP/Library/Think/Cache/Driver/File.class.php +++ b/ThinkPHP/Library/Think/Cache/Driver/File.class.php @@ -51,7 +51,7 @@ private function init() { * @return string */ private function filename($name) { - $name = md5($name); + $name = md5(C('DATA_CACHE_KEY').$name); if(C('DATA_CACHE_SUBDIR')) { // 使用子目录 $dir =''; From 86e0f34f202ec09ece8d3a921bca2e15bb8872d1 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Wed, 24 Dec 2014 21:25:41 +0800 Subject: [PATCH 021/166] =?UTF-8?q?=E5=A2=9E=E5=8A=A0VAR=5FAUTO=5FSTRING?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E7=94=A8=E4=BA=8E=E8=AE=BE=E7=BD=AE=E6=98=AF?= =?UTF-8?q?=E5=90=A6=E5=BC=BA=E5=88=B6=E8=BD=AC=E6=8D=A2=E8=BE=93=E5=85=A5?= =?UTF-8?q?=E5=8F=98=E9=87=8F=E4=B8=BA=E5=AD=97=E7=AC=A6=E4=B8=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Common/functions.php | 10 ++++++---- ThinkPHP/Conf/convention.php | 1 + 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/ThinkPHP/Common/functions.php b/ThinkPHP/Common/functions.php index f1faf823c..e1298dcde 100644 --- a/ThinkPHP/Common/functions.php +++ b/ThinkPHP/Common/functions.php @@ -271,7 +271,9 @@ function T($template='',$layer=''){ function I($name,$default='',$filter=null,$datas=null) { if(strpos($name,'/')){ // 指定修饰符 list($name,$type) = explode('/',$name,2); - } + }elseif(C('VAR_AUTO_STRING')){ // 默认强制转换为字符串 + $type = 's'; + } if(strpos($name,'.')) { // 指定参数来源 list($method,$name) = explode('.',$name,2); }else{ // 默认为自动判断 @@ -348,9 +350,6 @@ function I($name,$default='',$filter=null,$datas=null) { } if(!empty($type)){ switch(strtolower($type)){ - case 's': // 字符串 - $data = (string)$data; - break; case 'a': // 数组 $data = (array)$data; break; @@ -363,6 +362,9 @@ function I($name,$default='',$filter=null,$datas=null) { case 'b': // 布尔 $data = (boolean)$data; break; + case 's': // 字符串 + default: + $data = (string)$data; } } }else{ // 变量默认值 diff --git a/ThinkPHP/Conf/convention.php b/ThinkPHP/Conf/convention.php index 8b7c32d7f..4061933ac 100644 --- a/ThinkPHP/Conf/convention.php +++ b/ThinkPHP/Conf/convention.php @@ -157,6 +157,7 @@ '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, // 是否检查应用目录是否创建 From 98e871080bbb4a51b8bb35ddf26b061e461b3b94 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Thu, 25 Dec 2014 11:04:22 +0800 Subject: [PATCH 022/166] =?UTF-8?q?=E6=94=B9=E8=BF=9B=E5=AF=B9=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E8=A1=A8=E5=AD=97=E6=AE=B5=E5=90=8D=E7=9A=84=E5=A4=A7?= =?UTF-8?q?=E5=B0=8F=E5=86=99=E6=94=AF=E6=8C=81=20=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E4=B8=AD=E5=AE=9A=E4=B9=89=E5=A6=82=E4=B8=8B?= =?UTF-8?q?=E5=8D=B3=E5=8F=AF=E4=BF=9D=E7=95=99=E5=AE=9E=E9=99=85=E7=9A=84?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E5=90=8D=E5=A4=A7=E5=B0=8F=E5=86=99=20'DB=5F?= =?UTF-8?q?PARAMS'=3D>array(\PDO::ATTR=5FCASE=20=20=20=3D>=20=20\PDO::CASE?= =?UTF-8?q?=5FNATURAL),?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Db/Driver.class.php | 2 +- ThinkPHP/Library/Think/Db/Driver/Mysql.class.php | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ThinkPHP/Library/Think/Db/Driver.class.php b/ThinkPHP/Library/Think/Db/Driver.class.php index 1b0b2777f..6e26f2da9 100644 --- a/ThinkPHP/Library/Think/Db/Driver.class.php +++ b/ThinkPHP/Library/Think/Db/Driver.class.php @@ -80,7 +80,7 @@ public function __construct($config=''){ if(!empty($config)) { $this->config = array_merge($this->config,$config); if(is_array($this->config['params'])){ - $this->options += $this->config['params']; + $this->options = $this->config['params'] + $this->options; } } } diff --git a/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php b/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php index 653e5fbb0..c949c65b6 100644 --- a/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php +++ b/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php @@ -54,6 +54,9 @@ public function getFields($tableName) { $info = array(); if($result) { foreach ($result as $key => $val) { + if(\PDO::CASE_LOWER != $this->_linkID->getAttribute(\PDO::ATTR_CASE)){ + $val = array_change_key_case ( $val , CASE_LOWER ); + } $info[$val['field']] = array( 'name' => $val['field'], 'type' => $val['type'], From e8112b837d64213893d86ea0a1a4f270cc7e9571 Mon Sep 17 00:00:00 2001 From: huangdijia Date: Thu, 25 Dec 2014 15:07:32 +0800 Subject: [PATCH 023/166] =?UTF-8?q?addAll/insertAll=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E6=94=AF=E6=8C=81ON=20DUPLICATE=20KEY=20UPDATE=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=EF=BC=8C=E7=9B=AE=E5=89=8D=E5=8F=AA=E6=94=AF=E6=8C=81?= =?UTF-8?q?mysql?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Db/Driver/Mysql.class.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php b/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php index c949c65b6..9ca43df50 100644 --- a/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php +++ b/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php @@ -129,8 +129,10 @@ public function insertAll($dataSet,$options=array(),$replace=false) { } $values[] = '('.implode(',', $value).')'; } - $sql = ($replace?'REPLACE':'INSERT').' INTO '.$this->parseTable($options['table']).' ('.implode(',', $fields).') VALUES '.implode(',',$values); - $sql .= $this->parseComment(!empty($options['comment'])?$options['comment']:''); + // 兼容数字传入方式 + $replace= (is_numeric($replace) && $replace>0)?true:$replace; + $sql = (true===$replace?'REPLACE':'INSERT').' INTO '.$this->parseTable($options['table']).' ('.implode(',', $fields).') VALUES '.implode(',',$values).$this->parseDuplicate($replace); + $sql .= $this->parseComment(!empty($options['comment'])?$options['comment']:''); return $this->execute($sql,!empty($options['fetch_sql']) ? true : false); } From 7c1dc4ad4712be40b5acf8b8d70d50f99991ea4d Mon Sep 17 00:00:00 2001 From: thinkphp Date: Sat, 27 Dec 2014 09:51:36 +0800 Subject: [PATCH 024/166] =?UTF-8?q?=E6=94=B9=E8=BF=9B=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=BA=93=E7=9A=84=E5=BC=82=E5=B8=B8=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E5=9C=A8=E9=9D=9E=E8=B0=83=E8=AF=95=E6=A8=A1=E5=BC=8F=E4=B8=8B?= =?UTF-8?q?=E9=9D=A2=20=E9=81=BF=E5=85=8D=E6=8A=9B=E5=87=BA=E5=BC=82?= =?UTF-8?q?=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Db/Driver.class.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/ThinkPHP/Library/Think/Db/Driver.class.php b/ThinkPHP/Library/Think/Db/Driver.class.php index 6e26f2da9..7cd0e9718 100644 --- a/ThinkPHP/Library/Think/Db/Driver.class.php +++ b/ThinkPHP/Library/Think/Db/Driver.class.php @@ -105,7 +105,7 @@ public function connect($config='',$linkNum=0,$autoConnection=false) { if($autoConnection){ trace($e->getMessage(),'','ERR'); return $this->connect($autoConnection,$linkNum); - }else{ + }elseif($this->config['debug']){ E($e->getMessage()); } } @@ -154,8 +154,10 @@ public function query($str,$fetchSql=false) { // 调试开始 $this->debug(true); $this->PDOStatement = $this->_linkID->prepare($str); - if(false === $this->PDOStatement) - E($this->error()); + if(false === $this->PDOStatement){ + $this->error(); + return false; + } foreach ($this->bind as $key => $val) { if(is_array($val)){ $this->PDOStatement->bindValue($key, $val[0], $val[1]); @@ -201,7 +203,8 @@ public function execute($str,$fetchSql=false) { $this->debug(true); $this->PDOStatement = $this->_linkID->prepare($str); if(false === $this->PDOStatement) { - E($this->error()); + $this->error(); + return false; } foreach ($this->bind as $key => $val) { if(is_array($val)){ From f8b51a9fff5589ac93426186664c62e3b42b1b43 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Sat, 27 Dec 2014 10:18:26 +0800 Subject: [PATCH 025/166] =?UTF-8?q?=E6=94=B9=E8=BF=9B=E4=B8=80=E5=A4=84?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Db/Driver.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ThinkPHP/Library/Think/Db/Driver.class.php b/ThinkPHP/Library/Think/Db/Driver.class.php index 7cd0e9718..b9f6daa8b 100644 --- a/ThinkPHP/Library/Think/Db/Driver.class.php +++ b/ThinkPHP/Library/Think/Db/Driver.class.php @@ -105,7 +105,7 @@ public function connect($config='',$linkNum=0,$autoConnection=false) { if($autoConnection){ trace($e->getMessage(),'','ERR'); return $this->connect($autoConnection,$linkNum); - }elseif($this->config['debug']){ + }elseif($config['debug']){ E($e->getMessage()); } } From 37d4c23d8d1cc870165a812d977daf2d81c51ab2 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Sat, 27 Dec 2014 11:03:06 +0800 Subject: [PATCH 026/166] =?UTF-8?q?=E6=94=B9=E8=BF=9B=E5=AF=B9=E5=AD=90?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E7=9A=84=E6=95=B0=E6=8D=AE=E8=A1=A8=E6=A3=80?= =?UTF-8?q?=E6=B5=8B=20=E9=81=BF=E5=85=8D=E6=97=A0=E6=95=88=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Model.class.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ThinkPHP/Library/Think/Model.class.php b/ThinkPHP/Library/Think/Model.class.php index 2170e43b5..eea69e355 100644 --- a/ThinkPHP/Library/Think/Model.class.php +++ b/ThinkPHP/Library/Think/Model.class.php @@ -1559,6 +1559,10 @@ public function getDbFields(){ $table = key($this->options['table']); }else{ $table = $this->options['table']; + if(strpos($table,')')){ + // 子查询 + return false; + } } $fields = $this->db->getFields($table); return $fields ? array_keys($fields) : false; From 4400972e985e168a6315a0e7a30583c104ab5cec Mon Sep 17 00:00:00 2001 From: thinkphp Date: Mon, 29 Dec 2014 12:00:24 +0800 Subject: [PATCH 027/166] =?UTF-8?q?=E5=A2=9E=E5=8A=A0Lite=E6=A8=A1?= =?UTF-8?q?=E5=BC=8F=EF=BC=88=E6=B5=8B=E8=AF=95=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Mode/Lite/App.class.php | 156 +++ ThinkPHP/Mode/Lite/Controller.class.php | 276 +++++ ThinkPHP/Mode/Lite/Dispatcher.class.php | 270 +++++ ThinkPHP/Mode/Lite/Model.class.php | 1485 +++++++++++++++++++++++ ThinkPHP/Mode/Lite/View.class.php | 293 +++++ ThinkPHP/Mode/Lite/functions.php | 1417 +++++++++++++++++++++ ThinkPHP/Mode/lite.php | 47 + 7 files changed, 3944 insertions(+) create mode 100644 ThinkPHP/Mode/Lite/App.class.php create mode 100644 ThinkPHP/Mode/Lite/Controller.class.php create mode 100644 ThinkPHP/Mode/Lite/Dispatcher.class.php create mode 100644 ThinkPHP/Mode/Lite/Model.class.php create mode 100644 ThinkPHP/Mode/Lite/View.class.php create mode 100644 ThinkPHP/Mode/Lite/functions.php create mode 100644 ThinkPHP/Mode/lite.php diff --git a/ThinkPHP/Mode/Lite/App.class.php b/ThinkPHP/Mode/Lite/App.class.php new file mode 100644 index 000000000..78e5a14c9 --- /dev/null +++ b/ThinkPHP/Mode/Lite/App.class.php @@ -0,0 +1,156 @@ + +// +---------------------------------------------------------------------- +namespace Think; +/** + * ThinkPHP 应用程序类 执行应用过程管理 + */ +class App { + + /** + * 应用程序初始化 + * @access public + * @return void + */ + static public function init() { + + // 日志目录转换为绝对路径 默认情况下存储到公共模块下面 + C('LOG_PATH', realpath(LOG_PATH).'/Common/'); + + // 定义当前请求的系统常量 + define('NOW_TIME', $_SERVER['REQUEST_TIME']); + define('REQUEST_METHOD',$_SERVER['REQUEST_METHOD']); + define('IS_GET', REQUEST_METHOD =='GET' ? true : false); + define('IS_POST', REQUEST_METHOD =='POST' ? true : false); + define('IS_PUT', REQUEST_METHOD =='PUT' ? true : false); + define('IS_DELETE', REQUEST_METHOD =='DELETE' ? true : false); + + // URL调度 + Dispatcher::dispatch(); + + if(C('REQUEST_VARS_FILTER')){ + // 全局安全过滤 + array_walk_recursive($_GET, 'think_filter'); + array_walk_recursive($_POST, 'think_filter'); + array_walk_recursive($_REQUEST, 'think_filter'); + } + + define('IS_AJAX', ((isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') || !empty($_POST[C('VAR_AJAX_SUBMIT')]) || !empty($_GET[C('VAR_AJAX_SUBMIT')])) ? true : false); + + // TMPL_EXCEPTION_FILE 改为绝对地址 + C('TMPL_EXCEPTION_FILE',realpath(C('TMPL_EXCEPTION_FILE'))); + return ; + } + + /** + * 执行应用程序 + * @access public + * @return void + */ + static public function exec() { + + if(!preg_match('/^[A-Za-z](\/|\w)*$/',CONTROLLER_NAME)){ // 安全检测 + $module = false; + }else{ + //创建控制器实例 + $module = controller(CONTROLLER_NAME); + } + + if(!$module) { + // 是否定义Empty控制器 + $module = A('Empty'); + if(!$module){ + E(L('_CONTROLLER_NOT_EXIST_').':'.CONTROLLER_NAME); + } + } + + // 获取当前操作名 支持动态路由 + $action = ACTION_NAME.C('ACTION_SUFFIX'); + + try{ + if(!preg_match('/^[A-Za-z](\w)*$/',$action)){ + // 非法操作 + throw new \ReflectionException(); + } + //执行当前操作 + $method = new \ReflectionMethod($module, $action); + if($method->isPublic() && !$method->isStatic()) { + $class = new \ReflectionClass($module); + // URL参数绑定检测 + if($method->getNumberOfParameters()>0 && C('URL_PARAMS_BIND')){ + switch($_SERVER['REQUEST_METHOD']) { + case 'POST': + $vars = array_merge($_GET,$_POST); + break; + case 'PUT': + parse_str(file_get_contents('php://input'), $vars); + break; + default: + $vars = $_GET; + } + $params = $method->getParameters(); + $paramsBindType = C('URL_PARAMS_BIND_TYPE'); + foreach ($params as $param){ + $name = $param->getName(); + if( 1 == $paramsBindType && !empty($vars) ){ + $args[] = array_shift($vars); + }elseif( 0 == $paramsBindType && isset($vars[$name])){ + $args[] = $vars[$name]; + }elseif($param->isDefaultValueAvailable()){ + $args[] = $param->getDefaultValue(); + }else{ + E(L('_PARAM_ERROR_').':'.$name); + } + } + // 开启绑定参数过滤机制 + if(C('URL_PARAMS_SAFE')){ + $filters = C('URL_PARAMS_FILTER')?:C('DEFAULT_FILTER'); + if($filters) { + $filters = explode(',',$filters); + foreach($filters as $filter){ + $args = array_map_recursive($filter,$args); // 参数过滤 + } + } + } + array_walk_recursive($args,'think_filter'); + $method->invokeArgs($module,$args); + }else{ + $method->invoke($module); + } + }else{ + // 操作方法不是Public 抛出异常 + throw new \ReflectionException(); + } + } catch (\ReflectionException $e) { + // 方法调用发生异常后 引导到__call方法处理 + $method = new \ReflectionMethod($module,'__call'); + $method->invokeArgs($module,array($action,'')); + } + return ; + } + + /** + * 运行应用实例 入口文件使用的快捷方法 + * @access public + * @return void + */ + static public function run() { + App::init(); + // Session初始化 + if(!IS_CLI){ + session(C('SESSION_OPTIONS')); + } + // 记录应用初始化时间 + G('initTime'); + App::exec(); + return ; + } + +} \ No newline at end of file diff --git a/ThinkPHP/Mode/Lite/Controller.class.php b/ThinkPHP/Mode/Lite/Controller.class.php new file mode 100644 index 000000000..406589385 --- /dev/null +++ b/ThinkPHP/Mode/Lite/Controller.class.php @@ -0,0 +1,276 @@ + +// +---------------------------------------------------------------------- +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() { + //实例化视图类 + $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 + * @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); + } + } + + /** + * 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 ; + } + } + +} diff --git a/ThinkPHP/Mode/Lite/Dispatcher.class.php b/ThinkPHP/Mode/Lite/Dispatcher.class.php new file mode 100644 index 000000000..b4da4bd0a --- /dev/null +++ b/ThinkPHP/Mode/Lite/Dispatcher.class.php @@ -0,0 +1,270 @@ + +// +---------------------------------------------------------------------- +namespace Think; +/** + * ThinkPHP内置的Dispatcher类 + * 完成URL解析、路由和调度 + */ +class Dispatcher { + + /** + * URL映射到控制器 + * @access public + * @return void + */ + static public function dispatch() { + $varPath = C('VAR_PATHINFO'); + $varModule = C('VAR_MODULE'); + $varController = C('VAR_CONTROLLER'); + $varAction = C('VAR_ACTION'); + $urlCase = C('URL_CASE_INSENSITIVE'); + if(isset($_GET[$varPath])) { // 判断URL里面是否有兼容模式参数 + $_SERVER['PATH_INFO'] = $_GET[$varPath]; + unset($_GET[$varPath]); + }elseif(IS_CLI){ // CLI模式下 index.php module/controller/action/params/... + $_SERVER['PATH_INFO'] = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : ''; + } + + // 开启子域名部署 + if(C('APP_SUB_DOMAIN_DEPLOY')) { + $rules = C('APP_SUB_DOMAIN_RULES'); + if(isset($rules[$_SERVER['HTTP_HOST']])) { // 完整域名或者IP配置 + define('APP_DOMAIN',$_SERVER['HTTP_HOST']); // 当前完整域名 + $rule = $rules[APP_DOMAIN]; + }else{ + if(strpos(C('APP_DOMAIN_SUFFIX'),'.')){ // com.cn net.cn + $domain = array_slice(explode('.', $_SERVER['HTTP_HOST']), 0, -3); + }else{ + $domain = array_slice(explode('.', $_SERVER['HTTP_HOST']), 0, -2); + } + if(!empty($domain)) { + $subDomain = implode('.', $domain); + define('SUB_DOMAIN',$subDomain); // 当前完整子域名 + $domain2 = array_pop($domain); // 二级域名 + if($domain) { // 存在三级域名 + $domain3 = array_pop($domain); + } + if(isset($rules[$subDomain])) { // 子域名 + $rule = $rules[$subDomain]; + }elseif(isset($rules['*.' . $domain2]) && !empty($domain3)){ // 泛三级域名 + $rule = $rules['*.' . $domain2]; + $panDomain = $domain3; + }elseif(isset($rules['*']) && !empty($domain2) && 'www' != $domain2 ){ // 泛二级域名 + $rule = $rules['*']; + $panDomain = $domain2; + } + } + } + + if(!empty($rule)) { + // 子域名部署规则 '子域名'=>array('模块名[/控制器名]','var1=a&var2=b'); + if(is_array($rule)){ + list($rule,$vars) = $rule; + } + $array = explode('/',$rule); + // 模块绑定 + define('BIND_MODULE',array_shift($array)); + // 控制器绑定 + if(!empty($array)) { + $controller = array_shift($array); + if($controller){ + define('BIND_CONTROLLER',$controller); + } + } + if(isset($vars)) { // 传入参数 + parse_str($vars,$parms); + if(isset($panDomain)){ + $pos = array_search('*', $parms); + if(false !== $pos) { + // 泛域名作为参数 + $parms[$pos] = $panDomain; + } + } + $_GET = array_merge($_GET,$parms); + } + } + } + // 分析PATHINFO信息 + if(!isset($_SERVER['PATH_INFO'])) { + $types = explode(',',C('URL_PATHINFO_FETCH')); + foreach ($types as $type){ + if(0===strpos($type,':')) {// 支持函数判断 + $_SERVER['PATH_INFO'] = call_user_func(substr($type,1)); + break; + }elseif(!empty($_SERVER[$type])) { + $_SERVER['PATH_INFO'] = (0 === strpos($_SERVER[$type],$_SERVER['SCRIPT_NAME']))? + substr($_SERVER[$type], strlen($_SERVER['SCRIPT_NAME'])) : $_SERVER[$type]; + break; + } + } + } + + $depr = C('URL_PATHINFO_DEPR'); + define('MODULE_PATHINFO_DEPR', $depr); + + if(empty($_SERVER['PATH_INFO'])) { + $_SERVER['PATH_INFO'] = ''; + define('__INFO__',''); + define('__EXT__',''); + }else{ + define('__INFO__',trim($_SERVER['PATH_INFO'],'/')); + // URL后缀 + define('__EXT__', strtolower(pathinfo($_SERVER['PATH_INFO'],PATHINFO_EXTENSION))); + $_SERVER['PATH_INFO'] = __INFO__; + if(!defined('BIND_MODULE') && (!C('URL_ROUTER_ON') || !Route::check())){ + if (__INFO__ && C('MULTI_MODULE')){ // 获取模块名 + $paths = explode($depr,__INFO__,2); + $allowList = C('MODULE_ALLOW_LIST'); // 允许的模块列表 + $module = preg_replace('/\.' . __EXT__ . '$/i', '',$paths[0]); + if( empty($allowList) || (is_array($allowList) && in_array_case($module, $allowList))){ + $_GET[$varModule] = $module; + $_SERVER['PATH_INFO'] = isset($paths[1])?$paths[1]:''; + } + } + } + } + + // URL常量 + define('__SELF__',strip_tags($_SERVER[C('URL_REQUEST_URI')])); + + // 获取模块名称 + define('MODULE_NAME', defined('BIND_MODULE')? BIND_MODULE : self::getModule($varModule)); + + // 检测模块是否存在 + if( MODULE_NAME && (defined('BIND_MODULE') || !in_array_case(MODULE_NAME,C('MODULE_DENY_LIST')) ) && is_dir(APP_PATH.MODULE_NAME)){ + // 定义当前模块路径 + define('MODULE_PATH', APP_PATH.MODULE_NAME.'/'); + // 定义当前模块的模版缓存路径 + C('CACHE_PATH',CACHE_PATH.MODULE_NAME.'/'); + // 定义当前模块的日志目录 + C('LOG_PATH', realpath(LOG_PATH).'/'.MODULE_NAME.'/'); + + // 加载模块配置文件 + if(is_file(MODULE_PATH.'Conf/config'.CONF_EXT)) + C(load_config(MODULE_PATH.'Conf/config'.CONF_EXT)); + + // 加载模块别名定义 + if(is_file(MODULE_PATH.'Conf/alias.php')) + Think::addMap(include MODULE_PATH.'Conf/alias.php'); + + // 加载模块函数文件 + if(is_file(MODULE_PATH.'Common/function.php')) + include MODULE_PATH.'Common/function.php'; + }else{ + E(L('_MODULE_NOT_EXIST_').':'.MODULE_NAME); + } + + if(!defined('__APP__')){ + $urlMode = C('URL_MODEL'); + if($urlMode == URL_COMPAT ){// 兼容模式判断 + define('PHP_FILE',_PHP_FILE_.'?'.$varPath.'='); + }elseif($urlMode == URL_REWRITE ) { + $url = dirname(_PHP_FILE_); + if($url == '/' || $url == '\\') + $url = ''; + define('PHP_FILE',$url); + }else { + define('PHP_FILE',_PHP_FILE_); + } + // 当前应用地址 + define('__APP__',strip_tags(PHP_FILE)); + } + // 模块URL地址 + $moduleName = defined('MODULE_ALIAS')? MODULE_ALIAS : MODULE_NAME; + define('__MODULE__',(defined('BIND_MODULE') || !C('MULTI_MODULE'))? __APP__ : __APP__.'/'.($urlCase ? strtolower($moduleName) : $moduleName)); + + if('' != $_SERVER['PATH_INFO'] && (!C('URL_ROUTER_ON') || !Route::check()) ){ // 检测路由规则 如果没有则按默认规则调度URL + // 检查禁止访问的URL后缀 + if(C('URL_DENY_SUFFIX') && preg_match('/\.('.trim(C('URL_DENY_SUFFIX'),'.').')$/i', $_SERVER['PATH_INFO'])){ + send_http_status(404); + exit; + } + + // 去除URL后缀 + $_SERVER['PATH_INFO'] = preg_replace(C('URL_HTML_SUFFIX')? '/\.('.trim(C('URL_HTML_SUFFIX'),'.').')$/i' : '/\.'.__EXT__.'$/i', '', $_SERVER['PATH_INFO']); + + $depr = C('URL_PATHINFO_DEPR'); + $paths = explode($depr,trim($_SERVER['PATH_INFO'],$depr)); + + $_GET[$varController] = array_shift($paths); + // 获取操作 + $_GET[$varAction] = array_shift($paths); + + // 解析剩余的URL参数 + $var = array(); + if(C('URL_PARAMS_BIND') && 1 == C('URL_PARAMS_BIND_TYPE')){ + // URL参数按顺序绑定变量 + $var = $paths; + }else{ + preg_replace_callback('/(\w+)\/([^\/]+)/', function($match) use(&$var){$var[$match[1]]=strip_tags($match[2]);}, implode('/',$paths)); + } + $_GET = array_merge($var,$_GET); + } + // 获取控制器和操作名 + define('CONTROLLER_NAME', self::getController($varController,$urlCase)); + define('ACTION_NAME', self::getAction($varAction,$urlCase)); + + // 当前控制器的UR地址 + define('__CONTROLLER__',__MODULE__.$depr.( $urlCase ? parse_name(CONTROLLER_NAME) : CONTROLLER_NAME ) ); + + // 当前操作的URL地址 + define('__ACTION__',__CONTROLLER__.$depr.ACTION_NAME); + + //保证$_REQUEST正常取值 + $_REQUEST = array_merge($_POST,$_GET); + } + + /** + * 获得实际的控制器名称 + */ + static private function getController($var,$urlCase) { + $controller = (!empty($_GET[$var])? $_GET[$var]:C('DEFAULT_CONTROLLER')); + unset($_GET[$var]); + if($urlCase) { + // URL地址不区分大小写 + // 智能识别方式 user_type 识别到 UserTypeController 控制器 + $controller = parse_name($controller,1); + } + return strip_tags(ucfirst($controller)); + } + + /** + * 获得实际的操作名称 + */ + static private function getAction($var,$urlCase) { + $action = !empty($_POST[$var]) ? + $_POST[$var] : + (!empty($_GET[$var])?$_GET[$var]:C('DEFAULT_ACTION')); + unset($_POST[$var],$_GET[$var]); + return strip_tags( $urlCase? strtolower($action) : $action ); + } + + /** + * 获得实际的模块名称 + */ + static private function getModule($var) { + $module = (!empty($_GET[$var])?$_GET[$var]:C('DEFAULT_MODULE')); + unset($_GET[$var]); + if($maps = C('URL_MODULE_MAP')) { + if(isset($maps[strtolower($module)])) { + // 记录当前别名 + define('MODULE_ALIAS',strtolower($module)); + // 获取实际的模块名 + return ucfirst($maps[MODULE_ALIAS]); + }elseif(array_search(strtolower($module),$maps)){ + // 禁止访问原始模块 + return ''; + } + } + return strip_tags(ucfirst($module)); + } + +} diff --git a/ThinkPHP/Mode/Lite/Model.class.php b/ThinkPHP/Mode/Lite/Model.class.php new file mode 100644 index 000000000..9135078da --- /dev/null +++ b/ThinkPHP/Mode/Lite/Model.class.php @@ -0,0 +1,1485 @@ + +// +---------------------------------------------------------------------- +namespace Think; +/** + * ThinkPHP Model模型类 + * 实现了ORM和ActiveRecords模式 + */ +class Model { + + // 当前数据库操作对象 + protected $db = null; + // 数据库对象池 + private $_db = array(); + // 主键名称 + protected $pk = 'id'; + // 主键是否自动增长 + protected $autoinc = false; + // 数据表前缀 + protected $tablePrefix = null; + // 模型名称 + protected $name = ''; + // 数据库名称 + protected $dbName = ''; + //数据库配置 + protected $connection = ''; + // 数据表名(不包含表前缀) + protected $tableName = ''; + // 实际数据表名(包含表前缀) + protected $trueTableName = ''; + // 最近错误信息 + protected $error = ''; + // 字段信息 + protected $fields = array(); + // 数据信息 + protected $data = array(); + // 查询表达式参数 + protected $options = array(); + protected $_validate = array(); // 自动验证定义 + protected $_auto = array(); // 自动完成定义 + protected $_map = array(); // 字段映射定义 + protected $_scope = array(); // 命名范围定义 + // 是否自动检测数据表字段信息 + protected $autoCheckFields = true; + // 是否批处理验证 + protected $patchValidate = false; + // 链操作方法列表 + protected $methods = array('strict','order','alias','having','group','lock','distinct','auto','filter','validate','result','token','index','force'); + + /** + * 架构函数 + * 取得DB类的实例对象 字段检查 + * @access public + * @param string $name 模型名称 + * @param string $tablePrefix 表前缀 + * @param mixed $connection 数据库连接信息 + */ + public function __construct($name='',$tablePrefix='',$connection='') { + // 模型初始化 + $this->_initialize(); + // 获取模型名称 + if(!empty($name)) { + if(strpos($name,'.')) { // 支持 数据库名.模型名的 定义 + list($this->dbName,$this->name) = explode('.',$name); + }else{ + $this->name = $name; + } + }elseif(empty($this->name)){ + $this->name = $this->getModelName(); + } + // 设置表前缀 + if(is_null($tablePrefix)) {// 前缀为Null表示没有前缀 + $this->tablePrefix = ''; + }elseif('' != $tablePrefix) { + $this->tablePrefix = $tablePrefix; + }elseif(!isset($this->tablePrefix)){ + $this->tablePrefix = C('DB_PREFIX'); + } + + // 数据库初始化操作 + // 获取数据库操作对象 + // 当前模型有独立的数据库连接信息 + $this->db(0,empty($this->connection)?$connection:$this->connection,true); + } + + /** + * 自动检测数据表信息 + * @access protected + * @return void + */ + protected function _checkTableInfo() { + // 如果不是Model类 自动记录数据表信息 + // 只在第一次执行记录 + if(empty($this->fields)) { + // 如果数据表字段没有定义则自动获取 + if(C('DB_FIELDS_CACHE')) { + $db = $this->dbName?:C('DB_NAME'); + $fields = F('_fields/'.strtolower($db.'.'.$this->tablePrefix.$this->name)); + if($fields) { + $this->fields = $fields; + if(!empty($fields['_pk'])){ + $this->pk = $fields['_pk']; + } + return ; + } + } + // 每次都会读取数据表信息 + $this->flush(); + } + } + + /** + * 获取字段信息并缓存 + * @access public + * @return void + */ + public function flush() { + // 缓存不存在则查询数据表信息 + $this->db->setModel($this->name); + $fields = $this->db->getFields($this->getTableName()); + if(!$fields) { // 无法获取字段信息 + return false; + } + $this->fields = array_keys($fields); + unset($this->fields['_pk']); + foreach ($fields as $key=>$val){ + // 记录字段类型 + $type[$key] = $val['type']; + if($val['primary']) { + // 增加复合主键支持 + if (isset($this->fields['_pk']) && $this->fields['_pk'] != null) { + if (is_string($this->fields['_pk'])) { + $this->pk = array($this->fields['_pk']); + $this->fields['_pk'] = $this->pk; + } + $this->pk[] = $key; + $this->fields['_pk'][] = $key; + } else { + $this->pk = $key; + $this->fields['_pk'] = $key; + } + if($val['autoinc']) $this->autoinc = true; + } + } + // 记录字段类型信息 + $this->fields['_type'] = $type; + + // 2008-3-7 增加缓存开关控制 + if(C('DB_FIELDS_CACHE')){ + // 永久缓存数据表信息 + $db = $this->dbName?:C('DB_NAME'); + F('_fields/'.strtolower($db.'.'.$this->tablePrefix.$this->name),$this->fields); + } + } + + /** + * 设置数据对象的值 + * @access public + * @param string $name 名称 + * @param mixed $value 值 + * @return void + */ + public function __set($name,$value) { + // 设置数据对象属性 + $this->data[$name] = $value; + } + + /** + * 获取数据对象的值 + * @access public + * @param string $name 名称 + * @return mixed + */ + public function __get($name) { + return isset($this->data[$name])?$this->data[$name]:null; + } + + /** + * 检测数据对象的值 + * @access public + * @param string $name 名称 + * @return boolean + */ + public function __isset($name) { + return isset($this->data[$name]); + } + + /** + * 销毁数据对象的值 + * @access public + * @param string $name 名称 + * @return void + */ + public function __unset($name) { + unset($this->data[$name]); + } + + /** + * 利用__call方法实现一些特殊的Model方法 + * @access public + * @param string $method 方法名称 + * @param array $args 调用参数 + * @return mixed + */ + public function __call($method,$args) { + if(in_array(strtolower($method),$this->methods,true)) { + // 连贯操作的实现 + $this->options[strtolower($method)] = $args[0]; + return $this; + }elseif(in_array(strtolower($method),array('count','sum','min','max','avg'),true)){ + // 统计查询的实现 + $field = isset($args[0])?$args[0]:'*'; + return $this->getField(strtoupper($method).'('.$field.') AS tp_'.$method); + }elseif(strtolower(substr($method,0,5))=='getby') { + // 根据某个字段获取记录 + $field = parse_name(substr($method,5)); + $where[$field] = $args[0]; + return $this->where($where)->find(); + }elseif(strtolower(substr($method,0,10))=='getfieldby') { + // 根据某个字段获取记录的某个值 + $name = parse_name(substr($method,10)); + $where[$name] =$args[0]; + return $this->where($where)->getField($args[1]); + }elseif(isset($this->_scope[$method])){// 命名范围的单独调用支持 + return $this->scope($method,$args[0]); + }else{ + E(__CLASS__.':'.$method.L('_METHOD_NOT_EXIST_')); + return; + } + } + // 回调方法 初始化模型 + protected function _initialize() {} + + /** + * 对保存到数据库的数据进行处理 + * @access protected + * @param mixed $data 要操作的数据 + * @return boolean + */ + protected function _facade($data) { + + // 检查数据字段合法性 + if(!empty($this->fields)) { + if(!empty($this->options['field'])) { + $fields = $this->options['field']; + unset($this->options['field']); + if(is_string($fields)) { + $fields = explode(',',$fields); + } + }else{ + $fields = $this->fields; + } + foreach ($data as $key=>$val){ + if(!in_array($key,$fields,true)){ + if(!empty($this->options['strict'])){ + E(L('_DATA_TYPE_INVALID_').':['.$key.'=>'.$val.']'); + } + unset($data[$key]); + }elseif(is_scalar($val)) { + // 字段类型检查 和 强制转换 + $this->_parseType($data,$key); + } + } + } + + // 安全过滤 + if(!empty($this->options['filter'])) { + $data = array_map($this->options['filter'],$data); + unset($this->options['filter']); + } + $this->_before_write($data); + return $data; + } + + // 写入数据前的回调方法 包括新增和更新 + protected function _before_write(&$data) {} + + /** + * 新增数据 + * @access public + * @param mixed $data 数据 + * @param array $options 表达式 + * @param boolean $replace 是否replace + * @return mixed + */ + public function add($data='',$options=array(),$replace=false) { + if(empty($data)) { + // 没有传递数据,获取当前数据对象的值 + if(!empty($this->data)) { + $data = $this->data; + // 重置数据 + $this->data = array(); + }else{ + $this->error = L('_DATA_TYPE_INVALID_'); + return false; + } + } + // 数据处理 + $data = $this->_facade($data); + // 分析表达式 + $options = $this->_parseOptions($options); + if(false === $this->_before_insert($data,$options)) { + return false; + } + // 写入数据到数据库 + $result = $this->db->insert($data,$options,$replace); + if(false !== $result && is_numeric($result)) { + $pk = $this->getPk(); + // 增加复合主键支持 + if (is_array($pk)) return $result; + $insertId = $this->getLastInsID(); + if($insertId) { + // 自增主键返回插入ID + $data[$pk] = $insertId; + if(false === $this->_after_insert($data,$options)) { + return false; + } + return $insertId; + } + if(false === $this->_after_insert($data,$options)) { + return false; + } + } + return $result; + } + // 插入数据前的回调方法 + protected function _before_insert(&$data,$options) {} + // 插入成功后的回调方法 + protected function _after_insert($data,$options) {} + + public function addAll($dataList,$options=array(),$replace=false){ + if(empty($dataList)) { + $this->error = L('_DATA_TYPE_INVALID_'); + return false; + } + // 数据处理 + foreach ($dataList as $key=>$data){ + $dataList[$key] = $this->_facade($data); + } + // 分析表达式 + $options = $this->_parseOptions($options); + // 写入数据到数据库 + $result = $this->db->insertAll($dataList,$options,$replace); + if(false !== $result ) { + $insertId = $this->getLastInsID(); + if($insertId) { + return $insertId; + } + } + return $result; + } + + /** + * 保存数据 + * @access public + * @param mixed $data 数据 + * @param array $options 表达式 + * @return boolean + */ + public function save($data='',$options=array()) { + if(empty($data)) { + // 没有传递数据,获取当前数据对象的值 + if(!empty($this->data)) { + $data = $this->data; + // 重置数据 + $this->data = array(); + }else{ + $this->error = L('_DATA_TYPE_INVALID_'); + return false; + } + } + // 数据处理 + $data = $this->_facade($data); + if(empty($data)){ + // 没有数据则不执行 + $this->error = L('_DATA_TYPE_INVALID_'); + return false; + } + // 分析表达式 + $options = $this->_parseOptions($options); + $pk = $this->getPk(); + if(!isset($options['where']) ) { + // 如果存在主键数据 则自动作为更新条件 + if (is_string($pk) && isset($data[$pk])) { + $where[$pk] = $data[$pk]; + unset($data[$pk]); + } elseif (is_array($pk)) { + // 增加复合主键支持 + foreach ($pk as $field) { + if(isset($data[$field])) { + $where[$field] = $data[$field]; + } else { + // 如果缺少复合主键数据则不执行 + $this->error = L('_OPERATION_WRONG_'); + return false; + } + unset($data[$field]); + } + } + if(!isset($where)){ + // 如果没有任何更新条件则不执行 + $this->error = L('_OPERATION_WRONG_'); + return false; + }else{ + $options['where'] = $where; + } + } + + if(is_array($options['where']) && isset($options['where'][$pk])){ + $pkValue = $options['where'][$pk]; + } + if(false === $this->_before_update($data,$options)) { + return false; + } + $result = $this->db->update($data,$options); + if(false !== $result && is_numeric($result)) { + if(isset($pkValue)) $data[$pk] = $pkValue; + $this->_after_update($data,$options); + } + return $result; + } + // 更新数据前的回调方法 + protected function _before_update(&$data,$options) {} + // 更新成功后的回调方法 + protected function _after_update($data,$options) {} + + /** + * 删除数据 + * @access public + * @param mixed $options 表达式 + * @return mixed + */ + public function delete($options=array()) { + $pk = $this->getPk(); + if(empty($options) && empty($this->options['where'])) { + // 如果删除条件为空 则删除当前数据对象所对应的记录 + if(!empty($this->data) && isset($this->data[$pk])) + return $this->delete($this->data[$pk]); + else + return false; + } + if(is_numeric($options) || is_string($options)) { + // 根据主键删除记录 + if(strpos($options,',')) { + $where[$pk] = array('IN', $options); + }else{ + $where[$pk] = $options; + } + $options = array(); + $options['where'] = $where; + } + // 根据复合主键删除记录 + if (is_array($options) && (count($options) > 0) && is_array($pk)) { + $count = 0; + foreach (array_keys($options) as $key) { + if (is_int($key)) $count++; + } + if ($count == count($pk)) { + $i = 0; + foreach ($pk as $field) { + $where[$field] = $options[$i]; + unset($options[$i++]); + } + $options['where'] = $where; + } else { + return false; + } + } + // 分析表达式 + $options = $this->_parseOptions($options); + if(empty($options['where'])){ + // 如果条件为空 不进行删除操作 除非设置 1=1 + return false; + } + if(is_array($options['where']) && isset($options['where'][$pk])){ + $pkValue = $options['where'][$pk]; + } + + if(false === $this->_before_delete($options)) { + return false; + } + $result = $this->db->delete($options); + if(false !== $result && is_numeric($result)) { + $data = array(); + if(isset($pkValue)) $data[$pk] = $pkValue; + $this->_after_delete($data,$options); + } + // 返回删除记录个数 + return $result; + } + // 删除数据前的回调方法 + protected function _before_delete($options) {} + // 删除成功后的回调方法 + protected function _after_delete($data,$options) {} + + /** + * 查询数据集 + * @access public + * @param array $options 表达式参数 + * @return mixed + */ + public function select($options=array()) { + $pk = $this->getPk(); + if(is_string($options) || is_numeric($options)) { + // 根据主键查询 + if(strpos($options,',')) { + $where[$pk] = array('IN',$options); + }else{ + $where[$pk] = $options; + } + $options = array(); + $options['where'] = $where; + }elseif (is_array($options) && (count($options) > 0) && is_array($pk)) { + // 根据复合主键查询 + $count = 0; + foreach (array_keys($options) as $key) { + if (is_int($key)) $count++; + } + if ($count == count($pk)) { + $i = 0; + foreach ($pk as $field) { + $where[$field] = $options[$i]; + unset($options[$i++]); + } + $options['where'] = $where; + } else { + return false; + } + } elseif(false === $options){ // 用于子查询 不查询只返回SQL + $options = array(); + // 分析表达式 + $options = $this->_parseOptions($options); + return '( '.$this->fetchSql(true)->select($options).' )'; + } + // 分析表达式 + $options = $this->_parseOptions($options); + // 判断查询缓存 + if(isset($options['cache'])){ + $cache = $options['cache']; + $key = is_string($cache['key'])?$cache['key']:md5(serialize($options)); + $data = S($key,'',$cache); + if(false !== $data){ + return $data; + } + } + $resultSet = $this->db->select($options); + if(false === $resultSet) { + return false; + } + if(empty($resultSet)) { // 查询结果为空 + return null; + } + + if(is_string($resultSet)){ + return $resultSet; + } + + $resultSet = array_map(array($this,'_read_data'),$resultSet); + $this->_after_select($resultSet,$options); + if(isset($options['index'])){ // 对数据集进行索引 + $index = explode(',',$options['index']); + foreach ($resultSet as $result){ + $_key = $result[$index[0]]; + if(isset($index[1]) && isset($result[$index[1]])){ + $cols[$_key] = $result[$index[1]]; + }else{ + $cols[$_key] = $result; + } + } + $resultSet = $cols; + } + if(isset($cache)){ + S($key,$resultSet,$cache); + } + return $resultSet; + } + // 查询成功后的回调方法 + protected function _after_select(&$resultSet,$options) {} + + /** + * 分析表达式 + * @access protected + * @param array $options 表达式参数 + * @return array + */ + protected function _parseOptions($options=array()) { + if(is_array($options)) + $options = array_merge($this->options,$options); + + if(!isset($options['table'])){ + // 自动获取表名 + $options['table'] = $this->getTableName(); + $fields = $this->fields; + }else{ + // 指定数据表 则重新获取字段列表 但不支持类型检测 + $fields = $this->getDbFields(); + } + + // 数据表别名 + if(!empty($options['alias'])) { + $options['table'] .= ' '.$options['alias']; + } + // 记录操作的模型名称 + $options['model'] = $this->name; + + // 字段类型验证 + if(isset($options['where']) && is_array($options['where']) && !empty($fields) && !isset($options['join'])) { + // 对数组查询条件进行字段类型检查 + foreach ($options['where'] as $key=>$val){ + $key = trim($key); + if(in_array($key,$fields,true)){ + if(is_scalar($val)) { + $this->_parseType($options['where'],$key); + } + }elseif(!is_numeric($key) && '_' != substr($key,0,1) && false === strpos($key,'.') && false === strpos($key,'(') && false === strpos($key,'|') && false === strpos($key,'&')){ + if(!empty($this->options['strict'])){ + E(L('_ERROR_QUERY_EXPRESS_').':['.$key.'=>'.$val.']'); + } + unset($options['where'][$key]); + } + } + } + // 查询过后清空sql表达式组装 避免影响下次查询 + $this->options = array(); + // 表达式过滤 + $this->_options_filter($options); + return $options; + } + // 表达式过滤回调方法 + protected function _options_filter(&$options) {} + + /** + * 数据类型检测 + * @access protected + * @param mixed $data 数据 + * @param string $key 字段名 + * @return void + */ + protected function _parseType(&$data,$key) { + if(!isset($this->options['bind'][':'.$key]) && isset($this->fields['_type'][$key])){ + $fieldType = strtolower($this->fields['_type'][$key]); + if(false !== strpos($fieldType,'enum')){ + // 支持ENUM类型优先检测 + }elseif(false === strpos($fieldType,'bigint') && false !== strpos($fieldType,'int')) { + $data[$key] = intval($data[$key]); + }elseif(false !== strpos($fieldType,'float') || false !== strpos($fieldType,'double')){ + $data[$key] = floatval($data[$key]); + }elseif(false !== strpos($fieldType,'bool')){ + $data[$key] = (bool)$data[$key]; + } + } + } + + /** + * 数据读取后的处理 + * @access protected + * @param array $data 当前数据 + * @return array + */ + protected function _read_data($data) { + // 检查字段映射 + if(!empty($this->_map) && C('READ_DATA_MAP')) { + foreach ($this->_map as $key=>$val){ + if(isset($data[$val])) { + $data[$key] = $data[$val]; + unset($data[$val]); + } + } + } + return $data; + } + + /** + * 查询数据 + * @access public + * @param mixed $options 表达式参数 + * @return mixed + */ + public function find($options=array()) { + if(is_numeric($options) || is_string($options)) { + $where[$this->getPk()] = $options; + $options = array(); + $options['where'] = $where; + } + // 根据复合主键查找记录 + $pk = $this->getPk(); + if (is_array($options) && (count($options) > 0) && is_array($pk)) { + // 根据复合主键查询 + $count = 0; + foreach (array_keys($options) as $key) { + if (is_int($key)) $count++; + } + if ($count == count($pk)) { + $i = 0; + foreach ($pk as $field) { + $where[$field] = $options[$i]; + unset($options[$i++]); + } + $options['where'] = $where; + } else { + return false; + } + } + // 总是查找一条记录 + $options['limit'] = 1; + // 分析表达式 + $options = $this->_parseOptions($options); + // 判断查询缓存 + if(isset($options['cache'])){ + $cache = $options['cache']; + $key = is_string($cache['key'])?$cache['key']:md5(serialize($options)); + $data = S($key,'',$cache); + if(false !== $data){ + $this->data = $data; + return $data; + } + } + $resultSet = $this->db->select($options); + if(false === $resultSet) { + return false; + } + if(empty($resultSet)) {// 查询结果为空 + return null; + } + if(is_string($resultSet)){ + return $resultSet; + } + + // 读取数据后的处理 + $data = $this->_read_data($resultSet[0]); + $this->_after_find($data,$options); + $this->data = $data; + if(isset($cache)){ + S($key,$data,$cache); + } + return $this->data; + } + // 查询成功的回调方法 + protected function _after_find(&$result,$options) {} + + /** + * 设置记录的某个字段值 + * 支持使用数据库字段和方法 + * @access public + * @param string|array $field 字段名 + * @param string $value 字段值 + * @return boolean + */ + public function setField($field,$value='') { + if(is_array($field)) { + $data = $field; + }else{ + $data[$field] = $value; + } + return $this->save($data); + } + + /** + * 字段值增长 + * @access public + * @param string $field 字段名 + * @param integer $step 增长值 + * @param integer $lazyTime 延时时间(s) + * @return boolean + */ + public function setInc($field,$step=1) { + return $this->setField($field,array('exp',$field.'+'.$step)); + } + + /** + * 字段值减少 + * @access public + * @param string $field 字段名 + * @param integer $step 减少值 + * @param integer $lazyTime 延时时间(s) + * @return boolean + */ + public function setDec($field,$step=1) { + return $this->setField($field,array('exp',$field.'-'.$step)); + } + + /** + * 获取一条记录的某个字段值 + * @access public + * @param string $field 字段名 + * @param string $spea 字段数据间隔符号 NULL返回数组 + * @return mixed + */ + public function getField($field,$sepa=null) { + $options['field'] = $field; + $options = $this->_parseOptions($options); + // 判断查询缓存 + if(isset($options['cache'])){ + $cache = $options['cache']; + $key = is_string($cache['key'])?$cache['key']:md5($sepa.serialize($options)); + $data = S($key,'',$cache); + if(false !== $data){ + return $data; + } + } + $field = trim($field); + if(strpos($field,',') && false !== $sepa) { // 多字段 + if(!isset($options['limit'])){ + $options['limit'] = is_numeric($sepa)?$sepa:''; + } + $resultSet = $this->db->select($options); + if(!empty($resultSet)) { + $_field = explode(',', $field); + $field = array_keys($resultSet[0]); + $key1 = array_shift($field); + $key2 = array_shift($field); + $cols = array(); + $count = count($_field); + foreach ($resultSet as $result){ + $name = $result[$key1]; + if(2==$count) { + $cols[$name] = $result[$key2]; + }else{ + $cols[$name] = is_string($sepa)?implode($sepa,array_slice($result,1)):$result; + } + } + if(isset($cache)){ + S($key,$cols,$cache); + } + return $cols; + } + }else{ // 查找一条记录 + // 返回数据个数 + if(true !== $sepa) {// 当sepa指定为true的时候 返回所有数据 + $options['limit'] = is_numeric($sepa)?$sepa:1; + } + $result = $this->db->select($options); + if(!empty($result)) { + if(true !== $sepa && 1==$options['limit']) { + $data = reset($result[0]); + if(isset($cache)){ + S($key,$data,$cache); + } + return $data; + } + foreach ($result as $val){ + $array[] = $val[$field]; + } + if(isset($cache)){ + S($key,$array,$cache); + } + return $array; + } + } + return null; + } + + /** + * 创建数据对象 但不保存到数据库 + * @access public + * @param mixed $data 创建数据 + * @return mixed + */ + public function create($data='') { + // 如果没有传值默认取POST数据 + if(empty($data)) { + $data = I('post.'); + }elseif(is_object($data)){ + $data = get_object_vars($data); + } + // 验证数据 + if(empty($data) || !is_array($data)) { + $this->error = L('_DATA_TYPE_INVALID_'); + return false; + } + + // 检测提交字段的合法性 + if(isset($this->options['field'])) { // $this->field('field1,field2...')->create() + $fields = $this->options['field']; + unset($this->options['field']); + } + if(isset($fields)) { + if(is_string($fields)) { + $fields = explode(',',$fields); + } + } + + // 验证完成生成数据对象 + if($this->autoCheckFields) { // 开启字段检测 则过滤非法字段数据 + $fields = $this->getDbFields(); + foreach ($data as $key=>$val){ + if(!in_array($key,$fields)) { + unset($data[$key]); + }elseif(MAGIC_QUOTES_GPC && is_string($val)){ + $data[$key] = stripslashes($val); + } + } + } + + // 赋值当前数据对象 + $this->data = $data; + // 返回创建的数据以供其他调用 + return $data; + } + + /** + * 使用正则验证数据 + * @access public + * @param string $value 要验证的数据 + * @param string $rule 验证规则 + * @return boolean + */ + public function regex($value,$rule) { + $validate = array( + 'require' => '/\S+/', + 'email' => '/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/', + 'url' => '/^http(s?):\/\/(?:[A-za-z0-9-]+\.)+[A-za-z]{2,4}(:\d+)?(?:[\/\?#][\/=\?%\-&~`@[\]\':+!\.#\w]*)?$/', + 'currency' => '/^\d+(\.\d+)?$/', + 'number' => '/^\d+$/', + 'zip' => '/^\d{6}$/', + 'integer' => '/^[-\+]?\d+$/', + 'double' => '/^[-\+]?\d+(\.\d+)?$/', + 'english' => '/^[A-Za-z]+$/', + ); + // 检查是否有内置的正则表达式 + if(isset($validate[strtolower($rule)])) + $rule = $validate[strtolower($rule)]; + return preg_match($rule,$value)===1; + } + + /** + * 验证数据 支持 in between equal length regex expire ip_allow ip_deny + * @access public + * @param string $value 验证数据 + * @param mixed $rule 验证表达式 + * @param string $type 验证方式 默认为正则验证 + * @return boolean + */ + public function check($value,$rule,$type='regex'){ + $type = strtolower(trim($type)); + switch($type) { + case 'in': // 验证是否在某个指定范围之内 逗号分隔字符串或者数组 + case 'notin': + $range = is_array($rule)? $rule : explode(',',$rule); + return $type == 'in' ? in_array($value ,$range) : !in_array($value ,$range); + case 'between': // 验证是否在某个范围 + case 'notbetween': // 验证是否不在某个范围 + if (is_array($rule)){ + $min = $rule[0]; + $max = $rule[1]; + }else{ + list($min,$max) = explode(',',$rule); + } + return $type == 'between' ? $value>=$min && $value<=$max : $value<$min || $value>$max; + case 'equal': // 验证是否等于某个值 + case 'notequal': // 验证是否等于某个值 + return $type == 'equal' ? $value == $rule : $value != $rule; + case 'length': // 验证长度 + $length = mb_strlen($value,'utf-8'); // 当前数据长度 + if(strpos($rule,',')) { // 长度区间 + list($min,$max) = explode(',',$rule); + return $length >= $min && $length <= $max; + }else{// 指定长度 + return $length == $rule; + } + case 'expire': + list($start,$end) = explode(',',$rule); + if(!is_numeric($start)) $start = strtotime($start); + if(!is_numeric($end)) $end = strtotime($end); + return NOW_TIME >= $start && NOW_TIME <= $end; + case 'ip_allow': // IP 操作许可验证 + return in_array(get_client_ip(),explode(',',$rule)); + case 'ip_deny': // IP 操作禁止验证 + return !in_array(get_client_ip(),explode(',',$rule)); + case 'regex': + default: // 默认使用正则验证 可以使用验证类中定义的验证名称 + // 检查附加规则 + return $this->regex($value,$rule); + } + } + + /** + * SQL查询 + * @access public + * @param string $sql SQL指令 + * @return mixed + */ + public function query($sql) { + return $this->db->query($sql); + } + + /** + * 执行SQL语句 + * @access public + * @param string $sql SQL指令 + * @return false | integer + */ + public function execute($sql) { + return $this->db->execute($sql); + } + + /** + * 切换当前的数据库连接 + * @access public + * @param integer $linkNum 连接序号 + * @param mixed $config 数据库连接信息 + * @param boolean $force 强制重新连接 + * @return Model + */ + public function db($linkNum='',$config='',$force=false) { + if('' === $linkNum && $this->db) { + return $this->db; + } + + if(!isset($this->_db[$linkNum]) || $force ) { + // 创建一个新的实例 + if(!empty($config) && is_string($config) && false === strpos($config,'/')) { // 支持读取配置参数 + $config = C($config); + } + $this->_db[$linkNum] = Db::getInstance($config); + }elseif(NULL === $config){ + $this->_db[$linkNum]->close(); // 关闭数据库连接 + unset($this->_db[$linkNum]); + return ; + } + + // 切换数据库连接 + $this->db = $this->_db[$linkNum]; + $this->_after_db(); + // 字段检测 + if(!empty($this->name) && $this->autoCheckFields) $this->_checkTableInfo(); + return $this; + } + // 数据库切换后回调方法 + protected function _after_db() {} + + /** + * 得到当前的数据对象名称 + * @access public + * @return string + */ + public function getModelName() { + if(empty($this->name)){ + $name = substr(get_class($this),0,-strlen(C('DEFAULT_M_LAYER'))); + if ( $pos = strrpos($name,'\\') ) {//有命名空间 + $this->name = substr($name,$pos+1); + }else{ + $this->name = $name; + } + } + return $this->name; + } + + /** + * 得到完整的数据表名 + * @access public + * @return string + */ + public function getTableName() { + if(empty($this->trueTableName)) { + $tableName = !empty($this->tablePrefix) ? $this->tablePrefix : ''; + if(!empty($this->tableName)) { + $tableName .= $this->tableName; + }else{ + $tableName .= parse_name($this->name); + } + $this->trueTableName = strtolower($tableName); + } + return (!empty($this->dbName)?$this->dbName.'.':'').$this->trueTableName; + } + + /** + * 启动事务 + * @access public + * @return void + */ + public function startTrans() { + $this->commit(); + $this->db->startTrans(); + return ; + } + + /** + * 提交事务 + * @access public + * @return boolean + */ + public function commit() { + return $this->db->commit(); + } + + /** + * 事务回滚 + * @access public + * @return boolean + */ + public function rollback() { + return $this->db->rollback(); + } + + /** + * 返回模型的错误信息 + * @access public + * @return string + */ + public function getError(){ + return $this->error; + } + + /** + * 返回数据库的错误信息 + * @access public + * @return string + */ + public function getDbError() { + return $this->db->getError(); + } + + /** + * 返回最后插入的ID + * @access public + * @return string + */ + public function getLastInsID() { + return $this->db->getLastInsID(); + } + + /** + * 返回最后执行的sql语句 + * @access public + * @return string + */ + public function getLastSql() { + return $this->db->getLastSql($this->name); + } + // 鉴于getLastSql比较常用 增加_sql 别名 + public function _sql(){ + return $this->getLastSql(); + } + + /** + * 获取主键名称 + * @access public + * @return string + */ + public function getPk() { + return $this->pk; + } + + /** + * 获取数据表字段信息 + * @access public + * @return array + */ + public function getDbFields(){ + if(isset($this->options['table'])) {// 动态指定表名 + if(is_array($this->options['table'])){ + $table = key($this->options['table']); + }else{ + $table = $this->options['table']; + } + $fields = $this->db->getFields($table); + return $fields ? array_keys($fields) : false; + } + if($this->fields) { + $fields = $this->fields; + unset($fields['_type'],$fields['_pk']); + return $fields; + } + return false; + } + + /** + * 设置数据对象值 + * @access public + * @param mixed $data 数据 + * @return Model + */ + public function data($data=''){ + if('' === $data && !empty($this->data)) { + return $this->data; + } + if(is_object($data)){ + $data = get_object_vars($data); + }elseif(is_string($data)){ + parse_str($data,$data); + }elseif(!is_array($data)){ + E(L('_DATA_TYPE_INVALID_')); + } + $this->data = $data; + return $this; + } + + /** + * 指定当前的数据表 + * @access public + * @param mixed $table + * @return Model + */ + public function table($table) { + $prefix = $this->tablePrefix; + if(is_array($table)) { + $this->options['table'] = $table; + }elseif(!empty($table)) { + //将__TABLE_NAME__替换成带前缀的表名 + $table = preg_replace_callback("/__([A-Z0-9_-]+)__/sU", function($match) use($prefix){ return $prefix.strtolower($match[1]);}, $table); + $this->options['table'] = $table; + } + return $this; + } + + /** + * USING支持 用于多表删除 + * @access public + * @param mixed $using + * @return Model + */ + public function using($using){ + $prefix = $this->tablePrefix; + if(is_array($using)) { + $this->options['using'] = $using; + }elseif(!empty($using)) { + //将__TABLE_NAME__替换成带前缀的表名 + $using = preg_replace_callback("/__([A-Z0-9_-]+)__/sU", function($match) use($prefix){ return $prefix.strtolower($match[1]);}, $using); + $this->options['using'] = $using; + } + return $this; + } + + /** + * 查询SQL组装 join + * @access public + * @param mixed $join + * @param string $type JOIN类型 + * @return Model + */ + public function join($join,$type='INNER') { + $prefix = $this->tablePrefix; + if(is_array($join)) { + foreach ($join as $key=>&$_join){ + $_join = preg_replace_callback("/__([A-Z0-9_-]+)__/sU", function($match) use($prefix){ return $prefix.strtolower($match[1]);}, $_join); + $_join = false !== stripos($_join,'JOIN')? $_join : $type.' JOIN ' .$_join; + } + $this->options['join'] = $join; + }elseif(!empty($join)) { + //将__TABLE_NAME__字符串替换成带前缀的表名 + $join = preg_replace_callback("/__([A-Z0-9_-]+)__/sU", function($match) use($prefix){ return $prefix.strtolower($match[1]);}, $join); + $this->options['join'][] = false !== stripos($join,'JOIN')? $join : $type.' JOIN '.$join; + } + return $this; + } + + /** + * 查询SQL组装 union + * @access public + * @param mixed $union + * @param boolean $all + * @return Model + */ + public function union($union,$all=false) { + if(empty($union)) return $this; + if($all) { + $this->options['union']['_all'] = true; + } + if(is_object($union)) { + $union = get_object_vars($union); + } + // 转换union表达式 + if(is_string($union) ) { + $prefix = $this->tablePrefix; + //将__TABLE_NAME__字符串替换成带前缀的表名 + $options = preg_replace_callback("/__([A-Z0-9_-]+)__/sU", function($match) use($prefix){ return $prefix.strtolower($match[1]);}, $union); + }elseif(is_array($union)){ + if(isset($union[0])) { + $this->options['union'] = array_merge($this->options['union'],$union); + return $this; + }else{ + $options = $union; + } + }else{ + E(L('_DATA_TYPE_INVALID_')); + } + $this->options['union'][] = $options; + return $this; + } + + /** + * 查询缓存 + * @access public + * @param mixed $key + * @param integer $expire + * @param string $type + * @return Model + */ + public function cache($key=true,$expire=null,$type=''){ + // 增加快捷调用方式 cache(10) 等同于 cache(true, 10) + if(is_numeric($key) && is_null($expire)){ + $expire = $key; + $key = true; + } + if(false !== $key) + $this->options['cache'] = array('key'=>$key,'expire'=>$expire,'type'=>$type); + return $this; + } + + /** + * 指定查询字段 支持字段排除 + * @access public + * @param mixed $field + * @param boolean $except 是否排除 + * @return Model + */ + public function field($field,$except=false){ + if(true === $field) {// 获取全部字段 + $fields = $this->getDbFields(); + $field = $fields?:'*'; + }elseif($except) {// 字段排除 + if(is_string($field)) { + $field = explode(',',$field); + } + $fields = $this->getDbFields(); + $field = $fields?array_diff($fields,$field):$field; + } + $this->options['field'] = $field; + return $this; + } + + /** + * 调用命名范围 + * @access public + * @param mixed $scope 命名范围名称 支持多个 和直接定义 + * @param array $args 参数 + * @return Model + */ + public function scope($scope='',$args=NULL){ + if('' === $scope) { + if(isset($this->_scope['default'])) { + // 默认的命名范围 + $options = $this->_scope['default']; + }else{ + return $this; + } + }elseif(is_string($scope)){ // 支持多个命名范围调用 用逗号分割 + $scopes = explode(',',$scope); + $options = array(); + foreach ($scopes as $name){ + if(!isset($this->_scope[$name])) continue; + $options = array_merge($options,$this->_scope[$name]); + } + if(!empty($args) && is_array($args)) { + $options = array_merge($options,$args); + } + }elseif(is_array($scope)){ // 直接传入命名范围定义 + $options = $scope; + } + + if(is_array($options) && !empty($options)){ + $this->options = array_merge($this->options,array_change_key_case($options)); + } + return $this; + } + + /** + * 指定查询条件 支持安全过滤 + * @access public + * @param mixed $where 条件表达式 + * @param mixed $parse 预处理参数 + * @return Model + */ + public function where($where,$parse=null){ + if(!is_null($parse) && is_string($where)) { + if(!is_array($parse)) { + $parse = func_get_args(); + array_shift($parse); + } + $parse = array_map(array($this->db,'escapeString'),$parse); + $where = vsprintf($where,$parse); + }elseif(is_object($where)){ + $where = get_object_vars($where); + } + if(is_string($where) && '' != $where){ + $map = array(); + $map['_string'] = $where; + $where = $map; + } + if(isset($this->options['where'])){ + $this->options['where'] = array_merge($this->options['where'],$where); + }else{ + $this->options['where'] = $where; + } + + return $this; + } + + /** + * 指定查询数量 + * @access public + * @param mixed $offset 起始位置 + * @param mixed $length 查询数量 + * @return Model + */ + public function limit($offset,$length=null){ + if(is_null($length) && strpos($offset,',')){ + list($offset,$length) = explode(',',$offset); + } + $this->options['limit'] = intval($offset).( $length? ','.intval($length) : '' ); + return $this; + } + + /** + * 指定分页 + * @access public + * @param mixed $page 页数 + * @param mixed $listRows 每页数量 + * @return Model + */ + public function page($page,$listRows=null){ + if(is_null($listRows) && strpos($page,',')){ + list($page,$listRows) = explode(',',$page); + } + $this->options['page'] = array(intval($page),intval($listRows)); + return $this; + } + + /** + * 查询注释 + * @access public + * @param string $comment 注释 + * @return Model + */ + public function comment($comment){ + $this->options['comment'] = $comment; + return $this; + } + + /** + * 获取执行的SQL语句 + * @access public + * @param boolean $fetch 是否返回sql + * @return Model + */ + public function fetchSql($fetch){ + $this->options['fetch_sql'] = $fetch; + return $this; + } + + /** + * 参数绑定 + * @access public + * @param string $key 参数名 + * @param mixed $value 绑定的变量及绑定参数 + * @return Model + */ + public function bind($key,$value=false) { + if(is_array($key)){ + $this->options['bind'] = $key; + }else{ + $num = func_num_args(); + if($num>2){ + $params = func_get_args(); + array_shift($params); + $this->options['bind'][$key] = $params; + }else{ + $this->options['bind'][$key] = $value; + } + } + return $this; + } + + /** + * 设置模型的属性值 + * @access public + * @param string $name 名称 + * @param mixed $value 值 + * @return Model + */ + public function setProperty($name,$value) { + if(property_exists($this,$name)) + $this->$name = $value; + return $this; + } + +} diff --git a/ThinkPHP/Mode/Lite/View.class.php b/ThinkPHP/Mode/Lite/View.class.php new file mode 100644 index 000000000..064343fe1 --- /dev/null +++ b/ThinkPHP/Mode/Lite/View.class.php @@ -0,0 +1,293 @@ + +// +---------------------------------------------------------------------- +namespace Think; +/** + * ThinkPHP 视图类 + */ +class View { + /** + * 模板输出变量 + * @var tVar + * @access protected + */ + protected $tVar = array(); + + /** + * 模板主题 + * @var theme + * @access protected + */ + protected $theme = ''; + + /** + * 模板变量赋值 + * @access public + * @param mixed $name + * @param mixed $value + */ + public function assign($name,$value=''){ + if(is_array($name)) { + $this->tVar = array_merge($this->tVar,$name); + }else { + $this->tVar[$name] = $value; + } + } + + /** + * 取得模板变量的值 + * @access public + * @param string $name + * @return mixed + */ + public function get($name=''){ + if('' === $name) { + return $this->tVar; + } + return isset($this->tVar[$name])?$this->tVar[$name]:false; + } + + /** + * 加载模板和页面输出 可以返回输出内容 + * @access public + * @param string $templateFile 模板文件名 + * @param string $charset 模板输出字符集 + * @param string $contentType 输出类型 + * @param string $content 模板输出内容 + * @param string $prefix 模板缓存前缀 + * @return mixed + */ + public function display($templateFile='',$charset='',$contentType='',$content='',$prefix='') { + G('viewStartTime'); + // 解析并获取模板内容 + $content = $this->fetch($templateFile,$content,$prefix); + // 输出模板内容 + $this->render($content,$charset,$contentType); + } + + /** + * 输出内容文本可以包括Html + * @access private + * @param string $content 输出内容 + * @param string $charset 模板输出字符集 + * @param string $contentType 输出类型 + * @return mixed + */ + private function render($content,$charset='',$contentType=''){ + if(empty($charset)) $charset = C('DEFAULT_CHARSET'); + if(empty($contentType)) $contentType = C('TMPL_CONTENT_TYPE'); + // 网页字符编码 + header('Content-Type:'.$contentType.'; charset='.$charset); + header('Cache-control: '.C('HTTP_CACHE_CONTROL')); // 页面缓存控制 + header('X-Powered-By:ThinkPHP'); + // 输出模板文件 + echo $content; + } + + /** + * 解析和获取模板内容 用于输出 + * @access public + * @param string $templateFile 模板文件名 + * @param string $content 模板输出内容 + * @param string $prefix 模板缓存前缀 + * @return string + */ + public function fetch($templateFile='',$content='',$prefix='') { + if(empty($content)) { + $templateFile = $this->parseTemplate($templateFile); + // 模板文件不存在直接返回 + if(!is_file($templateFile)) E(L('_TEMPLATE_NOT_EXIST_').':'.$templateFile); + }else{ + defined('THEME_PATH') or define('THEME_PATH', $this->getThemePath()); + } + // 页面缓存 + ob_start(); + ob_implicit_flush(0); + if('php' == strtolower(C('TMPL_ENGINE_TYPE'))) { // 使用PHP原生模板 + $_content = $content; + // 模板阵列变量分解成为独立变量 + extract($this->tVar, EXTR_OVERWRITE); + // 直接载入PHP模板 + empty($_content)?include $templateFile:eval('?>'.$_content); + }else{ + // 视图解析标签 + $params = array('var'=>$this->tVar,'file'=>$templateFile,'content'=>$content,'prefix'=>$prefix); + $_content = !empty($content)?:$templateFile; + if((!empty($content) && $this->checkContentCache($content,$prefix)) || $this->checkCache($templateFile,$prefix)) { // 缓存有效 + //载入模版缓存文件 + Storage::load(C('CACHE_PATH').$prefix.md5($_content).C('TMPL_CACHFILE_SUFFIX'),$this->tVar); + }else{ + $tpl = Think::instance('Think\\Template'); + // 编译并加载模板文件 + $tpl->fetch($_content,$this->tVar,$prefix); + } + } + // 获取并清空缓存 + $content = ob_get_clean(); + // 内容过滤标签 + // 系统默认的特殊变量替换 + $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; + } + + /** + * 检查缓存文件是否有效 + * 如果无效则需要重新编译 + * @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; + } + } + + /** + * 自动定位模板文件 + * @access protected + * @param string $template 模板文件规则 + * @return string + */ + public function parseTemplate($template='') { + if(is_file($template)) { + return $template; + } + $depr = C('TMPL_FILE_DEPR'); + $template = str_replace(':', $depr, $template); + + // 获取当前模块 + $module = MODULE_NAME; + if(strpos($template,'@')){ // 跨模块调用模版文件 + list($module,$template) = explode('@',$template); + } + // 获取当前主题的模版路径 + defined('THEME_PATH') or define('THEME_PATH', $this->getThemePath($module)); + + // 分析模板文件规则 + if('' == $template) { + // 如果模板文件名为空 按照默认规则定位 + $template = CONTROLLER_NAME . $depr . ACTION_NAME; + }elseif(false === strpos($template, $depr)){ + $template = CONTROLLER_NAME . $depr . $template; + } + $file = THEME_PATH.$template.C('TMPL_TEMPLATE_SUFFIX'); + if(C('TMPL_LOAD_DEFAULTTHEME') && THEME_NAME != C('DEFAULT_THEME') && !is_file($file)){ + // 找不到当前主题模板的时候定位默认主题中的模板 + $file = dirname(THEME_PATH).'/'.C('DEFAULT_THEME').'/'.$template.C('TMPL_TEMPLATE_SUFFIX'); + } + return $file; + } + + /** + * 获取当前的模板路径 + * @access protected + * @param string $module 模块名 + * @return string + */ + protected function getThemePath($module=MODULE_NAME){ + // 获取当前主题名称 + $theme = $this->getTemplateTheme(); + // 获取当前主题的模版路径 + $tmplPath = C('VIEW_PATH'); // 模块设置独立的视图目录 + if(!$tmplPath){ + // 定义TMPL_PATH 则改变全局的视图目录到模块之外 + $tmplPath = defined('TMPL_PATH')? TMPL_PATH.$module.'/' : APP_PATH.$module.'/'.C('DEFAULT_V_LAYER').'/'; + } + return $tmplPath.$theme; + } + + /** + * 设置当前输出的模板主题 + * @access public + * @param mixed $theme 主题名称 + * @return View + */ + public function theme($theme){ + $this->theme = $theme; + return $this; + } + + /** + * 获取当前的模板主题 + * @access private + * @return string + */ + private function getTemplateTheme() { + if($this->theme) { // 指定模板主题 + $theme = $this->theme; + }else{ + /* 获取模板主题名称 */ + $theme = C('DEFAULT_THEME'); + if(C('TMPL_DETECT_THEME')) {// 自动侦测模板主题 + $t = C('VAR_TEMPLATE'); + if (isset($_GET[$t])){ + $theme = $_GET[$t]; + }elseif(cookie('think_template')){ + $theme = cookie('think_template'); + } + if(!in_array($theme,explode(',',C('THEME_LIST')))){ + $theme = C('DEFAULT_THEME'); + } + cookie('think_template',$theme,864000); + } + } + defined('THEME_NAME') || define('THEME_NAME', $theme); // 当前模板主题名称 + return $theme?$theme . '/':''; + } + +} \ No newline at end of file diff --git a/ThinkPHP/Mode/Lite/functions.php b/ThinkPHP/Mode/Lite/functions.php new file mode 100644 index 000000000..813edc349 --- /dev/null +++ b/ThinkPHP/Mode/Lite/functions.php @@ -0,0 +1,1417 @@ + +// +---------------------------------------------------------------------- + +/** + * Think 系统函数库 + */ + +/** + * 获取和设置配置参数 支持批量定义 + * @param string|array $name 配置变量 + * @param mixed $value 配置值 + * @param mixed $default 默认值 + * @return mixed + */ +function C($name=null, $value=null,$default=null) { + static $_config = array(); + // 无参数时获取所有 + if (empty($name)) { + return $_config; + } + // 优先执行设置获取或赋值 + if (is_string($name)) { + if (!strpos($name, '.')) { + $name = strtoupper($name); + if (is_null($value)) + return isset($_config[$name]) ? $_config[$name] : $default; + $_config[$name] = $value; + return null; + } + // 二维数组设置和获取支持 + $name = explode('.', $name); + $name[0] = strtoupper($name[0]); + if (is_null($value)) + return isset($_config[$name[0]][$name[1]]) ? $_config[$name[0]][$name[1]] : $default; + $_config[$name[0]][$name[1]] = $value; + return null; + } + // 批量设置 + if (is_array($name)){ + $_config = array_merge($_config, array_change_key_case($name,CASE_UPPER)); + return null; + } + return null; // 避免非法参数 +} + +/** + * 加载配置文件 支持格式转换 仅支持一级配置 + * @param string $file 配置文件名 + * @param string $parse 配置解析方法 有些格式需要用户自己解析 + * @return array + */ +function load_config($file,$parse=CONF_PARSE){ + $ext = pathinfo($file,PATHINFO_EXTENSION); + switch($ext){ + case 'php': + return include $file; + case 'ini': + return parse_ini_file($file); + case 'yaml': + return yaml_parse_file($file); + case 'xml': + return (array)simplexml_load_file($file); + case 'json': + return json_decode(file_get_contents($file), true); + default: + if(function_exists($parse)){ + return $parse($file); + }else{ + E(L('_NOT_SUPPORT_').':'.$ext); + } + } +} + +/** + * 解析yaml文件返回一个数组 + * @param string $file 配置文件名 + * @return array + */ +if (!function_exists('yaml_parse_file')) { + function yaml_parse_file($file) { + vendor('spyc.Spyc'); + return Spyc::YAMLLoad($file); + } +} + +/** + * 抛出异常处理 + * @param string $msg 异常消息 + * @param integer $code 异常代码 默认为0 + * @throws Think\Exception + * @return void + */ +function E($msg, $code=0) { + throw new Think\Exception($msg, $code); +} + +/** + * 记录和统计时间(微秒)和内存使用情况 + * 使用方法: + * + * G('begin'); // 记录开始标记位 + * // ... 区间运行代码 + * G('end'); // 记录结束标签位 + * echo G('begin','end',6); // 统计区间运行时间 精确到小数后6位 + * echo G('begin','end','m'); // 统计区间内存使用情况 + * 如果end标记位没有定义,则会自动以当前作为标记位 + * 其中统计内存使用需要 MEMORY_LIMIT_ON 常量为true才有效 + * + * @param string $start 开始标签 + * @param string $end 结束标签 + * @param integer|string $dec 小数位或者m + * @return mixed + */ +function G($start,$end='',$dec=4) { + static $_info = array(); + static $_mem = array(); + if(is_float($end)) { // 记录时间 + $_info[$start] = $end; + }elseif(!empty($end)){ // 统计时间和内存使用 + if(!isset($_info[$end])) $_info[$end] = microtime(TRUE); + if(MEMORY_LIMIT_ON && $dec=='m'){ + if(!isset($_mem[$end])) $_mem[$end] = memory_get_usage(); + return number_format(($_mem[$end]-$_mem[$start])/1024); + }else{ + return number_format(($_info[$end]-$_info[$start]),$dec); + } + + }else{ // 记录时间和内存使用 + $_info[$start] = microtime(TRUE); + if(MEMORY_LIMIT_ON) $_mem[$start] = memory_get_usage(); + } + return null; +} + +/** + * 获取和设置语言定义(不区分大小写) + * @param string|array $name 语言变量 + * @param mixed $value 语言值或者变量 + * @return mixed + */ +function L($name=null, $value=null) { + static $_lang = array(); + // 空参数返回所有定义 + if (empty($name)) + return $_lang; + // 判断语言获取(或设置) + // 若不存在,直接返回全大写$name + if (is_string($name)) { + $name = strtoupper($name); + if (is_null($value)){ + return isset($_lang[$name]) ? $_lang[$name] : $name; + }elseif(is_array($value)){ + // 支持变量 + $replace = array_keys($value); + foreach($replace as &$v){ + $v = '{$'.$v.'}'; + } + return str_replace($replace,$value,isset($_lang[$name]) ? $_lang[$name] : $name); + } + $_lang[$name] = $value; // 语言定义 + return null; + } + // 批量定义 + if (is_array($name)) + $_lang = array_merge($_lang, array_change_key_case($name, CASE_UPPER)); + return null; +} + +/** + * 添加和获取页面Trace记录 + * @param string $value 变量 + * @param string $label 标签 + * @param string $level 日志级别 + * @param boolean $record 是否记录日志 + * @return void|array + */ +function trace($value='[think]',$label='',$level='DEBUG',$record=false) { + return Think\Think::trace($value,$label,$level,$record); +} + +/** + * 编译文件 + * @param string $filename 文件名 + * @return string + */ +function compile($filename) { + $content = php_strip_whitespace($filename); + $content = trim(substr($content, 5)); + // 替换预编译指令 + $content = preg_replace('/\/\/\[RUNTIME\](.*?)\/\/\[\/RUNTIME\]/s', '', $content); + if(0===strpos($content,'namespace')){ + $content = preg_replace('/namespace\s(.*?);/','namespace \\1{',$content,1); + }else{ + $content = 'namespace {'.$content; + } + if ('?>' == substr($content, -2)) + $content = substr($content, 0, -2); + return $content.'}'; +} + +/** + * 获取模版文件 格式 资源://模块@主题/控制器/操作 + * @param string $template 模版资源地址 + * @param string $layer 视图层(目录)名称 + * @return string + */ +function T($template='',$layer=''){ + + // 解析模版资源地址 + if(false === strpos($template,'://')){ + $template = 'http://'.str_replace(':', '/',$template); + } + $info = parse_url($template); + $file = $info['host'].(isset($info['path'])?$info['path']:''); + $module = isset($info['user'])?$info['user'].'/':MODULE_NAME.'/'; + $extend = $info['scheme']; + $layer = $layer?$layer:C('DEFAULT_V_LAYER'); + + // 获取当前主题的模版路径 + $auto = C('AUTOLOAD_NAMESPACE'); + if($auto && isset($auto[$extend])){ // 扩展资源 + $baseUrl = $auto[$extend].$module.$layer.'/'; + }elseif(C('VIEW_PATH')){ + // 改变模块视图目录 + $baseUrl = C('VIEW_PATH'); + }elseif(defined('TMPL_PATH')){ + // 指定全局视图目录 + $baseUrl = TMPL_PATH.$module; + }else{ + $baseUrl = APP_PATH.$module.$layer.'/'; + } + + // 获取主题 + $theme = substr_count($file,'/')<2 ? C('DEFAULT_THEME') : ''; + + // 分析模板文件规则 + $depr = C('TMPL_FILE_DEPR'); + if('' == $file) { + // 如果模板文件名为空 按照默认规则定位 + $file = CONTROLLER_NAME . $depr . ACTION_NAME; + }elseif(false === strpos($file, '/')){ + $file = CONTROLLER_NAME . $depr . $file; + }elseif('/' != $depr){ + $file = substr_count($file,'/')>1 ? substr_replace($file,$depr,strrpos($file,'/'),1) : str_replace('/', $depr, $file); + } + return $baseUrl.($theme?$theme.'/':'').$file.C('TMPL_TEMPLATE_SUFFIX'); +} + +/** + * 获取输入参数 支持过滤和默认值 + * 使用方法: + * + * I('id',0); 获取id参数 自动判断get或者post + * I('post.name','','htmlspecialchars'); 获取$_POST['name'] + * I('get.'); 获取$_GET + * + * @param string $name 变量的名称 支持指定类型 + * @param mixed $default 不存在的时候默认值 + * @param mixed $filter 参数过滤方法 + * @param mixed $datas 要获取的额外数据源 + * @return mixed + */ +function I($name,$default='',$filter=null,$datas=null) { + if(strpos($name,'/')){ // 指定修饰符 + list($name,$type) = explode('/',$name,2); + }elseif(C('VAR_AUTO_STRING')){ // 默认强制转换为字符串 + $type = 's'; + } + if(strpos($name,'.')) { // 指定参数来源 + list($method,$name) = explode('.',$name,2); + }else{ // 默认为自动判断 + $method = 'param'; + } + switch(strtolower($method)) { + case 'get' : $input =& $_GET;break; + case 'post' : $input =& $_POST;break; + case 'put' : parse_str(file_get_contents('php://input'), $input);break; + case 'param' : + switch($_SERVER['REQUEST_METHOD']) { + case 'POST': + $input = $_POST; + break; + case 'PUT': + parse_str(file_get_contents('php://input'), $input); + break; + default: + $input = $_GET; + } + break; + case 'path' : + $input = array(); + if(!empty($_SERVER['PATH_INFO'])){ + $depr = C('URL_PATHINFO_DEPR'); + $input = explode($depr,trim($_SERVER['PATH_INFO'],$depr)); + } + break; + case 'request' : $input =& $_REQUEST; break; + case 'session' : $input =& $_SESSION; break; + case 'cookie' : $input =& $_COOKIE; break; + case 'server' : $input =& $_SERVER; break; + case 'globals' : $input =& $GLOBALS; break; + case 'data' : $input =& $datas; break; + default: + return NULL; + } + if(''==$name) { // 获取全部变量 + $data = $input; + $filters = isset($filter)?$filter:C('DEFAULT_FILTER'); + if($filters) { + if(is_string($filters)){ + $filters = explode(',',$filters); + } + foreach($filters as $filter){ + $data = array_map_recursive($filter,$data); // 参数过滤 + } + } + }elseif(isset($input[$name])) { // 取值操作 + $data = $input[$name]; + $filters = isset($filter)?$filter:C('DEFAULT_FILTER'); + if($filters) { + if(is_string($filters)){ + $filters = explode(',',$filters); + }elseif(is_int($filters)){ + $filters = array($filters); + } + + foreach($filters as $filter){ + if(function_exists($filter)) { + $data = is_array($data) ? array_map_recursive($filter,$data) : $filter($data); // 参数过滤 + }elseif(0===strpos($filter,'/')){ + // 支持正则验证 + if(1 !== preg_match($filter,(string)$data)){ + return isset($default) ? $default : NULL; + } + }else{ + $data = filter_var($data,is_int($filter) ? $filter : filter_id($filter)); + if(false === $data) { + return isset($default) ? $default : NULL; + } + } + } + } + if(!empty($type)){ + switch(strtolower($type)){ + case 'a': // 数组 + $data = (array)$data; + break; + case 'd': // 数字 + $data = (int)$data; + break; + case 'f': // 浮点 + $data = (float)$data; + break; + case 'b': // 布尔 + $data = (boolean)$data; + break; + case 's': // 字符串 + default: + $data = (string)$data; + } + } + }else{ // 变量默认值 + $data = isset($default)?$default:NULL; + } + is_array($data) && array_walk_recursive($data,'think_filter'); + return $data; +} + +function array_map_recursive($filter, $data) { + $result = array(); + foreach ($data as $key => $val) { + $result[$key] = is_array($val) + ? array_map_recursive($filter, $val) + : call_user_func($filter, $val); + } + return $result; + } + +/** + * 设置和获取统计数据 + * 使用方法: + * + * N('db',1); // 记录数据库操作次数 + * N('read',1); // 记录读取次数 + * echo N('db'); // 获取当前页面数据库的所有操作次数 + * echo N('read'); // 获取当前页面读取次数 + * + * @param string $key 标识位置 + * @param integer $step 步进值 + * @param boolean $save 是否保存结果 + * @return mixed + */ +function N($key, $step=0,$save=false) { + static $_num = array(); + if (!isset($_num[$key])) { + $_num[$key] = (false !== $save)? S('N_'.$key) : 0; + } + if (empty($step)){ + return $_num[$key]; + }else{ + $_num[$key] = $_num[$key] + (int)$step; + } + if(false !== $save){ // 保存结果 + S('N_'.$key,$_num[$key],$save); + } + return null; +} + +/** + * 字符串命名风格转换 + * type 0 将Java风格转换为C的风格 1 将C风格转换为Java的风格 + * @param string $name 字符串 + * @param integer $type 转换类型 + * @return string + */ +function parse_name($name, $type=0) { + if ($type) { + return ucfirst(preg_replace_callback('/_([a-zA-Z])/', function($match){return strtoupper($match[1]);}, $name)); + } else { + return strtolower(trim(preg_replace("/[A-Z]/", "_\\0", $name), "_")); + } +} + +/** + * 优化的require_once + * @param string $filename 文件地址 + * @return boolean + */ +function require_cache($filename) { + static $_importFiles = array(); + if (!isset($_importFiles[$filename])) { + if (file_exists_case($filename)) { + require $filename; + $_importFiles[$filename] = true; + } else { + $_importFiles[$filename] = false; + } + } + return $_importFiles[$filename]; +} + +/** + * 区分大小写的文件存在判断 + * @param string $filename 文件地址 + * @return boolean + */ +function file_exists_case($filename) { + if (is_file($filename)) { + if (IS_WIN && APP_DEBUG) { + if (basename(realpath($filename)) != basename($filename)) + return false; + } + return true; + } + return false; +} + +/** + * 导入所需的类库 同java的Import 本函数有缓存功能 + * @param string $class 类库命名空间字符串 + * @param string $baseUrl 起始路径 + * @param string $ext 导入的文件扩展名 + * @return boolean + */ +function import($class, $baseUrl = '', $ext=EXT) { + static $_file = array(); + $class = str_replace(array('.', '#'), array('/', '.'), $class); + if (isset($_file[$class . $baseUrl])) + return true; + else + $_file[$class . $baseUrl] = true; + $class_strut = explode('/', $class); + if (empty($baseUrl)) { + if ('@' == $class_strut[0] || MODULE_NAME == $class_strut[0]) { + //加载当前模块的类库 + $baseUrl = MODULE_PATH; + $class = substr_replace($class, '', 0, strlen($class_strut[0]) + 1); + }elseif ('Common' == $class_strut[0]) { + //加载公共模块的类库 + $baseUrl = COMMON_PATH; + $class = substr($class, 7); + }elseif (in_array($class_strut[0],array('Think','Org','Behavior','Com','Vendor')) || is_dir(LIB_PATH.$class_strut[0])) { + // 系统类库包和第三方类库包 + $baseUrl = LIB_PATH; + }else { // 加载其他模块的类库 + $baseUrl = APP_PATH; + } + } + if (substr($baseUrl, -1) != '/') + $baseUrl .= '/'; + $classfile = $baseUrl . $class . $ext; + if (!class_exists(basename($class),false)) { + // 如果类不存在 则导入类库文件 + return require_cache($classfile); + } + return null; +} + +/** + * 基于命名空间方式导入函数库 + * load('@.Util.Array') + * @param string $name 函数库命名空间字符串 + * @param string $baseUrl 起始路径 + * @param string $ext 导入的文件扩展名 + * @return void + */ +function load($name, $baseUrl='', $ext='.php') { + $name = str_replace(array('.', '#'), array('/', '.'), $name); + if (empty($baseUrl)) { + if (0 === strpos($name, '@/')) {//加载当前模块函数库 + $baseUrl = MODULE_PATH.'Common/'; + $name = substr($name, 2); + } else { //加载其他模块函数库 + $array = explode('/', $name); + $baseUrl = APP_PATH . array_shift($array).'/Common/'; + $name = implode('/',$array); + } + } + if (substr($baseUrl, -1) != '/') + $baseUrl .= '/'; + require_cache($baseUrl . $name . $ext); +} + +/** + * 快速导入第三方框架类库 所有第三方框架的类库文件统一放到 系统的Vendor目录下面 + * @param string $class 类库 + * @param string $baseUrl 基础目录 + * @param string $ext 类库后缀 + * @return boolean + */ +function vendor($class, $baseUrl = '', $ext='.php') { + if (empty($baseUrl)) + $baseUrl = VENDOR_PATH; + return import($class, $baseUrl, $ext); +} + +/** + * 实例化模型类 格式 [资源://][模块/]模型 + * @param string $name 资源地址 + * @param string $layer 模型层名称 + * @return Think\Model + */ +function D($name='',$layer='') { + if(empty($name)) return new Think\Model; + static $_model = array(); + $layer = $layer? : 'Controller'; + if(isset($_model[$name.$layer])) + return $_model[$name.$layer]; + $class = parse_res_name($name,$layer); + if(class_exists($class)) { + $model = new $class(basename($name)); + }elseif(false === strpos($name,'/')){ + // 自动加载公共模块下面的模型 + $class = '\\Common\\'.$layer.'\\'.$name.$layer; + $model = class_exists($class)? new $class($name) : new Think\Model($name); + }else { + $model = new Think\Model(basename($name)); + } + $_model[$name.$layer] = $model; + return $model; +} + +/** + * 实例化一个没有模型文件的Model + * @param string $name Model名称 支持指定基础模型 例如 MongoModel:User + * @param string $tablePrefix 表前缀 + * @param mixed $connection 数据库连接信息 + * @return Think\Model + */ +function M($name='', $tablePrefix='',$connection='') { + static $_model = array(); + if(strpos($name,':')) { + list($class,$name) = explode(':',$name); + }else{ + $class = 'Think\\Model'; + } + $guid = (is_array($connection)?implode('',$connection):$connection).$tablePrefix . $name . '_' . $class; + if (!isset($_model[$guid])) + $_model[$guid] = new $class($name,$tablePrefix,$connection); + return $_model[$guid]; +} + +/** + * 解析资源地址并导入类库文件 + * 例如 module/controller addon://module/behavior + * @param string $name 资源地址 格式:[扩展://][模块/]资源名 + * @param string $layer 分层名称 + * @return string + */ +function parse_res_name($name,$layer){ + if(strpos($name,'://')) {// 指定扩展资源 + list($extend,$name) = explode('://',$name); + }else{ + $extend = ''; + } + if(strpos($name,'/')){ // 指定模块 + list($module,$name) = explode('/',$name,2); + }else{ + $module = defined('MODULE_NAME') ? MODULE_NAME : '' ; + } + $array = explode('/',$name); + $class = $module.'\\'.$layer; + foreach($array as $name){ + $class .= '\\'.parse_name($name, 1); + } + // 导入资源类库 + if($extend){ // 扩展资源 + $class = $extend.'\\'.$class; + } + + return $class.$layer; +} + +/** + * 用于实例化访问控制器 + * @param string $name 控制器名 + * @param string $path 控制器命名空间(路径) + * @return Think\Controller|false + */ +function controller($name){ + $class = MODULE_NAME .'\\Controller'; + $array = explode('/',$name); + foreach($array as $name){ + $class .= '\\'.parse_name($name, 1); + } + $class .= $layer; + + if(class_exists($class)) { + return new $class(); + }else { + return false; + } +} + +/** + * 实例化多层控制器 格式:[资源://][模块/]控制器 + * @param string $name 资源地址 + * @param string $layer 控制层名称 + * @return Think\Controller|false + */ +function A($name,$layer='',$level=0) { + static $_action = array(); + $layer = $layer? : 'Controller'; + if(isset($_action[$name.$layer])) + return $_action[$name.$layer]; + + $class = parse_res_name($name,$layer); + if(class_exists($class)) { + $action = new $class(); + $_action[$name.$layer] = $action; + return $action; + }else { + return false; + } +} + + +/** + * 远程调用控制器的操作方法 URL 参数格式 [资源://][模块/]控制器/操作 + * @param string $url 调用地址 + * @param string|array $vars 调用参数 支持字符串和数组 + * @param string $layer 要调用的控制层名称 + * @return mixed + */ +function R($url,$vars=array(),$layer='') { + $info = pathinfo($url); + $action = $info['basename']; + $module = $info['dirname']; + $class = A($module,$layer); + if($class){ + if(is_string($vars)) { + parse_str($vars,$vars); + } + return call_user_func_array(array(&$class,$action.C('ACTION_SUFFIX')),$vars); + }else{ + return false; + } +} + +/** + * 处理标签扩展 + * @param string $tag 标签名称 + * @param mixed $params 传入参数 + * @return void + */ +function tag($tag, &$params=NULL) { + \Think\Hook::listen($tag,$params); +} + +/** + * 执行某个行为 + * @param string $name 行为名称 + * @param string $tag 标签名称(行为类无需传入) + * @param Mixed $params 传入的参数 + * @return void + */ +function B($name, $tag='',&$params=NULL) { + if(''==$tag){ + $name .= 'Behavior'; + } + \Think\Hook::exec($name,$tag,$params); +} + +/** + * 去除代码中的空白和注释 + * @param string $content 代码内容 + * @return string + */ +function strip_whitespace($content) { + $stripStr = ''; + //分析php源码 + $tokens = token_get_all($content); + $last_space = false; + for ($i = 0, $j = count($tokens); $i < $j; $i++) { + if (is_string($tokens[$i])) { + $last_space = false; + $stripStr .= $tokens[$i]; + } else { + switch ($tokens[$i][0]) { + //过滤各种PHP注释 + case T_COMMENT: + case T_DOC_COMMENT: + break; + //过滤空格 + case T_WHITESPACE: + if (!$last_space) { + $stripStr .= ' '; + $last_space = true; + } + break; + case T_START_HEREDOC: + $stripStr .= "<<'; + } else { + $output = $label . print_r($var, true); + } + } else { + ob_start(); + var_dump($var); + $output = ob_get_clean(); + if (!extension_loaded('xdebug')) { + $output = preg_replace('/\]\=\>\n(\s+)/m', '] => ', $output); + $output = '
' . $label . htmlspecialchars($output, ENT_QUOTES) . '
'; + } + } + if ($echo) { + echo($output); + return null; + }else + return $output; +} + +/** + * 设置当前页面的布局 + * @param string|false $layout 布局名称 为false的时候表示关闭布局 + * @return void + */ +function layout($layout) { + if(false !== $layout) { + // 开启布局 + C('LAYOUT_ON',true); + if(is_string($layout)) { // 设置新的布局模板 + C('LAYOUT_NAME',$layout); + } + }else{// 临时关闭布局 + C('LAYOUT_ON',false); + } +} + +/** + * URL组装 支持不同URL模式 + * @param string $url URL表达式,格式:'[模块/控制器/操作#锚点@域名]?参数1=值1&参数2=值2...' + * @param string|array $vars 传入的参数,支持数组和字符串 + * @param string|boolean $suffix 伪静态后缀,默认为true表示获取配置值 + * @param boolean $domain 是否显示域名 + * @return string + */ +function U($url='',$vars='',$suffix=true,$domain=false) { + // 解析URL + $info = parse_url($url); + $url = !empty($info['path'])?$info['path']:ACTION_NAME; + if(isset($info['fragment'])) { // 解析锚点 + $anchor = $info['fragment']; + if(false !== strpos($anchor,'?')) { // 解析参数 + list($anchor,$info['query']) = explode('?',$anchor,2); + } + if(false !== strpos($anchor,'@')) { // 解析域名 + list($anchor,$host) = explode('@',$anchor, 2); + } + }elseif(false !== strpos($url,'@')) { // 解析域名 + list($url,$host) = explode('@',$info['path'], 2); + } + // 解析子域名 + if(isset($host)) { + $domain = $host.(strpos($host,'.')?'':strstr($_SERVER['HTTP_HOST'],'.')); + }elseif($domain===true){ + $domain = $_SERVER['HTTP_HOST']; + if(C('APP_SUB_DOMAIN_DEPLOY') ) { // 开启子域名部署 + $domain = $domain=='localhost'?'localhost':'www'.strstr($_SERVER['HTTP_HOST'],'.'); + // '子域名'=>array('模块[/控制器]'); + foreach (C('APP_SUB_DOMAIN_RULES') as $key => $rule) { + $rule = is_array($rule)?$rule[0]:$rule; + if(false === strpos($key,'*') && 0=== strpos($url,$rule)) { + $domain = $key.strstr($domain,'.'); // 生成对应子域名 + $url = substr_replace($url,'',0,strlen($rule)); + break; + } + } + } + } + + // 解析参数 + if(is_string($vars)) { // aaa=1&bbb=2 转换成数组 + parse_str($vars,$vars); + }elseif(!is_array($vars)){ + $vars = array(); + } + if(isset($info['query'])) { // 解析地址里面参数 合并到vars + parse_str($info['query'],$params); + $vars = array_merge($params,$vars); + } + + // URL组装 + $depr = C('URL_PATHINFO_DEPR'); + $urlCase = C('URL_CASE_INSENSITIVE'); + if($url) { + if(0=== strpos($url,'/')) {// 定义路由 + $route = true; + $url = substr($url,1); + if('/' != $depr) { + $url = str_replace('/',$depr,$url); + } + }else{ + if('/' != $depr) { // 安全替换 + $url = str_replace('/',$depr,$url); + } + // 解析模块、控制器和操作 + $url = trim($url,$depr); + $path = explode($depr,$url); + $var = array(); + $varModule = C('VAR_MODULE'); + $varController = C('VAR_CONTROLLER'); + $varAction = C('VAR_ACTION'); + $var[$varAction] = !empty($path)?array_pop($path):ACTION_NAME; + $var[$varController] = !empty($path)?array_pop($path):CONTROLLER_NAME; + if($urlCase) { + $var[$varController] = parse_name($var[$varController]); + } + $module = ''; + + if(!empty($path)) { + $var[$varModule] = implode($depr,$path); + }else{ + if(C('MULTI_MODULE')) { + if(MODULE_NAME != C('DEFAULT_MODULE') || !C('MODULE_ALLOW_LIST')){ + $var[$varModule]= MODULE_NAME; + } + } + } + if($maps = C('URL_MODULE_MAP')) { + if($_module = array_search(strtolower($var[$varModule]),$maps)){ + $var[$varModule] = $_module; + } + } + if(isset($var[$varModule])){ + $module = $var[$varModule]; + unset($var[$varModule]); + } + + } + } + + if(C('URL_MODEL') == 0) { // 普通模式URL转换 + $url = __APP__.'?'.C('VAR_MODULE')."={$module}&".http_build_query(array_reverse($var)); + if($urlCase){ + $url = strtolower($url); + } + if(!empty($vars)) { + $vars = http_build_query($vars); + $url .= '&'.$vars; + } + }else{ // PATHINFO模式或者兼容URL模式 + if(isset($route)) { + $url = __APP__.'/'.rtrim($url,$depr); + }else{ + $module = (defined('BIND_MODULE') && BIND_MODULE==$module )? '' : $module; + $url = __APP__.'/'.($module?$module.MODULE_PATHINFO_DEPR:'').implode($depr,array_reverse($var)); + } + if($urlCase){ + $url = strtolower($url); + } + if(!empty($vars)) { // 添加参数 + foreach ($vars as $var => $val){ + if('' !== trim($val)) $url .= $depr . $var . $depr . urlencode($val); + } + } + if($suffix) { + $suffix = $suffix===true?C('URL_HTML_SUFFIX'):$suffix; + if($pos = strpos($suffix, '|')){ + $suffix = substr($suffix, 0, $pos); + } + if($suffix && '/' != substr($url,-1)){ + $url .= '.'.ltrim($suffix,'.'); + } + } + } + if(isset($anchor)){ + $url .= '#'.$anchor; + } + if($domain) { + $url = (is_ssl()?'https://':'http://').$domain.$url; + } + return $url; +} + +/** + * 渲染输出Widget + * @param string $name Widget名称 + * @param array $data 传入的参数 + * @return void + */ +function W($name, $data=array()) { + R($name,$data,'Widget'); +} + +/** + * 判断是否SSL协议 + * @return boolean + */ +function is_ssl() { + if(isset($_SERVER['HTTPS']) && ('1' == $_SERVER['HTTPS'] || 'on' == strtolower($_SERVER['HTTPS']))){ + return true; + }elseif(isset($_SERVER['SERVER_PORT']) && ('443' == $_SERVER['SERVER_PORT'] )) { + return true; + } + return false; +} + +/** + * URL重定向 + * @param string $url 重定向的URL地址 + * @param integer $time 重定向的等待时间(秒) + * @param string $msg 重定向前的提示信息 + * @return void + */ +function redirect($url, $time=0, $msg='') { + //多行URL地址支持 + $url = str_replace(array("\n", "\r"), '', $url); + if (empty($msg)) + $msg = "系统将在{$time}秒之后自动跳转到{$url}!"; + if (!headers_sent()) { + // redirect + if (0 === $time) { + header('Location: ' . $url); + } else { + header("refresh:{$time};url={$url}"); + echo($msg); + } + exit(); + } else { + $str = ""; + if ($time != 0) + $str .= $msg; + exit($str); + } +} + +/** + * 缓存管理 + * @param mixed $name 缓存名称,如果为数组表示进行缓存设置 + * @param mixed $value 缓存值 + * @param mixed $options 缓存参数 + * @return mixed + */ +function S($name,$value='',$options=null) { + static $cache = ''; + if(is_array($options) && empty($cache)){ + // 缓存操作的同时初始化 + $type = isset($options['type'])?$options['type']:''; + $cache = Think\Cache::getInstance($type,$options); + }elseif(is_array($name)) { // 缓存初始化 + $type = isset($name['type'])?$name['type']:''; + $cache = Think\Cache::getInstance($type,$name); + return $cache; + }elseif(empty($cache)) { // 自动初始化 + $cache = Think\Cache::getInstance(); + } + if(''=== $value){ // 获取缓存 + return $cache->get($name); + }elseif(is_null($value)) { // 删除缓存 + return $cache->rm($name); + }else { // 缓存数据 + if(is_array($options)) { + $expire = isset($options['expire'])?$options['expire']:NULL; + }else{ + $expire = is_numeric($options)?$options:NULL; + } + return $cache->set($name, $value, $expire); + } +} + +/** + * 快速文件数据读取和保存 针对简单类型数据 字符串、数组 + * @param string $name 缓存名称 + * @param mixed $value 缓存值 + * @param string $path 缓存路径 + * @return mixed + */ +function F($name, $value='', $path=DATA_PATH) { + static $_cache = array(); + $filename = $path . $name . '.php'; + if ('' !== $value) { + if (is_null($value)) { + // 删除缓存 + if(false !== strpos($name,'*')){ + return false; // TODO + }else{ + unset($_cache[$name]); + return Think\Storage::unlink($filename,'F'); + } + } else { + Think\Storage::put($filename,serialize($value),'F'); + // 缓存数据 + $_cache[$name] = $value; + return null; + } + } + // 获取缓存数据 + if (isset($_cache[$name])) + return $_cache[$name]; + if (Think\Storage::has($filename,'F')){ + $value = unserialize(Think\Storage::read($filename,'F')); + $_cache[$name] = $value; + } else { + $value = false; + } + return $value; +} + +/** + * 根据PHP各种类型变量生成唯一标识号 + * @param mixed $mix 变量 + * @return string + */ +function to_guid_string($mix) { + if (is_object($mix)) { + return spl_object_hash($mix); + } elseif (is_resource($mix)) { + $mix = get_resource_type($mix) . strval($mix); + } else { + $mix = serialize($mix); + } + return md5($mix); +} + +/** + * XML编码 + * @param mixed $data 数据 + * @param string $root 根节点名 + * @param string $item 数字索引的子节点名 + * @param string $attr 根节点属性 + * @param string $id 数字索引子节点key转换的属性名 + * @param string $encoding 数据编码 + * @return string + */ +function xml_encode($data, $root='think', $item='item', $attr='', $id='id', $encoding='utf-8') { + if(is_array($attr)){ + $_attr = array(); + foreach ($attr as $key => $value) { + $_attr[] = "{$key}=\"{$value}\""; + } + $attr = implode(' ', $_attr); + } + $attr = trim($attr); + $attr = empty($attr) ? '' : " {$attr}"; + $xml = ""; + $xml .= "<{$root}{$attr}>"; + $xml .= data_to_xml($data, $item, $id); + $xml .= ""; + return $xml; +} + +/** + * 数据XML编码 + * @param mixed $data 数据 + * @param string $item 数字索引时的节点名称 + * @param string $id 数字索引key转换为的属性名 + * @return string + */ +function data_to_xml($data, $item='item', $id='id') { + $xml = $attr = ''; + foreach ($data as $key => $val) { + if(is_numeric($key)){ + $id && $attr = " {$id}=\"{$key}\""; + $key = $item; + } + $xml .= "<{$key}{$attr}>"; + $xml .= (is_array($val) || is_object($val)) ? data_to_xml($val, $item, $id) : $val; + $xml .= ""; + } + return $xml; +} + +/** + * session管理函数 + * @param string|array $name session名称 如果为数组则表示进行session设置 + * @param mixed $value session值 + * @return mixed + */ +function session($name='',$value='') { + $prefix = C('SESSION_PREFIX'); + if(is_array($name)) { // session初始化 在session_start 之前调用 + if(isset($name['prefix'])) C('SESSION_PREFIX',$name['prefix']); + if(C('VAR_SESSION_ID') && isset($_REQUEST[C('VAR_SESSION_ID')])){ + session_id($_REQUEST[C('VAR_SESSION_ID')]); + }elseif(isset($name['id'])) { + session_id($name['id']); + } + if('common' != APP_MODE){ // 其它模式可能不支持 + ini_set('session.auto_start', 0); + } + if(isset($name['name'])) session_name($name['name']); + if(isset($name['path'])) session_save_path($name['path']); + if(isset($name['domain'])) ini_set('session.cookie_domain', $name['domain']); + if(isset($name['expire'])) ini_set('session.gc_maxlifetime', $name['expire']); + if(isset($name['use_trans_sid'])) ini_set('session.use_trans_sid', $name['use_trans_sid']?1:0); + if(isset($name['use_cookies'])) ini_set('session.use_cookies', $name['use_cookies']?1:0); + if(isset($name['cache_limiter'])) session_cache_limiter($name['cache_limiter']); + if(isset($name['cache_expire'])) session_cache_expire($name['cache_expire']); + if(isset($name['type'])) C('SESSION_TYPE',$name['type']); + if(C('SESSION_TYPE')) { // 读取session驱动 + $type = C('SESSION_TYPE'); + $class = strpos($type,'\\')? $type : 'Think\\Session\\Driver\\'. ucwords(strtolower($type)); + $hander = new $class(); + session_set_save_handler( + array(&$hander,"open"), + array(&$hander,"close"), + array(&$hander,"read"), + array(&$hander,"write"), + array(&$hander,"destroy"), + array(&$hander,"gc")); + } + // 启动session + if(C('SESSION_AUTO_START')) session_start(); + }elseif('' === $value){ + if(''===$name){ + // 获取全部的session + return $prefix ? $_SESSION[$prefix] : $_SESSION; + }elseif(0===strpos($name,'[')) { // session 操作 + if('[pause]'==$name){ // 暂停session + session_write_close(); + }elseif('[start]'==$name){ // 启动session + session_start(); + }elseif('[destroy]'==$name){ // 销毁session + $_SESSION = array(); + session_unset(); + session_destroy(); + }elseif('[regenerate]'==$name){ // 重新生成id + session_regenerate_id(); + } + }elseif(0===strpos($name,'?')){ // 检查session + $name = substr($name,1); + if(strpos($name,'.')){ // 支持数组 + list($name1,$name2) = explode('.',$name); + return $prefix?isset($_SESSION[$prefix][$name1][$name2]):isset($_SESSION[$name1][$name2]); + }else{ + return $prefix?isset($_SESSION[$prefix][$name]):isset($_SESSION[$name]); + } + }elseif(is_null($name)){ // 清空session + if($prefix) { + unset($_SESSION[$prefix]); + }else{ + $_SESSION = array(); + } + }elseif($prefix){ // 获取session + if(strpos($name,'.')){ + list($name1,$name2) = explode('.',$name); + return isset($_SESSION[$prefix][$name1][$name2])?$_SESSION[$prefix][$name1][$name2]:null; + }else{ + return isset($_SESSION[$prefix][$name])?$_SESSION[$prefix][$name]:null; + } + }else{ + if(strpos($name,'.')){ + list($name1,$name2) = explode('.',$name); + return isset($_SESSION[$name1][$name2])?$_SESSION[$name1][$name2]:null; + }else{ + return isset($_SESSION[$name])?$_SESSION[$name]:null; + } + } + }elseif(is_null($value)){ // 删除session + if(strpos($name,'.')){ + list($name1,$name2) = explode('.',$name); + if($prefix){ + unset($_SESSION[$prefix][$name1][$name2]); + }else{ + unset($_SESSION[$name1][$name2]); + } + }else{ + if($prefix){ + unset($_SESSION[$prefix][$name]); + }else{ + unset($_SESSION[$name]); + } + } + }else{ // 设置session + if(strpos($name,'.')){ + list($name1,$name2) = explode('.',$name); + if($prefix){ + $_SESSION[$prefix][$name1][$name2] = $value; + }else{ + $_SESSION[$name1][$name2] = $value; + } + }else{ + if($prefix){ + $_SESSION[$prefix][$name] = $value; + }else{ + $_SESSION[$name] = $value; + } + } + } + return null; +} + +/** + * Cookie 设置、获取、删除 + * @param string $name cookie名称 + * @param mixed $value cookie值 + * @param mixed $option cookie参数 + * @return mixed + */ +function cookie($name='', $value='', $option=null) { + // 默认设置 + $config = array( + 'prefix' => C('COOKIE_PREFIX'), // cookie 名称前缀 + 'expire' => C('COOKIE_EXPIRE'), // cookie 保存时间 + 'path' => C('COOKIE_PATH'), // cookie 保存路径 + 'domain' => C('COOKIE_DOMAIN'), // cookie 有效域名 + 'secure' => C('COOKIE_SECURE'), // cookie 启用安全传输 + 'httponly' => C('COOKIE_HTTPONLY'), // httponly设置 + ); + // 参数设置(会覆盖黙认设置) + if (!is_null($option)) { + if (is_numeric($option)) + $option = array('expire' => $option); + elseif (is_string($option)) + parse_str($option, $option); + $config = array_merge($config, array_change_key_case($option)); + } + if(!empty($config['httponly'])){ + ini_set("session.cookie_httponly", 1); + } + // 清除指定前缀的所有cookie + if (is_null($name)) { + if (empty($_COOKIE)) + return null; + // 要删除的cookie前缀,不指定则删除config设置的指定前缀 + $prefix = empty($value) ? $config['prefix'] : $value; + if (!empty($prefix)) {// 如果前缀为空字符串将不作处理直接返回 + foreach ($_COOKIE as $key => $val) { + if (0 === stripos($key, $prefix)) { + setcookie($key, '', time() - 3600, $config['path'], $config['domain'],$config['secure'],$config['httponly']); + unset($_COOKIE[$key]); + } + } + } + return null; + }elseif('' === $name){ + // 获取全部的cookie + return $_COOKIE; + } + $name = $config['prefix'] . str_replace('.', '_', $name); + if ('' === $value) { + if(isset($_COOKIE[$name])){ + $value = $_COOKIE[$name]; + if(0===strpos($value,'think:')){ + $value = substr($value,6); + return array_map('urldecode',json_decode(MAGIC_QUOTES_GPC?stripslashes($value):$value,true)); + }else{ + return $value; + } + }else{ + return null; + } + } else { + if (is_null($value)) { + setcookie($name, '', time() - 3600, $config['path'], $config['domain'],$config['secure'],$config['httponly']); + unset($_COOKIE[$name]); // 删除指定cookie + } else { + // 设置cookie + if(is_array($value)){ + $value = 'think:'.json_encode(array_map('urlencode',$value)); + } + $expire = !empty($config['expire']) ? time() + intval($config['expire']) : 0; + setcookie($name, $value, $expire, $config['path'], $config['domain'],$config['secure'],$config['httponly']); + $_COOKIE[$name] = $value; + } + } + return null; +} + +/** + * 发送HTTP状态 + * @param integer $code 状态码 + * @return void + */ +function send_http_status($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]); + } +} + +function think_filter(&$value){ + // TODO 其他安全过滤 + + // 过滤查询特殊字符 + if(preg_match('/^(EXP|NEQ|GT|EGT|LT|ELT|OR|XOR|LIKE|NOTLIKE|NOT BETWEEN|NOTBETWEEN|BETWEEN|NOTIN|NOT IN|IN)$/i',$value)){ + $value .= ' '; + } +} + +// 不区分大小写的in_array实现 +function in_array_case($value,$array){ + return in_array(strtolower($value),array_map('strtolower',$array)); +} diff --git a/ThinkPHP/Mode/lite.php b/ThinkPHP/Mode/lite.php new file mode 100644 index 000000000..2aca0f381 --- /dev/null +++ b/ThinkPHP/Mode/lite.php @@ -0,0 +1,47 @@ + +// +---------------------------------------------------------------------- + +/** + * ThinkPHP Lite模式定义 + */ +return array( + // 配置文件 + 'config' => array( + THINK_PATH.'Conf/convention.php', // 系统惯例配置 + CONF_PATH.'config'.CONF_EXT, // 应用公共配置 + ), + + // 别名定义 + 'alias' => array( + 'Think\Exception' => CORE_PATH . 'Exception'.EXT, + 'Think\Model' => CORE_PATH . 'Model'.EXT, + 'Think\Db' => CORE_PATH . 'Db'.EXT, + 'Think\Cache' => CORE_PATH . 'Cache'.EXT, + 'Think\Cache\Driver\File' => CORE_PATH . 'Cache/Driver/File'.EXT, + 'Think\Storage' => CORE_PATH . 'Storage'.EXT, + ), + + // 函数和类文件 + 'core' => array( + MODE_PATH.'Lite/functions.php', + COMMON_PATH.'Common/function.php', + CORE_PATH . 'Hook'.EXT, + CORE_PATH . 'App'.EXT, + CORE_PATH . 'Dispatcher'.EXT, + //CORE_PATH . 'Log'.EXT, + CORE_PATH . 'Route'.EXT, + CORE_PATH . 'Controller'.EXT, + CORE_PATH . 'View'.EXT, + ), + // 行为扩展定义 + 'tags' => array( + ), +); From ce09054bfa8478fa82996037742fa2629d6f14d8 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Mon, 29 Dec 2014 19:49:48 +0800 Subject: [PATCH 028/166] =?UTF-8?q?=E4=BF=AE=E6=AD=A3select(false)?= =?UTF-8?q?=E7=9A=84=E7=94=A8=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Model.class.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/ThinkPHP/Library/Think/Model.class.php b/ThinkPHP/Library/Think/Model.class.php index eea69e355..edd9bbdcb 100644 --- a/ThinkPHP/Library/Think/Model.class.php +++ b/ThinkPHP/Library/Think/Model.class.php @@ -563,10 +563,7 @@ public function select($options=array()) { return false; } } elseif(false === $options){ // 用于子查询 不查询只返回SQL - $options = array(); - // 分析表达式 - $options = $this->_parseOptions($options); - return '( '.$this->fetchSql(true)->select($options).' )'; + return $this->buildSql(); } // 分析表达式 $options = $this->_parseOptions($options); From 7a02ecdb8130a0c95807c9e0c6db3578bd080e7e Mon Sep 17 00:00:00 2001 From: thinkphp Date: Thu, 1 Jan 2015 19:39:35 +0800 Subject: [PATCH 029/166] =?UTF-8?q?=E6=94=B9=E8=BF=9BS=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Common/functions.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ThinkPHP/Common/functions.php b/ThinkPHP/Common/functions.php index e1298dcde..b8b8a337e 100644 --- a/ThinkPHP/Common/functions.php +++ b/ThinkPHP/Common/functions.php @@ -1061,7 +1061,7 @@ function redirect($url, $time=0, $msg='') { */ function S($name,$value='',$options=null) { static $cache = ''; - if(is_array($options) && empty($cache)){ + if(is_array($options)){ // 缓存操作的同时初始化 $type = isset($options['type'])?$options['type']:''; $cache = Think\Cache::getInstance($type,$options); @@ -1209,7 +1209,10 @@ function session($name='',$value='') { if(isset($name['name'])) session_name($name['name']); if(isset($name['path'])) session_save_path($name['path']); if(isset($name['domain'])) ini_set('session.cookie_domain', $name['domain']); - if(isset($name['expire'])) ini_set('session.gc_maxlifetime', $name['expire']); + if(isset($name['expire'])) { + ini_set('session.gc_maxlifetime', $name['expire']); + ini_set('session.cookie_lifetime', $name['expire']); + } if(isset($name['use_trans_sid'])) ini_set('session.use_trans_sid', $name['use_trans_sid']?1:0); if(isset($name['use_cookies'])) ini_set('session.use_cookies', $name['use_cookies']?1:0); if(isset($name['cache_limiter'])) session_cache_limiter($name['cache_limiter']); From 6aca88222b2be7191fb5ee47dac61b0ed4d2312e Mon Sep 17 00:00:00 2001 From: thinkphp Date: Sun, 4 Jan 2015 09:54:14 +0800 Subject: [PATCH 030/166] =?UTF-8?q?=E6=9B=B4=E6=96=B0oracle=E9=A9=B1?= =?UTF-8?q?=E5=8A=A8=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Library/Think/Db/Driver/Oracle.class.php | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/ThinkPHP/Library/Think/Db/Driver/Oracle.class.php b/ThinkPHP/Library/Think/Db/Driver/Oracle.class.php index 956d6042f..6bf5477f4 100644 --- a/ThinkPHP/Library/Think/Db/Driver/Oracle.class.php +++ b/ThinkPHP/Library/Think/Db/Driver/Oracle.class.php @@ -38,15 +38,20 @@ protected function parseDsn($config){ * 执行语句 * @access public * @param string $str sql指令 + * @param boolean $fetchSql 不执行只是获取SQL * @return integer */ - public function execute($str,$bind=[]) { + public function execute($str,$fetchSql=false) { $this->initConnect(true); if ( !$this->_linkID ) return false; $this->queryStr = $str; - if(!empty($bind)){ - $this->queryStr .= '[ '.print_r($bind,true).' ]'; - } + 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; + } $flag = false; if(preg_match("/^\s*(INSERT\s+INTO)\s+(\w+)\s+/i", $str, $match)) { $this->table = C("DB_SEQUENCE_PREFIX").str_ireplace(C("DB_PREFIX"), "", $match[2]); @@ -55,13 +60,23 @@ public function execute($str,$bind=[]) { //释放前次的查询结果 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()); + $this->error(); + return false; + } + foreach ($this->bind as $key => $val) { + if(is_array($val)){ + $this->PDOStatement->bindValue($key, $val[0], $val[1]); + }else{ + $this->PDOStatement->bindValue($key, $val); + } } - $result = $this->PDOStatement->execute($bind); + $this->bind = array(); + $result = $this->PDOStatement->execute(); $this->debug(false); if ( false === $result) { $this->error(); From 4a05f330ffba319a899e3bd2c4baa549c70df2c4 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Mon, 5 Jan 2015 16:17:01 +0800 Subject: [PATCH 031/166] =?UTF-8?q?=E4=BF=AE=E6=AD=A3mysql=E9=A9=B1?= =?UTF-8?q?=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Db/Driver/Mysql.class.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php b/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php index 9ca43df50..7b635fd99 100644 --- a/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php +++ b/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php @@ -49,7 +49,13 @@ protected function parseDsn($config){ public function getFields($tableName) { $this->initConnect(true); list($tableName) = explode(' ', $tableName); - $sql = 'SHOW COLUMNS FROM `'.$tableName.'`'; + if(strpos($tableName,'.')){ + list($dbName,$tableName) = explode('.',$tableName); + $sql = 'SHOW COLUMNS FROM `'.$dbName.'`.`'.$tableName.'`'; + }else{ + $sql = 'SHOW COLUMNS FROM `'.$tableName.'`'; + } + $result = $this->query($sql); $info = array(); if($result) { From a58171f4ae0ad8111471fc3540858a89556195c1 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Tue, 6 Jan 2015 21:10:59 +0800 Subject: [PATCH 032/166] =?UTF-8?q?=E4=BC=98=E5=8C=96mysql=E9=A9=B1?= =?UTF-8?q?=E5=8A=A8=E4=B8=80=E5=A4=84=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Db/Driver/Mysql.class.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php b/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php index 7b635fd99..4cc5e32bd 100644 --- a/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php +++ b/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php @@ -151,10 +151,14 @@ public function insertAll($dataSet,$options=array(),$replace=false) { protected function parseDuplicate($duplicate){ // 布尔值或空则返回空字符串 if(is_bool($duplicate) || empty($duplicate)) return ''; - // field1,field2 转数组 - if(is_string($duplicate)) $duplicate = explode(',', $duplicate); - // 对象转数组 - if(is_object($duplicate)) $duplicate = get_class_vars($duplicate); + + if(is_string($duplicate)){ + // field1,field2 转数组 + $duplicate = explode(',', $duplicate); + }elseif(is_object($duplicate)){ + // 对象转数组 + $duplicate = get_class_vars($duplicate); + } $updates = array(); foreach((array) $duplicate as $key=>$val){ if(is_numeric($key)){ // array('field1', 'field2', 'field3') 解析为 ON DUPLICATE KEY UPDATE field1=VALUES(field1), field2=VALUES(field2), field3=VALUES(field3) From 8c57640ed6b5415bb07a05f0a56180d0d17f5da2 Mon Sep 17 00:00:00 2001 From: Feelop Date: Wed, 7 Jan 2015 16:33:43 +0800 Subject: [PATCH 033/166] =?UTF-8?q?=E6=9B=B4=E6=96=B0Driver=E9=A9=B1?= =?UTF-8?q?=E5=8A=A8=20parseSet=E5=87=BD=E6=95=B0=20=E6=9B=B4=E5=8A=A0?= =?UTF-8?q?=E4=BC=A0=E5=80=BCNULL=E7=9A=84=E5=88=A4=E6=96=AD=E5=92=8C?= =?UTF-8?q?=E8=A7=A3=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 更改传值 NULL的判断和解析 --- ThinkPHP/Library/Think/Db/Driver.class.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ThinkPHP/Library/Think/Db/Driver.class.php b/ThinkPHP/Library/Think/Db/Driver.class.php index b9f6daa8b..81e7773b1 100644 --- a/ThinkPHP/Library/Think/Db/Driver.class.php +++ b/ThinkPHP/Library/Think/Db/Driver.class.php @@ -361,6 +361,8 @@ protected function parseSet($data) { foreach ($data as $key=>$val){ if(is_array($val) && 'exp' == $val[0]){ $set[] = $this->parseKey($key).'='.$val[1]; + }elseif(is_null($val)){ + $set[] = $this->parseKey($key).'=NULL'; }elseif(is_scalar($val)) {// 过滤非标量数据 if(0===strpos($val,':') && in_array($val,array_keys($this->bind)) ){ $set[] = $this->parseKey($key).'='.$this->escapeString($val); From 0f40195d6adf02ef66bce06f2e3cee706a6c2a32 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Wed, 7 Jan 2015 19:29:32 +0800 Subject: [PATCH 034/166] =?UTF-8?q?=E5=8F=98=E9=87=8F=E5=90=8D=E8=B0=83?= =?UTF-8?q?=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Template.class.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/ThinkPHP/Library/Think/Template.class.php b/ThinkPHP/Library/Think/Template.class.php index b8c7a964f..c43a97a1b 100644 --- a/ThinkPHP/Library/Think/Template.class.php +++ b/ThinkPHP/Library/Think/Template.class.php @@ -66,7 +66,7 @@ public function set($name,$value) { /** * 加载模板 * @access public - * @param string $tmplTemplateFile 模板文件 + * @param string $templateFile 模板文件 * @param array $templateVar 模板变量 * @param string $prefix 模板标识前缀 * @return void @@ -80,21 +80,21 @@ public function fetch($templateFile,$templateVar,$prefix='') { /** * 加载主模板并缓存 * @access public - * @param string $tmplTemplateFile 模板文件 + * @param string $templateFile 模板文件 * @param string $prefix 模板标识前缀 * @return string * @throws ThinkExecption */ - public function loadTemplate ($tmplTemplateFile,$prefix='') { - if(is_file($tmplTemplateFile)) { - $this->templateFile = $tmplTemplateFile; + public function loadTemplate ($templateFile,$prefix='') { + if(is_file($templateFile)) { + $this->templateFile = $templateFile; // 读取模板文件内容 - $tmplContent = file_get_contents($tmplTemplateFile); + $tmplContent = file_get_contents($templateFile); }else{ - $tmplContent = $tmplTemplateFile; + $tmplContent = $templateFile; } // 根据模版文件名定位缓存文件 - $tmplCacheFile = $this->config['cache_path'].$prefix.md5($tmplTemplateFile).$this->config['cache_suffix']; + $tmplCacheFile = $this->config['cache_path'].$prefix.md5($templateFile).$this->config['cache_suffix']; // 判断是否启用布局 if(C('LAYOUT_ON')) { From 0b6b5b4eec291df3233e808679063583b39d1a2d Mon Sep 17 00:00:00 2001 From: thinkphp Date: Thu, 8 Jan 2015 14:24:34 +0800 Subject: [PATCH 035/166] =?UTF-8?q?=E6=94=B9=E8=BF=9Bmemcached=E7=BC=93?= =?UTF-8?q?=E5=AD=98=E9=A9=B1=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Think/Cache/Driver/Memcached.class.php | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/ThinkPHP/Library/Think/Cache/Driver/Memcached.class.php b/ThinkPHP/Library/Think/Cache/Driver/Memcached.class.php index b7f7bd68b..381527c12 100644 --- a/ThinkPHP/Library/Think/Cache/Driver/Memcached.class.php +++ b/ThinkPHP/Library/Think/Cache/Driver/Memcached.class.php @@ -17,23 +17,21 @@ /** * Memcached缓存驱动 */ -class Memcached extends Cache -{ +class Memcached extends Cache { /** * * @param array $options */ - public function __construct($options = array()) - { + public function __construct($options = array()) { if ( !extension_loaded('memcached') ) { E(L('_NOT_SUPPORT_').':memcached'); } $options = array_merge(array( - 'servers' => C('MEMCACHED_SERVER') ? C('MEMCACHED_SERVER') : null, - 'lib_options' => C('MEMCACHED_LIB') ? C('MEMCACHED_LIB') : null - ), $options); + 'servers' => C('MEMCACHED_SERVER') ? C('MEMCACHED_SERVER') : null, + 'lib_options' => C('MEMCACHED_LIB') ? C('MEMCACHED_LIB') : null + ), $options); $this->options = $options; $this->options['expire'] = isset($options['expire'])? $options['expire'] : C('DATA_CACHE_TIME'); @@ -51,10 +49,8 @@ public function __construct($options = array()) * @param string $name 缓存变量名 * @return mixed */ - public function get($name) - { + public function get($name) { N('cache_read',1); - $this->handler->get($this->options['prefix'].$name); return $this->handler->get($this->options['prefix'].$name); } @@ -66,8 +62,7 @@ public function get($name) * @param integer $expire 有效时间(秒) * @return boolean */ - public function set($name, $value, $expire = null) - { + public function set($name, $value, $expire = null) { N('cache_write',1); if(is_null($expire)) { $expire = $this->options['expire']; From 685111c7358cf4d358fbe99db7bcf748e427e18f Mon Sep 17 00:00:00 2001 From: thinkphp Date: Sun, 11 Jan 2015 20:03:36 +0800 Subject: [PATCH 036/166] =?UTF-8?q?=E4=BF=AE=E6=AD=A3I=E5=87=BD=E6=95=B0?= =?UTF-8?q?=E5=AF=B9=E6=AD=A3=E5=88=99=E7=9A=84=E6=94=AF=E6=8C=81=20?= =?UTF-8?q?=EF=BC=88=E8=8E=B7=E5=8F=96=E5=85=A8=E9=83=A8=E5=8F=98=E9=87=8F?= =?UTF-8?q?=E7=9A=84=E6=97=B6=E5=80=99=E6=9A=82=E4=B8=8D=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E6=AD=A3=E5=88=99=E8=A1=A8=E8=BE=BE=E5=BC=8F?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Common/functions.php | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/ThinkPHP/Common/functions.php b/ThinkPHP/Common/functions.php index b8b8a337e..0876081c7 100644 --- a/ThinkPHP/Common/functions.php +++ b/ThinkPHP/Common/functions.php @@ -327,23 +327,25 @@ function I($name,$default='',$filter=null,$datas=null) { $filters = isset($filter)?$filter:C('DEFAULT_FILTER'); if($filters) { if(is_string($filters)){ - $filters = explode(',',$filters); + if(0 === strpos($filters,'/') && 1 !== preg_match($filters,(string)$data)){ + // 支持正则验证 + return isset($default) ? $default : NULL; + }else{ + $filters = explode(',',$filters); + } }elseif(is_int($filters)){ $filters = array($filters); } - foreach($filters as $filter){ - if(function_exists($filter)) { - $data = is_array($data) ? array_map_recursive($filter,$data) : $filter($data); // 参数过滤 - }elseif(0===strpos($filter,'/')){ - // 支持正则验证 - if(1 !== preg_match($filter,(string)$data)){ - return isset($default) ? $default : NULL; - } - }else{ - $data = filter_var($data,is_int($filter) ? $filter : filter_id($filter)); - if(false === $data) { - return isset($default) ? $default : NULL; + if(is_array($filters)){ + foreach($filters as $filter){ + if(function_exists($filter)) { + $data = is_array($data) ? array_map_recursive($filter,$data) : $filter($data); // 参数过滤 + }else{ + $data = filter_var($data,is_int($filter) ? $filter : filter_id($filter)); + if(false === $data) { + return isset($default) ? $default : NULL; + } } } } From 8834f17b9286c987356f3801a9208e01c3ca1435 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Wed, 14 Jan 2015 14:14:27 +0800 Subject: [PATCH 037/166] =?UTF-8?q?=E6=94=B9=E8=BF=9BAuth=E7=B1=BB?= =?UTF-8?q?=E7=9A=84getGrous=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Auth.class.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ThinkPHP/Library/Think/Auth.class.php b/ThinkPHP/Library/Think/Auth.class.php index d2f16ed26..4c1dea1cd 100644 --- a/ThinkPHP/Library/Think/Auth.class.php +++ b/ThinkPHP/Library/Think/Auth.class.php @@ -141,8 +141,8 @@ public function check($name, $uid, $type=1, $mode='url', $relation='or') { * 根据用户id获取用户组,返回值为数组 * @param uid int 用户id * @return array 用户所属的用户组 array( - * array('uid'=>'用户id','group_id'=>'用户组id','title'=>'用户组名称','rules'=>'用户组拥有的规则id,多个,号隔开'), - * ...) + * array('uid'=>'用户id','group_id'=>'用户组id','title'=>'用户组名称','rules'=>'用户组拥有的规则id,多个,号隔开'), + * ...) */ public function getGroups($uid) { static $groups = array(); @@ -152,7 +152,7 @@ public function getGroups($uid) { ->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('rules')->select(); + ->field('uid,group_id,title,rules')->select(); $groups[$uid]=$user_groups?:array(); return $groups[$uid]; } From 7cd85879c85eefef1a1cea34bfb50f907610fed8 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Wed, 14 Jan 2015 16:15:10 +0800 Subject: [PATCH 038/166] =?UTF-8?q?=E6=94=B9=E8=BF=9BB=E5=92=8CW=E6=96=B9?= =?UTF-8?q?=E6=B3=95=E5=A2=9E=E5=8A=A0=E8=BF=94=E5=9B=9E=E5=80=BC=20?= =?UTF-8?q?=E5=85=BC=E5=AE=B93.2.2=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Common/functions.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ThinkPHP/Common/functions.php b/ThinkPHP/Common/functions.php index 0876081c7..75481cd6c 100644 --- a/ThinkPHP/Common/functions.php +++ b/ThinkPHP/Common/functions.php @@ -725,7 +725,7 @@ function B($name, $tag='',&$params=NULL) { if(''==$tag){ $name .= 'Behavior'; } - \Think\Hook::exec($name,$tag,$params); + return \Think\Hook::exec($name,$tag,$params); } /** @@ -1009,7 +1009,7 @@ function U($url='',$vars='',$suffix=true,$domain=false) { * @return void */ function W($name, $data=array()) { - R($name,$data,'Widget'); + return R($name,$data,'Widget'); } /** From a84648d43bcb5318c24bdfc0a91acb61aad60c22 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Thu, 15 Jan 2015 15:56:12 +0800 Subject: [PATCH 039/166] =?UTF-8?q?=E6=9B=B4=E6=96=B0Lite=E6=A8=A1?= =?UTF-8?q?=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Mode/Lite/Controller.class.php | 15 +-- ThinkPHP/Mode/Lite/Dispatcher.class.php | 14 +- ThinkPHP/Mode/Lite/convention.php | 163 ++++++++++++++++++++++++ ThinkPHP/Mode/Lite/functions.php | 91 ++++--------- ThinkPHP/Mode/lite.php | 2 +- 5 files changed, 201 insertions(+), 84 deletions(-) create mode 100644 ThinkPHP/Mode/Lite/convention.php diff --git a/ThinkPHP/Mode/Lite/Controller.class.php b/ThinkPHP/Mode/Lite/Controller.class.php index 406589385..9d25a7a34 100644 --- a/ThinkPHP/Mode/Lite/Controller.class.php +++ b/ThinkPHP/Mode/Lite/Controller.class.php @@ -195,21 +195,20 @@ protected function ajaxReturn($data,$type='',$json_option=0) { 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)); + $data = json_encode($data,$json_option); + break; 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).');'); + $handler = isset($_GET[C('VAR_JSONP_HANDLER')]) ? $_GET[C('VAR_JSONP_HANDLER')] : C('DEFAULT_JSONP_HANDLER'); + $data = $handler.'('.json_encode($data,$json_option).');'; + break; case 'EVAL' : // 返回可执行的js脚本 header('Content-Type:text/html; charset=utf-8'); - exit($data); + break; } + exit($data); } /** diff --git a/ThinkPHP/Mode/Lite/Dispatcher.class.php b/ThinkPHP/Mode/Lite/Dispatcher.class.php index b4da4bd0a..ff5c5dc28 100644 --- a/ThinkPHP/Mode/Lite/Dispatcher.class.php +++ b/ThinkPHP/Mode/Lite/Dispatcher.class.php @@ -65,20 +65,14 @@ static public function dispatch() { } if(!empty($rule)) { - // 子域名部署规则 '子域名'=>array('模块名[/控制器名]','var1=a&var2=b'); + // 子域名部署规则 '子域名'=>array('模块名','var1=a&var2=b'); if(is_array($rule)){ list($rule,$vars) = $rule; } $array = explode('/',$rule); // 模块绑定 define('BIND_MODULE',array_shift($array)); - // 控制器绑定 - if(!empty($array)) { - $controller = array_shift($array); - if($controller){ - define('BIND_CONTROLLER',$controller); - } - } + if(isset($vars)) { // 传入参数 parse_str($vars,$parms); if(isset($panDomain)){ @@ -120,7 +114,7 @@ static public function dispatch() { define('__EXT__', strtolower(pathinfo($_SERVER['PATH_INFO'],PATHINFO_EXTENSION))); $_SERVER['PATH_INFO'] = __INFO__; if(!defined('BIND_MODULE') && (!C('URL_ROUTER_ON') || !Route::check())){ - if (__INFO__ && C('MULTI_MODULE')){ // 获取模块名 + if (__INFO__ ){ // 获取模块名 $paths = explode($depr,__INFO__,2); $allowList = C('MODULE_ALLOW_LIST'); // 允许的模块列表 $module = preg_replace('/\.' . __EXT__ . '$/i', '',$paths[0]); @@ -179,7 +173,7 @@ static public function dispatch() { } // 模块URL地址 $moduleName = defined('MODULE_ALIAS')? MODULE_ALIAS : MODULE_NAME; - define('__MODULE__',(defined('BIND_MODULE') || !C('MULTI_MODULE'))? __APP__ : __APP__.'/'.($urlCase ? strtolower($moduleName) : $moduleName)); + define('__MODULE__',defined('BIND_MODULE') ? __APP__ : __APP__.'/'.($urlCase ? strtolower($moduleName) : $moduleName)); if('' != $_SERVER['PATH_INFO'] && (!C('URL_ROUTER_ON') || !Route::check()) ){ // 检测路由规则 如果没有则按默认规则调度URL // 检查禁止访问的URL后缀 diff --git a/ThinkPHP/Mode/Lite/convention.php b/ThinkPHP/Mode/Lite/convention.php new file mode 100644 index 000000000..982377df6 --- /dev/null +++ b/ThinkPHP/Mode/Lite/convention.php @@ -0,0 +1,163 @@ + +// +---------------------------------------------------------------------- + +/** + * ThinkPHP惯例配置文件 + * 该文件请不要修改,如果要覆盖惯例配置的值,可在应用配置文件中设定和惯例不符的配置项 + * 配置名称大小写任意,系统会统一转换成小写 + * 所有配置参数都可以在生效前动态改变 + */ +defined('THINK_PATH') or exit(); +return array( + /* 应用设定 */ + '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'), + + /* 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' => false, // 是否自动开启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', // 数据加密方式 + +); diff --git a/ThinkPHP/Mode/Lite/functions.php b/ThinkPHP/Mode/Lite/functions.php index 813edc349..7cf10acdc 100644 --- a/ThinkPHP/Mode/Lite/functions.php +++ b/ThinkPHP/Mode/Lite/functions.php @@ -125,8 +125,10 @@ function G($start,$end='',$dec=4) { if(is_float($end)) { // 记录时间 $_info[$start] = $end; }elseif(!empty($end)){ // 统计时间和内存使用 - if(!isset($_info[$end])) $_info[$end] = microtime(TRUE); - if(MEMORY_LIMIT_ON && $dec=='m'){ + if(!isset($_info[$end])) { + $_info[$end] = microtime(true); + } + if($dec=='m'){ if(!isset($_mem[$end])) $_mem[$end] = memory_get_usage(); return number_format(($_mem[$end]-$_mem[$start])/1024); }else{ @@ -134,8 +136,8 @@ function G($start,$end='',$dec=4) { } }else{ // 记录时间和内存使用 - $_info[$start] = microtime(TRUE); - if(MEMORY_LIMIT_ON) $_mem[$start] = memory_get_usage(); + $_info[$start] = microtime(true); + $_mem[$start] = memory_get_usage(); } return null; } @@ -149,8 +151,9 @@ function G($start,$end='',$dec=4) { function L($name=null, $value=null) { static $_lang = array(); // 空参数返回所有定义 - if (empty($name)) + if (empty($name)){ return $_lang; + } // 判断语言获取(或设置) // 若不存在,直接返回全大写$name if (is_string($name)) { @@ -169,8 +172,9 @@ function L($name=null, $value=null) { return null; } // 批量定义 - if (is_array($name)) + if (is_array($name)){ $_lang = array_merge($_lang, array_change_key_case($name, CASE_UPPER)); + } return null; } @@ -201,8 +205,9 @@ function compile($filename) { }else{ $content = 'namespace {'.$content; } - if ('?>' == substr($content, -2)) + if ('?>' == substr($content, -2)){ $content = substr($content, 0, -2); + } return $content.'}'; } @@ -524,8 +529,9 @@ function load($name, $baseUrl='', $ext='.php') { $name = implode('/',$array); } } - if (substr($baseUrl, -1) != '/') + if (substr($baseUrl, -1) != '/'){ $baseUrl .= '/'; + } require_cache($baseUrl . $name . $ext); } @@ -537,8 +543,9 @@ function load($name, $baseUrl='', $ext='.php') { * @return boolean */ function vendor($class, $baseUrl = '', $ext='.php') { - if (empty($baseUrl)) + if (empty($baseUrl)){ $baseUrl = VENDOR_PATH; + } return import($class, $baseUrl, $ext); } @@ -551,9 +558,10 @@ function vendor($class, $baseUrl = '', $ext='.php') { function D($name='',$layer='') { if(empty($name)) return new Think\Model; static $_model = array(); - $layer = $layer? : 'Controller'; - if(isset($_model[$name.$layer])) + $layer = $layer? : 'Model'; + if(isset($_model[$name.$layer])){ return $_model[$name.$layer]; + } $class = parse_res_name($name,$layer); if(class_exists($class)) { $model = new $class(basename($name)); @@ -583,8 +591,9 @@ function M($name='', $tablePrefix='',$connection='') { $class = 'Think\\Model'; } $guid = (is_array($connection)?implode('',$connection):$connection).$tablePrefix . $name . '_' . $class; - if (!isset($_model[$guid])) + if (!isset($_model[$guid])){ $_model[$guid] = new $class($name,$tablePrefix,$connection); + } return $_model[$guid]; } @@ -622,7 +631,6 @@ function parse_res_name($name,$layer){ /** * 用于实例化访问控制器 * @param string $name 控制器名 - * @param string $path 控制器命名空间(路径) * @return Think\Controller|false */ function controller($name){ @@ -646,11 +654,12 @@ function controller($name){ * @param string $layer 控制层名称 * @return Think\Controller|false */ -function A($name,$layer='',$level=0) { +function A($name,$layer='') { static $_action = array(); $layer = $layer? : 'Controller'; - if(isset($_action[$name.$layer])) + if(isset($_action[$name.$layer])){ return $_action[$name.$layer]; + } $class = parse_res_name($name,$layer); if(class_exists($class)) { @@ -706,7 +715,7 @@ function B($name, $tag='',&$params=NULL) { if(''==$tag){ $name .= 'Behavior'; } - \Think\Hook::exec($name,$tag,$params); + return \Think\Hook::exec($name,$tag,$params); } /** @@ -962,7 +971,7 @@ function U($url='',$vars='',$suffix=true,$domain=false) { * @return void */ function W($name, $data=array()) { - R($name,$data,'Widget'); + return R($name,$data,'Widget'); } /** @@ -1095,54 +1104,6 @@ function to_guid_string($mix) { return md5($mix); } -/** - * XML编码 - * @param mixed $data 数据 - * @param string $root 根节点名 - * @param string $item 数字索引的子节点名 - * @param string $attr 根节点属性 - * @param string $id 数字索引子节点key转换的属性名 - * @param string $encoding 数据编码 - * @return string - */ -function xml_encode($data, $root='think', $item='item', $attr='', $id='id', $encoding='utf-8') { - if(is_array($attr)){ - $_attr = array(); - foreach ($attr as $key => $value) { - $_attr[] = "{$key}=\"{$value}\""; - } - $attr = implode(' ', $_attr); - } - $attr = trim($attr); - $attr = empty($attr) ? '' : " {$attr}"; - $xml = ""; - $xml .= "<{$root}{$attr}>"; - $xml .= data_to_xml($data, $item, $id); - $xml .= ""; - return $xml; -} - -/** - * 数据XML编码 - * @param mixed $data 数据 - * @param string $item 数字索引时的节点名称 - * @param string $id 数字索引key转换为的属性名 - * @return string - */ -function data_to_xml($data, $item='item', $id='id') { - $xml = $attr = ''; - foreach ($data as $key => $val) { - if(is_numeric($key)){ - $id && $attr = " {$id}=\"{$key}\""; - $key = $item; - } - $xml .= "<{$key}{$attr}>"; - $xml .= (is_array($val) || is_object($val)) ? data_to_xml($val, $item, $id) : $val; - $xml .= ""; - } - return $xml; -} - /** * session管理函数 * @param string|array $name session名称 如果为数组则表示进行session设置 diff --git a/ThinkPHP/Mode/lite.php b/ThinkPHP/Mode/lite.php index 2aca0f381..22f1cc2e4 100644 --- a/ThinkPHP/Mode/lite.php +++ b/ThinkPHP/Mode/lite.php @@ -15,7 +15,7 @@ return array( // 配置文件 'config' => array( - THINK_PATH.'Conf/convention.php', // 系统惯例配置 + MODE_PATH.'Lite/convention.php', // 系统惯例配置 CONF_PATH.'config'.CONF_EXT, // 应用公共配置 ), From 90156097f6a9796a2f1f1c40b62d8d749ea202f3 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Thu, 15 Jan 2015 22:02:12 +0800 Subject: [PATCH 040/166] =?UTF-8?q?=E6=94=B9=E8=BF=9BI=E5=87=BD=E6=95=B0?= =?UTF-8?q?=E5=AF=B9PUT=E6=95=B0=E6=8D=AE=E7=9A=84=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Common/functions.php | 53 ++++++++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 14 deletions(-) diff --git a/ThinkPHP/Common/functions.php b/ThinkPHP/Common/functions.php index 75481cd6c..1e1efe3a5 100644 --- a/ThinkPHP/Common/functions.php +++ b/ThinkPHP/Common/functions.php @@ -269,6 +269,7 @@ function T($template='',$layer=''){ * @return mixed */ function I($name,$default='',$filter=null,$datas=null) { + static $_PUT = null; if(strpos($name,'/')){ // 指定修饰符 list($name,$type) = explode('/',$name,2); }elseif(C('VAR_AUTO_STRING')){ // 默认强制转换为字符串 @@ -280,16 +281,28 @@ function I($name,$default='',$filter=null,$datas=null) { $method = 'param'; } switch(strtolower($method)) { - case 'get' : $input =& $_GET;break; - case 'post' : $input =& $_POST;break; - case 'put' : parse_str(file_get_contents('php://input'), $input);break; + case 'get' : + $input =& $_GET; + break; + case 'post' : + $input =& $_POST; + break; + case 'put' : + if(is_null($_PUT)){ + parse_str(file_get_contents('php://input'), $_PUT); + } + $input = $_PUT; + break; case 'param' : switch($_SERVER['REQUEST_METHOD']) { case 'POST': $input = $_POST; break; case 'PUT': - parse_str(file_get_contents('php://input'), $input); + if(is_null($_PUT)){ + parse_str(file_get_contents('php://input'), $_PUT); + } + $input = $_PUT; break; default: $input = $_GET; @@ -302,14 +315,26 @@ function I($name,$default='',$filter=null,$datas=null) { $input = explode($depr,trim($_SERVER['PATH_INFO'],$depr)); } break; - case 'request' : $input =& $_REQUEST; break; - case 'session' : $input =& $_SESSION; break; - case 'cookie' : $input =& $_COOKIE; break; - case 'server' : $input =& $_SERVER; break; - case 'globals' : $input =& $GLOBALS; break; - case 'data' : $input =& $datas; break; + case 'request' : + $input =& $_REQUEST; + break; + case 'session' : + $input =& $_SESSION; + break; + case 'cookie' : + $input =& $_COOKIE; + break; + case 'server' : + $input =& $_SERVER; + break; + case 'globals' : + $input =& $GLOBALS; + break; + case 'data' : + $input =& $datas; + break; default: - return NULL; + return null; } if(''==$name) { // 获取全部变量 $data = $input; @@ -329,7 +354,7 @@ function I($name,$default='',$filter=null,$datas=null) { if(is_string($filters)){ if(0 === strpos($filters,'/') && 1 !== preg_match($filters,(string)$data)){ // 支持正则验证 - return isset($default) ? $default : NULL; + return isset($default) ? $default : null; }else{ $filters = explode(',',$filters); } @@ -344,7 +369,7 @@ function I($name,$default='',$filter=null,$datas=null) { }else{ $data = filter_var($data,is_int($filter) ? $filter : filter_id($filter)); if(false === $data) { - return isset($default) ? $default : NULL; + return isset($default) ? $default : null; } } } @@ -370,7 +395,7 @@ function I($name,$default='',$filter=null,$datas=null) { } } }else{ // 变量默认值 - $data = isset($default)?$default:NULL; + $data = isset($default)?$default:null; } is_array($data) && array_walk_recursive($data,'think_filter'); return $data; From 65cf221a19c55f55efb495801c70370823054b42 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Thu, 15 Jan 2015 22:15:23 +0800 Subject: [PATCH 041/166] =?UTF-8?q?=E5=AE=8C=E5=96=84=E8=A1=8C=E4=B8=BA?= =?UTF-8?q?=E5=92=8C=E4=BF=AE=E6=AD=A3=E4=B8=80=E4=BA=9B=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Behavior/TokenBuildBehavior.class.php | 2 +- .../Library/Behavior/WriteHtmlCacheBehavior.class.php | 10 +++++++--- ThinkPHP/Library/Think/Storage/Driver/File.class.php | 8 +++++--- .../Think/Upload/Driver/Bcs/requestcore.class.php | 3 --- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/ThinkPHP/Library/Behavior/TokenBuildBehavior.class.php b/ThinkPHP/Library/Behavior/TokenBuildBehavior.class.php index 642ecf077..6e7888a6f 100644 --- a/ThinkPHP/Library/Behavior/TokenBuildBehavior.class.php +++ b/ThinkPHP/Library/Behavior/TokenBuildBehavior.class.php @@ -44,7 +44,7 @@ private function getToken(){ if(isset($_SESSION[$tokenName][$tokenKey])) {// 相同页面不重复生成session $tokenValue = $_SESSION[$tokenName][$tokenKey]; }else{ - $tokenValue = $tokenType(microtime(TRUE)); + $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值 diff --git a/ThinkPHP/Library/Behavior/WriteHtmlCacheBehavior.class.php b/ThinkPHP/Library/Behavior/WriteHtmlCacheBehavior.class.php index f41e37fe5..6248867cc 100644 --- a/ThinkPHP/Library/Behavior/WriteHtmlCacheBehavior.class.php +++ b/ThinkPHP/Library/Behavior/WriteHtmlCacheBehavior.class.php @@ -16,10 +16,14 @@ class WriteHtmlCacheBehavior { // 行为扩展的执行入口必须是run - public function run(&$content){ - if(C('HTML_CACHE_ON') && defined('HTML_FILE_NAME')) { + 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'); + Storage::put(HTML_FILE_NAME, $content, 'html'); } } } \ No newline at end of file diff --git a/ThinkPHP/Library/Think/Storage/Driver/File.class.php b/ThinkPHP/Library/Think/Storage/Driver/File.class.php index e4d85f242..ea9d92572 100644 --- a/ThinkPHP/Library/Think/Storage/Driver/File.class.php +++ b/ThinkPHP/Library/Think/Storage/Driver/File.class.php @@ -41,8 +41,9 @@ public function read($filename,$type=''){ */ public function put($filename,$content,$type=''){ $dir = dirname($filename); - if(!is_dir($dir)) - mkdir($dir,0755,true); + if(!is_dir($dir)){ + mkdir($dir,0777,true); + } if(false === file_put_contents($filename,$content)){ E(L('_STORAGE_WRITE_ERROR_').':'.$filename); }else{ @@ -73,8 +74,9 @@ public function append($filename,$content,$type=''){ * @return void */ public function load($_filename,$vars=null){ - if(!is_null($vars)) + if(!is_null($vars)){ extract($vars, EXTR_OVERWRITE); + } include $_filename; } diff --git a/ThinkPHP/Library/Think/Upload/Driver/Bcs/requestcore.class.php b/ThinkPHP/Library/Think/Upload/Driver/Bcs/requestcore.class.php index c401bcd1f..283f23e80 100644 --- a/ThinkPHP/Library/Think/Upload/Driver/Bcs/requestcore.class.php +++ b/ThinkPHP/Library/Think/Upload/Driver/Bcs/requestcore.class.php @@ -1,8 +1,5 @@ Date: Fri, 16 Jan 2015 15:16:39 +0800 Subject: [PATCH 042/166] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E7=BC=93=E5=AD=98?= =?UTF-8?q?=E9=A9=B1=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Think/Cache/Driver/Memcache.class.php | 6 +++--- .../Think/Cache/Driver/Memcached.class.php | 4 ++-- .../Think/Cache/Driver/Memcachesae.class.php | 21 +++++++------------ .../Think/Cache/Driver/Redis.class.php | 15 +++++++------ 4 files changed, 20 insertions(+), 26 deletions(-) diff --git a/ThinkPHP/Library/Think/Cache/Driver/Memcache.class.php b/ThinkPHP/Library/Think/Cache/Driver/Memcache.class.php index 827104311..ff53ebe1e 100644 --- a/ThinkPHP/Library/Think/Cache/Driver/Memcache.class.php +++ b/ThinkPHP/Library/Think/Cache/Driver/Memcache.class.php @@ -27,9 +27,9 @@ function __construct($options=array()) { } $options = array_merge(array ( - 'host' => C('MEMCACHE_HOST') ? C('MEMCACHE_HOST') : '127.0.0.1', - 'port' => C('MEMCACHE_PORT') ? C('MEMCACHE_PORT') : 11211, - 'timeout' => C('DATA_CACHE_TIMEOUT') ? C('DATA_CACHE_TIMEOUT') : false, + 'host' => C('MEMCACHE_HOST') ? : '127.0.0.1', + 'port' => C('MEMCACHE_PORT') ? : 11211, + 'timeout' => C('DATA_CACHE_TIMEOUT') ? : false, 'persistent' => false, ),$options); diff --git a/ThinkPHP/Library/Think/Cache/Driver/Memcached.class.php b/ThinkPHP/Library/Think/Cache/Driver/Memcached.class.php index 381527c12..929bdcaea 100644 --- a/ThinkPHP/Library/Think/Cache/Driver/Memcached.class.php +++ b/ThinkPHP/Library/Think/Cache/Driver/Memcached.class.php @@ -29,8 +29,8 @@ public function __construct($options = array()) { } $options = array_merge(array( - 'servers' => C('MEMCACHED_SERVER') ? C('MEMCACHED_SERVER') : null, - 'lib_options' => C('MEMCACHED_LIB') ? C('MEMCACHED_LIB') : null + 'servers' => C('MEMCACHED_SERVER') ? : null, + 'lib_options' => C('MEMCACHED_LIB') ? : null ), $options); $this->options = $options; diff --git a/ThinkPHP/Library/Think/Cache/Driver/Memcachesae.class.php b/ThinkPHP/Library/Think/Cache/Driver/Memcachesae.class.php index 9742b6636..a1d1c5641 100644 --- a/ThinkPHP/Library/Think/Cache/Driver/Memcachesae.class.php +++ b/ThinkPHP/Library/Think/Cache/Driver/Memcachesae.class.php @@ -27,25 +27,20 @@ class Memcachesae extends Cache { * @access public */ function __construct($options=array()) { - if(empty($options)) { - $options = array ( - 'host' => C('MEMCACHE_HOST') ? C('MEMCACHE_HOST') : '127.0.0.1', - 'port' => C('MEMCACHE_PORT') ? C('MEMCACHE_PORT') : 11211, - 'timeout' => C('DATA_CACHE_TIMEOUT') ? C('DATA_CACHE_TIMEOUT') : false, - 'persistent' => false, - ); - } + $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 = isset($options['persistent']) ? 'pconnect' : 'connect'; - $this->handler = memcache_init();//[sae] 下实例化 + $this->handler = memcache_init();//[sae] 下实例化 //[sae] 下不用链接 $this->connected=true; - // $this->connected = $options['timeout'] === false ? - // $this->handler->$func($options['host'], $options['port']) : - // $this->handler->$func($options['host'], $options['port'], $options['timeout']); } /** diff --git a/ThinkPHP/Library/Think/Cache/Driver/Redis.class.php b/ThinkPHP/Library/Think/Cache/Driver/Redis.class.php index 4d2ee611a..132cefb66 100644 --- a/ThinkPHP/Library/Think/Cache/Driver/Redis.class.php +++ b/ThinkPHP/Library/Think/Cache/Driver/Redis.class.php @@ -26,14 +26,13 @@ public function __construct($options=array()) { if ( !extension_loaded('redis') ) { E(L('_NOT_SUPPORT_').':redis'); } - if(empty($options)) { - $options = array ( - 'host' => C('REDIS_HOST') ? C('REDIS_HOST') : '127.0.0.1', - 'port' => C('REDIS_PORT') ? C('REDIS_PORT') : 6379, - 'timeout' => C('DATA_CACHE_TIMEOUT') ? C('DATA_CACHE_TIMEOUT') : false, - 'persistent' => false, - ); - } + $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'); From 625d133c2008170ee365d859f06abee9901d529d Mon Sep 17 00:00:00 2001 From: thinkphp Date: Fri, 16 Jan 2015 21:54:41 +0800 Subject: [PATCH 043/166] =?UTF-8?q?=E8=A7=84=E8=8C=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Db/Driver/Firebird.class.php | 2 +- ThinkPHP/ThinkPHP.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ThinkPHP/Library/Think/Db/Driver/Firebird.class.php b/ThinkPHP/Library/Think/Db/Driver/Firebird.class.php index 3880539ad..6cc281dd3 100644 --- a/ThinkPHP/Library/Think/Db/Driver/Firebird.class.php +++ b/ThinkPHP/Library/Think/Db/Driver/Firebird.class.php @@ -101,7 +101,7 @@ public function getFields($tableName) { $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; + $info[trim($row['field_name'])]['primary']= true; } return $info; } diff --git a/ThinkPHP/ThinkPHP.php b/ThinkPHP/ThinkPHP.php index 291c7bc9d..16970a732 100644 --- a/ThinkPHP/ThinkPHP.php +++ b/ThinkPHP/ThinkPHP.php @@ -66,7 +66,7 @@ // 系统信息 if(version_compare(PHP_VERSION,'5.4.0','<')) { ini_set('magic_quotes_runtime',0); - define('MAGIC_QUOTES_GPC',get_magic_quotes_gpc()?True:False); + define('MAGIC_QUOTES_GPC',get_magic_quotes_gpc()? true : false); }else{ define('MAGIC_QUOTES_GPC',false); } From 105af01166d2b9038e16ed0e956a9c488c9d1886 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Mon, 19 Jan 2015 11:53:28 +0800 Subject: [PATCH 044/166] =?UTF-8?q?=E4=BF=AE=E6=AD=A3I=E5=87=BD=E6=95=B0?= =?UTF-8?q?=E7=9A=84=E6=AD=A3=E5=88=99=E6=A3=80=E6=B5=8B=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Common/functions.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/ThinkPHP/Common/functions.php b/ThinkPHP/Common/functions.php index 1e1efe3a5..58844c46d 100644 --- a/ThinkPHP/Common/functions.php +++ b/ThinkPHP/Common/functions.php @@ -352,9 +352,11 @@ function I($name,$default='',$filter=null,$datas=null) { $filters = isset($filter)?$filter:C('DEFAULT_FILTER'); if($filters) { if(is_string($filters)){ - if(0 === strpos($filters,'/') && 1 !== preg_match($filters,(string)$data)){ - // 支持正则验证 - return isset($default) ? $default : null; + if(0 === strpos($filters,'/')){ + if(1 !== preg_match($filters,(string)$data)){ + // 支持正则验证 + return isset($default) ? $default : null; + } }else{ $filters = explode(',',$filters); } From 38a81c9f1a8cc0b6d9c90755d42f1bc1fe1f0766 Mon Sep 17 00:00:00 2001 From: chen xinyong Date: Tue, 20 Jan 2015 09:42:25 +0800 Subject: [PATCH 045/166] =?UTF-8?q?=E5=AE=9A=E4=B9=89$=5Flogic=EF=BC=8C?= =?UTF-8?q?=E4=BF=AE=E5=A4=8Dmongo=E9=A9=B1=E5=8A=A8=5Fcomplex=E6=97=A0?= =?UTF-8?q?=E6=95=88bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Db/Driver/Mongo.class.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ThinkPHP/Library/Think/Db/Driver/Mongo.class.php b/ThinkPHP/Library/Think/Db/Driver/Mongo.class.php index f8234f733..a070b8ce7 100644 --- a/ThinkPHP/Library/Think/Db/Driver/Mongo.class.php +++ b/ThinkPHP/Library/Think/Db/Driver/Mongo.class.php @@ -736,6 +736,8 @@ public function parseWhere($where){ */ protected function parseThinkWhere($key,$val) { $query = array(); + $_logic = array('or','xor','nor', 'and'); + switch($key) { case '_query': // 字符串模式查询条件 parse_str($val,$query); From 1e9fa9caff2fbac9e368414350f74539830e1a7f Mon Sep 17 00:00:00 2001 From: thinkphp Date: Sat, 24 Jan 2015 20:32:11 +0800 Subject: [PATCH 046/166] =?UTF-8?q?=E4=BF=AE=E6=AD=A3getField=E6=96=B9?= =?UTF-8?q?=E6=B3=95=E6=94=AF=E6=8C=81fetchSql?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Model.class.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ThinkPHP/Library/Think/Model.class.php b/ThinkPHP/Library/Think/Model.class.php index edd9bbdcb..f85990d90 100644 --- a/ThinkPHP/Library/Think/Model.class.php +++ b/ThinkPHP/Library/Think/Model.class.php @@ -933,6 +933,9 @@ public function getField($field,$sepa=null) { } $resultSet = $this->db->select($options); if(!empty($resultSet)) { + if(is_string($resultSet)){ + return $resultSet; + } $_field = explode(',', $field); $field = array_keys($resultSet[0]); $key1 = array_shift($field); @@ -959,6 +962,9 @@ public function getField($field,$sepa=null) { } $result = $this->db->select($options); if(!empty($result)) { + if(is_string($result)){ + return $result; + } if(true !== $sepa && 1==$options['limit']) { $data = reset($result[0]); if(isset($cache)){ From 09bc7be1e0f50a287a663112ad1274227c5feabe Mon Sep 17 00:00:00 2001 From: thinkphp Date: Mon, 26 Jan 2015 16:27:17 +0800 Subject: [PATCH 047/166] =?UTF-8?q?=E4=BF=AE=E6=AD=A3ArrayList=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Org/Util/ArrayList.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ThinkPHP/Library/Org/Util/ArrayList.class.php b/ThinkPHP/Library/Org/Util/ArrayList.class.php index ef9443b88..4aae88984 100644 --- a/ThinkPHP/Library/Org/Util/ArrayList.class.php +++ b/ThinkPHP/Library/Org/Util/ArrayList.class.php @@ -16,7 +16,7 @@ * @subpackage Util * @author liu21st */ -class ArrayList implements IteratorAggregate { +class ArrayList implements \IteratorAggregate { /** * 集合元素 From 1fabaebd9b03afe1df8351c2d7921f41044ec969 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Wed, 28 Jan 2015 11:25:56 +0800 Subject: [PATCH 048/166] =?UTF-8?q?sqlsrv=E9=A9=B1=E5=8A=A8=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0union=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Db/Driver/Sqlsrv.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ThinkPHP/Library/Think/Db/Driver/Sqlsrv.class.php b/ThinkPHP/Library/Think/Db/Driver/Sqlsrv.class.php index c970bb32d..9df1c9256 100644 --- a/ThinkPHP/Library/Think/Db/Driver/Sqlsrv.class.php +++ b/ThinkPHP/Library/Think/Db/Driver/Sqlsrv.class.php @@ -17,7 +17,7 @@ * Sqlsrv数据库驱动 */ class Sqlsrv extends Driver{ - protected $selectSql = 'SELECT T1.* FROM (SELECT thinkphp.*, ROW_NUMBER() OVER (%ORDER%) AS ROW_NUMBER FROM (SELECT %DISTINCT% %FIELD% FROM %TABLE%%JOIN%%WHERE%%GROUP%%HAVING%) AS thinkphp) AS T1 %LIMIT%%COMMENT%'; + protected $selectSql = 'SELECT T1.* FROM (SELECT thinkphp.*, ROW_NUMBER() OVER (%ORDER%) AS ROW_NUMBER FROM (SELECT %DISTINCT% %FIELD% FROM %TABLE%%JOIN%%WHERE%%GROUP%%HAVING% %UNION%) AS thinkphp) AS T1 %LIMIT%%COMMENT%'; // PDO连接参数 protected $options = array( PDO::ATTR_CASE => PDO::CASE_LOWER, From 1ed483f11bc3f094a35ed258c137cd87c9b9290f Mon Sep 17 00:00:00 2001 From: thinkphp Date: Wed, 28 Jan 2015 14:41:16 +0800 Subject: [PATCH 049/166] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E5=BD=93=E6=A8=A1?= =?UTF-8?q?=E5=9E=8B=E7=9A=84select=E6=96=B9=E6=B3=95=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E7=BB=93=E6=9E=9C=E4=B8=BA=E7=A9=BA=E7=9A=84=E6=97=B6=E5=80=99?= =?UTF-8?q?=20=E6=B2=A1=E6=9C=89=E7=BC=93=E5=AD=98=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Model.class.php | 35 +++++++++++++------------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/ThinkPHP/Library/Think/Model.class.php b/ThinkPHP/Library/Think/Model.class.php index f85990d90..f598624d3 100644 --- a/ThinkPHP/Library/Think/Model.class.php +++ b/ThinkPHP/Library/Think/Model.class.php @@ -580,28 +580,27 @@ public function select($options=array()) { if(false === $resultSet) { return false; } - if(empty($resultSet)) { // 查询结果为空 - return null; - } - - if(is_string($resultSet)){ - return $resultSet; - } + if(!empty($resultSet)) { // 有查询结果 + if(is_string($resultSet)){ + return $resultSet; + } - $resultSet = array_map(array($this,'_read_data'),$resultSet); - $this->_after_select($resultSet,$options); - if(isset($options['index'])){ // 对数据集进行索引 - $index = explode(',',$options['index']); - foreach ($resultSet as $result){ - $_key = $result[$index[0]]; - if(isset($index[1]) && isset($result[$index[1]])){ - $cols[$_key] = $result[$index[1]]; - }else{ - $cols[$_key] = $result; + $resultSet = array_map(array($this,'_read_data'),$resultSet); + $this->_after_select($resultSet,$options); + if(isset($options['index'])){ // 对数据集进行索引 + $index = explode(',',$options['index']); + foreach ($resultSet as $result){ + $_key = $result[$index[0]]; + if(isset($index[1]) && isset($result[$index[1]])){ + $cols[$_key] = $result[$index[1]]; + }else{ + $cols[$_key] = $result; + } } + $resultSet = $cols; } - $resultSet = $cols; } + if(isset($cache)){ S($key,$resultSet,$cache); } From 5dad6fd6c22220830c08692461128e2e2f03deb0 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Wed, 28 Jan 2015 15:19:37 +0800 Subject: [PATCH 050/166] =?UTF-8?q?=E6=94=B9=E8=BF=9B=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=BA=93=E7=9A=84insert=E5=92=8Cinsertall=E6=96=B9=E6=B3=95=20?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=8F=92=E5=85=A5NULL?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Db/Driver.class.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ThinkPHP/Library/Think/Db/Driver.class.php b/ThinkPHP/Library/Think/Db/Driver.class.php index 81e7773b1..25ccd18f6 100644 --- a/ThinkPHP/Library/Think/Db/Driver.class.php +++ b/ThinkPHP/Library/Think/Db/Driver.class.php @@ -142,7 +142,7 @@ public function query($str,$fetchSql=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)); + $this->queryStr = strtr($this->queryStr,array_map(function($val) use($that){ return is_null($val)? 'NULL' : '\''.$that->escapeString($val).'\''; },$this->bind)); } if($fetchSql){ return $this->queryStr; @@ -190,7 +190,7 @@ public function execute($str,$fetchSql=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)); + $this->queryStr = strtr($this->queryStr,array_map(function($val) use($that){ return is_null($val)? 'NULL' : '\''.$that->escapeString($val).'\''; },$this->bind)); } if($fetchSql){ return $this->queryStr; @@ -792,7 +792,7 @@ public function insert($data,$options=array(),$replace=false) { if(is_array($val) && 'exp' == $val[0]){ $fields[] = $this->parseKey($key); $values[] = $val[1]; - }elseif(is_scalar($val)) { // 过滤非标量数据 + }elseif(is_null($val) || is_scalar($val)) { // 过滤非标量数据 $fields[] = $this->parseKey($key); if(0===strpos($val,':') && in_array($val,array_keys($this->bind))){ $values[] = $this->parseValue($val); @@ -830,7 +830,7 @@ public function insertAll($dataSet,$options=array(),$replace=false) { foreach ($data as $key=>$val){ if(is_array($val) && 'exp' == $val[0]){ $value[] = $val[1]; - }elseif(is_scalar($val)){ + }elseif(is_null($val) || is_scalar($val)){ if(0===strpos($val,':') && in_array($val,array_keys($this->bind))){ $value[] = $this->parseValue($val); }else{ From 386b4177bb81f595cd8d3beef657851eb9f78134 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Wed, 28 Jan 2015 16:53:55 +0800 Subject: [PATCH 051/166] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=86=99=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Db/Driver.class.php | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/ThinkPHP/Library/Think/Db/Driver.class.php b/ThinkPHP/Library/Think/Db/Driver.class.php index 25ccd18f6..716feec69 100644 --- a/ThinkPHP/Library/Think/Db/Driver.class.php +++ b/ThinkPHP/Library/Think/Db/Driver.class.php @@ -142,7 +142,7 @@ public function query($str,$fetchSql=false) { $this->queryStr = $str; if(!empty($this->bind)){ $that = $this; - $this->queryStr = strtr($this->queryStr,array_map(function($val) use($that){ return is_null($val)? 'NULL' : '\''.$that->escapeString($val).'\''; },$this->bind)); + $this->queryStr = strtr($this->queryStr,array_map(function($val) use($that){ return '\''.$that->escapeString($val).'\''; },$this->bind)); } if($fetchSql){ return $this->queryStr; @@ -190,7 +190,7 @@ public function execute($str,$fetchSql=false) { $this->queryStr = $str; if(!empty($this->bind)){ $that = $this; - $this->queryStr = strtr($this->queryStr,array_map(function($val) use($that){ return is_null($val)? 'NULL' : '\''.$that->escapeString($val).'\''; },$this->bind)); + $this->queryStr = strtr($this->queryStr,array_map(function($val) use($that){ return '\''.$that->escapeString($val).'\''; },$this->bind)); } if($fetchSql){ return $this->queryStr; @@ -792,7 +792,10 @@ public function insert($data,$options=array(),$replace=false) { if(is_array($val) && 'exp' == $val[0]){ $fields[] = $this->parseKey($key); $values[] = $val[1]; - }elseif(is_null($val) || is_scalar($val)) { // 过滤非标量数据 + }elseif(is_null($val)){ + $fields[] = $this->parseKey($key); + $values[] = 'NULL'; + }elseif(is_scalar($val)) { // 过滤非标量数据 $fields[] = $this->parseKey($key); if(0===strpos($val,':') && in_array($val,array_keys($this->bind))){ $values[] = $this->parseValue($val); @@ -829,8 +832,10 @@ public function insertAll($dataSet,$options=array(),$replace=false) { $value = array(); foreach ($data as $key=>$val){ if(is_array($val) && 'exp' == $val[0]){ - $value[] = $val[1]; - }elseif(is_null($val) || is_scalar($val)){ + $value[] = $val[1]; + }elseif(is_null($val)){ + $value[] = 'NULL'; + }elseif(is_scalar($val)){ if(0===strpos($val,':') && in_array($val,array_keys($this->bind))){ $value[] = $this->parseValue($val); }else{ From aef9e5104d84262b0ce7df0976efb19740d0d318 Mon Sep 17 00:00:00 2001 From: SifuLi Date: Thu, 5 Feb 2015 11:30:00 +0800 Subject: [PATCH 052/166] Update Model.class.php MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 防止出现:NOTIC: [8] Undefined index: d55a9248a3e614e6c220e1d8bcc2e7f4 这样的警告 --- ThinkPHP/Library/Think/Model.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ThinkPHP/Library/Think/Model.class.php b/ThinkPHP/Library/Think/Model.class.php index f598624d3..b447a8bb3 100644 --- a/ThinkPHP/Library/Think/Model.class.php +++ b/ThinkPHP/Library/Think/Model.class.php @@ -1080,7 +1080,7 @@ public function autoCheckToken($data) { // 令牌验证 list($key,$value) = explode('_',$data[$name]); - if($value && $_SESSION[$name][$key] === $value) { // 防止重复提交 + if(isset($_SESSION[$name][$key]) && $value && $_SESSION[$name][$key] === $value) { // 防止重复提交 unset($_SESSION[$name][$key]); // 验证完成销毁session return true; } From 51965bea26f240a08cd3fc0a56c7bb60b33bcd07 Mon Sep 17 00:00:00 2001 From: Wang Shuai Date: Fri, 6 Feb 2015 23:18:14 +0800 Subject: [PATCH 053/166] Update Mysql.class.php MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 当php大于5.3.6,但编译的pdo_mysql是低版本时会出问题; 很多扩展都是这样,虽然文档中说是按PHP版本判断,实际应该按扩展版本来判断 --- ThinkPHP/Library/Think/Db/Driver/Mysql.class.php | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php b/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php index 4cc5e32bd..7e343b91d 100644 --- a/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php +++ b/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php @@ -32,12 +32,9 @@ protected function parseDsn($config){ } if(!empty($config['charset'])){ - if(version_compare(PHP_VERSION,'5.3.6','<')){ - // PHP5.3.6以下不支持charset设置 - $this->options[\PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES '.$config['charset']; - }else{ - $dsn .= ';charset='.$config['charset']; - } + //为兼容各版本PHP,用两种方式设置编码 + $this->options[\PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES '.$config['charset']; + $dsn .= ';charset='.$config['charset']; } return $dsn; } From e5c67dd8d5c5fbea31bbd47adcb1ceb56eaac57b Mon Sep 17 00:00:00 2001 From: thinkphp Date: Sat, 7 Feb 2015 16:45:42 +0800 Subject: [PATCH 054/166] =?UTF-8?q?fetchSql=E6=96=B9=E6=B3=95=E7=9A=84?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E9=BB=98=E8=AE=A4=E5=80=BC=E4=B8=BAtrue=20?= =?UTF-8?q?=E4=BE=BF=E4=BA=8E=E8=B0=83=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Model.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ThinkPHP/Library/Think/Model.class.php b/ThinkPHP/Library/Think/Model.class.php index f598624d3..60642dd95 100644 --- a/ThinkPHP/Library/Think/Model.class.php +++ b/ThinkPHP/Library/Think/Model.class.php @@ -1846,7 +1846,7 @@ public function comment($comment){ * @param boolean $fetch 是否返回sql * @return Model */ - public function fetchSql($fetch){ + public function fetchSql($fetch=true){ $this->options['fetch_sql'] = $fetch; return $this; } From dfc578e15f1fd3104838d19ce91be02d300a5690 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Mon, 9 Feb 2015 19:36:21 +0800 Subject: [PATCH 055/166] =?UTF-8?q?=E6=94=B9=E8=BF=9Bmodel=E7=B1=BB?= =?UTF-8?q?=E7=9A=84select=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Model.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ThinkPHP/Library/Think/Model.class.php b/ThinkPHP/Library/Think/Model.class.php index 6e84e8dce..3ad21b167 100644 --- a/ThinkPHP/Library/Think/Model.class.php +++ b/ThinkPHP/Library/Think/Model.class.php @@ -563,7 +563,7 @@ public function select($options=array()) { return false; } } elseif(false === $options){ // 用于子查询 不查询只返回SQL - return $this->buildSql(); + $options['fetch_sql'] = true; } // 分析表达式 $options = $this->_parseOptions($options); From 2c376ff2c86fa8c69036022ad8adf63bdea750f8 Mon Sep 17 00:00:00 2001 From: Bakkan Hwang <852122068@qq.com> Date: Fri, 13 Feb 2015 12:17:48 +0800 Subject: [PATCH 056/166] =?UTF-8?q?=E4=BF=9D=E8=AF=81$=5FREQUEST=E6=AD=A3?= =?UTF-8?q?=E5=B8=B8=E5=8F=96=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit $_REQUEST = array_merge($_POST,$_GET,$_COOKIE); 少了 $_COOKIE ,正常个毛线 --- ThinkPHP/Library/Think/Dispatcher.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ThinkPHP/Library/Think/Dispatcher.class.php b/ThinkPHP/Library/Think/Dispatcher.class.php index 72ac8faac..3e9e07e65 100644 --- a/ThinkPHP/Library/Think/Dispatcher.class.php +++ b/ThinkPHP/Library/Think/Dispatcher.class.php @@ -245,7 +245,7 @@ static public function dispatch() { define('__ACTION__',__CONTROLLER__.$depr.(defined('ACTION_ALIAS')?ACTION_ALIAS:ACTION_NAME)); //保证$_REQUEST正常取值 - $_REQUEST = array_merge($_POST,$_GET); + $_REQUEST = array_merge($_POST,$_GET,$_COOKIE); // -- 加了$_COOKIE. 保证哦.. } /** From d52fbb0fcbef3c6a44fed001ceab70e02bda744e Mon Sep 17 00:00:00 2001 From: MouLingtao Date: Fri, 13 Feb 2015 14:27:17 +0800 Subject: [PATCH 057/166] =?UTF-8?q?=E4=BF=AE=E5=A4=8DMongoModel=E7=9A=84ge?= =?UTF-8?q?tField=E6=96=B9=E6=B3=95=E4=B8=8D=E8=83=BD=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E5=80=BC=E7=9A=84BUG?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Model/MongoModel.class.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ThinkPHP/Library/Think/Model/MongoModel.class.php b/ThinkPHP/Library/Think/Model/MongoModel.class.php index 2d0c2255e..5ff89f68a 100644 --- a/ThinkPHP/Library/Think/Model/MongoModel.class.php +++ b/ThinkPHP/Library/Think/Model/MongoModel.class.php @@ -306,10 +306,10 @@ public function getField($field,$sepa=null) { // 返回数据个数 if(true !== $sepa) {// 当sepa指定为true的时候 返回所有数据 $options['limit'] = is_numeric($sepa)?$sepa:1; - } // 查找一条记录 - $result = $this->db->find($options); + } // 查找符合的记录 + $result = $this->db->select($options); if(!empty($result)) { - if(1==$options['limit']) return reset($result[0]); + if(1==$options['limit']) return reset($result)[$field]; foreach ($result as $val){ $array[] = $val[$field]; } From 4c74395e97b0733cf6fbb0796d1835e79a000e6f Mon Sep 17 00:00:00 2001 From: thinkphp Date: Sat, 21 Feb 2015 09:33:37 +0800 Subject: [PATCH 058/166] =?UTF-8?q?=E4=BF=AE=E6=AD=A3session=E4=B8=80?= =?UTF-8?q?=E5=A4=84=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Common/functions.php | 2 +- ThinkPHP/Library/Think/Page.class.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ThinkPHP/Common/functions.php b/ThinkPHP/Common/functions.php index 58844c46d..99edfa690 100644 --- a/ThinkPHP/Common/functions.php +++ b/ThinkPHP/Common/functions.php @@ -1232,7 +1232,7 @@ function session($name='',$value='') { }elseif(isset($name['id'])) { session_id($name['id']); } - if('common' != APP_MODE){ // 其它模式可能不支持 + if('common' == APP_MODE){ // 其它模式可能不支持 ini_set('session.auto_start', 0); } if(isset($name['name'])) session_name($name['name']); diff --git a/ThinkPHP/Library/Think/Page.class.php b/ThinkPHP/Library/Think/Page.class.php index e45ddb03c..8a57cb62f 100644 --- a/ThinkPHP/Library/Think/Page.class.php +++ b/ThinkPHP/Library/Think/Page.class.php @@ -86,7 +86,7 @@ public function show() { $this->nowPage = $this->totalPages; } - /* 计算分页零时变量 */ + /* 计算分页临时变量 */ $now_cool_page = $this->rollPage/2; $now_cool_page_ceil = ceil($now_cool_page); $this->lastSuffix && $this->config['last'] = $this->totalPages; From ca873c968d9a9084f91e44f2770c454ebaada9bf Mon Sep 17 00:00:00 2001 From: thinkphp Date: Wed, 25 Feb 2015 09:28:31 +0800 Subject: [PATCH 059/166] =?UTF-8?q?=E6=94=B9=E8=BF=9B=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=BA=93=E7=B1=BB=E5=9E=8B=E9=85=8D=E7=BD=AE=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=A4=A7=E5=86=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Db.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ThinkPHP/Library/Think/Db.class.php b/ThinkPHP/Library/Think/Db.class.php index a9d6e892d..730b1fc44 100644 --- a/ThinkPHP/Library/Think/Db.class.php +++ b/ThinkPHP/Library/Think/Db.class.php @@ -34,7 +34,7 @@ static public function getInstance($config=array()) { // 兼容mysqli if('mysqli' == $options['type']) $options['type'] = 'mysql'; // 如果采用lite方式 仅支持原生SQL 包括query和execute方法 - $class = $options['lite']? 'Think\Db\Lite' : 'Think\\Db\\Driver\\'.ucwords($options['type']); + $class = $options['lite']? 'Think\Db\Lite' : 'Think\\Db\\Driver\\'.ucwords(strtolower($options['type'])); if(class_exists($class)){ self::$instance[$md5] = new $class($options); }else{ From 0c679b303961f36d0e773b51fd8c03a0f665dcde Mon Sep 17 00:00:00 2001 From: thinkphp Date: Thu, 5 Mar 2015 16:58:20 +0800 Subject: [PATCH 060/166] =?UTF-8?q?=E6=94=B9=E8=BF=9B=E4=B8=80=E5=A4=84?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E5=85=BC=E5=AE=B9=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Db/Driver/Pgsql.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ThinkPHP/Library/Think/Db/Driver/Pgsql.class.php b/ThinkPHP/Library/Think/Db/Driver/Pgsql.class.php index aefcb49e5..e1223a4ab 100644 --- a/ThinkPHP/Library/Think/Db/Driver/Pgsql.class.php +++ b/ThinkPHP/Library/Think/Db/Driver/Pgsql.class.php @@ -39,7 +39,7 @@ protected function parseDsn($config){ public function getFields($tableName) { list($tableName) = explode(' ', $tableName); $result = $this->query('select fields_name as "field",fields_type as "type",fields_not_null as "null",fields_key_name as "key",fields_default as "default",fields_default as "extra" from table_msg('.$tableName.');'); - $info = []; + $info = array(); if($result){ foreach ($result as $key => $val) { $info[$val['field']] = array( From 2483d96156dd4c4800a17332fad20388deb65248 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Sun, 8 Mar 2015 13:47:54 +0800 Subject: [PATCH 061/166] =?UTF-8?q?=E4=BF=AE=E6=AD=A3Log=E7=B1=BB=E7=9A=84?= =?UTF-8?q?write=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Log.class.php | 15 +++++++++------ ThinkPHP/Library/Think/Log/Driver/File.class.php | 8 +++++--- ThinkPHP/Library/Think/Log/Driver/Sae.class.php | 6 ++++-- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/ThinkPHP/Library/Think/Log.class.php b/ThinkPHP/Library/Think/Log.class.php index 2b888bcdf..09b1155ab 100644 --- a/ThinkPHP/Library/Think/Log.class.php +++ b/ThinkPHP/Library/Think/Log.class.php @@ -33,7 +33,7 @@ class Log { // 日志初始化 static public function init($config=array()){ - $type = isset($config['type'])?$config['type']:'File'; + $type = isset($config['type']) ? $config['type'] : 'File'; $class = strpos($type,'\\')? $type: 'Think\\Log\\Driver\\'. ucwords(strtolower($type)); unset($config['type']); self::$storage = new $class($config); @@ -65,10 +65,11 @@ static function record($message,$level=self::ERR,$record=false) { static function save($type='',$destination='') { if(empty(self::$log)) return ; - if(empty($destination)) + if(empty($destination)){ $destination = C('LOG_PATH').date('y_m_d').'.log'; + } if(!self::$storage){ - $type = $type?:C('LOG_TYPE'); + $type = $type ? : C('LOG_TYPE'); $class = 'Think\\Log\\Driver\\'. ucwords($type); self::$storage = new $class(); } @@ -90,12 +91,14 @@ static function save($type='',$destination='') { */ static function write($message,$level=self::ERR,$type='',$destination='') { if(!self::$storage){ - $type = $type?:C('LOG_TYPE'); + $type = $type ? : C('LOG_TYPE'); $class = 'Think\\Log\\Driver\\'. ucwords($type); - self::$storage = new $class(); + $config['log_path'] = C('LOG_PATH'); + self::$storage = new $class($config); } - if(empty($destination)) + if(empty($destination)){ $destination = C('LOG_PATH').date('y_m_d').'.log'; + } self::$storage->write("{$level}: {$message}", $destination); } } \ No newline at end of file diff --git a/ThinkPHP/Library/Think/Log/Driver/File.class.php b/ThinkPHP/Library/Think/Log/Driver/File.class.php index bbcc42910..290746e65 100644 --- a/ThinkPHP/Library/Think/Log/Driver/File.class.php +++ b/ThinkPHP/Library/Think/Log/Driver/File.class.php @@ -33,16 +33,18 @@ public function __construct($config=array()){ */ public function write($log,$destination='') { $now = date($this->config['log_time_format']); - if(empty($destination)) + if(empty($destination)){ $destination = $this->config['log_path'].date('y_m_d').'.log'; + } // 自动创建日志目录 $log_dir = dirname($destination); if (!is_dir($log_dir)) { mkdir($log_dir, 0755, true); } //检测日志文件大小,超过配置大小则备份日志文件重新生成 - if(is_file($destination) && floor($this->config['log_file_size']) <= filesize($destination) ) - rename($destination,dirname($destination).'/'.time().'-'.basename($destination)); + if(is_file($destination) && floor($this->config['log_file_size']) <= filesize($destination) ){ + rename($destination,dirname($destination).'/'.time().'-'.basename($destination)); + } error_log("[{$now}] ".$_SERVER['REMOTE_ADDR'].' '.$_SERVER['REQUEST_URI']."\r\n{$log}\r\n", 3,$destination); } } diff --git a/ThinkPHP/Library/Think/Log/Driver/Sae.class.php b/ThinkPHP/Library/Think/Log/Driver/Sae.class.php index 64c0ca9c8..accbcae5c 100644 --- a/ThinkPHP/Library/Think/Log/Driver/Sae.class.php +++ b/ThinkPHP/Library/Think/Log/Driver/Sae.class.php @@ -37,11 +37,13 @@ public function write($log,$destination='') { preg_replace('@(\w+)\=([^;]*)@e', '$appSettings[\'\\1\']="\\2";', $_SERVER['HTTP_APPCOOKIE']); $is_debug = in_array($_SERVER['HTTP_APPVERSION'], explode(',', $appSettings['debug'])) ? true : false; } - if($is_debug) + if($is_debug){ sae_set_display_errors(false);//记录日志不将日志打印出来 + } sae_debug($logstr); - if($is_debug) + if($is_debug){ sae_set_display_errors(true); + } } } From fe9721c71ecbac837acd7f5e326440c3c5b2dfd4 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Sun, 8 Mar 2015 21:53:22 +0800 Subject: [PATCH 062/166] =?UTF-8?q?=E6=94=B9=E8=BF=9BSession=E9=A9=B1?= =?UTF-8?q?=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Library/Think/Session/Driver/Db.class.php | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/ThinkPHP/Library/Think/Session/Driver/Db.class.php b/ThinkPHP/Library/Think/Session/Driver/Db.class.php index 1ea99beee..76ab3be26 100644 --- a/ThinkPHP/Library/Think/Session/Driver/Db.class.php +++ b/ThinkPHP/Library/Think/Session/Driver/Db.class.php @@ -42,7 +42,7 @@ class Db { * @param mixed $sessName */ public function open($savePath, $sessName) { - $this->lifeTime = C('SESSION_EXPIRE')?C('SESSION_EXPIRE'):ini_get('session.gc_maxlifetime'); + $this->lifeTime = C('SESSION_EXPIRE')?C('SESSION_EXPIRE'):ini_get('session.gc_maxlifetime'); $this->sessionTable = C('SESSION_TABLE')?C('SESSION_TABLE'):C("DB_PREFIX")."session"; //分布式数据库 $host = explode(',',C('DB_HOST')); @@ -121,10 +121,10 @@ public function close() { * @param string $sessID */ public function read($sessID) { - $hander = is_array($this->hander)?$this->hander[1]:$this->hander; - $res = mysql_query("SELECT session_data AS data FROM ".$this->sessionTable." WHERE session_id = '$sessID' AND session_expire >".time(),$hander); + $hander = is_array($this->hander)?$this->hander[1]:$this->hander; + $res = mysql_query('SELECT session_data AS data FROM '.$this->sessionTable." WHERE session_id = '$sessID' AND session_expire >".time(),$hander); if($res) { - $row = mysql_fetch_assoc($res); + $row = mysql_fetch_assoc($res); return $row['data']; } return ""; @@ -137,9 +137,10 @@ public function read($sessID) { * @param String $sessData */ public function write($sessID,$sessData) { - $hander = is_array($this->hander)?$this->hander[0]:$this->hander; - $expire = time() + $this->lifeTime; - mysql_query("REPLACE INTO ".$this->sessionTable." ( session_id, session_expire, session_data) VALUES( '$sessID', '$expire', '$sessData')",$hander); + $hander = is_array($this->hander)?$this->hander[0]:$this->hander; + $expire = time() + $this->lifeTime; + $sessData = addslashes($sessData); + mysql_query('REPLACE INTO '.$this->sessionTable." ( session_id, session_expire, session_data) VALUES( '$sessID', '$expire', '$sessData')",$hander); if(mysql_affected_rows($hander)) return true; return false; @@ -151,8 +152,8 @@ public function write($sessID,$sessData) { * @param string $sessID */ public function destroy($sessID) { - $hander = is_array($this->hander)?$this->hander[0]:$this->hander; - mysql_query("DELETE FROM ".$this->sessionTable." WHERE session_id = '$sessID'",$hander); + $hander = is_array($this->hander)?$this->hander[0]:$this->hander; + mysql_query('DELETE FROM '.$this->sessionTable." WHERE session_id = '$sessID'",$hander); if(mysql_affected_rows($hander)) return true; return false; @@ -164,8 +165,8 @@ public function destroy($sessID) { * @param string $sessMaxLifeTime */ public function gc($sessMaxLifeTime) { - $hander = is_array($this->hander)?$this->hander[0]:$this->hander; - mysql_query("DELETE FROM ".$this->sessionTable." WHERE session_expire < ".time(),$hander); + $hander = is_array($this->hander)?$this->hander[0]:$this->hander; + mysql_query('DELETE FROM '.$this->sessionTable.' WHERE session_expire < '.time(),$hander); return mysql_affected_rows($hander); } From 908b23433df8c002acd5035766fd29fa426734df Mon Sep 17 00:00:00 2001 From: thinkphp Date: Mon, 9 Mar 2015 21:26:28 +0800 Subject: [PATCH 063/166] =?UTF-8?q?=E6=94=B9=E8=BF=9BBuild=E7=B1=BB?= =?UTF-8?q?=E7=94=9F=E6=88=90=E7=9A=84=E9=BB=98=E8=AE=A4=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E6=A0=B7=E5=BC=8F=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Build.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ThinkPHP/Library/Think/Build.class.php b/ThinkPHP/Library/Think/Build.class.php index 627e7abf5..65281070c 100644 --- a/ThinkPHP/Library/Think/Build.class.php +++ b/ThinkPHP/Library/Think/Build.class.php @@ -19,7 +19,7 @@ class Build { use Think\Controller; class [CONTROLLER]Controller extends Controller { public function index(){ - $this->show(\'

:)

欢迎使用 ThinkPHP


版本 V{$Think.version}
\',\'utf-8\'); + $this->show(\'

:)

欢迎使用 ThinkPHP


版本 V{$Think.version}
\',\'utf-8\'); } }'; From e3e6c9a5581b7a94e62648af8ce240848844e297 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Tue, 10 Mar 2015 10:17:49 +0800 Subject: [PATCH 064/166] =?UTF-8?q?=E4=B8=83=E7=89=9B=E4=B8=8A=E4=BC=A0?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E5=8F=82=E6=95=B0=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Upload/Driver/Qiniu.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ThinkPHP/Library/Think/Upload/Driver/Qiniu.class.php b/ThinkPHP/Library/Think/Upload/Driver/Qiniu.class.php index 8a07eb310..c745f9f0b 100644 --- a/ThinkPHP/Library/Think/Upload/Driver/Qiniu.class.php +++ b/ThinkPHP/Library/Think/Upload/Driver/Qiniu.class.php @@ -26,7 +26,7 @@ class Qiniu{ private $error = ''; private $config = array( - 'secrectKey' => '', //七牛服务器 + 'secretKey' => '', //七牛服务器 'accessKey' => '', //七牛用户 'domain' => '', //七牛密码 'bucket' => '', //空间名称 From a6f86b4830f304e6896e3a0561d686d924a242ed Mon Sep 17 00:00:00 2001 From: thinkphp Date: Tue, 10 Mar 2015 10:24:28 +0800 Subject: [PATCH 065/166] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E4=B8=83=E7=89=9B?= =?UTF-8?q?=E9=A9=B1=E5=8A=A8=E5=AD=98=E5=82=A8=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Library/Think/Upload/Driver/Qiniu/QiniuStorage.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ThinkPHP/Library/Think/Upload/Driver/Qiniu/QiniuStorage.class.php b/ThinkPHP/Library/Think/Upload/Driver/Qiniu/QiniuStorage.class.php index 95763cdc9..f7948d23d 100644 --- a/ThinkPHP/Library/Think/Upload/Driver/Qiniu/QiniuStorage.class.php +++ b/ThinkPHP/Library/Think/Upload/Driver/Qiniu/QiniuStorage.class.php @@ -9,7 +9,7 @@ class QiniuStorage { public $timeout = ''; public function __construct($config){ - $this->sk = $config['secrectKey']; + $this->sk = $config['secretKey']; $this->ak = $config['accessKey']; $this->domain = $config['domain']; $this->bucket = $config['bucket']; From 0d45b2fbc97f2c70aa8253f2478c6525144b751f Mon Sep 17 00:00:00 2001 From: thinkphp Date: Thu, 26 Mar 2015 11:00:45 +0800 Subject: [PATCH 066/166] =?UTF-8?q?=E4=BF=AE=E6=AD=A3mysql=E9=A9=B1?= =?UTF-8?q?=E5=8A=A8=E7=9A=84addall=E6=96=B9=E6=B3=95=E5=AF=B9=E6=8F=92?= =?UTF-8?q?=E5=85=A5NULL=E7=9A=84=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Db/Driver/Mysql.class.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php b/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php index 7e343b91d..33da99037 100644 --- a/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php +++ b/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php @@ -120,6 +120,8 @@ public function insertAll($dataSet,$options=array(),$replace=false) { foreach ($data as $key=>$val){ if(is_array($val) && 'exp' == $val[0]){ $value[] = $val[1]; + }elseif(is_null($val)){ + $value[] = 'NULL'; }elseif(is_scalar($val)){ if(0===strpos($val,':') && in_array($val,array_keys($this->bind))){ $value[] = $this->parseValue($val); From 041cf615f208b7440ae8255abb1189e8dcdcbe84 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Tue, 14 Apr 2015 12:45:54 +0800 Subject: [PATCH 067/166] =?UTF-8?q?=E4=BF=AE=E6=AD=A3Model=E7=B1=BB?= =?UTF-8?q?=E5=BB=B6=E8=BF=9F=E5=86=99=E5=85=A5=E6=96=B9=E6=B3=95=E7=9A=84?= =?UTF-8?q?BUG?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Model.class.php | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/ThinkPHP/Library/Think/Model.class.php b/ThinkPHP/Library/Think/Model.class.php index 3ad21b167..7d7d2d9d5 100644 --- a/ThinkPHP/Library/Think/Model.class.php +++ b/ThinkPHP/Library/Think/Model.class.php @@ -854,7 +854,11 @@ public function setInc($field,$step=1,$lazyTime=0) { $condition = $this->options['where']; $guid = md5($this->name.'_'.$field.'_'.serialize($condition)); $step = $this->lazyWrite($guid,$step,$lazyTime); - if(false === $step ) return true; // 等待下次写入 + if(empty($step)) { + return true; // 等待下次写入 + }elseif($step < 0) { + $step = '-'.$step; + } } return $this->setField($field,array('exp',$field.'+'.$step)); } @@ -871,8 +875,12 @@ public function setDec($field,$step=1,$lazyTime=0) { if($lazyTime>0) {// 延迟写入 $condition = $this->options['where']; $guid = md5($this->name.'_'.$field.'_'.serialize($condition)); - $step = $this->lazyWrite($guid,$step,$lazyTime); - if(false === $step ) return true; // 等待下次写入 + $step = $this->lazyWrite($guid,-$step,$lazyTime); + if(empty($step)) { + return true; // 等待下次写入 + }elseif($step > 0) { + $step = '-'.$step; + } } return $this->setField($field,array('exp',$field.'-'.$step)); } From ce146ec046fa602ff97c61565ff2697f22204061 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Tue, 14 Apr 2015 12:48:14 +0800 Subject: [PATCH 068/166] =?UTF-8?q?=E8=A7=84=E8=8C=83=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Model.class.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/ThinkPHP/Library/Think/Model.class.php b/ThinkPHP/Library/Think/Model.class.php index 7d7d2d9d5..c97047adb 100644 --- a/ThinkPHP/Library/Think/Model.class.php +++ b/ThinkPHP/Library/Think/Model.class.php @@ -851,13 +851,13 @@ public function setField($field,$value='') { */ public function setInc($field,$step=1,$lazyTime=0) { if($lazyTime>0) {// 延迟写入 - $condition = $this->options['where']; - $guid = md5($this->name.'_'.$field.'_'.serialize($condition)); - $step = $this->lazyWrite($guid,$step,$lazyTime); + $condition = $this->options['where']; + $guid = md5($this->name.'_'.$field.'_'.serialize($condition)); + $step = $this->lazyWrite($guid,$step,$lazyTime); if(empty($step)) { return true; // 等待下次写入 }elseif($step < 0) { - $step = '-'.$step; + $step = '-'.$step; } } return $this->setField($field,array('exp',$field.'+'.$step)); @@ -873,13 +873,13 @@ public function setInc($field,$step=1,$lazyTime=0) { */ public function setDec($field,$step=1,$lazyTime=0) { if($lazyTime>0) {// 延迟写入 - $condition = $this->options['where']; - $guid = md5($this->name.'_'.$field.'_'.serialize($condition)); - $step = $this->lazyWrite($guid,-$step,$lazyTime); + $condition = $this->options['where']; + $guid = md5($this->name.'_'.$field.'_'.serialize($condition)); + $step = $this->lazyWrite($guid,-$step,$lazyTime); if(empty($step)) { return true; // 等待下次写入 }elseif($step > 0) { - $step = '-'.$step; + $step = '-'.$step; } } return $this->setField($field,array('exp',$field.'-'.$step)); From 9a7eb6f20dadf3aa777c1af0968795162ca57c41 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Tue, 14 Apr 2015 18:45:18 +0800 Subject: [PATCH 069/166] =?UTF-8?q?Model=E7=B1=BB=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E5=85=B3=E9=97=AD=E8=87=AA=E5=8A=A8=E9=AA=8C=E8=AF=81=E5=92=8C?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E5=AE=8C=E6=88=90=20=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E6=96=B9=E5=BC=8F=E4=B8=BA=20$model->validate(false)->auto(fal?= =?UTF-8?q?se)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Model.class.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ThinkPHP/Library/Think/Model.class.php b/ThinkPHP/Library/Think/Model.class.php index c97047adb..d00996ddf 100644 --- a/ThinkPHP/Library/Think/Model.class.php +++ b/ThinkPHP/Library/Think/Model.class.php @@ -1132,6 +1132,10 @@ public function regex($value,$rule) { * @return mixed */ private function autoOperation(&$data,$type) { + if(false === $this->options['auto']){ + // 关闭自动完成 + return true; + } if(!empty($this->options['auto'])) { $_auto = $this->options['auto']; unset($this->options['auto']); @@ -1185,6 +1189,10 @@ private function autoOperation(&$data,$type) { * @return boolean */ protected function autoValidation($data,$type) { + if(false === $this->options['validate'] ){ + // 关闭自动验证 + return true; + } if(!empty($this->options['validate'])) { $_validate = $this->options['validate']; unset($this->options['validate']); From ec767d8abb167360187a0d97740602683b7dcf46 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Tue, 14 Apr 2015 18:46:35 +0800 Subject: [PATCH 070/166] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E4=B8=80=E5=A4=84?= =?UTF-8?q?=E8=BF=94=E5=9B=9E=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Model.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ThinkPHP/Library/Think/Model.class.php b/ThinkPHP/Library/Think/Model.class.php index d00996ddf..739e3edf1 100644 --- a/ThinkPHP/Library/Think/Model.class.php +++ b/ThinkPHP/Library/Think/Model.class.php @@ -1134,7 +1134,7 @@ public function regex($value,$rule) { private function autoOperation(&$data,$type) { if(false === $this->options['auto']){ // 关闭自动完成 - return true; + return $data; } if(!empty($this->options['auto'])) { $_auto = $this->options['auto']; From fad4707ebfbe4e3d14999d8c74a6f91df5f4a32a Mon Sep 17 00:00:00 2001 From: ninjacn Date: Mon, 27 Apr 2015 14:34:16 +0800 Subject: [PATCH 071/166] =?UTF-8?q?=E8=BF=87=E6=BB=A4Phpstorm=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index e69de29bb..723ef36f4 100644 --- a/.gitignore +++ b/.gitignore @@ -0,0 +1 @@ +.idea \ No newline at end of file From 98a091ed4f8b4d458df64cc5f8608bc7d1535936 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Wed, 29 Apr 2015 11:48:00 +0800 Subject: [PATCH 072/166] =?UTF-8?q?=E6=94=B9=E8=BF=9BDb=E7=B1=BB=E4=B8=80?= =?UTF-8?q?=E5=A4=84=20=E8=AD=A6=E5=91=8A=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Db.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ThinkPHP/Library/Think/Db.class.php b/ThinkPHP/Library/Think/Db.class.php index 730b1fc44..5c46e2ff7 100644 --- a/ThinkPHP/Library/Think/Db.class.php +++ b/ThinkPHP/Library/Think/Db.class.php @@ -34,7 +34,7 @@ static public function getInstance($config=array()) { // 兼容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'])); + $class = !empty($options['lite'])? 'Think\Db\Lite' : 'Think\\Db\\Driver\\'.ucwords(strtolower($options['type'])); if(class_exists($class)){ self::$instance[$md5] = new $class($options); }else{ From 952b0e42841bac86d597a8cec2af57f1fa0637c0 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Wed, 6 May 2015 18:19:47 +0800 Subject: [PATCH 073/166] =?UTF-8?q?=E6=94=B9=E8=BF=9Bcreate=E6=96=B9?= =?UTF-8?q?=E6=B3=95=E7=9A=84=E5=AD=97=E6=AE=B5=E6=98=A0=E5=B0=84=E6=A3=80?= =?UTF-8?q?=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Model.class.php | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/ThinkPHP/Library/Think/Model.class.php b/ThinkPHP/Library/Think/Model.class.php index 739e3edf1..47e41e031 100644 --- a/ThinkPHP/Library/Think/Model.class.php +++ b/ThinkPHP/Library/Think/Model.class.php @@ -1015,14 +1015,7 @@ public function create($data='',$type='') { $type = $type?:(!empty($data[$this->getPk()])?self::MODEL_UPDATE:self::MODEL_INSERT); // 检查字段映射 - if(!empty($this->_map)) { - foreach ($this->_map as $key=>$val){ - if(isset($data[$key])) { - $data[$val] = $data[$key]; - unset($data[$key]); - } - } - } + $data = $this->parseFieldsMap($data,0); // 检测提交字段的合法性 if(isset($this->options['field'])) { // $this->field('field1,field2...')->create() From f16bbbbb46ec4c869fcb2e3699a2da8b3dbb1e4d Mon Sep 17 00:00:00 2001 From: thinkphp Date: Thu, 7 May 2015 11:43:03 +0800 Subject: [PATCH 074/166] =?UTF-8?q?=E6=94=B9=E8=BF=9B=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=BA=93=E9=A9=B1=E5=8A=A8=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Db/Driver.class.php | 41 ++++++++++++++-------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/ThinkPHP/Library/Think/Db/Driver.class.php b/ThinkPHP/Library/Think/Db/Driver.class.php index 716feec69..fb46bebc1 100644 --- a/ThinkPHP/Library/Think/Db/Driver.class.php +++ b/ThinkPHP/Library/Think/Db/Driver.class.php @@ -166,14 +166,19 @@ public function query($str,$fetchSql=false) { } } $this->bind = array(); - $result = $this->PDOStatement->execute(); - // 调试结束 - $this->debug(false); - if ( false === $result ) { + try{ + $result = $this->PDOStatement->execute(); + // 调试结束 + $this->debug(false); + if ( false === $result ) { + $this->error(); + return false; + } else { + return $this->getResult(); + } + }catch (\PDOException $e) { $this->error(); return false; - } else { - return $this->getResult(); } } @@ -214,17 +219,23 @@ public function execute($str,$fetchSql=false) { } } $this->bind = array(); - $result = $this->PDOStatement->execute(); - $this->debug(false); - if ( false === $result) { + try{ + $result = $this->PDOStatement->execute(); + // 调试结束 + $this->debug(false); + if ( false === $result) { + $this->error(); + return false; + } else { + $this->numRows = $this->PDOStatement->rowCount(); + if(preg_match("/^\s*(INSERT\s+INTO|REPLACE\s+INTO)\s+/i", $str)) { + $this->lastInsID = $this->_linkID->lastInsertId(); + } + return $this->numRows; + } + }catch (\PDOException $e) { $this->error(); return false; - } else { - $this->numRows = $this->PDOStatement->rowCount(); - if(preg_match("/^\s*(INSERT\s+INTO|REPLACE\s+INTO)\s+/i", $str)) { - $this->lastInsID = $this->_linkID->lastInsertId(); - } - return $this->numRows; } } From b17d89e4f65a22a8eee774726fdbaf0140b91ffc Mon Sep 17 00:00:00 2001 From: thinkphp Date: Wed, 20 May 2015 11:58:00 +0800 Subject: [PATCH 075/166] =?UTF-8?q?=E6=94=B9=E8=BF=9B=E5=AF=B9=E6=A8=A1?= =?UTF-8?q?=E5=9D=97URL=5FCASE=5FINSENSITIVE=E5=8F=82=E6=95=B0=E7=9A=84?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E8=AF=BB=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Dispatcher.class.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ThinkPHP/Library/Think/Dispatcher.class.php b/ThinkPHP/Library/Think/Dispatcher.class.php index 3e9e07e65..0065cfb67 100644 --- a/ThinkPHP/Library/Think/Dispatcher.class.php +++ b/ThinkPHP/Library/Think/Dispatcher.class.php @@ -170,6 +170,8 @@ static public function dispatch() { // 加载模块函数文件 if(is_file(MODULE_PATH.'Common/function.php')) include MODULE_PATH.'Common/function.php'; + + $urlCase = C('URL_CASE_INSENSITIVE'); // 加载模块的扩展配置文件 load_ext_file(MODULE_PATH); }else{ From bb4d3133b157a537440aca417eb1c0e9a3ff4178 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Mon, 25 May 2015 11:29:52 +0800 Subject: [PATCH 076/166] =?UTF-8?q?=E4=BF=AE=E6=AD=A3MongoModel=E4=B8=80?= =?UTF-8?q?=E5=A4=84=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Model/MongoModel.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ThinkPHP/Library/Think/Model/MongoModel.class.php b/ThinkPHP/Library/Think/Model/MongoModel.class.php index 5ff89f68a..e633a7490 100644 --- a/ThinkPHP/Library/Think/Model/MongoModel.class.php +++ b/ThinkPHP/Library/Think/Model/MongoModel.class.php @@ -309,7 +309,7 @@ public function getField($field,$sepa=null) { } // 查找符合的记录 $result = $this->db->select($options); if(!empty($result)) { - if(1==$options['limit']) return reset($result)[$field]; + if(1==$options['limit']) return reset($result[$field]); foreach ($result as $val){ $array[] = $val[$field]; } From 5aa26cf6f4c04a2b6cb63a319f415acd63e1ca26 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Mon, 25 May 2015 11:39:24 +0800 Subject: [PATCH 077/166] =?UTF-8?q?=E4=BF=AE=E6=AD=A3MongoModel=E7=B1=BB?= =?UTF-8?q?=E7=9A=84getField=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Model/MongoModel.class.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ThinkPHP/Library/Think/Model/MongoModel.class.php b/ThinkPHP/Library/Think/Model/MongoModel.class.php index e633a7490..d1927d788 100644 --- a/ThinkPHP/Library/Think/Model/MongoModel.class.php +++ b/ThinkPHP/Library/Think/Model/MongoModel.class.php @@ -309,7 +309,10 @@ public function getField($field,$sepa=null) { } // 查找符合的记录 $result = $this->db->select($options); if(!empty($result)) { - if(1==$options['limit']) return reset($result[$field]); + if(1==$options['limit']) { + $result = reset($result); + return $result[$field]; + } foreach ($result as $val){ $array[] = $val[$field]; } From 5809bf48babf2ff2716ff238557b3a193db8455f Mon Sep 17 00:00:00 2001 From: Feelop Date: Fri, 5 Jun 2015 10:57:02 +0800 Subject: [PATCH 078/166] =?UTF-8?q?=E6=B7=BB=E5=8A=A0procedure=E6=96=B9?= =?UTF-8?q?=E6=B3=95=EF=BC=8C=E7=BB=99=E4=B8=8Emysql=E5=AD=98=E5=82=A8?= =?UTF-8?q?=E8=BF=87=E7=A8=8B=E8=BF=94=E5=9B=9E=E5=A4=9A=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E9=9B=86=E7=9A=84=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加procedure方法,给与mysql存储过程返回多数据集的支持 因 \PDO::ATTR_ERRMODE = \PDO::ERRMODE_EXCEPTION的时候会抛出异常错误,所以将\PDO::ATTR_ERRMODE 改为\PDO::ERRMODE_WARNING,执行完成后恢复原来设置, 如有更好的方法请指正 --- .../Library/Think/Db/Driver/Mysql.class.php | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php b/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php index 33da99037..ee0a33858 100644 --- a/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php +++ b/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php @@ -182,4 +182,54 @@ protected function parseDuplicate($duplicate){ if(empty($updates)) return ''; return " ON DUPLICATE KEY UPDATE ".join(', ', $updates); } + + + + /** + * 执行存储过程查询 返回多个数据集 + * @access public + * @param string $str sql指令 + * @param boolean $fetchSql 不执行只是获取SQL + * @return mixed + */ + public function procedure($str,$fetchSql=false) { + $this->initConnect(false); + $this->_linkID->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_WARNING); + if ( !$this->_linkID ) return false; + $this->queryStr = $str; + if($fetchSql){ + return $this->queryStr; + } + //释放前次的查询结果 + if ( !empty($this->PDOStatement) ) $this->free(); + $this->queryTimes++; + N('db_query',1); // 兼容代码 + // 调试开始 + $this->debug(true); + $this->PDOStatement = $this->_linkID->prepare($str); + if(false === $this->PDOStatement){ + $this->error(); + return false; + } + try{ + $result = $this->PDOStatement->execute(); + // 调试结束 + $this->debug(false); + do + { + $result = $this->PDOStatement->fetchAll(\PDO::FETCH_ASSOC); + if ($result) + { + $resultArr[] = $result; + } + } + while ($this->PDOStatement->nextRowset()); + $this->_linkID->setAttribute(\PDO::ATTR_ERRMODE, $this->options[\PDO::ATTR_ERRMODE]); + return $resultArr; + }catch (\PDOException $e) { + $this->error(); + $this->_linkID->setAttribute(\PDO::ATTR_ERRMODE, $this->options[\PDO::ATTR_ERRMODE]); + return false; + } + } } From c9ab5e3d0fff363fede6bc6bbb5eb60547e0fa02 Mon Sep 17 00:00:00 2001 From: Feelop Date: Fri, 5 Jun 2015 11:12:32 +0800 Subject: [PATCH 079/166] Update Model.class.php --- ThinkPHP/Library/Think/Model.class.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/ThinkPHP/Library/Think/Model.class.php b/ThinkPHP/Library/Think/Model.class.php index 47e41e031..e56474bed 100644 --- a/ThinkPHP/Library/Think/Model.class.php +++ b/ThinkPHP/Library/Think/Model.class.php @@ -1355,6 +1355,17 @@ public function check($value,$rule,$type='regex'){ } } + /** + * 存储过程返回多数据集 + * @access public + * @param string $sql SQL指令 + * @param mixed $parse 是否需要解析SQL + * @return array + */ + public function procedure($sql, $parse = false) { + return $this->db->procedure($sql, $parse); + } + /** * SQL查询 * @access public From 2285cdd3844b8a23001767c1873c3c3fa5b185c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=B7=E9=9C=86?= Date: Tue, 9 Jun 2015 11:16:20 +0800 Subject: [PATCH 080/166] Update App.class.php MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 从原来的代码中提取出 invokeAction 方法 ,RestController 中也用到,解决RESTFul模式下 Action 获取不到参数的问题。 --- ThinkPHP/Library/Think/App.class.php | 140 ++++++++++++++------------- 1 file changed, 71 insertions(+), 69 deletions(-) diff --git a/ThinkPHP/Library/Think/App.class.php b/ThinkPHP/Library/Think/App.class.php index dfe9271aa..be153948a 100644 --- a/ThinkPHP/Library/Think/App.class.php +++ b/ThinkPHP/Library/Think/App.class.php @@ -107,73 +107,7 @@ static public function exec() { $action = ACTION_NAME.C('ACTION_SUFFIX'); } try{ - if(!preg_match('/^[A-Za-z](\w)*$/',$action)){ - // 非法操作 - throw new \ReflectionException(); - } - //执行当前操作 - $method = new \ReflectionMethod($module, $action); - if($method->isPublic() && !$method->isStatic()) { - $class = new \ReflectionClass($module); - // 前置操作 - if($class->hasMethod('_before_'.$action)) { - $before = $class->getMethod('_before_'.$action); - if($before->isPublic()) { - $before->invoke($module); - } - } - // URL参数绑定检测 - if($method->getNumberOfParameters()>0 && C('URL_PARAMS_BIND')){ - switch($_SERVER['REQUEST_METHOD']) { - case 'POST': - $vars = array_merge($_GET,$_POST); - break; - case 'PUT': - parse_str(file_get_contents('php://input'), $vars); - break; - default: - $vars = $_GET; - } - $params = $method->getParameters(); - $paramsBindType = C('URL_PARAMS_BIND_TYPE'); - foreach ($params as $param){ - $name = $param->getName(); - if( 1 == $paramsBindType && !empty($vars) ){ - $args[] = array_shift($vars); - }elseif( 0 == $paramsBindType && isset($vars[$name])){ - $args[] = $vars[$name]; - }elseif($param->isDefaultValueAvailable()){ - $args[] = $param->getDefaultValue(); - }else{ - E(L('_PARAM_ERROR_').':'.$name); - } - } - // 开启绑定参数过滤机制 - if(C('URL_PARAMS_SAFE')){ - $filters = C('URL_PARAMS_FILTER')?:C('DEFAULT_FILTER'); - if($filters) { - $filters = explode(',',$filters); - foreach($filters as $filter){ - $args = array_map_recursive($filter,$args); // 参数过滤 - } - } - } - array_walk_recursive($args,'think_filter'); - $method->invokeArgs($module,$args); - }else{ - $method->invoke($module); - } - // 后置操作 - if($class->hasMethod('_after_'.$action)) { - $after = $class->getMethod('_after_'.$action); - if($after->isPublic()) { - $after->invoke($module); - } - } - }else{ - // 操作方法不是Public 抛出异常 - throw new \ReflectionException(); - } + self::invokeAction($module,$action); } catch (\ReflectionException $e) { // 方法调用发生异常后 引导到__call方法处理 $method = new \ReflectionMethod($module,'__call'); @@ -181,7 +115,75 @@ static public function exec() { } return ; } - + public static function invokeAction($module,$action){ + if(!preg_match('/^[A-Za-z](\w)*$/',$action)){ + // 非法操作 + throw new \ReflectionException(); + } + //执行当前操作 + $method = new \ReflectionMethod($module, $action); + if($method->isPublic() && !$method->isStatic()) { + $class = new \ReflectionClass($module); + // 前置操作 + if($class->hasMethod('_before_'.$action)) { + $before = $class->getMethod('_before_'.$action); + if($before->isPublic()) { + $before->invoke($module); + } + } + // URL参数绑定检测 + if($method->getNumberOfParameters()>0 && C('URL_PARAMS_BIND')){ + switch($_SERVER['REQUEST_METHOD']) { + case 'POST': + $vars = array_merge($_GET,$_POST); + break; + case 'PUT': + parse_str(file_get_contents('php://input'), $vars); + break; + default: + $vars = $_GET; + } + $params = $method->getParameters(); + $paramsBindType = C('URL_PARAMS_BIND_TYPE'); + foreach ($params as $param){ + $name = $param->getName(); + if( 1 == $paramsBindType && !empty($vars) ){ + $args[] = array_shift($vars); + }elseif( 0 == $paramsBindType && isset($vars[$name])){ + $args[] = $vars[$name]; + }elseif($param->isDefaultValueAvailable()){ + $args[] = $param->getDefaultValue(); + }else{ + E(L('_PARAM_ERROR_').':'.$name); + } + } + // 开启绑定参数过滤机制 + if(C('URL_PARAMS_SAFE')){ + $filters = C('URL_PARAMS_FILTER')?:C('DEFAULT_FILTER'); + if($filters) { + $filters = explode(',',$filters); + foreach($filters as $filter){ + $args = array_map_recursive($filter,$args); // 参数过滤 + } + } + } + array_walk_recursive($args,'think_filter'); + $method->invokeArgs($module,$args); + }else{ + $method->invoke($module); + } + // 后置操作 + if($class->hasMethod('_after_'.$action)) { + $after = $class->getMethod('_after_'.$action); + if($after->isPublic()) { + $after->invoke($module); + } + } + }else{ + // 操作方法不是Public 抛出异常 + throw new \ReflectionException(); + } + } /** * 运行应用实例 入口文件使用的快捷方法 * @access public @@ -208,4 +210,4 @@ static public function run() { static public function logo(){ return 'iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyBpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBXaW5kb3dzIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjVERDVENkZGQjkyNDExRTE5REY3RDQ5RTQ2RTRDQUJCIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjVERDVENzAwQjkyNDExRTE5REY3RDQ5RTQ2RTRDQUJCIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6NURENUQ2RkRCOTI0MTFFMTlERjdENDlFNDZFNENBQkIiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NURENUQ2RkVCOTI0MTFFMTlERjdENDlFNDZFNENBQkIiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz5fx6IRAAAMCElEQVR42sxae3BU1Rk/9+69+8xuNtkHJAFCSIAkhMgjCCJQUi0GtEIVbP8Qq9LH2No6TmfaztjO2OnUdvqHFMfOVFTqIK0vUEEeqUBARCsEeYQkEPJoEvIiELLvvc9z+p27u2F3s5tsBB1OZiebu5dzf7/v/L7f952zMM8cWIwY+Mk2ulCp92Fnq3XvnzArr2NZnYNldDp0Gw+/OEQ4+obQn5D+4Ubb22+YOGsWi/Todh8AHglKEGkEsnHBQ162511GZFgW6ZCBM9/W4H3iNSQqIe09O196dLKX7d1O39OViP/wthtkND62if/wj/DbMpph8BY/m9xy8BoBmQk+mHqZQGNy4JYRwCoRbwa8l4JXw6M+orJxpU0U6ToKy/5bQsAiTeokGKkTx46RRxxEUgrwGgF4MWNNEJCGgYTvpgnY1IJWg5RzfqLgvcIgktX0i8dmMlFA8qCQ5L0Z/WObPLUxT1i4lWSYDISoEfBYGvM+LlMQQdkLHoWRRZ8zYQI62Thswe5WTORGwNXDcGjqeOA9AF7B8rhzsxMBEoJ8oJKaqPu4hblHMCMPwl9XeNWyb8xkB/DDGYKfMAE6aFL7xesZ389JlgG3XHEMI6UPDOP6JHHu67T2pwNPI69mCP4rEaBDUAJaKc/AOuXiwH07VCS3w5+UQMAuF/WqGI+yFIwVNBwemBD4r0wgQiKoFZa00sEYTwss32lA1tPwVxtc8jQ5/gWCwmGCyUD8vRT0sHBFW4GJDvZmrJFWRY1EkrGA6ZB8/10fOZSSj0E6F+BSP7xidiIzhBmKB09lEwHPkG+UQIyEN44EBiT5vrv2uJXyPQqSqO930fxvcvwbR/+JAkD9EfASgI9EHlp6YiHO4W+cAB20SnrFqxBbNljiXf1Pl1K2S0HCWfiog3YlAD5RGwwxK6oUjTweuVigLjyB0mX410mAFnMoVK1lvvUvgt8fUJH0JVyjuvcmg4dE5mUiFtD24AZ4qBVELxXKS+pMxN43kSdzNwudJ+bQbLlmnxvPOQoCugSap1GnSRoG8KOiKbH+rIA0lEeSAg3y6eeQ6XI2nrYnrPM89bUTgI0Pdqvl50vlNbtZxDUBcLBK0kPd5jPziyLdojJIN0pq5/mdzwL4UVvVInV5ncQEPNOUxa9d0TU+CW5l+FoI0GSDKHVVSOs+0KOsZoxwOzSZNFGv0mQ9avyLCh2Hpm+70Y0YJoJVgmQv822wnDC8Miq6VjJ5IFed0QD1YiAbT+nQE8v/RMZfmgmcCRHIIu7Bmcp39oM9fqEychcA747KxQ/AEyqQonl7hATtJmnhO2XYtgcia01aSbVMenAXrIomPcLgEBA4liGBzFZAT8zBYqW6brI67wg8sFVhxBhwLwBP2+tqBQqqK7VJKGh/BRrfTr6nWL7nYBaZdBJHqrX3kPEPap56xwE/GvjJTRMADeMCdcGpGXL1Xh4ZL8BDOlWkUpegfi0CeDzeA5YITzEnddv+IXL+UYCmqIvqC9UlUC/ki9FipwVjunL3yX7dOTLeXmVMAhbsGporPfyOBTm/BJ23gTVehsvXRnSewagUfpBXF3p5pygKS7OceqTjb7h2vjr/XKm0ZofKSI2Q/J102wHzatZkJPYQ5JoKsuK+EoHJakVzubzuLQDepCKllTZi9AG0DYg9ZLxhFaZsOu7bvlmVI5oPXJMQJcHxHClSln1apFTvAimeg48u0RWFeZW4lVcjbQWZuIQK1KozZfIDO6CSQmQQXdpBaiKZyEWThVK1uEc6v7V7uK0ysduExPZx4vysDR+4SelhBYm0R6LBuR4PXts8MYMcJPsINo4YZCDLj0sgB0/vLpPXvA2Tn42Cv5rsLulGubzW0sEd3d4W/mJt2Kck+DzDMijfPLOjyrDhXSh852B+OvflqAkoyXO1cYfujtc/i3jJSAwhgfFlp20laMLOku/bC7prgqW7lCn4auE5NhcXPd3M7x70+IceSgZvNljCd9k3fLjYsPElqLR14PXQZqD2ZNkkrAB79UeJUebFQmXpf8ZcAQt2XrMQdyNUVBqZoUzAFyp3V3xi/MubUA/mCT4Fhf038PC8XplhWnCmnK/ZzyC2BSTRSqKVOuY2kB8Jia0lvvRIVoP+vVWJbYarf6p655E2/nANBMCWkgD49DA0VAMyI1OLFMYCXiU9bmzi9/y5i/vsaTpHPHidTofzLbM65vMPva9HlovgXp0AvjtaqYMfDD0/4mAsYE92pxa+9k1QgCnRVObCpojpzsKTPvayPetTEgBdwnssjuc0kOBFX+q3HwRQxdrOLAqeYRjkMk/trTSu2Z9Lik7CfF0AvjtqAhS4NHobGXUnB5DQs8hG8p/wMX1r4+8xkmyvQ50JVq72TVeXbz3HvpWaQJi57hJYTw4kGbtS+C2TigQUtZUX+X27QQq2ePBZBru/0lxTm8fOOQ5yaZOZMAV+he4FqIMB+LQB0UgMSajANX29j+vbmly8ipRvHeSQoQOkM5iFXcPQCVwDMs5RBCQmaPOyvbNd6uwvQJ183BZQG3Zc+Eiv7vQOKu8YeDmMcJlt2ckyftVeMIGLBCmdMHl/tFILYwGPjXWO3zOfSq/+om+oa7Mlh2fpSsRGLp7RAW3FUVjNHgiMhyE6zBFjM2BdkdJGO7nP1kJXWAtBuBpPIAu7f+hhu7bFXIuC5xWrf0X2xreykOsUyKkF2gwadbrXDcXrfKxR43zGcSj4t/cCgr+a1iy6EjE5GYktUCl9fwfMeylyooGF48bN2IGLTw8x7StS7sj8TF9FmPGWQhm3rRR+o9lhvjJvSYAdfDUevI1M6bnX/OwWaDMOQ8RPgKRo0eulBTdT8AW2kl8e9L7UHghHwMfLiZPNoSpx0yugpQZaFqKWqxVSM3a2pN1SAhC2jf94I7ybBI7EL5A2Wvu5ht3xsoEt4+Ay/abXgCQAxyOeDsDlTCQzy75ohcGgv9Tra9uiymRUYTLrswOLlCdfAQf7HPDQQ4ErAH5EDXB9cMxWYpjtXApRncojS0sbV/cCgHTHwGNBJy+1PQE2x56FpaVR7wfQGZ37V+V+19EiHNvR6q1fRUjqvbjbMq1/qfHxbTrE10ePY2gPFk48D2CVMTf1AF4PXvyYR9dV6Wf7H413m3xTWQvYGhQ7mfYwA5mAX+18Vue05v/8jG/fZX/IW5MKPKtjSYlt0ellxh+/BOCPAwYaeVr0QofZFxJWVWC8znG70au6llVmktsF0bfHF6k8fvZ5esZJbwHwwnjg59tXz6sL/P0NUZDuSNu1mnJ8Vab17+cy005A9wtOpp3i0bZdpJLUil00semAwN45LgEViZYe3amNye0B6A9chviSlzXVsFtyN5/1H3gaNmMpn8Fz0GpYFp6Zw615H/LpUuRQQDMCL82n5DpBSawkvzIdN2ypiT8nSLth8Pk9jnjwdFzH3W4XW6KMBfwB569NdcGX93mC16tTflcArcYUc/mFuYbV+8zY0SAjAVoNErNgWjtwumJ3wbn/HlBFYdxHvSkJJEc+Ngal9opSwyo9YlITX2C/P/+gf8sxURSLR+mcZUmeqaS9wrh6vxW5zxFCOqFi90RbDWq/YwZmnu1+a6OvdpvRqkNxxe44lyl4OobEnpKA6Uox5EfH9xzPs/HRKrTPWdIQrK1VZDU7ETiD3Obpl+8wPPCRBbkbwNtpW9AbBe5L1SMlj3tdTxk/9W47JUmqS5HU+JzYymUKXjtWVmT9RenIhgXc+nroWLyxXJhmL112OdB8GCsk4f8oZJucnvmmtR85mBn10GZ0EKSCMUSAR3ukcXd5s7LvLD3me61WkuTCpJzYAyRurMB44EdEJzTfU271lUJC03YjXJXzYOGZwN4D8eB5jlfLrdWfzGRW7icMPfiSO6Oe7s20bmhdgLX4Z23B+s3JgQESzUDiMboSzDMHFpNMwccGePauhfwjzwnI2wu9zKGgEFg80jcZ7MHllk07s1H+5yojtUQTlH4nFdLKTGwDmPbIklOb1L1zO4T6N8NCuDLFLS/C63c0eNRimZ++s5BMBHxU11jHchI9oFVUxRh/eMDzHEzGYu0Lg8gJ7oS/tFCwoic44fyUtix0n/46vP4bf+//BRgAYwDDar4ncHIAAAAASUVORK5CYII='; } -} \ No newline at end of file +} From 00e4e6b3bd5c01bf3b28b2222cc49b5fdb6bae7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=B7=E9=9C=86?= Date: Tue, 9 Jun 2015 11:18:45 +0800 Subject: [PATCH 081/166] Update RestController.class.php MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 解决RESTFul模式下 Action 获取不到参数的问题! --- ThinkPHP/Library/Think/Controller/RestController.class.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ThinkPHP/Library/Think/Controller/RestController.class.php b/ThinkPHP/Library/Think/Controller/RestController.class.php index d30b446a1..2a6266275 100644 --- a/ThinkPHP/Library/Think/Controller/RestController.class.php +++ b/ThinkPHP/Library/Think/Controller/RestController.class.php @@ -10,6 +10,7 @@ // +---------------------------------------------------------------------- namespace Think\Controller; use Think\Controller; +use Think\App; /** * ThinkPHP REST控制器类 */ @@ -70,13 +71,13 @@ 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(); + App::invokeAction($this,$fun); }elseif($this->_method == $this->defaultMethod && method_exists($this,$method.'_'.$this->_type) ){ $fun = $method.'_'.$this->_type; - $this->$fun(); + App::invokeAction($this,$fun); }elseif($this->_type == $this->defaultType && method_exists($this,$method.'_'.$this->_method) ){ $fun = $method.'_'.$this->_method; - $this->$fun(); + App::invokeAction($this,$fun); }elseif(method_exists($this,'_empty')) { // 如果定义了_empty操作 则调用 $this->_empty($method,$args); From c58668e9abb75d2871e1c2df230883d646ea53b6 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Thu, 18 Jun 2015 15:22:22 +0800 Subject: [PATCH 082/166] =?UTF-8?q?crypt=E7=B1=BB=E5=BA=93=E7=9A=84?= =?UTF-8?q?=E6=96=B9=E6=B3=95=E7=94=B3=E6=98=8E=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Library/Think/Crypt/Driver/Crypt.class.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ThinkPHP/Library/Think/Crypt/Driver/Crypt.class.php b/ThinkPHP/Library/Think/Crypt/Driver/Crypt.class.php index e25468619..382425fed 100644 --- a/ThinkPHP/Library/Think/Crypt/Driver/Crypt.class.php +++ b/ThinkPHP/Library/Think/Crypt/Driver/Crypt.class.php @@ -28,14 +28,14 @@ class Crypt { public static function encrypt($str,$key,$expire=0){ $expire = sprintf('%010d', $expire ? $expire + time():0); $r = md5($key); - $c=0; + $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) . + $v .= substr($r,$c,1) . (substr($str,$i,1) ^ substr($r,$c,1)); $c++; } @@ -55,7 +55,7 @@ public static function decrypt($str,$key) { for ($i=0;$i<$len;$i++){ $md5 = substr($str,$i,1); $i++; - $v.= (substr($str,$i,1) ^ $md5); + $v .= (substr($str,$i,1) ^ $md5); } $data = $v; $expire = substr($data,0,10); @@ -67,15 +67,15 @@ public static function decrypt($str,$key) { } - function ed($str,$key) { + static private function ed($str,$key) { $r = md5($key); - $c=0; - $v = ""; + $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); + $v .= substr($str,$i,1) ^ substr($r,$c,1); $c++; } return $v; From adfedaafaad0064dddab9efcd7918ede5323a8fc Mon Sep 17 00:00:00 2001 From: thinkphp Date: Thu, 25 Jun 2015 14:19:20 +0800 Subject: [PATCH 083/166] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E4=B8=83=E7=89=9B?= =?UTF-8?q?=E9=A9=B1=E5=8A=A8=E7=B1=BB=E7=9A=84=E4=B8=80=E5=A4=84=E9=94=99?= =?UTF-8?q?=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Driver/Qiniu/QiniuStorage.class.php | 72 +++++++++---------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/ThinkPHP/Library/Think/Upload/Driver/Qiniu/QiniuStorage.class.php b/ThinkPHP/Library/Think/Upload/Driver/Qiniu/QiniuStorage.class.php index f7948d23d..472e0b46a 100644 --- a/ThinkPHP/Library/Think/Upload/Driver/Qiniu/QiniuStorage.class.php +++ b/ThinkPHP/Library/Think/Upload/Driver/Qiniu/QiniuStorage.class.php @@ -3,17 +3,17 @@ class QiniuStorage { - public $QINIU_RSF_HOST = 'http://rsf.qbox.me'; - public $QINIU_RS_HOST = 'http://rs.qbox.me'; - public $QINIU_UP_HOST = 'http://up.qiniu.com'; - public $timeout = ''; + public $QINIU_RSF_HOST = 'http://rsf.qbox.me'; + public $QINIU_RS_HOST = 'http://rs.qbox.me'; + public $QINIU_UP_HOST = 'http://up.qiniu.com'; + public $timeout = ''; public function __construct($config){ - $this->sk = $config['secretKey']; - $this->ak = $config['accessKey']; - $this->domain = $config['domain']; - $this->bucket = $config['bucket']; - $this->timeout = isset($config['timeout'])? $config['timeout'] : 3600; + $this->sk = $config['secretKey']; + $this->ak = $config['accessKey']; + $this->domain = $config['domain']; + $this->bucket = $config['bucket']; + $this->timeout = isset($config['timeout'])? $config['timeout'] : 3600; } static function sign($sk, $ak, $data){ @@ -27,13 +27,13 @@ static function signWithData($sk, $ak, $data){ } public function accessToken($url, $body=''){ - $parsed_url = parse_url($url); - $path = $parsed_url['path']; - $access = $path; + $parsed_url = parse_url($url); + $path = $parsed_url['path']; + $access = $path; if (isset($parsed_url['query'])) { $access .= "?" . $parsed_url['query']; } - $access .= "\n"; + $access .= "\n"; if($body){ $access .= $body; @@ -70,14 +70,14 @@ public function UploadToken($sk ,$ak ,$param){ public function upload($config, $file){ $uploadToken = $this->UploadToken($this->sk, $this->ak, $config); - $url = "{$this->QINIU_UP_HOST}"; + $url = "{$this->QINIU_UP_HOST}"; $mimeBoundary = md5(microtime()); - $header = array('Content-Type'=>'multipart/form-data;boundary='.$mimeBoundary); - $data = array(); + $header = array('Content-Type'=>'multipart/form-data;boundary='.$mimeBoundary); + $data = array(); $fields = array( - 'token'=>$uploadToken, - 'key'=>$config['saveName']? $config['save_name'] : $file['fileName'], + 'token' => $uploadToken, + 'key' => $config['saveName']? : $file['fileName'], ); if(is_array($config['custom_fields']) && $config['custom_fields'] !== array()){ @@ -93,10 +93,10 @@ public function upload($config, $file){ //文件 array_push($data, '--' . $mimeBoundary); - $name = $file['name']; - $fileName = $file['fileName']; - $fileBody = $file['fileBody']; - $fileName = self::Qiniu_escapeQuotes($fileName); + $name = $file['name']; + $fileName = $file['fileName']; + $fileBody = $file['fileBody']; + $fileName = self::Qiniu_escapeQuotes($fileName); array_push($data, "Content-Disposition: form-data; name=\"$name\"; filename=\"$fileName\""); array_push($data, 'Content-Type: application/octet-stream'); array_push($data, ''); @@ -105,14 +105,14 @@ public function upload($config, $file){ array_push($data, '--' . $mimeBoundary . '--'); array_push($data, ''); - $body = implode("\r\n", $data); - $response = $this->request($url, 'POST', $header, $body); + $body = implode("\r\n", $data); + $response = $this->request($url, 'POST', $header, $body); return $response; } public function dealWithType($key, $type){ - $param = $this->buildUrlParam(); - $url = ''; + $param = $this->buildUrlParam(); + $url = ''; switch($type){ case 'img': @@ -153,20 +153,20 @@ public function buildUrlParam(){ //获取某个路径下的文件列表 public function getList($query = array(), $path = ''){ - $query = array_merge(array('bucket'=>$this->bucket), $query); - $url = "{$this->QINIU_RSF_HOST}/list?".http_build_query($query); - $accessToken = $this->accessToken($url); - $response = $this->request($url, 'POST', array('Authorization'=>"QBox $accessToken")); + $query = array_merge(array('bucket'=>$this->bucket), $query); + $url = "{$this->QINIU_RSF_HOST}/list?".http_build_query($query); + $accessToken = $this->accessToken($url); + $response = $this->request($url, 'POST', array('Authorization'=>"QBox $accessToken")); return $response; } //获取某个文件的信息 public function info($key){ - $key = trim($key); - $url = "{$this->QINIU_RS_HOST}/stat/" . self::Qiniu_Encode("{$this->bucket}:{$key}"); - $accessToken = $this->accessToken($url); - $response = $this->request($url, 'POST', array( - 'Authorization'=>"QBox $accessToken", + $key = trim($key); + $url = "{$this->QINIU_RS_HOST}/stat/" . self::Qiniu_Encode("{$this->bucket}:{$key}"); + $accessToken = $this->accessToken($url); + $response = $this->request($url, 'POST', array( + 'Authorization' => "QBox $accessToken", )); return $response; } @@ -226,7 +226,7 @@ static function Qiniu_escapeQuotes($str){ } /** - * 请求百度云服务器 + * 请求云服务器 * @param string $path 请求的PATH * @param string $method 请求方法 * @param array $headers 请求header From 23ae314df607b05c0459704c3dbf0748e455ded9 Mon Sep 17 00:00:00 2001 From: hainuo Date: Thu, 2 Jul 2015 04:48:12 +0800 Subject: [PATCH 084/166] =?UTF-8?q?=E6=96=B0=E5=A2=9EMysqli=E7=9A=84sessio?= =?UTF-8?q?n=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 将本地版本库升级到PHP70alpha2后发现mysql不能使用于是将mysql改为mysqli 由于session信息放于数据库用于共享,所以将session的数据库驱动 中响应的mysql操作改为mysqli操作 --- .../Think/Session/Driver/Mysqli.class.php | 184 ++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 ThinkPHP/Library/Think/Session/Driver/Mysqli.class.php diff --git a/ThinkPHP/Library/Think/Session/Driver/Mysqli.class.php b/ThinkPHP/Library/Think/Session/Driver/Mysqli.class.php new file mode 100644 index 000000000..6df69bf10 --- /dev/null +++ b/ThinkPHP/Library/Think/Session/Driver/Mysqli.class.php @@ -0,0 +1,184 @@ + liu21st +// +---------------------------------------------------------------------- +// | change mysql to mysqli 解决php7没有mysql扩展时数据库存放session无法操作的问题 +// +---------------------------------------------------------------------- +namespace Think\Session\Driver; +/** + * 数据库方式Session驱动 + * CREATE TABLE think_session ( + * session_id varchar(255) NOT NULL, + * session_expire int(11) NOT NULL, + * session_data blob, + * UNIQUE KEY `session_id` (`session_id`) + * ); + */ +class Db +{ + + /** + * Session有效时间 + */ + protected $lifeTime = ''; + + /** + * session保存的数据库名 + */ + protected $sessionTable = ''; + + /** + * 数据库句柄 + */ + protected $hander = array(); + + /** + * 打开Session + * @access public + * @param string $savePath + * @param mixed $sessName + */ + public function open($savePath, $sessName) + { + $this->lifeTime = C('SESSION_EXPIRE') ? C('SESSION_EXPIRE') : ini_get('session.gc_maxlifetime'); + $this->sessionTable = C('SESSION_TABLE') ? C('SESSION_TABLE') : C("DB_PREFIX") . "session"; + //分布式数据库 + $host = explode(',', C('DB_HOST')); + $port = explode(',', C('DB_PORT')); + $name = explode(',', C('DB_NAME')); + $user = explode(',', C('DB_USER')); + $pwd = explode(',', C('DB_PWD')); + if (1 == C('DB_DEPLOY_TYPE')) { + //读写分离 + if (C('DB_RW_SEPARATE')) { + $w = floor(mt_rand(0, C('DB_MASTER_NUM') - 1)); + if (is_numeric(C('DB_SLAVE_NO'))) {//指定服务器读 + $r = C('DB_SLAVE_NO'); + } else { + $r = floor(mt_rand(C('DB_MASTER_NUM'), count($host) - 1)); + } + //主数据库链接 + $hander = mysqli_connect( + $host[$w] . (isset($port[$w]) ? ':' . $port[$w] : ':' . $port[0]), + isset($user[$w]) ? $user[$w] : $user[0], + isset($pwd[$w]) ? $pwd[$w] : $pwd[0] + ); + $dbSel = mysqli_select_db( + $hander, + isset($name[$w]) ? $name[$w] : $name[0] + ); + if (!$hander || !$dbSel) + return false; + $this->hander[0] = $hander; + //从数据库链接 + $hander = mysqli_connect( + $host[$r] . (isset($port[$r]) ? ':' . $port[$r] : ':' . $port[0]), + isset($user[$r]) ? $user[$r] : $user[0], + isset($pwd[$r]) ? $pwd[$r] : $pwd[0] + ); + $dbSel = mysqli_select_db( + $hander, + isset($name[$r]) ? $name[$r] : $name[0] + ); + if (!$hander || !$dbSel) + return false; + $this->hander[1] = $hander; + return true; + } + } + //从数据库链接 + $r = floor(mt_rand(0, count($host) - 1)); + $hander = mysqli_connect( + $host[$r] . (isset($port[$r]) ? ':' . $port[$r] : ':' . $port[0]), + isset($user[$r]) ? $user[$r] : $user[0], + isset($pwd[$r]) ? $pwd[$r] : $pwd[0] + ); + $dbSel = mysqli_select_db( + $hander, + isset($name[$r]) ? $name[$r] : $name[0] + ); + if (!$hander || !$dbSel) + return false; + $this->hander = $hander; + return true; + } + + /** + * 关闭Session + * @access public + */ + public function close() + { + if (is_array($this->hander)) { + $this->gc($this->lifeTime); + return (mysqli_close($this->hander[0]) && mysqli_close($this->hander[1])); + } + $this->gc($this->lifeTime); + return mysqli_close($this->hander); + } + + /** + * 读取Session + * @access public + * @param string $sessID + */ + public function read($sessID) + { + $hander = is_array($this->hander) ? $this->hander[1] : $this->hander; + $res = mysqli_query($hander, "SELECT session_data AS data FROM " . $this->sessionTable . " WHERE session_id = '$sessID' AND session_expire >" . time()); + if ($res) { + $row = mysqli_fetch_assoc($res); + return $row['data']; + } + return ""; + } + + /** + * 写入Session + * @access public + * @param string $sessID + * @param String $sessData + */ + public function write($sessID, $sessData) + { + $hander = is_array($this->hander) ? $this->hander[0] : $this->hander; + $expire = time() + $this->lifeTime; + mysqli_query($hander, "REPLACE INTO " . $this->sessionTable . " ( session_id, session_expire, session_data) VALUES( '$sessID', '$expire', '$sessData')"); + if (mysqli_affected_rows($hander)) + return true; + return false; + } + + /** + * 删除Session + * @access public + * @param string $sessID + */ + public function destroy($sessID) + { + $hander = is_array($this->hander) ? $this->hander[0] : $this->hander; + mysqli_query($hander, "DELETE FROM " . $this->sessionTable . " WHERE session_id = '$sessID'"); + if (mysqli_affected_rows($hander)) + return true; + return false; + } + + /** + * Session 垃圾回收 + * @access public + * @param string $sessMaxLifeTime + */ + public function gc($sessMaxLifeTime) + { + $hander = is_array($this->hander) ? $this->hander[0] : $this->hander; + mysqli_query($hander, "DELETE FROM " . $this->sessionTable . " WHERE session_expire < " . time()); + return mysqli_affected_rows($hander); + } + +} From 8409516c5f005f2da1adef341cbfca74d2f5aeba Mon Sep 17 00:00:00 2001 From: thinkphp Date: Fri, 3 Jul 2015 11:04:27 +0800 Subject: [PATCH 085/166] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E4=B8=80=E5=A4=84?= =?UTF-8?q?=E6=B3=A8=E9=87=8A=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Upload/Driver/Ftp.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ThinkPHP/Library/Think/Upload/Driver/Ftp.class.php b/ThinkPHP/Library/Think/Upload/Driver/Ftp.class.php index f5501ae90..fccf9a640 100644 --- a/ThinkPHP/Library/Think/Upload/Driver/Ftp.class.php +++ b/ThinkPHP/Library/Think/Upload/Driver/Ftp.class.php @@ -107,7 +107,7 @@ public function save($file, $replace=true) { /** * 创建目录 - * @param string $savepath 要创建的穆里 + * @param string $savepath 要创建的目录 * @return boolean 创建状态,true-成功,false-失败 */ public function mkdir($savepath){ From 6547443aa3f095aa04d4091e8c33eb853c1abd78 Mon Sep 17 00:00:00 2001 From: hainuo Date: Mon, 20 Jul 2015 15:01:17 +0800 Subject: [PATCH 086/166] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E7=B1=BB=E5=90=8D?= =?UTF-8?q?=E7=9A=84=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 对session的db类修改为mysql类方法后,没有更改文件的类名,导致服务不可用,先将类名修正为mysqli --- ThinkPHP/Library/Think/Session/Driver/Mysqli.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ThinkPHP/Library/Think/Session/Driver/Mysqli.class.php b/ThinkPHP/Library/Think/Session/Driver/Mysqli.class.php index 6df69bf10..b29ec2fbc 100644 --- a/ThinkPHP/Library/Think/Session/Driver/Mysqli.class.php +++ b/ThinkPHP/Library/Think/Session/Driver/Mysqli.class.php @@ -20,7 +20,7 @@ * UNIQUE KEY `session_id` (`session_id`) * ); */ -class Db +class Mysqli { /** From 24dd23a7c35088073dfc796ff6cdfcf0cef294ee Mon Sep 17 00:00:00 2001 From: latelan Date: Wed, 26 Aug 2015 16:43:32 +0800 Subject: [PATCH 087/166] Update Local.class.php MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修改注释错误 --- ThinkPHP/Library/Think/Upload/Driver/Local.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ThinkPHP/Library/Think/Upload/Driver/Local.class.php b/ThinkPHP/Library/Think/Upload/Driver/Local.class.php index 5988d5a34..756b09193 100644 --- a/ThinkPHP/Library/Think/Upload/Driver/Local.class.php +++ b/ThinkPHP/Library/Think/Upload/Driver/Local.class.php @@ -90,7 +90,7 @@ public function save($file, $replace=true) { /** * 创建目录 - * @param string $savepath 要创建的穆里 + * @param string $savepath 要创建的目录 * @return boolean 创建状态,true-成功,false-失败 */ public function mkdir($savepath){ From 111107a338d78630743bf36ecb26edc7f06a6020 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Thu, 27 Aug 2015 10:45:18 +0800 Subject: [PATCH 088/166] =?UTF-8?q?=E4=BF=AE=E6=AD=A3Imagick=E7=B1=BB?= =?UTF-8?q?=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Image/Driver/Imagick.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ThinkPHP/Library/Think/Image/Driver/Imagick.class.php b/ThinkPHP/Library/Think/Image/Driver/Imagick.class.php index 02a1934fa..df952a67c 100644 --- a/ThinkPHP/Library/Think/Image/Driver/Imagick.class.php +++ b/ThinkPHP/Library/Think/Image/Driver/Imagick.class.php @@ -190,8 +190,8 @@ private function _crop($w, $h, $x, $y, $width, $height, $img = null){ } //设置缓存尺寸 - $this->info['width'] = $w; - $this->info['height'] = $h; + $this->info['width'] = $width; + $this->info['height'] = $height; } /** From 98b0f5d79f160c36ba39c4b1d63d9c2b6c9f0166 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9F=8F=E6=96=B0=E6=98=9F?= Date: Sat, 5 Sep 2015 22:33:51 +0800 Subject: [PATCH 089/166] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E4=B8=80=E5=A4=84?= =?UTF-8?q?=E6=B3=A8=E9=87=8A=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit URL_CASE_INSENSITIVE 注释错误 --- ThinkPHP/Conf/convention.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ThinkPHP/Conf/convention.php b/ThinkPHP/Conf/convention.php index 4061933ac..7126042df 100644 --- a/ThinkPHP/Conf/convention.php +++ b/ThinkPHP/Conf/convention.php @@ -132,7 +132,7 @@ 'TAGLIB_PRE_LOAD' => '', // 需要额外加载的标签库(须指定标签库名称),多个以逗号分隔 /* URL设置 */ - 'URL_CASE_INSENSITIVE' => true, // 默认false 表示URL区分大小写 true则表示不区分大小写 + 'URL_CASE_INSENSITIVE' => true, // 默true 表示URL不区分大小写 false则表示区分大小写 'URL_MODEL' => 1, // URL访问模式,可选参数0、1、2、3,代表以下四种模式: // 0 (普通模式); 1 (PATHINFO 模式); 2 (REWRITE 模式); 3 (兼容模式) 默认为PATHINFO 模式 'URL_PATHINFO_DEPR' => '/', // PATHINFO模式下,各参数之间的分割符号 From 3ae71efbec213f5de1497523f3417fcbc267bf26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9F=8F=E6=96=B0=E6=98=9F?= Date: Sat, 5 Sep 2015 22:55:01 +0800 Subject: [PATCH 090/166] tabs to --- ThinkPHP/Conf/debug.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ThinkPHP/Conf/debug.php b/ThinkPHP/Conf/debug.php index 06674b925..71656a929 100644 --- a/ThinkPHP/Conf/debug.php +++ b/ThinkPHP/Conf/debug.php @@ -19,9 +19,9 @@ 'LOG_EXCEPTION_RECORD' => true, // 是否记录异常信息日志 'LOG_LEVEL' => 'EMERG,ALERT,CRIT,ERR,WARN,NOTIC,INFO,DEBUG,SQL', // 允许记录的日志级别 'DB_FIELDS_CACHE' => false, // 字段缓存信息 - 'DB_DEBUG' => true, // 开启调试模式 记录SQL日志 + 'DB_DEBUG' => true, // 开启调试模式 记录SQL日志 'TMPL_CACHE_ON' => false, // 是否开启模板编译缓存,设为false则每次都会重新编译 'TMPL_STRIP_SPACE' => false, // 是否去除模板文件里面的html空格与换行 'SHOW_ERROR_MSG' => true, // 显示错误信息 'URL_CASE_INSENSITIVE' => false, // URL区分大小写 -); \ No newline at end of file +); From 250cf488f844fd17cf70517ffdbbc7ac8a076103 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Sat, 26 Sep 2015 13:28:14 +0800 Subject: [PATCH 091/166] =?UTF-8?q?=E4=BF=AE=E6=AD=A3Unix=E7=8E=AF?= =?UTF-8?q?=E5=A2=83=E5=91=BD=E4=BB=A4=E8=A1=8C=E4=B8=8B=E9=9D=A2=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E4=BF=A1=E6=81=AF=E4=B9=B1=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Behavior/ContentReplaceBehavior.class.php | 2 +- ThinkPHP/Library/Think/Think.class.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ThinkPHP/Library/Behavior/ContentReplaceBehavior.class.php b/ThinkPHP/Library/Behavior/ContentReplaceBehavior.class.php index ed246a423..c572223b0 100644 --- a/ThinkPHP/Library/Behavior/ContentReplaceBehavior.class.php +++ b/ThinkPHP/Library/Behavior/ContentReplaceBehavior.class.php @@ -32,7 +32,7 @@ protected function templateContentReplace($content) { '__APP__' => __APP__, // 当前应用地址 '__MODULE__' => __MODULE__, '__ACTION__' => __ACTION__, // 当前操作地址 - '__SELF__' => __SELF__, // 当前页面地址 + '__SELF__' => htmlentities(__SELF__), // 当前页面地址 '__CONTROLLER__'=> __CONTROLLER__, '__URL__' => __CONTROLLER__, '__PUBLIC__' => __ROOT__.'/Public',// 站点公共目录 diff --git a/ThinkPHP/Library/Think/Think.class.php b/ThinkPHP/Library/Think/Think.class.php index 3bd18643e..34c8459f2 100644 --- a/ThinkPHP/Library/Think/Think.class.php +++ b/ThinkPHP/Library/Think/Think.class.php @@ -297,7 +297,7 @@ static public function halt($error) { $e = $error; } if(IS_CLI){ - exit(iconv('UTF-8','gbk',$e['message']).PHP_EOL.'FILE: '.$e['file'].'('.$e['line'].')'.PHP_EOL.$e['trace']); + exit((IS_WIN? iconv('UTF-8','gbk',$e['message']) : $e['message']).PHP_EOL.'FILE: '.$e['file'].'('.$e['line'].')'.PHP_EOL.$e['trace']); } } else { //否则定向到错误页面 From e8e12b58d406de32bdc62ed13d9651480043407e Mon Sep 17 00:00:00 2001 From: thinkphp Date: Sat, 26 Sep 2015 22:02:51 +0800 Subject: [PATCH 092/166] =?UTF-8?q?=E6=94=B9=E8=BF=9BPage=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Page.class.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/ThinkPHP/Library/Think/Page.class.php b/ThinkPHP/Library/Think/Page.class.php index 8a57cb62f..7d85addb7 100644 --- a/ThinkPHP/Library/Think/Page.class.php +++ b/ThinkPHP/Library/Think/Page.class.php @@ -17,7 +17,6 @@ class Page{ public $totalRows; // 总行数 public $totalPages; // 分页总页面数 public $rollPage = 11;// 分页栏每页显示的页数 - public $lastSuffix = true; // 最后一页是否显示总页数 private $p = 'p'; //分页参数名 private $url = ''; //当前链接URL @@ -89,7 +88,6 @@ public function show() { /* 计算分页临时变量 */ $now_cool_page = $this->rollPage/2; $now_cool_page_ceil = ceil($now_cool_page); - $this->lastSuffix && $this->config['last'] = $this->totalPages; //上一页 $up_row = $this->nowPage - 1; From 0674af75fbb2cd9747dea9fcd1d0f691361f1953 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Wed, 30 Sep 2015 09:01:45 +0800 Subject: [PATCH 093/166] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E4=B8=80=E5=A4=84?= =?UTF-8?q?=E8=AD=A6=E5=91=8A=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Model.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ThinkPHP/Library/Think/Model.class.php b/ThinkPHP/Library/Think/Model.class.php index e56474bed..8da08dbcd 100644 --- a/ThinkPHP/Library/Think/Model.class.php +++ b/ThinkPHP/Library/Think/Model.class.php @@ -1125,7 +1125,7 @@ public function regex($value,$rule) { * @return mixed */ private function autoOperation(&$data,$type) { - if(false === $this->options['auto']){ + if(isset($this->options['auto']) && false === $this->options['auto']){ // 关闭自动完成 return $data; } @@ -1182,7 +1182,7 @@ private function autoOperation(&$data,$type) { * @return boolean */ protected function autoValidation($data,$type) { - if(false === $this->options['validate'] ){ + if(isset($this->options['validate']) && false === $this->options['validate'] ){ // 关闭自动验证 return true; } From e027b1e3293e827c85f6b5884e8d6a07076c18aa Mon Sep 17 00:00:00 2001 From: thinkphp Date: Wed, 30 Sep 2015 09:09:33 +0800 Subject: [PATCH 094/166] =?UTF-8?q?=E6=94=B9=E8=BF=9BgetField=E6=96=B9?= =?UTF-8?q?=E6=B3=95=EF=BC=8C=E6=94=AF=E6=8C=81=E8=8E=B7=E5=8F=96=E7=94=A8?= =?UTF-8?q?=E4=BA=86=E5=88=AB=E5=90=8D=E7=9A=84=E5=AD=97=E6=AE=B5=E7=9A=84?= =?UTF-8?q?=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Model.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ThinkPHP/Library/Think/Model.class.php b/ThinkPHP/Library/Think/Model.class.php index 8da08dbcd..924ca369c 100644 --- a/ThinkPHP/Library/Think/Model.class.php +++ b/ThinkPHP/Library/Think/Model.class.php @@ -980,7 +980,7 @@ public function getField($field,$sepa=null) { return $data; } foreach ($result as $val){ - $array[] = $val[$field]; + $array[] = reset($val); } if(isset($cache)){ S($key,$array,$cache); From 2dfdd2ad67d745ea24584a8cf91d44143c771f7d Mon Sep 17 00:00:00 2001 From: thinkphp Date: Wed, 30 Sep 2015 09:19:59 +0800 Subject: [PATCH 095/166] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=20=E4=BD=BF=E7=94=A8?= =?UTF-8?q?unique=E9=AA=8C=E8=AF=81=E7=9A=84=E6=97=B6=E5=80=99=20=E5=BD=B1?= =?UTF-8?q?=E5=93=8Doptions=E5=A4=B1=E6=95=88=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Model.class.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ThinkPHP/Library/Think/Model.class.php b/ThinkPHP/Library/Think/Model.class.php index 924ca369c..0e920e559 100644 --- a/ThinkPHP/Library/Think/Model.class.php +++ b/ThinkPHP/Library/Think/Model.class.php @@ -1297,7 +1297,10 @@ protected function _validationFieldItem($data,$val) { if(!empty($data[$pk]) && is_string($pk)) { // 完善编辑的时候验证唯一 $map[$pk] = array('neq',$data[$pk]); } - if($this->where($map)->find()) return false; + $options = $this->options; + if($this->where($map)->find()) + return false; + $this->options = $options; return true; default: // 检查附加规则 return $this->check($data[$val[0]],$val[1],$val[4]); From 618ab2ef087217fba330ef549b7fe7eeb6f5367f Mon Sep 17 00:00:00 2001 From: thinkphp Date: Fri, 2 Oct 2015 15:47:47 +0800 Subject: [PATCH 096/166] =?UTF-8?q?composer=E4=BD=BF=E7=94=A8=E4=B8=AD?= =?UTF-8?q?=E5=9B=BD=E9=95=9C=E5=83=8F=E5=9C=B0=E5=9D=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- composer.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 5154e2e0e..fd56d75fa 100644 --- a/composer.json +++ b/composer.json @@ -14,5 +14,9 @@ "require": { "php": ">=5.3.0" }, - "minimum-stability": "dev" + "minimum-stability": "dev", + "repositories": [ + {"type": "composer", "url": "http://packagist.phpcomposer.com"}, + {"packagist": false} + ] } From 00bcdbaeadd938fd07e6dc29f05554bebb9ee0c6 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Sat, 3 Oct 2015 16:51:29 +0800 Subject: [PATCH 097/166] =?UTF-8?q?=E6=94=B9=E8=BF=9BMODULE=5FALLOW=5FLIST?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E5=88=A4=E6=96=AD=E6=9C=BA=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Dispatcher.class.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/ThinkPHP/Library/Think/Dispatcher.class.php b/ThinkPHP/Library/Think/Dispatcher.class.php index 0065cfb67..e793dcffb 100644 --- a/ThinkPHP/Library/Think/Dispatcher.class.php +++ b/ThinkPHP/Library/Think/Dispatcher.class.php @@ -122,13 +122,9 @@ static public function dispatch() { $_SERVER['PATH_INFO'] = __INFO__; if(!defined('BIND_MODULE') && (!C('URL_ROUTER_ON') || !Route::check())){ if (__INFO__ && C('MULTI_MODULE')){ // 获取模块名 - $paths = explode($depr,__INFO__,2); - $allowList = C('MODULE_ALLOW_LIST'); // 允许的模块列表 - $module = preg_replace('/\.' . __EXT__ . '$/i', '',$paths[0]); - if( empty($allowList) || (is_array($allowList) && in_array_case($module, $allowList))){ - $_GET[$varModule] = $module; - $_SERVER['PATH_INFO'] = isset($paths[1])?$paths[1]:''; - } + $paths = explode($depr,__INFO__,2); + $_GET[$varModule] = preg_replace('/\.' . __EXT__ . '$/i', '',$paths[0]); + $_SERVER['PATH_INFO'] = isset($paths[1])?$paths[1]:''; } } } @@ -140,7 +136,7 @@ static public function dispatch() { define('MODULE_NAME', defined('BIND_MODULE')? BIND_MODULE : self::getModule($varModule)); // 检测模块是否存在 - if( MODULE_NAME && (defined('BIND_MODULE') || !in_array_case(MODULE_NAME,C('MODULE_DENY_LIST')) ) && is_dir(APP_PATH.MODULE_NAME)){ + if( MODULE_NAME && !in_array_case(MODULE_NAME,C('MODULE_DENY_LIST')) && is_dir(APP_PATH.MODULE_NAME)){ // 定义当前模块路径 define('MODULE_PATH', APP_PATH.MODULE_NAME.'/'); // 定义当前模块的模版缓存路径 @@ -322,6 +318,10 @@ static private function getAction($var,$urlCase) { static private function getModule($var) { $module = (!empty($_GET[$var])?$_GET[$var]:C('DEFAULT_MODULE')); unset($_GET[$var]); + $allowList = C('MODULE_ALLOW_LIST'); // 允许的模块列表 + if( !empty($allowList) && is_array($allowList) && !in_array_case($module, $allowList)){ + E(L('_MODULE_NOT_EXIST_').':'.strip_tags(ucfirst($module))); + } if($maps = C('URL_MODULE_MAP')) { if(isset($maps[strtolower($module)])) { // 记录当前别名 From 4d9d04826b654bae535a74f8eacf4c204a7b4e7d Mon Sep 17 00:00:00 2001 From: thinkphp Date: Sun, 4 Oct 2015 13:41:16 +0800 Subject: [PATCH 098/166] =?UTF-8?q?PSR=E8=A7=84=E8=8C=83=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Common/functions.php | 1610 ++++++----- ThinkPHP/Conf/convention.php | 244 +- ThinkPHP/Conf/debug.php | 22 +- ThinkPHP/Lang/en-us.php | 8 +- ThinkPHP/Lang/pt-br.php | 6 +- ThinkPHP/Lang/zh-cn.php | 6 +- ThinkPHP/Lang/zh-tw.php | 6 +- .../Behavior/AgentCheckBehavior.class.php | 11 +- .../Library/Behavior/BorisBehavior.class.php | 40 +- .../Behavior/BrowserCheckBehavior.class.php | 23 +- .../Behavior/BuildLiteBehavior.class.php | 92 +- .../CheckActionRouteBehavior.class.php | 203 +- .../Behavior/CheckLangBehavior.class.php | 62 +- .../ChromeShowPageTraceBehavior.class.php | 946 +++--- .../Behavior/ContentReplaceBehavior.class.php | 38 +- .../Behavior/CronRunBehavior.class.php | 56 +- .../FireShowPageTraceBehavior.class.php | 1175 ++++---- .../Behavior/ParseTemplateBehavior.class.php | 80 +- .../Behavior/ReadHtmlCacheBehavior.class.php | 111 +- .../Behavior/RobotCheckBehavior.class.php | 30 +- .../Behavior/ShowPageTraceBehavior.class.php | 134 +- .../Behavior/ShowRuntimeBehavior.class.php | 64 +- .../Behavior/TokenBuildBehavior.class.php | 61 +- .../Behavior/UpgradeNoticeBehavior.class.php | 81 +- .../Behavior/WriteHtmlCacheBehavior.class.php | 12 +- ThinkPHP/Library/Org/Net/Http.class.php | 288 +- ThinkPHP/Library/Org/Net/IpLocation.class.php | 144 +- ThinkPHP/Library/Org/Util/ArrayList.class.php | 92 +- .../Library/Org/Util/CodeSwitch.class.php | 353 +-- ThinkPHP/Library/Org/Util/Date.class.php | 345 +-- ThinkPHP/Library/Org/Util/Rbac.class.php | 345 +-- ThinkPHP/Library/Org/Util/Stack.class.php | 12 +- ThinkPHP/Library/Org/Util/String.class.php | 231 +- ThinkPHP/Library/Think/App.class.php | 257 +- ThinkPHP/Library/Think/Auth.class.php | 193 +- ThinkPHP/Library/Think/Behavior.class.php | 6 +- ThinkPHP/Library/Think/Build.class.php | 171 +- ThinkPHP/Library/Think/Cache.class.php | 113 +- .../Think/Cache/Driver/Apachenote.class.php | 106 +- .../Library/Think/Cache/Driver/Apc.class.php | 55 +- .../Library/Think/Cache/Driver/Db.class.php | 116 +- .../Think/Cache/Driver/Eaccelerator.class.php | 51 +- .../Library/Think/Cache/Driver/File.class.php | 154 +- .../Think/Cache/Driver/Memcache.class.php | 78 +- .../Think/Cache/Driver/Memcached.class.php | 56 +- .../Think/Cache/Driver/Memcachesae.class.php | 109 +- .../Think/Cache/Driver/Redis.class.php | 85 +- .../Think/Cache/Driver/Shmop.class.php | 133 +- .../Think/Cache/Driver/Sqlite.class.php | 87 +- .../Think/Cache/Driver/Wincache.class.php | 53 +- .../Think/Cache/Driver/Xcache.class.php | 49 +- ThinkPHP/Library/Think/Controller.class.php | 214 +- .../Controller/HproseController.class.php | 42 +- .../Controller/JsonRpcController.class.php | 17 +- .../Think/Controller/RestController.class.php | 182 +- .../Think/Controller/RpcController.class.php | 36 +- .../Think/Controller/YarController.class.php | 24 +- ThinkPHP/Library/Think/Crypt.class.php | 35 +- .../Think/Crypt/Driver/Base64.class.php | 72 +- .../Think/Crypt/Driver/Crypt.class.php | 94 +- .../Library/Think/Crypt/Driver/Des.class.php | 422 +-- .../Think/Crypt/Driver/Think.class.php | 70 +- .../Think/Crypt/Driver/Xxtea.class.php | 95 +- ThinkPHP/Library/Think/Db.class.php | 144 +- ThinkPHP/Library/Think/Db/Driver.class.php | 1080 +++---- .../Think/Db/Driver/Firebird.class.php | 110 +- .../Library/Think/Db/Driver/Mongo.class.php | 771 ++--- .../Library/Think/Db/Driver/Mysql.class.php | 221 +- .../Library/Think/Db/Driver/Oracle.class.php | 116 +- .../Library/Think/Db/Driver/Pgsql.class.php | 48 +- .../Library/Think/Db/Driver/Sqlite.class.php | 51 +- .../Library/Think/Db/Driver/Sqlsrv.class.php | 125 +- ThinkPHP/Library/Think/Db/Lite.class.php | 367 ++- ThinkPHP/Library/Think/Dispatcher.class.php | 385 +-- ThinkPHP/Library/Think/Exception.class.php | 6 +- ThinkPHP/Library/Think/Hook.class.php | 98 +- ThinkPHP/Library/Think/Image.class.php | 84 +- .../Library/Think/Image/Driver/GIF.class.php | 1042 +++---- .../Library/Think/Image/Driver/Gd.class.php | 243 +- .../Think/Image/Driver/Imagick.class.php | 236 +- ThinkPHP/Library/Think/Log.class.php | 80 +- .../Library/Think/Log/Driver/File.class.php | 31 +- .../Library/Think/Log/Driver/Sae.class.php | 29 +- ThinkPHP/Library/Think/Model.class.php | 1759 +++++++----- .../Library/Think/Model/AdvModel.class.php | 487 ++-- .../Library/Think/Model/MergeModel.class.php | 377 +-- .../Library/Think/Model/MongoModel.class.php | 314 +- .../Think/Model/RelationModel.class.php | 562 ++-- .../Library/Think/Model/ViewModel.class.php | 240 +- ThinkPHP/Library/Think/Page.class.php | 79 +- ThinkPHP/Library/Think/Route.class.php | 320 ++- .../Library/Think/Session/Driver/Db.class.php | 264 +- .../Think/Session/Driver/Memcache.class.php | 113 +- .../Think/Session/Driver/Mysqli.class.php | 32 +- ThinkPHP/Library/Think/Storage.class.php | 18 +- .../Think/Storage/Driver/File.class.php | 88 +- .../Think/Storage/Driver/Sae.class.php | 157 +- ThinkPHP/Library/Think/Template.class.php | 679 +++-- .../Think/Template/Driver/Ease.class.php | 31 +- .../Think/Template/Driver/Lite.class.php | 29 +- .../Think/Template/Driver/Mobile.class.php | 15 +- .../Think/Template/Driver/Smart.class.php | 31 +- .../Think/Template/Driver/Smarty.class.php | 31 +- .../Library/Think/Template/TagLib.class.php | 251 +- .../Think/Template/TagLib/Cx.class.php | 613 ++-- .../Think/Template/TagLib/Html.class.php | 594 ++-- ThinkPHP/Library/Think/Think.class.php | 446 +-- ThinkPHP/Library/Think/Upload.class.php | 212 +- .../Library/Think/Upload/Driver/Bcs.class.php | 135 +- .../Think/Upload/Driver/Bcs/bcs.class.php | 2542 +++++++++-------- .../Upload/Driver/Bcs/mimetypes.class.php | 271 +- .../Upload/Driver/Bcs/requestcore.class.php | 1672 +++++------ .../Library/Think/Upload/Driver/Ftp.class.php | 42 +- .../Think/Upload/Driver/Local.class.php | 34 +- .../Think/Upload/Driver/Qiniu.class.php | 50 +- .../Driver/Qiniu/QiniuStorage.class.php | 697 ++--- .../Library/Think/Upload/Driver/Sae.class.php | 68 +- .../Think/Upload/Driver/Upyun.class.php | 72 +- ThinkPHP/Library/Think/Verify.class.php | 252 +- ThinkPHP/Library/Think/View.class.php | 156 +- ThinkPHP/Mode/Api/App.class.php | 129 +- ThinkPHP/Mode/Api/Controller.class.php | 61 +- ThinkPHP/Mode/Api/Dispatcher.class.php | 245 +- ThinkPHP/Mode/Api/functions.php | 1048 ++++--- ThinkPHP/Mode/Lite/App.class.php | 143 +- ThinkPHP/Mode/Lite/Controller.class.php | 188 +- ThinkPHP/Mode/Lite/Dispatcher.class.php | 290 +- ThinkPHP/Mode/Lite/Model.class.php | 1307 +++++---- ThinkPHP/Mode/Lite/View.class.php | 218 +- ThinkPHP/Mode/Lite/convention.php | 235 +- ThinkPHP/Mode/Lite/functions.php | 1376 +++++---- ThinkPHP/Mode/Sae/convention.php | 31 +- ThinkPHP/Mode/api.php | 38 +- ThinkPHP/Mode/common.php | 68 +- ThinkPHP/Mode/lite.php | 42 +- ThinkPHP/Mode/sae.php | 64 +- ThinkPHP/ThinkPHP.php | 117 +- index.php | 10 +- 138 files changed, 18893 insertions(+), 15823 deletions(-) diff --git a/ThinkPHP/Common/functions.php b/ThinkPHP/Common/functions.php index 99edfa690..024e21fec 100644 --- a/ThinkPHP/Common/functions.php +++ b/ThinkPHP/Common/functions.php @@ -20,7 +20,8 @@ * @param mixed $default 默认值 * @return mixed */ -function C($name=null, $value=null,$default=null) { +function C($name = null, $value = null, $default = null) +{ static $_config = array(); // 无参数时获取所有 if (empty($name)) { @@ -30,22 +31,26 @@ function C($name=null, $value=null,$default=null) { if (is_string($name)) { if (!strpos($name, '.')) { $name = strtoupper($name); - if (is_null($value)) + if (is_null($value)) { return isset($_config[$name]) ? $_config[$name] : $default; + } + $_config[$name] = $value; return null; } // 二维数组设置和获取支持 - $name = explode('.', $name); - $name[0] = strtoupper($name[0]); - if (is_null($value)) + $name = explode('.', $name); + $name[0] = strtoupper($name[0]); + if (is_null($value)) { return isset($_config[$name[0]][$name[1]]) ? $_config[$name[0]][$name[1]] : $default; + } + $_config[$name[0]][$name[1]] = $value; return null; } // 批量设置 - if (is_array($name)){ - $_config = array_merge($_config, array_change_key_case($name,CASE_UPPER)); + if (is_array($name)) { + $_config = array_merge($_config, array_change_key_case($name, CASE_UPPER)); return null; } return null; // 避免非法参数 @@ -57,24 +62,25 @@ function C($name=null, $value=null,$default=null) { * @param string $parse 配置解析方法 有些格式需要用户自己解析 * @return array */ -function load_config($file,$parse=CONF_PARSE){ - $ext = pathinfo($file,PATHINFO_EXTENSION); - switch($ext){ +function loadConfig($file, $parse = CONF_PARSE) +{ + $ext = pathinfo($file, PATHINFO_EXTENSION); + switch ($ext) { case 'php': return include $file; case 'ini': return parse_ini_file($file); case 'yaml': - return yaml_parse_file($file); - case 'xml': - return (array)simplexml_load_file($file); + return yamlParseFile($file); + case 'xml': + return (array) simplexml_load_file($file); case 'json': return json_decode(file_get_contents($file), true); default: - if(function_exists($parse)){ + if (function_exists($parse)) { return $parse($file); - }else{ - E(L('_NOT_SUPPORT_').':'.$ext); + } else { + E(L('_NOT_SUPPORT_') . ':' . $ext); } } } @@ -85,7 +91,8 @@ function load_config($file,$parse=CONF_PARSE){ * @return array */ if (!function_exists('yaml_parse_file')) { - function yaml_parse_file($file) { + function yamlParseFile($file) + { vendor('spyc.Spyc'); return Spyc::YAMLLoad($file); } @@ -98,7 +105,8 @@ function yaml_parse_file($file) { * @throws Think\Exception * @return void */ -function E($msg, $code=0) { +function E($msg, $code = 0) +{ throw new Think\Exception($msg, $code); } @@ -119,23 +127,36 @@ function E($msg, $code=0) { * @param integer|string $dec 小数位或者m * @return mixed */ -function G($start,$end='',$dec=4) { - static $_info = array(); - static $_mem = array(); - if(is_float($end)) { // 记录时间 - $_info[$start] = $end; - }elseif(!empty($end)){ // 统计时间和内存使用 - if(!isset($_info[$end])) $_info[$end] = microtime(TRUE); - if(MEMORY_LIMIT_ON && $dec=='m'){ - if(!isset($_mem[$end])) $_mem[$end] = memory_get_usage(); - return number_format(($_mem[$end]-$_mem[$start])/1024); - }else{ - return number_format(($_info[$end]-$_info[$start]),$dec); - } - - }else{ // 记录时间和内存使用 - $_info[$start] = microtime(TRUE); - if(MEMORY_LIMIT_ON) $_mem[$start] = memory_get_usage(); +function G($start, $end = '', $dec = 4) +{ + static $_info = array(); + static $_mem = array(); + if (is_float($end)) { + // 记录时间 + $_info[$start] = $end; + } elseif (!empty($end)) { + // 统计时间和内存使用 + if (!isset($_info[$end])) { + $_info[$end] = microtime(true); + } + + if (MEMORY_LIMIT_ON && 'm' == $dec) { + if (!isset($_mem[$end])) { + $_mem[$end] = memory_get_usage(); + } + + return number_format(($_mem[$end] - $_mem[$start]) / 1024); + } else { + return number_format(($_info[$end] - $_info[$start]), $dec); + } + + } else { + // 记录时间和内存使用 + $_info[$start] = microtime(true); + if (MEMORY_LIMIT_ON) { + $_mem[$start] = memory_get_usage(); + } + } return null; } @@ -146,31 +167,36 @@ function G($start,$end='',$dec=4) { * @param mixed $value 语言值或者变量 * @return mixed */ -function L($name=null, $value=null) { +function L($name = null, $value = null) +{ static $_lang = array(); // 空参数返回所有定义 - if (empty($name)) + if (empty($name)) { return $_lang; + } + // 判断语言获取(或设置) // 若不存在,直接返回全大写$name if (is_string($name)) { - $name = strtoupper($name); - if (is_null($value)){ + $name = strtoupper($name); + if (is_null($value)) { return isset($_lang[$name]) ? $_lang[$name] : $name; - }elseif(is_array($value)){ + } elseif (is_array($value)) { // 支持变量 $replace = array_keys($value); - foreach($replace as &$v){ - $v = '{$'.$v.'}'; + foreach ($replace as &$v) { + $v = '{$' . $v . '}'; } - return str_replace($replace,$value,isset($_lang[$name]) ? $_lang[$name] : $name); + return str_replace($replace, $value, isset($_lang[$name]) ? $_lang[$name] : $name); } $_lang[$name] = $value; // 语言定义 return null; } // 批量定义 - if (is_array($name)) + if (is_array($name)) { $_lang = array_merge($_lang, array_change_key_case($name, CASE_UPPER)); + } + return null; } @@ -182,8 +208,9 @@ function L($name=null, $value=null) { * @param boolean $record 是否记录日志 * @return void|array */ -function trace($value='[think]',$label='',$level='DEBUG',$record=false) { - return Think\Think::trace($value,$label,$level,$record); +function trace($value = '[think]', $label = '', $level = 'DEBUG', $record = false) +{ + return Think\Think::trace($value, $label, $level, $record); } /** @@ -191,19 +218,22 @@ function trace($value='[think]',$label='',$level='DEBUG',$record=false) { * @param string $filename 文件名 * @return string */ -function compile($filename) { - $content = php_strip_whitespace($filename); - $content = trim(substr($content, 5)); +function compile($filename) +{ + $content = php_strip_whitespace($filename); + $content = trim(substr($content, 5)); // 替换预编译指令 - $content = preg_replace('/\/\/\[RUNTIME\](.*?)\/\/\[\/RUNTIME\]/s', '', $content); - if(0===strpos($content,'namespace')){ - $content = preg_replace('/namespace\s(.*?);/','namespace \\1{',$content,1); - }else{ - $content = 'namespace {'.$content; - } - if ('?>' == substr($content, -2)) - $content = substr($content, 0, -2); - return $content.'}'; + $content = preg_replace('/\/\/\[RUNTIME\](.*?)\/\/\[\/RUNTIME\]/s', '', $content); + if (0 === strpos($content, 'namespace')) { + $content = preg_replace('/namespace\s(.*?);/', 'namespace \\1{', $content, 1); + } else { + $content = 'namespace {' . $content; + } + if ('?>' == substr($content, -2)) { + $content = substr($content, 0, -2); + } + + return $content . '}'; } /** @@ -212,46 +242,48 @@ function compile($filename) { * @param string $layer 视图层(目录)名称 * @return string */ -function T($template='',$layer=''){ +function T($template = '', $layer = '') +{ // 解析模版资源地址 - if(false === strpos($template,'://')){ - $template = 'http://'.str_replace(':', '/',$template); - } - $info = parse_url($template); - $file = $info['host'].(isset($info['path'])?$info['path']:''); - $module = isset($info['user'])?$info['user'].'/':MODULE_NAME.'/'; - $extend = $info['scheme']; - $layer = $layer?$layer:C('DEFAULT_V_LAYER'); + if (false === strpos($template, '://')) { + $template = 'http://' . str_replace(':', '/', $template); + } + $info = parse_url($template); + $file = $info['host'] . (isset($info['path']) ? $info['path'] : ''); + $module = isset($info['user']) ? $info['user'] . '/' : MODULE_NAME . '/'; + $extend = $info['scheme']; + $layer = $layer ? $layer : C('DEFAULT_V_LAYER'); // 获取当前主题的模版路径 - $auto = C('AUTOLOAD_NAMESPACE'); - if($auto && isset($auto[$extend])){ // 扩展资源 - $baseUrl = $auto[$extend].$module.$layer.'/'; - }elseif(C('VIEW_PATH')){ + $auto = C('AUTOLOAD_NAMESPACE'); + if ($auto && isset($auto[$extend])) { + // 扩展资源 + $baseUrl = $auto[$extend] . $module . $layer . '/'; + } elseif (C('VIEW_PATH')) { // 改变模块视图目录 - $baseUrl = C('VIEW_PATH'); - }elseif(defined('TMPL_PATH')){ + $baseUrl = C('VIEW_PATH'); + } elseif (defined('TMPL_PATH')) { // 指定全局视图目录 - $baseUrl = TMPL_PATH.$module; - }else{ - $baseUrl = APP_PATH.$module.$layer.'/'; + $baseUrl = TMPL_PATH . $module; + } else { + $baseUrl = APP_PATH . $module . $layer . '/'; } // 获取主题 - $theme = substr_count($file,'/')<2 ? C('DEFAULT_THEME') : ''; + $theme = substr_count($file, '/') < 2 ? C('DEFAULT_THEME') : ''; // 分析模板文件规则 - $depr = C('TMPL_FILE_DEPR'); - if('' == $file) { + $depr = C('TMPL_FILE_DEPR'); + if ('' == $file) { // 如果模板文件名为空 按照默认规则定位 $file = CONTROLLER_NAME . $depr . ACTION_NAME; - }elseif(false === strpos($file, '/')){ + } elseif (false === strpos($file, '/')) { $file = CONTROLLER_NAME . $depr . $file; - }elseif('/' != $depr){ - $file = substr_count($file,'/')>1 ? substr_replace($file,$depr,strrpos($file,'/'),1) : str_replace('/', $depr, $file); + } elseif ('/' != $depr) { + $file = substr_count($file, '/') > 1 ? substr_replace($file, $depr, strrpos($file, '/'), 1) : str_replace('/', $depr, $file); } - return $baseUrl.($theme?$theme.'/':'').$file.C('TMPL_TEMPLATE_SUFFIX'); + return $baseUrl . ($theme ? $theme . '/' : '') . $file . C('TMPL_TEMPLATE_SUFFIX'); } /** @@ -268,150 +300,159 @@ function T($template='',$layer=''){ * @param mixed $datas 要获取的额外数据源 * @return mixed */ -function I($name,$default='',$filter=null,$datas=null) { - static $_PUT = null; - if(strpos($name,'/')){ // 指定修饰符 - list($name,$type) = explode('/',$name,2); - }elseif(C('VAR_AUTO_STRING')){ // 默认强制转换为字符串 - $type = 's'; - } - if(strpos($name,'.')) { // 指定参数来源 - list($method,$name) = explode('.',$name,2); - }else{ // 默认为自动判断 - $method = 'param'; - } - switch(strtolower($method)) { - case 'get' : - $input =& $_GET; - break; - case 'post' : - $input =& $_POST; - break; - case 'put' : - if(is_null($_PUT)){ - parse_str(file_get_contents('php://input'), $_PUT); - } - $input = $_PUT; - break; - case 'param' : - switch($_SERVER['REQUEST_METHOD']) { +function I($name, $default = '', $filter = null, $datas = null) +{ + static $_PUT = null; + if (strpos($name, '/')) { + // 指定修饰符 + list($name, $type) = explode('/', $name, 2); + } elseif (C('VAR_AUTO_STRING')) { + // 默认强制转换为字符串 + $type = 's'; + } + if (strpos($name, '.')) { + // 指定参数来源 + list($method, $name) = explode('.', $name, 2); + } else { + // 默认为自动判断 + $method = 'param'; + } + switch (strtolower($method)) { + case 'get': + $input = &$_GET; + break; + case 'post': + $input = &$_POST; + break; + case 'put': + if (is_null($_PUT)) { + parse_str(file_get_contents('php://input'), $_PUT); + } + $input = $_PUT; + break; + case 'param': + switch ($_SERVER['REQUEST_METHOD']) { case 'POST': - $input = $_POST; + $input = $_POST; break; case 'PUT': - if(is_null($_PUT)){ - parse_str(file_get_contents('php://input'), $_PUT); - } - $input = $_PUT; + if (is_null($_PUT)) { + parse_str(file_get_contents('php://input'), $_PUT); + } + $input = $_PUT; break; default: - $input = $_GET; + $input = $_GET; } break; - case 'path' : - $input = array(); - if(!empty($_SERVER['PATH_INFO'])){ - $depr = C('URL_PATHINFO_DEPR'); - $input = explode($depr,trim($_SERVER['PATH_INFO'],$depr)); + case 'path': + $input = array(); + if (!empty($_SERVER['PATH_INFO'])) { + $depr = C('URL_PATHINFO_DEPR'); + $input = explode($depr, trim($_SERVER['PATH_INFO'], $depr)); } break; - case 'request' : - $input =& $_REQUEST; - break; - case 'session' : - $input =& $_SESSION; - break; - case 'cookie' : - $input =& $_COOKIE; - break; - case 'server' : - $input =& $_SERVER; - break; - case 'globals' : - $input =& $GLOBALS; - break; - case 'data' : - $input =& $datas; - break; + case 'request': + $input = &$_REQUEST; + break; + case 'session': + $input = &$_SESSION; + break; + case 'cookie': + $input = &$_COOKIE; + break; + case 'server': + $input = &$_SERVER; + break; + case 'globals': + $input = &$GLOBALS; + break; + case 'data': + $input = &$datas; + break; default: return null; } - if(''==$name) { // 获取全部变量 - $data = $input; - $filters = isset($filter)?$filter:C('DEFAULT_FILTER'); - if($filters) { - if(is_string($filters)){ - $filters = explode(',',$filters); + if ('' == $name) { + // 获取全部变量 + $data = $input; + $filters = isset($filter) ? $filter : C('DEFAULT_FILTER'); + if ($filters) { + if (is_string($filters)) { + $filters = explode(',', $filters); } - foreach($filters as $filter){ - $data = array_map_recursive($filter,$data); // 参数过滤 + foreach ($filters as $filter) { + $data = arrayMapRecursive($filter, $data); // 参数过滤 } } - }elseif(isset($input[$name])) { // 取值操作 - $data = $input[$name]; - $filters = isset($filter)?$filter:C('DEFAULT_FILTER'); - if($filters) { - if(is_string($filters)){ - if(0 === strpos($filters,'/')){ - if(1 !== preg_match($filters,(string)$data)){ + } elseif (isset($input[$name])) { + // 取值操作 + $data = $input[$name]; + $filters = isset($filter) ? $filter : C('DEFAULT_FILTER'); + if ($filters) { + if (is_string($filters)) { + if (0 === strpos($filters, '/')) { + if (1 !== preg_match($filters, (string) $data)) { // 支持正则验证 - return isset($default) ? $default : null; + return isset($default) ? $default : null; } - }else{ - $filters = explode(',',$filters); + } else { + $filters = explode(',', $filters); } - }elseif(is_int($filters)){ - $filters = array($filters); + } elseif (is_int($filters)) { + $filters = array($filters); } - - if(is_array($filters)){ - foreach($filters as $filter){ - if(function_exists($filter)) { - $data = is_array($data) ? array_map_recursive($filter,$data) : $filter($data); // 参数过滤 - }else{ - $data = filter_var($data,is_int($filter) ? $filter : filter_id($filter)); - if(false === $data) { - return isset($default) ? $default : null; + + if (is_array($filters)) { + foreach ($filters as $filter) { + if (function_exists($filter)) { + $data = is_array($data) ? arrayMapRecursive($filter, $data) : $filter($data); // 参数过滤 + } else { + $data = filter_var($data, is_int($filter) ? $filter : filter_id($filter)); + if (false === $data) { + return isset($default) ? $default : null; } } } } } - if(!empty($type)){ - switch(strtolower($type)){ - case 'a': // 数组 - $data = (array)$data; - break; - case 'd': // 数字 - $data = (int)$data; - break; - case 'f': // 浮点 - $data = (float)$data; - break; - case 'b': // 布尔 - $data = (boolean)$data; - break; - case 's': // 字符串 + if (!empty($type)) { + switch (strtolower($type)) { + case 'a': // 数组 + $data = (array) $data; + break; + case 'd': // 数字 + $data = (int) $data; + break; + case 'f': // 浮点 + $data = (float) $data; + break; + case 'b': // 布尔 + $data = (boolean) $data; + break; + case 's': // 字符串 default: - $data = (string)$data; - } + $data = (string) $data; + } } - }else{ // 变量默认值 - $data = isset($default)?$default:null; + } else { + // 变量默认值 + $data = isset($default) ? $default : null; } - is_array($data) && array_walk_recursive($data,'think_filter'); + is_array($data) && array_walk_recursive($data, 'think_filter'); return $data; } -function array_map_recursive($filter, $data) { +function arrayMapRecursive($filter, $data) +{ $result = array(); foreach ($data as $key => $val) { $result[$key] = is_array($val) - ? array_map_recursive($filter, $val) - : call_user_func($filter, $val); + ? arrayMapRecursive($filter, $val) + : call_user_func($filter, $val); } return $result; - } +} /** * 设置和获取统计数据 @@ -427,18 +468,20 @@ function array_map_recursive($filter, $data) { * @param boolean $save 是否保存结果 * @return mixed */ -function N($key, $step=0,$save=false) { - static $_num = array(); +function N($key, $step = 0, $save = false) +{ + static $_num = array(); if (!isset($_num[$key])) { - $_num[$key] = (false !== $save)? S('N_'.$key) : 0; + $_num[$key] = (false !== $save) ? S('N_' . $key) : 0; } - if (empty($step)){ + if (empty($step)) { return $_num[$key]; - }else{ - $_num[$key] = $_num[$key] + (int)$step; + } else { + $_num[$key] = $_num[$key] + (int) $step; } - if(false !== $save){ // 保存结果 - S('N_'.$key,$_num[$key],$save); + if (false !== $save) { + // 保存结果 + S('N_' . $key, $_num[$key], $save); } return null; } @@ -450,9 +493,10 @@ function N($key, $step=0,$save=false) { * @param integer $type 转换类型 * @return string */ -function parse_name($name, $type=0) { +function parseName($name, $type = 0) +{ if ($type) { - return ucfirst(preg_replace_callback('/_([a-zA-Z])/', function($match){return strtoupper($match[1]);}, $name)); + return ucfirst(preg_replace_callback('/_([a-zA-Z])/', function ($match) {return strtoupper($match[1]);}, $name)); } else { return strtolower(trim(preg_replace("/[A-Z]/", "_\\0", $name), "_")); } @@ -463,10 +507,11 @@ function parse_name($name, $type=0) { * @param string $filename 文件地址 * @return boolean */ -function require_cache($filename) { +function requireCache($filename) +{ static $_importFiles = array(); if (!isset($_importFiles[$filename])) { - if (file_exists_case($filename)) { + if (fileExistsCase($filename)) { require $filename; $_importFiles[$filename] = true; } else { @@ -481,11 +526,14 @@ function require_cache($filename) { * @param string $filename 文件地址 * @return boolean */ -function file_exists_case($filename) { +function fileExistsCase($filename) +{ if (is_file($filename)) { if (IS_WIN && APP_DEBUG) { - if (basename(realpath($filename)) != basename($filename)) + if (basename(realpath($filename)) != basename($filename)) { return false; + } + } return true; } @@ -499,36 +547,42 @@ function file_exists_case($filename) { * @param string $ext 导入的文件扩展名 * @return boolean */ -function import($class, $baseUrl = '', $ext=EXT) { +function import($class, $baseUrl = '', $ext = EXT) +{ static $_file = array(); - $class = str_replace(array('.', '#'), array('/', '.'), $class); - if (isset($_file[$class . $baseUrl])) + $class = str_replace(array('.', '#'), array('/', '.'), $class); + if (isset($_file[$class . $baseUrl])) { return true; - else + } else { $_file[$class . $baseUrl] = true; - $class_strut = explode('/', $class); + } + + $class_strut = explode('/', $class); if (empty($baseUrl)) { if ('@' == $class_strut[0] || MODULE_NAME == $class_strut[0]) { //加载当前模块的类库 $baseUrl = MODULE_PATH; $class = substr_replace($class, '', 0, strlen($class_strut[0]) + 1); - }elseif ('Common' == $class_strut[0]) { + } elseif ('Common' == $class_strut[0]) { //加载公共模块的类库 $baseUrl = COMMON_PATH; $class = substr($class, 7); - }elseif (in_array($class_strut[0],array('Think','Org','Behavior','Com','Vendor')) || is_dir(LIB_PATH.$class_strut[0])) { + } elseif (in_array($class_strut[0], array('Think', 'Org', 'Behavior', 'Com', 'Vendor')) || is_dir(LIB_PATH . $class_strut[0])) { // 系统类库包和第三方类库包 $baseUrl = LIB_PATH; - }else { // 加载其他模块的类库 + } else { + // 加载其他模块的类库 $baseUrl = APP_PATH; } } - if (substr($baseUrl, -1) != '/') - $baseUrl .= '/'; - $classfile = $baseUrl . $class . $ext; - if (!class_exists(basename($class),false)) { + if (substr($baseUrl, -1) != '/') { + $baseUrl .= '/'; + } + + $classfile = $baseUrl . $class . $ext; + if (!class_exists(basename($class), false)) { // 如果类不存在 则导入类库文件 - return require_cache($classfile); + return requireCache($classfile); } return null; } @@ -541,21 +595,26 @@ function import($class, $baseUrl = '', $ext=EXT) { * @param string $ext 导入的文件扩展名 * @return void */ -function load($name, $baseUrl='', $ext='.php') { +function load($name, $baseUrl = '', $ext = '.php') +{ $name = str_replace(array('.', '#'), array('/', '.'), $name); if (empty($baseUrl)) { - if (0 === strpos($name, '@/')) {//加载当前模块函数库 - $baseUrl = MODULE_PATH.'Common/'; - $name = substr($name, 2); - } else { //加载其他模块函数库 - $array = explode('/', $name); - $baseUrl = APP_PATH . array_shift($array).'/Common/'; - $name = implode('/',$array); - } - } - if (substr($baseUrl, -1) != '/') - $baseUrl .= '/'; - require_cache($baseUrl . $name . $ext); + if (0 === strpos($name, '@/')) { +//加载当前模块函数库 + $baseUrl = MODULE_PATH . 'Common/'; + $name = substr($name, 2); + } else { + //加载其他模块函数库 + $array = explode('/', $name); + $baseUrl = APP_PATH . array_shift($array) . '/Common/'; + $name = implode('/', $array); + } + } + if (substr($baseUrl, -1) != '/') { + $baseUrl .= '/'; + } + + requireCache($baseUrl . $name . $ext); } /** @@ -565,9 +624,12 @@ function load($name, $baseUrl='', $ext='.php') { * @param string $ext 类库后缀 * @return boolean */ -function vendor($class, $baseUrl = '', $ext='.php') { - if (empty($baseUrl)) +function vendor($class, $baseUrl = '', $ext = '.php') +{ + if (empty($baseUrl)) { $baseUrl = VENDOR_PATH; + } + return import($class, $baseUrl, $ext); } @@ -577,28 +639,34 @@ function vendor($class, $baseUrl = '', $ext='.php') { * @param string $layer 模型层名称 * @return Think\Model */ -function D($name='',$layer='') { - if(empty($name)) return new Think\Model; - static $_model = array(); - $layer = $layer? : C('DEFAULT_M_LAYER'); - if(isset($_model[$name.$layer])) - return $_model[$name.$layer]; - $class = parse_res_name($name,$layer); - if(class_exists($class)) { - $model = new $class(basename($name)); - }elseif(false === strpos($name,'/')){ +function D($name = '', $layer = '') +{ + if (empty($name)) { + return new Think\Model; + } + + static $_model = array(); + $layer = $layer ?: C('DEFAULT_M_LAYER'); + if (isset($_model[$name . $layer])) { + return $_model[$name . $layer]; + } + + $class = parseResName($name, $layer); + if (class_exists($class)) { + $model = new $class(basename($name)); + } elseif (false === strpos($name, '/')) { // 自动加载公共模块下面的模型 - if(!C('APP_USE_NAMESPACE')){ - import('Common/'.$layer.'/'.$class); - }else{ - $class = '\\Common\\'.$layer.'\\'.$name.$layer; + if (!C('APP_USE_NAMESPACE')) { + import('Common/' . $layer . '/' . $class); + } else { + $class = '\\Common\\' . $layer . '\\' . $name . $layer; } - $model = class_exists($class)? new $class($name) : new Think\Model($name); - }else { - Think\Log::record('D方法实例化没找到模型类'.$class,Think\Log::NOTICE); - $model = new Think\Model(basename($name)); + $model = class_exists($class) ? new $class($name) : new Think\Model($name); + } else { + Think\Log::record('D方法实例化没找到模型类' . $class, Think\Log::NOTICE); + $model = new Think\Model(basename($name)); } - $_model[$name.$layer] = $model; + $_model[$name . $layer] = $model; return $model; } @@ -609,16 +677,19 @@ function D($name='',$layer='') { * @param mixed $connection 数据库连接信息 * @return Think\Model */ -function M($name='', $tablePrefix='',$connection='') { - static $_model = array(); - if(strpos($name,':')) { - list($class,$name) = explode(':',$name); - }else{ - $class = 'Think\\Model'; - } - $guid = (is_array($connection)?implode('',$connection):$connection).$tablePrefix . $name . '_' . $class; - if (!isset($_model[$guid])) - $_model[$guid] = new $class($name,$tablePrefix,$connection); +function M($name = '', $tablePrefix = '', $connection = '') +{ + static $_model = array(); + if (strpos($name, ':')) { + list($class, $name) = explode(':', $name); + } else { + $class = 'Think\\Model'; + } + $guid = (is_array($connection) ? implode('', $connection) : $connection) . $tablePrefix . $name . '_' . $class; + if (!isset($_model[$guid])) { + $_model[$guid] = new $class($name, $tablePrefix, $connection); + } + return $_model[$guid]; } @@ -630,32 +701,36 @@ function M($name='', $tablePrefix='',$connection='') { * @param integer $level 控制器层次 * @return string */ -function parse_res_name($name,$layer,$level=1){ - if(strpos($name,'://')) {// 指定扩展资源 - list($extend,$name) = explode('://',$name); - }else{ - $extend = ''; - } - if(strpos($name,'/') && substr_count($name, '/')>=$level){ // 指定模块 - list($module,$name) = explode('/',$name,2); - }else{ - $module = defined('MODULE_NAME') ? MODULE_NAME : '' ; - } - $array = explode('/',$name); - if(!C('APP_USE_NAMESPACE')){ - $class = parse_name($name, 1); - import($module.'/'.$layer.'/'.$class.$layer); - }else{ - $class = $module.'\\'.$layer; - foreach($array as $name){ - $class .= '\\'.parse_name($name, 1); +function parseResName($name, $layer, $level = 1) +{ + if (strpos($name, '://')) { +// 指定扩展资源 + list($extend, $name) = explode('://', $name); + } else { + $extend = ''; + } + if (strpos($name, '/') && substr_count($name, '/') >= $level) { + // 指定模块 + list($module, $name) = explode('/', $name, 2); + } else { + $module = defined('MODULE_NAME') ? MODULE_NAME : ''; + } + $array = explode('/', $name); + if (!C('APP_USE_NAMESPACE')) { + $class = parseName($name, 1); + import($module . '/' . $layer . '/' . $class . $layer); + } else { + $class = $module . '\\' . $layer; + foreach ($array as $name) { + $class .= '\\' . parseName($name, 1); } // 导入资源类库 - if($extend){ // 扩展资源 - $class = $extend.'\\'.$class; + if ($extend) { + // 扩展资源 + $class = $extend . '\\' . $class; } } - return $class.$layer; + return $class . $layer; } /** @@ -664,22 +739,23 @@ function parse_res_name($name,$layer,$level=1){ * @param string $path 控制器命名空间(路径) * @return Think\Controller|false */ -function controller($name,$path=''){ - $layer = C('DEFAULT_C_LAYER'); - if(!C('APP_USE_NAMESPACE')){ - $class = parse_name($name, 1).$layer; - import(MODULE_NAME.'/'.$layer.'/'.$class); - }else{ - $class = ( $path ? basename(ADDON_PATH).'\\'.$path : MODULE_NAME ).'\\'.$layer; - $array = explode('/',$name); - foreach($array as $name){ - $class .= '\\'.parse_name($name, 1); - } - $class .= $layer; - } - if(class_exists($class)) { +function controller($name, $path = '') +{ + $layer = C('DEFAULT_C_LAYER'); + if (!C('APP_USE_NAMESPACE')) { + $class = parseName($name, 1) . $layer; + import(MODULE_NAME . '/' . $layer . '/' . $class); + } else { + $class = ($path ? basename(ADDON_PATH) . '\\' . $path : MODULE_NAME) . '\\' . $layer; + $array = explode('/', $name); + foreach ($array as $name) { + $class .= '\\' . parseName($name, 1); + } + $class .= $layer; + } + if (class_exists($class)) { return new $class(); - }else { + } else { return false; } } @@ -691,24 +767,25 @@ function controller($name,$path=''){ * @param integer $level 控制器层次 * @return Think\Controller|false */ -function A($name,$layer='',$level=0) { +function A($name, $layer = '', $level = 0) +{ static $_action = array(); - $layer = $layer? : C('DEFAULT_C_LAYER'); - $level = $level? : ($layer == C('DEFAULT_C_LAYER')?C('CONTROLLER_LEVEL'):1); - if(isset($_action[$name.$layer])) - return $_action[$name.$layer]; - - $class = parse_res_name($name,$layer,$level); - if(class_exists($class)) { - $action = new $class(); - $_action[$name.$layer] = $action; + $layer = $layer ?: C('DEFAULT_C_LAYER'); + $level = $level ?: (C('DEFAULT_C_LAYER') == $layer ? C('CONTROLLER_LEVEL') : 1); + if (isset($_action[$name . $layer])) { + return $_action[$name . $layer]; + } + + $class = parseResName($name, $layer, $level); + if (class_exists($class)) { + $action = new $class(); + $_action[$name . $layer] = $action; return $action; - }else { + } else { return false; } } - /** * 远程调用控制器的操作方法 URL 参数格式 [资源://][模块/]控制器/操作 * @param string $url 调用地址 @@ -716,17 +793,18 @@ function A($name,$layer='',$level=0) { * @param string $layer 要调用的控制层名称 * @return mixed */ -function R($url,$vars=array(),$layer='') { - $info = pathinfo($url); - $action = $info['basename']; - $module = $info['dirname']; - $class = A($module,$layer); - if($class){ - if(is_string($vars)) { - parse_str($vars,$vars); - } - return call_user_func_array(array(&$class,$action.C('ACTION_SUFFIX')),$vars); - }else{ +function R($url, $vars = array(), $layer = '') +{ + $info = pathinfo($url); + $action = $info['basename']; + $module = $info['dirname']; + $class = A($module, $layer); + if ($class) { + if (is_string($vars)) { + parse_str($vars, $vars); + } + return call_user_func_array(array(&$class, $action . C('ACTION_SUFFIX')), $vars); + } else { return false; } } @@ -737,22 +815,24 @@ function R($url,$vars=array(),$layer='') { * @param mixed $params 传入参数 * @return void */ -function tag($tag, &$params=NULL) { - \Think\Hook::listen($tag,$params); +function tag($tag, &$params = null) +{ + \Think\Hook::listen($tag, $params); } /** * 执行某个行为 * @param string $name 行为名称 - * @param string $tag 标签名称(行为类无需传入) + * @param string $tag 标签名称(行为类无需传入) * @param Mixed $params 传入的参数 * @return void */ -function B($name, $tag='',&$params=NULL) { - if(''==$tag){ - $name .= 'Behavior'; +function B($name, $tag = '', &$params = null) +{ + if ('' == $tag) { + $name .= 'Behavior'; } - return \Think\Hook::exec($name,$tag,$params); + return \Think\Hook::exec($name, $tag, $params); } /** @@ -760,15 +840,16 @@ function B($name, $tag='',&$params=NULL) { * @param string $content 代码内容 * @return string */ -function strip_whitespace($content) { - $stripStr = ''; +function stripWhitespace($content) +{ + $stripStr = ''; //分析php源码 $tokens = token_get_all($content); $last_space = false; for ($i = 0, $j = count($tokens); $i < $j; $i++) { if (is_string($tokens[$i])) { $last_space = false; - $stripStr .= $tokens[$i]; + $stripStr .= $tokens[$i]; } else { switch ($tokens[$i][0]) { //过滤各种PHP注释 @@ -778,7 +859,7 @@ function strip_whitespace($content) { //过滤空格 case T_WHITESPACE: if (!$last_space) { - $stripStr .= ' '; + $stripStr .= ' '; $last_space = true; } break; @@ -787,18 +868,18 @@ function strip_whitespace($content) { break; case T_END_HEREDOC: $stripStr .= "THINK;\n"; - for($k = $i+1; $k < $j; $k++) { - if(is_string($tokens[$k]) && $tokens[$k] == ';') { + for ($k = $i + 1; $k < $j; $k++) { + if (is_string($tokens[$k]) && ';' == $tokens[$k]) { $i = $k; break; - } else if($tokens[$k][0] == T_CLOSE_TAG) { + } else if (T_CLOSE_TAG == $tokens[$k][0]) { break; } } break; default: $last_space = false; - $stripStr .= $tokens[$i][1]; + $stripStr .= $tokens[$i][1]; } } } @@ -812,12 +893,15 @@ function strip_whitespace($content) { * @param integer $code 异常代码 默认为0 * @return void */ -function throw_exception($msg, $type='Think\\Exception', $code=0) { - Think\Log::record('建议使用E方法替代throw_exception',Think\Log::NOTICE); - if (class_exists($type, false)) +function throwException($msg, $type = 'Think\\Exception', $code = 0) +{ + Think\Log::record('建议使用E方法替代throw_exception', Think\Log::NOTICE); + if (class_exists($type, false)) { throw new $type($msg, $code); - else - Think\Think::halt($msg); // 异常类型不存在则输出错误信息字串 + } else { + Think\Think::halt($msg); + } + // 异常类型不存在则输出错误信息字串 } /** @@ -828,8 +912,9 @@ function throw_exception($msg, $type='Think\\Exception', $code=0) { * @param boolean $strict 是否严谨 默认为true * @return void|string */ -function dump($var, $echo=true, $label=null, $strict=true) { - $label = ($label === null) ? '' : rtrim($label) . ' '; +function dump($var, $echo = true, $label = null, $strict = true) +{ + $label = (null === $label) ? '' : rtrim($label) . ' '; if (!$strict) { if (ini_get('html_errors')) { $output = print_r($var, true); @@ -847,10 +932,12 @@ function dump($var, $echo=true, $label=null, $strict=true) { } } if ($echo) { - echo($output); + echo ($output); return null; - }else + } else { return $output; + } + } /** @@ -858,15 +945,18 @@ function dump($var, $echo=true, $label=null, $strict=true) { * @param string|false $layout 布局名称 为false的时候表示关闭布局 * @return void */ -function layout($layout) { - if(false !== $layout) { +function layout($layout) +{ + if (false !== $layout) { // 开启布局 - C('LAYOUT_ON',true); - if(is_string($layout)) { // 设置新的布局模板 - C('LAYOUT_NAME',$layout); + C('LAYOUT_ON', true); + if (is_string($layout)) { + // 设置新的布局模板 + C('LAYOUT_NAME', $layout); } - }else{// 临时关闭布局 - C('LAYOUT_ON',false); + } else { +// 临时关闭布局 + C('LAYOUT_ON', false); } } @@ -878,34 +968,40 @@ function layout($layout) { * @param boolean $domain 是否显示域名 * @return string */ -function U($url='',$vars='',$suffix=true,$domain=false) { +function U($url = '', $vars = '', $suffix = true, $domain = false) +{ // 解析URL - $info = parse_url($url); - $url = !empty($info['path'])?$info['path']:ACTION_NAME; - if(isset($info['fragment'])) { // 解析锚点 - $anchor = $info['fragment']; - if(false !== strpos($anchor,'?')) { // 解析参数 - list($anchor,$info['query']) = explode('?',$anchor,2); - } - if(false !== strpos($anchor,'@')) { // 解析域名 - list($anchor,$host) = explode('@',$anchor, 2); - } - }elseif(false !== strpos($url,'@')) { // 解析域名 - list($url,$host) = explode('@',$info['path'], 2); + $info = parse_url($url); + $url = !empty($info['path']) ? $info['path'] : ACTION_NAME; + if (isset($info['fragment'])) { + // 解析锚点 + $anchor = $info['fragment']; + if (false !== strpos($anchor, '?')) { + // 解析参数 + list($anchor, $info['query']) = explode('?', $anchor, 2); + } + if (false !== strpos($anchor, '@')) { + // 解析域名 + list($anchor, $host) = explode('@', $anchor, 2); + } + } elseif (false !== strpos($url, '@')) { + // 解析域名 + list($url, $host) = explode('@', $info['path'], 2); } // 解析子域名 - if(isset($host)) { - $domain = $host.(strpos($host,'.')?'':strstr($_SERVER['HTTP_HOST'],'.')); - }elseif($domain===true){ + if (isset($host)) { + $domain = $host . (strpos($host, '.') ? '' : strstr($_SERVER['HTTP_HOST'], '.')); + } elseif (true === $domain) { $domain = $_SERVER['HTTP_HOST']; - if(C('APP_SUB_DOMAIN_DEPLOY') ) { // 开启子域名部署 - $domain = $domain=='localhost'?'localhost':'www'.strstr($_SERVER['HTTP_HOST'],'.'); + if (C('APP_SUB_DOMAIN_DEPLOY')) { + // 开启子域名部署 + $domain = 'localhost' == $domain ? 'localhost' : 'www' . strstr($_SERVER['HTTP_HOST'], '.'); // '子域名'=>array('模块[/控制器]'); foreach (C('APP_SUB_DOMAIN_RULES') as $key => $rule) { - $rule = is_array($rule)?$rule[0]:$rule; - if(false === strpos($key,'*') && 0=== strpos($url,$rule)) { - $domain = $key.strstr($domain,'.'); // 生成对应子域名 - $url = substr_replace($url,'',0,strlen($rule)); + $rule = is_array($rule) ? $rule[0] : $rule; + if (false === strpos($key, '*') && 0 === strpos($url, $rule)) { + $domain = $key . strstr($domain, '.'); // 生成对应子域名 + $url = substr_replace($url, '', 0, strlen($rule)); break; } } @@ -913,118 +1009,128 @@ function U($url='',$vars='',$suffix=true,$domain=false) { } // 解析参数 - if(is_string($vars)) { // aaa=1&bbb=2 转换成数组 - parse_str($vars,$vars); - }elseif(!is_array($vars)){ + if (is_string($vars)) { + // aaa=1&bbb=2 转换成数组 + parse_str($vars, $vars); + } elseif (!is_array($vars)) { $vars = array(); } - if(isset($info['query'])) { // 解析地址里面参数 合并到vars - parse_str($info['query'],$params); - $vars = array_merge($params,$vars); + if (isset($info['query'])) { + // 解析地址里面参数 合并到vars + parse_str($info['query'], $params); + $vars = array_merge($params, $vars); } - + // URL组装 - $depr = C('URL_PATHINFO_DEPR'); - $urlCase = C('URL_CASE_INSENSITIVE'); - if($url) { - if(0=== strpos($url,'/')) {// 定义路由 - $route = true; - $url = substr($url,1); - if('/' != $depr) { - $url = str_replace('/',$depr,$url); + $depr = C('URL_PATHINFO_DEPR'); + $urlCase = C('URL_CASE_INSENSITIVE'); + if ($url) { + if (0 === strpos($url, '/')) { +// 定义路由 + $route = true; + $url = substr($url, 1); + if ('/' != $depr) { + $url = str_replace('/', $depr, $url); } - }else{ - if('/' != $depr) { // 安全替换 - $url = str_replace('/',$depr,$url); + } else { + if ('/' != $depr) { + // 安全替换 + $url = str_replace('/', $depr, $url); } // 解析模块、控制器和操作 - $url = trim($url,$depr); - $path = explode($depr,$url); - $var = array(); - $varModule = C('VAR_MODULE'); - $varController = C('VAR_CONTROLLER'); - $varAction = C('VAR_ACTION'); - $var[$varAction] = !empty($path)?array_pop($path):ACTION_NAME; - $var[$varController] = !empty($path)?array_pop($path):CONTROLLER_NAME; - if($maps = C('URL_ACTION_MAP')) { - if(isset($maps[strtolower($var[$varController])])) { - $maps = $maps[strtolower($var[$varController])]; - if($action = array_search(strtolower($var[$varAction]),$maps)){ + $url = trim($url, $depr); + $path = explode($depr, $url); + $var = array(); + $varModule = C('VAR_MODULE'); + $varController = C('VAR_CONTROLLER'); + $varAction = C('VAR_ACTION'); + $var[$varAction] = !empty($path) ? array_pop($path) : ACTION_NAME; + $var[$varController] = !empty($path) ? array_pop($path) : CONTROLLER_NAME; + if ($maps = C('URL_ACTION_MAP')) { + if (isset($maps[strtolower($var[$varController])])) { + $maps = $maps[strtolower($var[$varController])]; + if ($action = array_search(strtolower($var[$varAction]), $maps)) { $var[$varAction] = $action; } } } - if($maps = C('URL_CONTROLLER_MAP')) { - if($controller = array_search(strtolower($var[$varController]),$maps)){ + if ($maps = C('URL_CONTROLLER_MAP')) { + if ($controller = array_search(strtolower($var[$varController]), $maps)) { $var[$varController] = $controller; } } - if($urlCase) { - $var[$varController] = parse_name($var[$varController]); + if ($urlCase) { + $var[$varController] = parseName($var[$varController]); } - $module = ''; - - if(!empty($path)) { - $var[$varModule] = implode($depr,$path); - }else{ - if(C('MULTI_MODULE')) { - if(MODULE_NAME != C('DEFAULT_MODULE') || !C('MODULE_ALLOW_LIST')){ - $var[$varModule]= MODULE_NAME; + $module = ''; + + if (!empty($path)) { + $var[$varModule] = implode($depr, $path); + } else { + if (C('MULTI_MODULE')) { + if (MODULE_NAME != C('DEFAULT_MODULE') || !C('MODULE_ALLOW_LIST')) { + $var[$varModule] = MODULE_NAME; } } } - if($maps = C('URL_MODULE_MAP')) { - if($_module = array_search(strtolower($var[$varModule]),$maps)){ + if ($maps = C('URL_MODULE_MAP')) { + if ($_module = array_search(strtolower($var[$varModule]), $maps)) { $var[$varModule] = $_module; } } - if(isset($var[$varModule])){ - $module = $var[$varModule]; + if (isset($var[$varModule])) { + $module = $var[$varModule]; unset($var[$varModule]); } - + } } - if(C('URL_MODEL') == 0) { // 普通模式URL转换 - $url = __APP__.'?'.C('VAR_MODULE')."={$module}&".http_build_query(array_reverse($var)); - if($urlCase){ - $url = strtolower($url); - } - if(!empty($vars)) { - $vars = http_build_query($vars); - $url .= '&'.$vars; + if (C('URL_MODEL') == 0) { + // 普通模式URL转换 + $url = __APP__ . '?' . C('VAR_MODULE') . "={$module}&" . http_build_query(array_reverse($var)); + if ($urlCase) { + $url = strtolower($url); } - }else{ // PATHINFO模式或者兼容URL模式 - if(isset($route)) { - $url = __APP__.'/'.rtrim($url,$depr); - }else{ - $module = (defined('BIND_MODULE') && BIND_MODULE==$module )? '' : $module; - $url = __APP__.'/'.($module?$module.MODULE_PATHINFO_DEPR:'').implode($depr,array_reverse($var)); + if (!empty($vars)) { + $vars = http_build_query($vars); + $url .= '&' . $vars; } - if($urlCase){ - $url = strtolower($url); + } else { + // PATHINFO模式或者兼容URL模式 + if (isset($route)) { + $url = __APP__ . '/' . rtrim($url, $depr); + } else { + $module = (defined('BIND_MODULE') && BIND_MODULE == $module) ? '' : $module; + $url = __APP__ . '/' . ($module ? $module . MODULE_PATHINFO_DEPR : '') . implode($depr, array_reverse($var)); + } + if ($urlCase) { + $url = strtolower($url); } - if(!empty($vars)) { // 添加参数 - foreach ($vars as $var => $val){ - if('' !== trim($val)) $url .= $depr . $var . $depr . urlencode($val); - } + if (!empty($vars)) { + // 添加参数 + foreach ($vars as $var => $val) { + if ('' !== trim($val)) { + $url .= $depr . $var . $depr . urlencode($val); + } + + } } - if($suffix) { - $suffix = $suffix===true?C('URL_HTML_SUFFIX'):$suffix; - if($pos = strpos($suffix, '|')){ + if ($suffix) { + $suffix = true === $suffix ? C('URL_HTML_SUFFIX') : $suffix; + if ($pos = strpos($suffix, '|')) { $suffix = substr($suffix, 0, $pos); } - if($suffix && '/' != substr($url,-1)){ - $url .= '.'.ltrim($suffix,'.'); + if ($suffix && '/' != substr($url, -1)) { + $url .= '.' . ltrim($suffix, '.'); } } } - if(isset($anchor)){ - $url .= '#'.$anchor; + if (isset($anchor)) { + $url .= '#' . $anchor; } - if($domain) { - $url = (is_ssl()?'https://':'http://').$domain.$url; + if ($domain) { + $url = (isSsl() ? 'https://' : 'http://') . $domain . $url; } return $url; } @@ -1035,18 +1141,20 @@ function U($url='',$vars='',$suffix=true,$domain=false) { * @param array $data 传入的参数 * @return void */ -function W($name, $data=array()) { - return R($name,$data,'Widget'); +function W($name, $data = array()) +{ + return R($name, $data, 'Widget'); } /** * 判断是否SSL协议 * @return boolean */ -function is_ssl() { - if(isset($_SERVER['HTTPS']) && ('1' == $_SERVER['HTTPS'] || 'on' == strtolower($_SERVER['HTTPS']))){ +function isSsl() +{ + if (isset($_SERVER['HTTPS']) && ('1' == $_SERVER['HTTPS'] || 'on' == strtolower($_SERVER['HTTPS']))) { return true; - }elseif(isset($_SERVER['SERVER_PORT']) && ('443' == $_SERVER['SERVER_PORT'] )) { + } elseif (isset($_SERVER['SERVER_PORT']) && ('443' == $_SERVER['SERVER_PORT'])) { return true; } return false; @@ -1059,24 +1167,29 @@ function is_ssl() { * @param string $msg 重定向前的提示信息 * @return void */ -function redirect($url, $time=0, $msg='') { +function redirect($url, $time = 0, $msg = '') +{ //多行URL地址支持 - $url = str_replace(array("\n", "\r"), '', $url); - if (empty($msg)) - $msg = "系统将在{$time}秒之后自动跳转到{$url}!"; + $url = str_replace(array("\n", "\r"), '', $url); + if (empty($msg)) { + $msg = "系统将在{$time}秒之后自动跳转到{$url}!"; + } + if (!headers_sent()) { // redirect if (0 === $time) { header('Location: ' . $url); } else { header("refresh:{$time};url={$url}"); - echo($msg); + echo ($msg); } exit(); } else { - $str = ""; - if ($time != 0) + $str = ""; + if (0 != $time) { $str .= $msg; + } + exit($str); } } @@ -1088,28 +1201,34 @@ function redirect($url, $time=0, $msg='') { * @param mixed $options 缓存参数 * @return mixed */ -function S($name,$value='',$options=null) { - static $cache = ''; - if(is_array($options)){ +function S($name, $value = '', $options = null) +{ + static $cache = ''; + if (is_array($options)) { // 缓存操作的同时初始化 - $type = isset($options['type'])?$options['type']:''; - $cache = Think\Cache::getInstance($type,$options); - }elseif(is_array($name)) { // 缓存初始化 - $type = isset($name['type'])?$name['type']:''; - $cache = Think\Cache::getInstance($type,$name); + $type = isset($options['type']) ? $options['type'] : ''; + $cache = Think\Cache::getInstance($type, $options); + } elseif (is_array($name)) { + // 缓存初始化 + $type = isset($name['type']) ? $name['type'] : ''; + $cache = Think\Cache::getInstance($type, $name); return $cache; - }elseif(empty($cache)) { // 自动初始化 - $cache = Think\Cache::getInstance(); + } elseif (empty($cache)) { + // 自动初始化 + $cache = Think\Cache::getInstance(); } - if(''=== $value){ // 获取缓存 + if ('' === $value) { + // 获取缓存 return $cache->get($name); - }elseif(is_null($value)) { // 删除缓存 + } elseif (is_null($value)) { + // 删除缓存 return $cache->rm($name); - }else { // 缓存数据 - if(is_array($options)) { - $expire = isset($options['expire'])?$options['expire']:NULL; - }else{ - $expire = is_numeric($options)?$options:NULL; + } else { + // 缓存数据 + if (is_array($options)) { + $expire = isset($options['expire']) ? $options['expire'] : null; + } else { + $expire = is_numeric($options) ? $options : null; } return $cache->set($name, $value, $expire); } @@ -1122,33 +1241,36 @@ function S($name,$value='',$options=null) { * @param string $path 缓存路径 * @return mixed */ -function F($name, $value='', $path=DATA_PATH) { - static $_cache = array(); - $filename = $path . $name . '.php'; +function F($name, $value = '', $path = DATA_PATH) +{ + static $_cache = array(); + $filename = $path . $name . '.php'; if ('' !== $value) { if (is_null($value)) { // 删除缓存 - if(false !== strpos($name,'*')){ - return false; // TODO - }else{ + if (false !== strpos($name, '*')) { + return false; // TODO + } else { unset($_cache[$name]); - return Think\Storage::unlink($filename,'F'); + return Think\Storage::unlink($filename, 'F'); } } else { - Think\Storage::put($filename,serialize($value),'F'); + Think\Storage::put($filename, serialize($value), 'F'); // 缓存数据 - $_cache[$name] = $value; + $_cache[$name] = $value; return null; } } // 获取缓存数据 - if (isset($_cache[$name])) + if (isset($_cache[$name])) { return $_cache[$name]; - if (Think\Storage::has($filename,'F')){ - $value = unserialize(Think\Storage::read($filename,'F')); - $_cache[$name] = $value; + } + + if (Think\Storage::has($filename, 'F')) { + $value = unserialize(Think\Storage::read($filename, 'F')); + $_cache[$name] = $value; } else { - $value = false; + $value = false; } return $value; } @@ -1158,7 +1280,8 @@ function F($name, $value='', $path=DATA_PATH) { * @param mixed $mix 变量 * @return string */ -function to_guid_string($mix) { +function toGuidString($mix) +{ if (is_object($mix)) { return spl_object_hash($mix); } elseif (is_resource($mix)) { @@ -1179,20 +1302,21 @@ function to_guid_string($mix) { * @param string $encoding 数据编码 * @return string */ -function xml_encode($data, $root='think', $item='item', $attr='', $id='id', $encoding='utf-8') { - if(is_array($attr)){ +function xmlEncode($data, $root = 'think', $item = 'item', $attr = '', $id = 'id', $encoding = 'utf-8') +{ + if (is_array($attr)) { $_attr = array(); foreach ($attr as $key => $value) { $_attr[] = "{$key}=\"{$value}\""; } $attr = implode(' ', $_attr); } - $attr = trim($attr); - $attr = empty($attr) ? '' : " {$attr}"; - $xml = ""; - $xml .= "<{$root}{$attr}>"; - $xml .= data_to_xml($data, $item, $id); - $xml .= ""; + $attr = trim($attr); + $attr = empty($attr) ? '' : " {$attr}"; + $xml = ""; + $xml .= "<{$root}{$attr}>"; + $xml .= dataToXml($data, $item, $id); + $xml .= ""; return $xml; } @@ -1203,16 +1327,17 @@ function xml_encode($data, $root='think', $item='item', $attr='', $id='id', $enc * @param string $id 数字索引key转换为的属性名 * @return string */ -function data_to_xml($data, $item='item', $id='id') { +function dataToXml($data, $item = 'item', $id = 'id') +{ $xml = $attr = ''; foreach ($data as $key => $val) { - if(is_numeric($key)){ + if (is_numeric($key)) { $id && $attr = " {$id}=\"{$key}\""; - $key = $item; + $key = $item; } - $xml .= "<{$key}{$attr}>"; - $xml .= (is_array($val) || is_object($val)) ? data_to_xml($val, $item, $id) : $val; - $xml .= ""; + $xml .= "<{$key}{$attr}>"; + $xml .= (is_array($val) || is_object($val)) ? dataToXml($val, $item, $id) : $val; + $xml .= ""; } return $xml; } @@ -1223,119 +1348,163 @@ function data_to_xml($data, $item='item', $id='id') { * @param mixed $value session值 * @return mixed */ -function session($name='',$value='') { - $prefix = C('SESSION_PREFIX'); - if(is_array($name)) { // session初始化 在session_start 之前调用 - if(isset($name['prefix'])) C('SESSION_PREFIX',$name['prefix']); - if(C('VAR_SESSION_ID') && isset($_REQUEST[C('VAR_SESSION_ID')])){ +function session($name = '', $value = '') +{ + $prefix = C('SESSION_PREFIX'); + if (is_array($name)) { + // session初始化 在session_start 之前调用 + if (isset($name['prefix'])) { + C('SESSION_PREFIX', $name['prefix']); + } + + if (C('VAR_SESSION_ID') && isset($_REQUEST[C('VAR_SESSION_ID')])) { session_id($_REQUEST[C('VAR_SESSION_ID')]); - }elseif(isset($name['id'])) { + } elseif (isset($name['id'])) { session_id($name['id']); } - if('common' == APP_MODE){ // 其它模式可能不支持 + if ('common' == APP_MODE) { + // 其它模式可能不支持 ini_set('session.auto_start', 0); } - if(isset($name['name'])) session_name($name['name']); - if(isset($name['path'])) session_save_path($name['path']); - if(isset($name['domain'])) ini_set('session.cookie_domain', $name['domain']); - if(isset($name['expire'])) { - ini_set('session.gc_maxlifetime', $name['expire']); - ini_set('session.cookie_lifetime', $name['expire']); - } - if(isset($name['use_trans_sid'])) ini_set('session.use_trans_sid', $name['use_trans_sid']?1:0); - if(isset($name['use_cookies'])) ini_set('session.use_cookies', $name['use_cookies']?1:0); - if(isset($name['cache_limiter'])) session_cache_limiter($name['cache_limiter']); - if(isset($name['cache_expire'])) session_cache_expire($name['cache_expire']); - if(isset($name['type'])) C('SESSION_TYPE',$name['type']); - if(C('SESSION_TYPE')) { // 读取session驱动 - $type = C('SESSION_TYPE'); - $class = strpos($type,'\\')? $type : 'Think\\Session\\Driver\\'. ucwords(strtolower($type)); - $hander = new $class(); + if (isset($name['name'])) { + session_name($name['name']); + } + + if (isset($name['path'])) { + session_save_path($name['path']); + } + + if (isset($name['domain'])) { + ini_set('session.cookie_domain', $name['domain']); + } + + if (isset($name['expire'])) { + ini_set('session.gc_maxlifetime', $name['expire']); + ini_set('session.cookie_lifetime', $name['expire']); + } + if (isset($name['use_trans_sid'])) { + ini_set('session.use_trans_sid', $name['use_trans_sid'] ? 1 : 0); + } + + if (isset($name['use_cookies'])) { + ini_set('session.use_cookies', $name['use_cookies'] ? 1 : 0); + } + + if (isset($name['cache_limiter'])) { + session_cache_limiter($name['cache_limiter']); + } + + if (isset($name['cache_expire'])) { + session_cache_expire($name['cache_expire']); + } + + if (isset($name['type'])) { + C('SESSION_TYPE', $name['type']); + } + + if (C('SESSION_TYPE')) { + // 读取session驱动 + $type = C('SESSION_TYPE'); + $class = strpos($type, '\\') ? $type : 'Think\\Session\\Driver\\' . ucwords(strtolower($type)); + $hander = new $class(); session_set_save_handler( - array(&$hander,"open"), - array(&$hander,"close"), - array(&$hander,"read"), - array(&$hander,"write"), - array(&$hander,"destroy"), - array(&$hander,"gc")); + array(&$hander, "open"), + array(&$hander, "close"), + array(&$hander, "read"), + array(&$hander, "write"), + array(&$hander, "destroy"), + array(&$hander, "gc")); } // 启动session - if(C('SESSION_AUTO_START')) session_start(); - }elseif('' === $value){ - if(''===$name){ + if (C('SESSION_AUTO_START')) { + session_start(); + } + + } elseif ('' === $value) { + if ('' === $name) { // 获取全部的session return $prefix ? $_SESSION[$prefix] : $_SESSION; - }elseif(0===strpos($name,'[')) { // session 操作 - if('[pause]'==$name){ // 暂停session + } elseif (0 === strpos($name, '[')) { + // session 操作 + if ('[pause]' == $name) { // 暂停session session_write_close(); - }elseif('[start]'==$name){ // 启动session + } elseif ('[start]' == $name) { + // 启动session session_start(); - }elseif('[destroy]'==$name){ // 销毁session - $_SESSION = array(); + } elseif ('[destroy]' == $name) { + // 销毁session + $_SESSION = array(); session_unset(); session_destroy(); - }elseif('[regenerate]'==$name){ // 重新生成id + } elseif ('[regenerate]' == $name) { + // 重新生成id session_regenerate_id(); } - }elseif(0===strpos($name,'?')){ // 检查session - $name = substr($name,1); - if(strpos($name,'.')){ // 支持数组 - list($name1,$name2) = explode('.',$name); - return $prefix?isset($_SESSION[$prefix][$name1][$name2]):isset($_SESSION[$name1][$name2]); - }else{ - return $prefix?isset($_SESSION[$prefix][$name]):isset($_SESSION[$name]); + } elseif (0 === strpos($name, '?')) { + // 检查session + $name = substr($name, 1); + if (strpos($name, '.')) { + // 支持数组 + list($name1, $name2) = explode('.', $name); + return $prefix ? isset($_SESSION[$prefix][$name1][$name2]) : isset($_SESSION[$name1][$name2]); + } else { + return $prefix ? isset($_SESSION[$prefix][$name]) : isset($_SESSION[$name]); } - }elseif(is_null($name)){ // 清空session - if($prefix) { + } elseif (is_null($name)) { + // 清空session + if ($prefix) { unset($_SESSION[$prefix]); - }else{ + } else { $_SESSION = array(); } - }elseif($prefix){ // 获取session - if(strpos($name,'.')){ - list($name1,$name2) = explode('.',$name); - return isset($_SESSION[$prefix][$name1][$name2])?$_SESSION[$prefix][$name1][$name2]:null; - }else{ - return isset($_SESSION[$prefix][$name])?$_SESSION[$prefix][$name]:null; - } - }else{ - if(strpos($name,'.')){ - list($name1,$name2) = explode('.',$name); - return isset($_SESSION[$name1][$name2])?$_SESSION[$name1][$name2]:null; - }else{ - return isset($_SESSION[$name])?$_SESSION[$name]:null; - } - } - }elseif(is_null($value)){ // 删除session - if(strpos($name,'.')){ - list($name1,$name2) = explode('.',$name); - if($prefix){ + } elseif ($prefix) { + // 获取session + if (strpos($name, '.')) { + list($name1, $name2) = explode('.', $name); + return isset($_SESSION[$prefix][$name1][$name2]) ? $_SESSION[$prefix][$name1][$name2] : null; + } else { + return isset($_SESSION[$prefix][$name]) ? $_SESSION[$prefix][$name] : null; + } + } else { + if (strpos($name, '.')) { + list($name1, $name2) = explode('.', $name); + return isset($_SESSION[$name1][$name2]) ? $_SESSION[$name1][$name2] : null; + } else { + return isset($_SESSION[$name]) ? $_SESSION[$name] : null; + } + } + } elseif (is_null($value)) { + // 删除session + if (strpos($name, '.')) { + list($name1, $name2) = explode('.', $name); + if ($prefix) { unset($_SESSION[$prefix][$name1][$name2]); - }else{ + } else { unset($_SESSION[$name1][$name2]); } - }else{ - if($prefix){ + } else { + if ($prefix) { unset($_SESSION[$prefix][$name]); - }else{ + } else { unset($_SESSION[$name]); } } - }else{ // 设置session - if(strpos($name,'.')){ - list($name1,$name2) = explode('.',$name); - if($prefix){ - $_SESSION[$prefix][$name1][$name2] = $value; - }else{ - $_SESSION[$name1][$name2] = $value; - } - }else{ - if($prefix){ - $_SESSION[$prefix][$name] = $value; - }else{ - $_SESSION[$name] = $value; - } - } + } else { + // 设置session + if (strpos($name, '.')) { + list($name1, $name2) = explode('.', $name); + if ($prefix) { + $_SESSION[$prefix][$name1][$name2] = $value; + } else { + $_SESSION[$name1][$name2] = $value; + } + } else { + if ($prefix) { + $_SESSION[$prefix][$name] = $value; + } else { + $_SESSION[$name] = $value; + } + } } return null; } @@ -1347,70 +1516,76 @@ function session($name='',$value='') { * @param mixed $option cookie参数 * @return mixed */ -function cookie($name='', $value='', $option=null) { +function cookie($name = '', $value = '', $option = null) +{ // 默认设置 $config = array( - 'prefix' => C('COOKIE_PREFIX'), // cookie 名称前缀 - 'expire' => C('COOKIE_EXPIRE'), // cookie 保存时间 - 'path' => C('COOKIE_PATH'), // cookie 保存路径 - 'domain' => C('COOKIE_DOMAIN'), // cookie 有效域名 - 'secure' => C('COOKIE_SECURE'), // cookie 启用安全传输 - 'httponly' => C('COOKIE_HTTPONLY'), // httponly设置 + 'prefix' => C('COOKIE_PREFIX'), // cookie 名称前缀 + 'expire' => C('COOKIE_EXPIRE'), // cookie 保存时间 + 'path' => C('COOKIE_PATH'), // cookie 保存路径 + 'domain' => C('COOKIE_DOMAIN'), // cookie 有效域名 + 'secure' => C('COOKIE_SECURE'), // cookie 启用安全传输 + 'httponly' => C('COOKIE_HTTPONLY'), // httponly设置 ); // 参数设置(会覆盖黙认设置) if (!is_null($option)) { - if (is_numeric($option)) + if (is_numeric($option)) { $option = array('expire' => $option); - elseif (is_string($option)) + } elseif (is_string($option)) { parse_str($option, $option); - $config = array_merge($config, array_change_key_case($option)); + } + + $config = array_merge($config, array_change_key_case($option)); } - if(!empty($config['httponly'])){ + if (!empty($config['httponly'])) { ini_set("session.cookie_httponly", 1); } // 清除指定前缀的所有cookie if (is_null($name)) { - if (empty($_COOKIE)) + if (empty($_COOKIE)) { return null; + } + // 要删除的cookie前缀,不指定则删除config设置的指定前缀 $prefix = empty($value) ? $config['prefix'] : $value; - if (!empty($prefix)) {// 如果前缀为空字符串将不作处理直接返回 + if (!empty($prefix)) { +// 如果前缀为空字符串将不作处理直接返回 foreach ($_COOKIE as $key => $val) { if (0 === stripos($key, $prefix)) { - setcookie($key, '', time() - 3600, $config['path'], $config['domain'],$config['secure'],$config['httponly']); + setcookie($key, '', time() - 3600, $config['path'], $config['domain'], $config['secure'], $config['httponly']); unset($_COOKIE[$key]); } } } return null; - }elseif('' === $name){ + } elseif ('' === $name) { // 获取全部的cookie return $_COOKIE; } $name = $config['prefix'] . str_replace('.', '_', $name); if ('' === $value) { - if(isset($_COOKIE[$name])){ - $value = $_COOKIE[$name]; - if(0===strpos($value,'think:')){ - $value = substr($value,6); - return array_map('urldecode',json_decode(MAGIC_QUOTES_GPC?stripslashes($value):$value,true)); - }else{ + if (isset($_COOKIE[$name])) { + $value = $_COOKIE[$name]; + if (0 === strpos($value, 'think:')) { + $value = substr($value, 6); + return array_map('urldecode', json_decode(MAGIC_QUOTES_GPC ? stripslashes($value) : $value, true)); + } else { return $value; } - }else{ + } else { return null; } } else { if (is_null($value)) { - setcookie($name, '', time() - 3600, $config['path'], $config['domain'],$config['secure'],$config['httponly']); + setcookie($name, '', time() - 3600, $config['path'], $config['domain'], $config['secure'], $config['httponly']); unset($_COOKIE[$name]); // 删除指定cookie } else { // 设置cookie - if(is_array($value)){ - $value = 'think:'.json_encode(array_map('urlencode',$value)); + if (is_array($value)) { + $value = 'think:' . json_encode(array_map('urlencode', $value)); } $expire = !empty($config['expire']) ? time() + intval($config['expire']) : 0; - setcookie($name, $value, $expire, $config['path'], $config['domain'],$config['secure'],$config['httponly']); + setcookie($name, $value, $expire, $config['path'], $config['domain'], $config['secure'], $config['httponly']); $_COOKIE[$name] = $value; } } @@ -1422,22 +1597,29 @@ function cookie($name='', $value='', $option=null) { * @var string $path 文件路径 * @return void */ -function load_ext_file($path) { +function loadExtFile($path) +{ // 加载自定义外部文件 - if($files = C('LOAD_EXT_FILE')) { - $files = explode(',',$files); - foreach ($files as $file){ - $file = $path.'Common/'.$file.'.php'; - if(is_file($file)) include $file; + if ($files = C('LOAD_EXT_FILE')) { + $files = explode(',', $files); + foreach ($files as $file) { + $file = $path . 'Common/' . $file . '.php'; + if (is_file($file)) { + include $file; + } + } } // 加载自定义的动态配置文件 - if($configs = C('LOAD_EXT_CONFIG')) { - if(is_string($configs)) $configs = explode(',',$configs); - foreach ($configs as $key=>$config){ - $file = is_file($config)? $config : $path.'Conf/'.$config.CONF_EXT; - if(is_file($file)) { - is_numeric($key)?C(load_config($file)):C($key,load_config($file)); + if ($configs = C('LOAD_EXT_CONFIG')) { + if (is_string($configs)) { + $configs = explode(',', $configs); + } + + foreach ($configs as $key => $config) { + $file = is_file($config) ? $config : $path . 'Conf/' . $config . CONF_EXT; + if (is_file($file)) { + is_numeric($key) ? C(loadConfig($file)) : C($key, loadConfig($file)); } } } @@ -1446,29 +1628,36 @@ function load_ext_file($path) { /** * 获取客户端IP地址 * @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字 - * @param boolean $adv 是否进行高级模式获取(有可能被伪装) + * @param boolean $adv 是否进行高级模式获取(有可能被伪装) * @return mixed */ -function get_client_ip($type = 0,$adv=false) { - $type = $type ? 1 : 0; - static $ip = NULL; - if ($ip !== NULL) return $ip[$type]; - if($adv){ +function getClientIp($type = 0, $adv = false) +{ + $type = $type ? 1 : 0; + static $ip = null; + if (null !== $ip) { + return $ip[$type]; + } + + if ($adv) { if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { - $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); - $pos = array_search('unknown',$arr); - if(false !== $pos) unset($arr[$pos]); - $ip = trim($arr[0]); - }elseif (isset($_SERVER['HTTP_CLIENT_IP'])) { - $ip = $_SERVER['HTTP_CLIENT_IP']; - }elseif (isset($_SERVER['REMOTE_ADDR'])) { - $ip = $_SERVER['REMOTE_ADDR']; - } - }elseif (isset($_SERVER['REMOTE_ADDR'])) { - $ip = $_SERVER['REMOTE_ADDR']; + $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); + $pos = array_search('unknown', $arr); + if (false !== $pos) { + unset($arr[$pos]); + } + + $ip = trim($arr[0]); + } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) { + $ip = $_SERVER['HTTP_CLIENT_IP']; + } elseif (isset($_SERVER['REMOTE_ADDR'])) { + $ip = $_SERVER['REMOTE_ADDR']; + } + } elseif (isset($_SERVER['REMOTE_ADDR'])) { + $ip = $_SERVER['REMOTE_ADDR']; } // IP地址合法验证 - $long = sprintf("%u",ip2long($ip)); + $long = sprintf("%u", ip2long($ip)); $ip = $long ? array($ip, $long) : array('0.0.0.0', 0); return $ip[$type]; } @@ -1478,73 +1667,76 @@ function get_client_ip($type = 0,$adv=false) { * @param integer $code 状态码 * @return void */ -function send_http_status($code) { +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' + // 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]); + if (isset($_status[$code])) { + header('HTTP/1.1 ' . $code . ' ' . $_status[$code]); // 确保FastCGI模式下正常 - header('Status:'.$code.' '.$_status[$code]); + header('Status:' . $code . ' ' . $_status[$code]); } } -function think_filter(&$value){ - // TODO 其他安全过滤 +function thinkFilter(&$value) +{ + // TODO 其他安全过滤 - // 过滤查询特殊字符 - if(preg_match('/^(EXP|NEQ|GT|EGT|LT|ELT|OR|XOR|LIKE|NOTLIKE|NOT BETWEEN|NOTBETWEEN|BETWEEN|NOTIN|NOT IN|IN)$/i',$value)){ + // 过滤查询特殊字符 + if (preg_match('/^(EXP|NEQ|GT|EGT|LT|ELT|OR|XOR|LIKE|NOTLIKE|NOT BETWEEN|NOTBETWEEN|BETWEEN|NOTIN|NOT IN|IN)$/i', $value)) { $value .= ' '; } } // 不区分大小写的in_array实现 -function in_array_case($value,$array){ - return in_array(strtolower($value),array_map('strtolower',$array)); +function inArrayCase($value, $array) +{ + return in_array(strtolower($value), array_map('strtolower', $array)); } diff --git a/ThinkPHP/Conf/convention.php b/ThinkPHP/Conf/convention.php index 7126042df..eedfd7ffb 100644 --- a/ThinkPHP/Conf/convention.php +++ b/ThinkPHP/Conf/convention.php @@ -15,153 +15,153 @@ * 配置名称大小写任意,系统会统一转换成小写 * 所有配置参数都可以在生效前动态改变 */ -defined('THINK_PATH') or exit(); -return array( + +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后有效 + '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设置 + '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函数... + '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' => '', // 指定从服务器序号 + '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, // 子目录缓存级别 + '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, // 每个级别的错误信息 最大记录数 + '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, // 是否记录异常信息日志 + '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 前缀 + '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_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 + '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' => '', // 需要额外加载的标签库(须指定标签库名称),多个以逗号分隔 - + 'TAGLIB_BEGIN' => '<', // 标签库标签开始标记 + 'TAGLIB_END' => '>', // 标签库标签结束标记 + 'TAGLIB_LOAD' => true, // 是否使用内置标签库之外的其它标签库,默认自动检测 + 'TAGLIB_BUILD_IN' => 'cx', // 内置标签库名称(标签使用不必指定标签库名称),以逗号分隔 注意解析顺序 + 'TAGLIB_PRE_LOAD' => '', // 需要额外加载的标签库(须指定标签库名称),多个以逗号分隔 + /* URL设置 */ - 'URL_CASE_INSENSITIVE' => true, // 默true 表示URL不区分大小写 false则表示区分大小写 - 'URL_MODEL' => 1, // URL访问模式,可选参数0、1、2、3,代表以下四种模式: + 'URL_CASE_INSENSITIVE' => true, // 默true 表示URL不区分大小写 false则表示区分大小写 + '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映射定义规则 + '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, // 输入变量是否自动强制转换为字符串 如果开启则数组变量需要手动传入变量修饰符获取变量 + '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', // 数据加密方式 + 'HTTP_CACHE_CONTROL' => 'private', // 网页缓存控制 + 'CHECK_APP_DIR' => true, // 是否检查应用目录是否创建 + 'FILE_UPLOAD_TYPE' => 'Local', // 文件上传方式 + 'DATA_CRYPT_TYPE' => 'Think', // 数据加密方式 ); diff --git a/ThinkPHP/Conf/debug.php b/ThinkPHP/Conf/debug.php index 71656a929..39957ced8 100644 --- a/ThinkPHP/Conf/debug.php +++ b/ThinkPHP/Conf/debug.php @@ -12,16 +12,16 @@ /** * 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区分大小写 +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区分大小写 ); diff --git a/ThinkPHP/Lang/en-us.php b/ThinkPHP/Lang/en-us.php index 706b9dafc..bc29609b1 100644 --- a/ThinkPHP/Lang/en-us.php +++ b/ThinkPHP/Lang/en-us.php @@ -13,9 +13,9 @@ * ThinkPHP English language package */ return array( - /* core language package */ + /* core language package */ '_MODULE_NOT_EXIST_' => "Module can't be loaded", - '_CONTROLLER_NOT_EXIST_' => "Controller 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", @@ -32,7 +32,7 @@ '_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', + '_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', @@ -47,5 +47,5 @@ '_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', + '_ERROR_QUERY_EXPRESS_' => 'Query express error', ); diff --git a/ThinkPHP/Lang/pt-br.php b/ThinkPHP/Lang/pt-br.php index e0ef3fac1..0569a0371 100644 --- a/ThinkPHP/Lang/pt-br.php +++ b/ThinkPHP/Lang/pt-br.php @@ -13,7 +13,7 @@ * ThinkPHP Portuguese language package */ return array( - /* core language package */ + /* 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', @@ -32,7 +32,7 @@ '_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', + '_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', @@ -47,5 +47,5 @@ '_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', + '_ERROR_QUERY_EXPRESS_' => 'Erros na expressão da query', ); diff --git a/ThinkPHP/Lang/zh-cn.php b/ThinkPHP/Lang/zh-cn.php index 57ef25bc6..355b0c711 100644 --- a/ThinkPHP/Lang/zh-cn.php +++ b/ThinkPHP/Lang/zh-cn.php @@ -13,9 +13,9 @@ * ThinkPHP 简体中文语言包 */ return array( - /* 核心语言变量 */ + /* 核心语言变量 */ '_MODULE_NOT_EXIST_' => '无法加载模块', - '_CONTROLLER_NOT_EXIST_' => '无法加载控制器', + '_CONTROLLER_NOT_EXIST_' => '无法加载控制器', '_ERROR_ACTION_' => '非法操作', '_LANGUAGE_NOT_LOAD_' => '无法加载语言包', '_TEMPLATE_NOT_EXIST_' => '模板不存在', @@ -32,7 +32,7 @@ '_NO_DB_CONFIG_' => '没有定义数据库配置', '_NOT_SUPPORT_' => '系统不支持', '_CACHE_TYPE_INVALID_' => '无法加载缓存类型', - '_FILE_NOT_WRITABLE_' => '目录(文件)不可写', + '_FILE_NOT_WRITABLE_' => '目录(文件)不可写', '_METHOD_NOT_EXIST_' => '方法不存在!', '_CLASS_NOT_EXIST_' => '实例化一个不存在的类!', '_CLASS_CONFLICT_' => '类名冲突', diff --git a/ThinkPHP/Lang/zh-tw.php b/ThinkPHP/Lang/zh-tw.php index 327f3349c..fc928f62e 100644 --- a/ThinkPHP/Lang/zh-tw.php +++ b/ThinkPHP/Lang/zh-tw.php @@ -13,7 +13,7 @@ * ThinkPHP 繁体中文語言包 */ return array( - /* 核心語言變數 */ + /* 核心語言變數 */ '_MODULE_NOT_EXIST_' => '無法載入模組', '_CONTROLLER_NOT_EXIST_' => '無法載入控制器', '_ERROR_ACTION_' => '非法操作', @@ -32,7 +32,7 @@ '_NO_DB_CONFIG_' => '沒有定義資料庫設定', '_NOT_SUPPORT_' => '系統不支援', '_CACHE_TYPE_INVALID_' => '無法載入快取類型', - '_FILE_NOT_WRITABLE_' => '目錄(檔案)不可寫', + '_FILE_NOT_WRITABLE_' => '目錄(檔案)不可寫', '_METHOD_NOT_EXIST_' => '方法不存在!', '_CLASS_NOT_EXIST_' => '實例化一個不存在的類別!', '_CLASS_CONFLICT_' => '類別名稱衝突', @@ -47,5 +47,5 @@ '_RECORD_HAS_UPDATE_' => '記錄已經更新', '_NOT_ALLOW_PHP_' => '模板禁用PHP代碼', '_PARAM_ERROR_' => '參數錯誤或者未定義', - '_ERROR_QUERY_EXPRESS_' => '錯誤的查詢條件', + '_ERROR_QUERY_EXPRESS_' => '錯誤的查詢條件', ); diff --git a/ThinkPHP/Library/Behavior/AgentCheckBehavior.class.php b/ThinkPHP/Library/Behavior/AgentCheckBehavior.class.php index 77c271b40..f663d7fbe 100644 --- a/ThinkPHP/Library/Behavior/AgentCheckBehavior.class.php +++ b/ThinkPHP/Library/Behavior/AgentCheckBehavior.class.php @@ -9,14 +9,17 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Behavior; + /** * 行为扩展:代理检测 */ -class AgentCheckBehavior { - public function run(&$params) { +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'])) { + $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'); } diff --git a/ThinkPHP/Library/Behavior/BorisBehavior.class.php b/ThinkPHP/Library/Behavior/BorisBehavior.class.php index 714374680..840b914eb 100644 --- a/ThinkPHP/Library/Behavior/BorisBehavior.class.php +++ b/ThinkPHP/Library/Behavior/BorisBehavior.class.php @@ -9,31 +9,37 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Behavior; + use Think\Think; + /** * Boris行为扩展 */ -class BorisBehavior { - public function run(&$params) { - if(IS_CLI){ - if(!function_exists('pcntl_signal')) +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\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(); + $boris = new \Boris\Boris(">>> "); + $config = new \Boris\Config(); $config->apply($boris, true); - $options = new \Boris\CLIOptionsHandler(); + $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(); diff --git a/ThinkPHP/Library/Behavior/BrowserCheckBehavior.class.php b/ThinkPHP/Library/Behavior/BrowserCheckBehavior.class.php index b1ed89623..f55549711 100644 --- a/ThinkPHP/Library/Behavior/BrowserCheckBehavior.class.php +++ b/ThinkPHP/Library/Behavior/BrowserCheckBehavior.class.php @@ -9,26 +9,29 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Behavior; + /** * 浏览器防刷新检测 */ -class BrowserCheckBehavior { - public function run(&$params) { - if($_SERVER['REQUEST_METHOD'] == 'GET') { - // 启用页面防刷新机制 - $guid = md5($_SERVER['PHP_SELF']); +class BrowserCheckBehavior +{ + public function run(&$params) + { + if ('GET' == $_SERVER['REQUEST_METHOD']) { + // 启用页面防刷新机制 + $guid = md5($_SERVER['PHP_SELF']); // 浏览器防刷新的时间间隔(秒) 默认为10 - $refleshTime = C('LIMIT_REFLESH_TIMES',null,10); + $refleshTime = C('LIMIT_REFLESH_TIMES', null, 10); // 检查页面刷新间隔 - if(cookie('_last_visit_time_'.$guid) && cookie('_last_visit_time_'.$guid)>time()-$refleshTime) { + if (cookie('_last_visit_time_' . $guid) && cookie('_last_visit_time_' . $guid) > time() - $refleshTime) { // 页面刷新读取浏览器缓存 header('HTTP/1.1 304 Not Modified'); exit; - }else{ + } else { // 缓存当前地址访问时间 - cookie('_last_visit_time_'.$guid, $_SERVER['REQUEST_TIME']); + 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'); } } } -} \ No newline at end of file +} diff --git a/ThinkPHP/Library/Behavior/BuildLiteBehavior.class.php b/ThinkPHP/Library/Behavior/BuildLiteBehavior.class.php index 5b8f9b818..294c27d38 100644 --- a/ThinkPHP/Library/Behavior/BuildLiteBehavior.class.php +++ b/ThinkPHP/Library/Behavior/BuildLiteBehavior.class.php @@ -9,65 +9,75 @@ // | Author: liu21st // +---------------------------------------------------------------------- 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) { +use Think\Hook as Hook; +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']).'}'; + $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, - ); + $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); - } + 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();}'; + $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(' $val) { $key = strtoupper($key); @@ -80,8 +90,8 @@ private function buildArrayDefine($array) { } elseif (is_string($val)) { $content .= "define('" . $key . "','" . addslashes($val) . "');"; } - $content .= "\n"; + $content .= "\n"; } return $content; } -} \ No newline at end of file +} diff --git a/ThinkPHP/Library/Behavior/CheckActionRouteBehavior.class.php b/ThinkPHP/Library/Behavior/CheckActionRouteBehavior.class.php index 5e1fb9cfc..c78b7b76d 100644 --- a/ThinkPHP/Library/Behavior/CheckActionRouteBehavior.class.php +++ b/ThinkPHP/Library/Behavior/CheckActionRouteBehavior.class.php @@ -9,40 +9,52 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Behavior; + /** * 系统行为扩展:操作路由检测 */ -class CheckActionRouteBehavior { +class CheckActionRouteBehavior +{ // 行为扩展的执行入口必须是run - public function run(&$config){ + public function run(&$config) + { // 优先检测是否存在PATH_INFO - $regx = trim($_SERVER['PATH_INFO'],'/'); - if(empty($regx)) return ; + $regx = trim($_SERVER['PATH_INFO'], '/'); + if (empty($regx)) { + return; + } + // 路由定义文件优先于config中的配置定义 // 路由处理 - $routes = $config['routes']; - if(!empty($routes)) { + $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) { + $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); + } else { + $rule = substr($rule, 0, -1); } } - $match = $this->checkUrlMatch($regx,$rule); - if($match) return C('ACTION_NAME',$this->parseRule($rule,$route,$regx)); + $match = $this->checkUrlMatch($regx, $rule); + if ($match) { + return C('ACTION_NAME', $this->parseRule($rule, $route, $regx)); + } + } } } @@ -50,26 +62,28 @@ public function run(&$config){ } // 检测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])) { + 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)) { + } elseif (strpos($val, '^')) { + $array = explode('|', substr(strstr($val, '^'), 1)); + if (in_array($m1[$key], $array)) { $match = false; break; } } - }elseif(0 !== strcasecmp($val,$m1[$key])){ + } elseif (0 !== strcasecmp($val, $m1[$key])) { $match = false; break; } @@ -79,14 +93,17 @@ private function checkUrlMatch($regx,$rule) { // 解析规范的路由地址 // 地址格式 操作?参数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; + 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; @@ -101,58 +118,62 @@ private function parseUrl($url) { // 外部地址中可以用动态变量 采用 :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) { + private function parseRule($rule, $route, $regx) + { // 获取路由地址规则 - $url = is_array($route)?$route[0]:$route; + $url = is_array($route) ? $route[0] : $route; // 获取URL地址中的参数 - $paths = explode('/',$regx); + $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 = 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中的静态变量 + } 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); + 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); + header("Location: $url", true, (is_array($route) && isset($route[1])) ? $route[1] : 301); exit; - }else{ + } else { // 解析路由地址 - $var = $this->parseUrl($url); + $var = $this->parseUrl($url); // 解析路由地址里面的动态参数 - $values = array_values($matches); - foreach ($var as $key=>$val){ - if(0===strpos($val,':')) { - $var[$key] = $values[substr($val,1)-1]; + $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); + $var = array_merge($matches, $var); // 解析剩余的URL参数 - if($paths) { - preg_replace('@(\w+)\/([^\/]+)@e', '$var[strtolower(\'\\1\')]=strip_tags(\'\\2\');', implode('/',$paths)); + 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); + if (is_array($route) && isset($route[1])) { + parse_str($route[1], $params); + $var = array_merge($var, $params); } - $action = $var[C('VAR_ACTION')]; + $action = $var[C('VAR_ACTION')]; unset($var[C('VAR_ACTION')]); - $_GET = array_merge($var,$_GET); + $_GET = array_merge($var, $_GET); return $action; } } @@ -165,30 +186,32 @@ private function parseRule($rule,$route,$regx) { // 参数值和外部地址中可以用动态变量 采用 :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) { + 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); + $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{ + } else { // 解析路由地址 - $var = $this->parseUrl($url); + $var = $this->parseUrl($url); // 解析剩余的URL参数 - $regx = substr_replace($regx,'',0,strlen($matches[0])); - if($regx) { + $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); + if (is_array($route) && isset($route[1])) { + parse_str($route[1], $params); + $var = array_merge($var, $params); } - $action = $var[C('VAR_ACTION')]; + $action = $var[C('VAR_ACTION')]; unset($var[C('VAR_ACTION')]); - $_GET = array_merge($var,$_GET); + $_GET = array_merge($var, $_GET); } return $action; } -} \ No newline at end of file +} diff --git a/ThinkPHP/Library/Behavior/CheckLangBehavior.class.php b/ThinkPHP/Library/Behavior/CheckLangBehavior.class.php index c4d46a24d..2fd22a536 100644 --- a/ThinkPHP/Library/Behavior/CheckLangBehavior.class.php +++ b/ThinkPHP/Library/Behavior/CheckLangBehavior.class.php @@ -9,13 +9,16 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Behavior; + /** * 语言检测 并自动加载语言包 */ -class CheckLangBehavior { +class CheckLangBehavior +{ // 行为扩展的执行入口必须是run - public function run(&$params){ + public function run(&$params) + { // 检测语言 $this->checkLanguage(); } @@ -26,52 +29,61 @@ public function run(&$params){ * @access private * @return void */ - private function checkLanguage() { + private function checkLanguage() + { // 不开启语言包功能,仅仅加载框架语言文件直接返回 - if (!C('LANG_SWITCH_ON',null,false)){ + 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'); + $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')){// 获取上次用户的选择 + 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'])){// 自动侦测浏览器语言 + } 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); + cookie('think_language', $langSet, 3600); } - if(false === stripos($langList,$langSet)) { // 非法语言参数 + if (false === stripos($langList, $langSet)) { + // 非法语言参数 $langSet = C('DEFAULT_LANG'); } } // 定义当前语言 - define('LANG_SET',strtolower($langSet)); + define('LANG_SET', strtolower($langSet)); // 读取框架语言包 - $file = THINK_PATH.'Lang/'.LANG_SET.'.php'; - if(LANG_SET != C('DEFAULT_LANG') && is_file($file)) + $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)) + $file = LANG_PATH . LANG_SET . '.php'; + if (is_file($file)) { L(include $file); - + } + // 读取模块语言包 - $file = MODULE_PATH.'Lang/'.LANG_SET.'.php'; - if(is_file($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)) + $file = MODULE_PATH . 'Lang/' . LANG_SET . '/' . strtolower(CONTROLLER_NAME) . '.php'; + if (is_file($file)) { L(include $file); + } + } } diff --git a/ThinkPHP/Library/Behavior/ChromeShowPageTraceBehavior.class.php b/ThinkPHP/Library/Behavior/ChromeShowPageTraceBehavior.class.php index 8abf89240..60415a6de 100644 --- a/ThinkPHP/Library/Behavior/ChromeShowPageTraceBehavior.class.php +++ b/ThinkPHP/Library/Behavior/ChromeShowPageTraceBehavior.class.php @@ -13,7 +13,7 @@ /** * 将Trace信息输出到chrome浏览器的控制器,从而不影响ajax效果和页面的布局。 * 使用前,你需要先安装 chrome log 这个插件: http://craig.is/writing/chrome-logger。 - * 定义应用的tags.php文件 Application/Common/Conf/tags.php, + * 定义应用的tags.php文件 Application/Common/Conf/tags.php, * * array( @@ -27,584 +27,594 @@ * */ namespace Behavior; + +use Behavior\ChromePhp as ChromePhp; use Think\Log; /** * 系统行为扩展 页面Trace显示输出 */ -class ChromeShowPageTraceBehavior { +class ChromeShowPageTraceBehavior +{ - protected $tracePageTabs = array('BASE'=>'基本','FILE'=>'文件','INFO'=>'流程','ERR|NOTIC'=>'错误','SQL'=>'SQL','DEBUG'=>'调试'); + protected $tracePageTabs = array('BASE' => '基本', 'FILE' => '文件', 'INFO' => '流程', 'ERR|NOTIC' => '错误', 'SQL' => 'SQL', 'DEBUG' => '调试'); // 行为扩展的执行入口必须是run - public function run(&$params){ - if(C('SHOW_PAGE_TRACE')) $this->showTrace(); + 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 )'; + 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 = 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); + $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; + $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; + $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(); + 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]:''; + $trace[$title] = $result; + } else { + $trace[$title] = isset($debug[$name]) ? $debug[$name] : ''; } } } - chrome_debug('TRACE信息:'.__SELF__,'group'); + chromeDebug('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'); + foreach ($trace as $title => $log) { + '错误' == $title ? chromeDebug($title, 'group') : chromeDebug($title, 'groupCollapsed'); + foreach ($log as $i => $logstr) { + chromeDebug($i . '.' . $logstr, 'log'); } - chrome_debug('','groupEnd'); + chromeDebug('', '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]; + chromeDebug('', '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"; + $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"; + } else { + $content .= print_r($val, true) . "\r\n"; } $content .= "\r\n"; } } - error_log(str_replace('
',"\r\n",$content), 3,LOG_PATH.date('y_m_d').'_trace.log'); + error_log(str_replace('
', "\r\n", $content), 3, LOG_PATH . date('y_m_d') . '_trace.log'); } - unset($files,$info,$base); + unset($files, $info, $base); } /** * 获取运行时间 */ - private function showTime() { + private function showTime() + { // 显示运行时间 - G('beginTime',$GLOBALS['_beginTime']); + 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 )'; + 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')){ +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); + function chromeDebug($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()); } - } - 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 */ -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() - ); + 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']; + } - /** - * @var array - */ - protected $_backtraces = array(); + /** + * gets instance of this class + * + * @return ChromePhp + */ + public static function getInstance() + { + if (null === self::$_instance) { + self::$_instance = new self(); + } + return self::$_instance; + } - /** - * @var bool - */ - protected $_error_triggered = false; + /** + * 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); + } - /** - * @var array - */ - protected $_settings = array( - self::BACKTRACE_LEVEL => 1 - ); + /** + * 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); + } - /** - * @var ChromePhp - */ - protected static $_instance; + /** + * 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); + } - /** - * Prevent recursion when working with objects referring to each other - * - * @var array - */ - protected $_processed = array(); + /** + * sends a group log + * + * @param string value + */ + public static function group() + { + $args = func_get_args(); + return self::_log(self::GROUP, $args); + } - /** - * 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']; - } + /** + * 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); + } - /** - * gets instance of this class - * - * @return ChromePhp - */ - public static function getInstance() - { - if (self::$_instance === null) { - self::$_instance = new self(); + /** + * sends a collapsed group log + * + * @param string value + */ + public static function groupCollapsed() + { + $args = func_get_args(); + return self::_log(self::GROUP_COLLAPSED, $args); } - 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); - } + /** + * ends a group log + * + * @param string value + */ + public static function groupEnd() + { + $args = func_get_args(); + return self::_log(self::GROUP_END, $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); - } + /** + * sends a table log + * + * @param string value + */ + public static function table() + { + $args = func_get_args(); + return self::_log(self::TABLE, $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); - } + /** + * 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 && self::GROUP_END != $type) { + return; + } - /** - * sends a group log - * - * @param string value - */ - public static function group() - { - $args = func_get_args(); - return self::_log(self::GROUP, $args); - } + $logger = self::getInstance(); - /** - * 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); - } + $logger->_processed = array(); - /** - * sends a collapsed group log - * - * @param string value - */ - public static function groupCollapsed() - { - $args = func_get_args(); - return self::_log(self::GROUP_COLLAPSED, $args); - } + $logs = array(); + foreach ($args as $arg) { + $logs[] = $logger->_convert($arg); + } - /** - * ends a group log - * - * @param string value - */ - public static function groupEnd() - { - $args = func_get_args(); - return self::_log(self::GROUP_END, $args); - } + $backtrace = debug_backtrace(false); + $level = $logger->getSetting(self::BACKTRACE_LEVEL); - /** - * sends a table log - * - * @param string value - */ - public static function table() - { - $args = func_get_args(); - return self::_log(self::TABLE, $args); - } + $backtrace_message = 'unknown'; + if (isset($backtrace[$level]['file']) && isset($backtrace[$level]['line'])) { + $backtrace_message = $backtrace[$level]['file'] . ' : ' . $backtrace[$level]['line']; + } - /** - * 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->_addRow($logs, $backtrace_message, $type); } - $logger = self::getInstance(); + /** + * 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; + } - $logger->_processed = array(); + //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; - $logs = array(); - foreach ($args as $arg) { - $logs[] = $logger->_convert($arg); - } + $object_as_array = array(); - $backtrace = debug_backtrace(false); - $level = $logger->getSetting(self::BACKTRACE_LEVEL); + // first add the class name + $object_as_array['___class_name'] = get_class($object); - $backtrace_message = 'unknown'; - if (isset($backtrace[$level]['file']) && isset($backtrace[$level]['line'])) { - $backtrace_message = $backtrace[$level]['file'] . ' : ' . $backtrace[$level]['line']; - } + // loop through object vars + $object_vars = get_object_vars($object); + foreach ($object_vars as $key => $value) { - $logger->_addRow($logs, $backtrace_message, $type); - } + // 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); + } - /** - * 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; - } + $reflection = new ReflectionClass($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; + // loop through the properties and add those + foreach ($reflection->getProperties() as $property) { - $object_as_array = array(); + // 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); + } - // first add the class name - $object_as_array['___class_name'] = get_class($object); + try { + $value = $property->getValue($object); + } catch (ReflectionException $e) { + $value = 'only PHP 5.3 can access private/protected properties'; + } - // 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) . ']'; + } - // 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); } - $object_as_array[$key] = $this->_convert($value); + return $object_as_array; } - $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; + /** + * 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(); } - $type = $this->_getPropertyKey($property); - if ($this->_php_version >= 5.3) { - $property->setAccessible(true); + if ($property->isProtected()) { + return 'protected' . $static . ' ' . $property->getName(); } - try { - $value = $property->getValue($object); - } catch (ReflectionException $e) { - $value = 'only PHP 5.3 can access private/protected properties'; + if ($property->isPrivate()) { + return 'private' . $static . ' ' . $property->getName(); } + } - // same instance as parent object - if ($value === $object || in_array($value, $this->_processed, true)) { - $value = 'recursion - parent object [' . get_class($value) . ']'; + /** + * 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; } - $object_as_array[$type] = $this->_convert($value); - } - return $object_as_array; - } + // for group, groupEnd, and groupCollapsed + // take out the backtrace since it is not useful + if (self::GROUP == $type || self::GROUP_END == $type || self::GROUP_COLLAPSED == $type) { + $backtrace = null; + } - /** - * 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 (null !== $backtrace) { + $this->_backtraces[] = $backtrace; + } - if ($property->isProtected()) { - return 'protected' . $static . ' ' . $property->getName(); - } + $row = array($logs, $backtrace, $type); - if ($property->isPrivate()) { - return 'private' . $static . ' ' . $property->getName(); + $this->_json['rows'][] = $row; + $this->_writeHeader($this->_json); } - } - /** - * 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; + protected function _writeHeader($data) + { + header(self::HEADER_NAME . ': ' . $this->_encode($data)); } - // 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; + /** + * 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))); } - if ($backtrace !== null) { - $this->_backtraces[] = $backtrace; + /** + * adds a setting + * + * @param string key + * @param mixed value + * @return void + */ + public function addSetting($key, $value) + { + $this->_settings[$key] = $value; } - $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); + /** + * 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; + /** + * gets a setting + * + * @param string key + * @return mixed + */ + public function getSetting($key) + { + if (!isset($this->_settings[$key])) { + return null; + } + return $this->_settings[$key]; } - return $this->_settings[$key]; } } -} diff --git a/ThinkPHP/Library/Behavior/ContentReplaceBehavior.class.php b/ThinkPHP/Library/Behavior/ContentReplaceBehavior.class.php index c572223b0..8a30496f5 100644 --- a/ThinkPHP/Library/Behavior/ContentReplaceBehavior.class.php +++ b/ThinkPHP/Library/Behavior/ContentReplaceBehavior.class.php @@ -9,13 +9,16 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Behavior; + /** * 系统行为扩展:模板内容输出替换 */ -class ContentReplaceBehavior { +class ContentReplaceBehavior +{ // 行为扩展的执行入口必须是run - public function run(&$content){ + public function run(&$content) + { $content = $this->templateContentReplace($content); } @@ -25,23 +28,26 @@ public function run(&$content){ * @param string $content 模板内容 * @return string */ - protected function templateContentReplace($content) { + protected function templateContentReplace($content) + { // 系统默认的特殊变量替换 - $replace = array( - '__ROOT__' => __ROOT__, // 当前网站地址 - '__APP__' => __APP__, // 当前应用地址 - '__MODULE__' => __MODULE__, - '__ACTION__' => __ACTION__, // 当前操作地址 - '__SELF__' => htmlentities(__SELF__), // 当前页面地址 - '__CONTROLLER__'=> __CONTROLLER__, - '__URL__' => __CONTROLLER__, - '__PUBLIC__' => __ROOT__.'/Public',// 站点公共目录 + $replace = array( + '__ROOT__' => __ROOT__, // 当前网站地址 + '__APP__' => __APP__, // 当前应用地址 + '__MODULE__' => __MODULE__, + '__ACTION__' => __ACTION__, // 当前操作地址 + '__SELF__' => htmlentities(__SELF__), // 当前页面地址 + '__CONTROLLER__' => __CONTROLLER__, + '__URL__' => __CONTROLLER__, + '__PUBLIC__' => __ROOT__ . '/Public', // 站点公共目录 ); // 允许用户自定义模板的字符串替换 - if(is_array(C('TMPL_PARSE_STRING')) ) - $replace = array_merge($replace,C('TMPL_PARSE_STRING')); - $content = str_replace(array_keys($replace),array_values($replace),$content); + 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; } -} \ No newline at end of file +} diff --git a/ThinkPHP/Library/Behavior/CronRunBehavior.class.php b/ThinkPHP/Library/Behavior/CronRunBehavior.class.php index 36c732eec..74dd50138 100644 --- a/ThinkPHP/Library/Behavior/CronRunBehavior.class.php +++ b/ThinkPHP/Library/Behavior/CronRunBehavior.class.php @@ -9,16 +9,20 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Behavior; + /** * 自动执行任务 */ -class CronRunBehavior { +use Think\Log as Log; +class CronRunBehavior +{ - public function run(&$params) { + 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 ; + $lockfile = RUNTIME_PATH . 'cron.lock'; + if (is_writable($lockfile) && filemtime($lockfile) > $_SERVER['REQUEST_TIME'] - C('CRON_MAX_TIME', null, 60)) { + return; } else { touch($lockfile); } @@ -29,38 +33,38 @@ public function run(&$params) { // 格式 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 (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]) { + 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'; + include COMMON_PATH . 'Cron/' . $cron[0] . '.php'; G('cronEnd'); - $_useTime = G('cronStart','cronEnd', 6); + $_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; + $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) { + if ($update) { // 记录Cron执行日志 - \Think\Log::write(implode('',$log)); + \Think\Log::write(implode('', $log)); // 更新cron文件 - $content = ""; - file_put_contents(RUNTIME_PATH.'~crons.php',$content); + $content = ""; + file_put_contents(RUNTIME_PATH . '~crons.php', $content); } } // 解除锁定 unlink($lockfile); - return ; + return; } -} \ No newline at end of file +} diff --git a/ThinkPHP/Library/Behavior/FireShowPageTraceBehavior.class.php b/ThinkPHP/Library/Behavior/FireShowPageTraceBehavior.class.php index 82c828a7b..0fbd2c4d2 100644 --- a/ThinkPHP/Library/Behavior/FireShowPageTraceBehavior.class.php +++ b/ThinkPHP/Library/Behavior/FireShowPageTraceBehavior.class.php @@ -13,7 +13,7 @@ /** * 将Trace信息输出到火狐的firebug,从而不影响ajax效果和页面的布局。 * 使用前,你需要先在火狐浏览器上安装firebug和firePHP两个插件。 - * 定义应用的tags.php文件, + * 定义应用的tags.php文件, * * array( @@ -28,113 +28,124 @@ * */ namespace Behavior; + /** * 系统行为扩展 页面Trace显示输出 */ -class FireShowPageTraceBehavior { - protected $tracePagTabs = array('BASE'=>'基本','FILE'=>'文件','INFO'=>'流程','ERR|NOTIC'=>'错误','SQL'=>'SQL','DEBUG'=>'调试'); +use Behavior\FirePHP as FirePHP; +use Think\Exception as Exception; +class FireShowPageTraceBehavior +{ + protected $tracePagTabs = array('BASE' => '基本', 'FILE' => '文件', 'INFO' => '流程', 'ERR|NOTIC' => '错误', 'SQL' => 'SQL', 'DEBUG' => '调试'); // 行为扩展的执行入口必须是run - public function run(&$params){ - if(C('FIRE_SHOW_PAGE_TRACE',null,true)) $this->showTrace(); + public function run(&$params) + { + if (C('FIRE_SHOW_PAGE_TRACE', null, true)) { + $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 )'; + 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(), - '内存开销'=> 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 = array(); + $base = array( + '请求信息' => date('Y-m-d H:i:s', $_SERVER['REQUEST_TIME']) . ' ' . $_SERVER['SERVER_PROTOCOL'] . ' ' . $_SERVER['REQUEST_METHOD'] . ' : ' . __SELF__, + '运行时间' => $this->showTime(), + '内存开销' => 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 = CONF_PATH.'trace.php'; - if(is_file($traceFile)) { - $base = array_merge($base,include $traceFile); + $traceFile = CONF_PATH . 'trace.php'; + if (is_file($traceFile)) { + $base = array_merge($base, include $traceFile); } - $debug = trace(); - $tabs = C('TRACE_PAGE_TABS',null,$this->tracePagTabs); - foreach ($tabs as $name=>$title){ - switch(strtoupper($name)) { - case 'BASE':// 基本信息 - $trace[$title] = $base; + $debug = trace(); + $tabs = C('TRACE_PAGE_TABS', null, $this->tracePagTabs); + foreach ($tabs as $name => $title) { + switch (strtoupper($name)) { + case 'BASE': // 基本信息 + $trace[$title] = $base; break; case 'FILE': // 文件信息 - $trace[$title] = $info; + $trace[$title] = $info; break; - default:// 调试信息 - if(strpos($name,'|')) {// 多组信息 - $array = explode('|',$name); - $result = array(); - foreach($array as $name){ - $result += isset($debug[$name])?$debug[$name]:array(); + default: // 调试信息 + 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]:''; + $trace[$title] = $result; + } else { + $trace[$title] = isset($debug[$name]) ? $debug[$name] : ''; } } } - foreach ($trace as $key=>$val){ - if(!is_array($val) && empty($val)) - $val=array(); - if(is_array($val)){ - $fire=array( - array('','') - ); - foreach($val as $k=>$v){ - $fire[]=array($k,$v); + foreach ($trace as $key => $val) { + if (!is_array($val) && empty($val)) { + $val = array(); + } + + if (is_array($val)) { + $fire = array( + array('', ''), + ); + foreach ($val as $k => $v) { + $fire[] = array($k, $v); + } + fb(array($key, $fire), FirePHP::TABLE); + } else { + fb($val, $key); } - fb(array($key,$fire),FirePHP::TABLE); - }else{ - fb($val,$key); } - } - unset($files,$info,$log,$base); + unset($files, $info, $log, $base); } /** * 获取运行时间 */ - private function showTime() { + private function showTime() + { // 显示运行时间 - G('beginTime',$GLOBALS['_beginTime']); + 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 )'; + 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 )'; } } - function fb() { $instance = FirePHP::getInstance(true); - + $args = func_get_args(); - return call_user_func_array(array($instance,'fb'),$args); + return call_user_func_array(array($instance, 'fb'), $args); } - class FB { /** * Enable and disable logging to Firebug - * + * * @see FirePHP->setEnabled() * @param boolean $Enabled TRUE to enable, FALSE to disable * @return void @@ -144,10 +155,10 @@ public static function setEnabled($Enabled) $instance = FirePHP::getInstance(true); $instance->setEnabled($Enabled); } - + /** * Check if logging is enabled - * + * * @see FirePHP->getEnabled() * @return boolean TRUE if enabled */ @@ -155,13 +166,13 @@ public static function getEnabled() { $instance = FirePHP::getInstance(true); return $instance->getEnabled(); - } - + } + /** * Specify a filter to be used when encoding an object - * + * * Filters are used to exclude object members. - * + * * @see FirePHP->setObjectFilter() * @param string $Class The class name of the object * @param array $Filter An array or members to exclude @@ -169,13 +180,13 @@ public static function getEnabled() */ public static function setObjectFilter($Class, $Filter) { - $instance = FirePHP::getInstance(true); - $instance->setObjectFilter($Class, $Filter); + $instance = FirePHP::getInstance(true); + $instance->setObjectFilter($Class, $Filter); } - + /** * Set some options for the library - * + * * @see FirePHP->setOptions() * @param array $Options The options to be set * @return void @@ -188,7 +199,7 @@ public static function setOptions($Options) /** * Get options for the library - * + * * @see FirePHP->getOptions() * @return array The options */ @@ -200,7 +211,7 @@ public static function getOptions() /** * Log object to firebug - * + * * @see http://www.firephp.org/Wiki/Reference/Fb * @param mixed $Object * @return true @@ -209,13 +220,13 @@ public static function getOptions() public static function send() { $instance = FirePHP::getInstance(true); - $args = func_get_args(); - return call_user_func_array(array($instance,'fb'),$args); + $args = func_get_args(); + return call_user_func_array(array($instance, 'fb'), $args); } /** * Start a group for following messages - * + * * Options: * Collapsed: [true|false] * Color: [#RRGGBB|ColorName] @@ -224,7 +235,7 @@ public static function send() * @param array $Options OPTIONAL Instructions on how to log the group * @return true */ - public static function group($Name, $Options=null) + public static function group($Name, $Options = null) { $instance = FirePHP::getInstance(true); return $instance->group($Name, $Options); @@ -250,10 +261,10 @@ public static function groupEnd() * @return true * @throws Exception */ - public static function log($Object, $Label=null) + public static function log($Object, $Label = null) { return self::send($Object, $Label, FirePHP::LOG); - } + } /** * Log object with label to firebug console @@ -264,10 +275,10 @@ public static function log($Object, $Label=null) * @return true * @throws Exception */ - public static function info($Object, $Label=null) + public static function info($Object, $Label = null) { return self::send($Object, $Label, FirePHP::INFO); - } + } /** * Log object with label to firebug console @@ -278,10 +289,10 @@ public static function info($Object, $Label=null) * @return true * @throws Exception */ - public static function warn($Object, $Label=null) + public static function warn($Object, $Label = null) { return self::send($Object, $Label, FirePHP::WARN); - } + } /** * Log object with label to firebug console @@ -292,10 +303,10 @@ public static function warn($Object, $Label=null) * @return true * @throws Exception */ - public static function error($Object, $Label=null) + public static function error($Object, $Label = null) { return self::send($Object, $Label, FirePHP::ERROR); - } + } /** * Dumps key and variable to firebug server panel @@ -309,7 +320,7 @@ public static function error($Object, $Label=null) public static function dump($Key, $Variable) { return self::send($Variable, $Key, FirePHP::DUMP); - } + } /** * Log a trace in the firebug console @@ -322,7 +333,7 @@ public static function dump($Key, $Variable) public static function trace($Label) { return self::send($Label, FirePHP::TRACE); - } + } /** * Log a table in the firebug console @@ -336,7 +347,7 @@ public static function trace($Label) public static function table($Label, $Table) { return self::send($Table, $Label, FirePHP::TABLE); - } + } } @@ -351,140 +362,141 @@ public static function table($Label, $Table) } if (!defined('E_USER_DEPRECATED')) { define('E_USER_DEPRECATED', 16384); -} - +} + /** * Sends the given data to the FirePHP Firefox Extension. * The data can be displayed in the Firebug Console or in the * "Server" request tab. - * + * * For more information see: http://www.firephp.org/ - * + * * @copyright Copyright (C) 2007-2009 Christoph Dorn * @author Christoph Dorn * @license http://www.opensource.org/licenses/bsd-license.php * @package FirePHPCore */ -class FirePHP { +class FirePHP +{ /** * FirePHP version * * @var string */ - const VERSION = '0.3'; // @pinf replace '0.3' with '%%package.version%%' + const VERSION = '0.3'; // @pinf replace '0.3' with '%%package.version%%' /** * Firebug LOG level * * Logs a message to firebug console. - * + * * @var string */ const LOG = 'LOG'; - + /** * Firebug INFO level * * Logs a message to firebug console and displays an info icon before the message. - * + * * @var string */ const INFO = 'INFO'; - + /** * Firebug WARN level * * Logs a message to firebug console, displays an warning icon before the message and colors the line turquoise. - * + * * @var string */ const WARN = 'WARN'; - + /** * Firebug ERROR level * * Logs a message to firebug console, displays an error icon before the message and colors the line yellow. Also increments the firebug error count. - * + * * @var string */ const ERROR = 'ERROR'; - + /** * Dumps a variable to firebug's server panel * * @var string */ const DUMP = 'DUMP'; - + /** * Displays a stack trace in firebug console * * @var string */ const TRACE = 'TRACE'; - + /** * Displays an exception in firebug console - * + * * Increments the firebug error count. * * @var string */ const EXCEPTION = 'EXCEPTION'; - + /** * Displays an table in firebug console * * @var string */ const TABLE = 'TABLE'; - + /** * Starts a group in firebug console - * + * * @var string */ const GROUP_START = 'GROUP_START'; - + /** * Ends a group in firebug console - * + * * @var string */ const GROUP_END = 'GROUP_END'; - + /** * Singleton instance of FirePHP * * @var FirePHP */ protected static $instance = null; - + /** * Flag whether we are logging from within the exception handler - * + * * @var boolean */ protected $inExceptionHandler = false; - + /** * Flag whether to throw PHP errors that have been converted to ErrorExceptions - * + * * @var boolean */ protected $throwErrorExceptions = true; - + /** * Flag whether to convert PHP assertion errors to Exceptions - * + * * @var boolean */ protected $convertAssertionErrorsToExceptions = true; - + /** * Flag whether to throw PHP assertion errors that have been converted to Exceptions - * + * * @var boolean */ protected $throwAssertionExceptions = false; @@ -495,59 +507,59 @@ class FirePHP { * @var int */ protected $messageIndex = 1; - + /** * Options for the library - * + * * @var array */ protected $options = array('maxDepth' => 10, - 'maxObjectDepth' => 5, - 'maxArrayDepth' => 5, - 'useNativeJsonEncode' => true, - 'includeLineNumbers' => true); + 'maxObjectDepth' => 5, + 'maxArrayDepth' => 5, + 'useNativeJsonEncode' => true, + 'includeLineNumbers' => true); /** * Filters used to exclude object members when encoding - * + * * @var array */ protected $objectFilters = array( - 'firephp' => array('objectStack', 'instance', 'json_objectStack'), - 'firephp_test_class' => array('objectStack', 'instance', 'json_objectStack') + 'firephp' => array('objectStack', 'instance', 'json_objectStack'), + 'firephp_test_class' => array('objectStack', 'instance', 'json_objectStack'), ); /** * A stack of objects used to detect recursion during object encoding - * + * * @var object */ protected $objectStack = array(); /** * Flag to enable/disable logging - * + * * @var boolean */ protected $enabled = true; /** * The insight console to log to if applicable - * + * * @var object */ protected $logToInsightConsole = null; /** * When the object gets serialized only include specific object members. - * + * * @return array - */ + */ public function __sleep() { - return array('options','objectFilters','enabled'); + return array('options', 'objectFilters', 'enabled'); } - + /** * Gets singleton instance of FirePHP * @@ -556,12 +568,12 @@ public function __sleep() */ public static function getInstance($AutoCreate = false) { - if ($AutoCreate===true && !self::$instance) { + if (true === $AutoCreate && !self::$instance) { self::init(); } return self::$instance; } - + /** * Creates FirePHP object and stores it for singleton access * @@ -574,7 +586,7 @@ public static function init() /** * Set the instance of the FirePHP singleton - * + * * @param FirePHP $instance The FirePHP object instance * @return FirePHP */ @@ -585,14 +597,14 @@ public static function setInstance($instance) /** * Set an Insight console to direct all logging calls to - * + * * @param object $console The console object to log to * @return void */ public function setLogToInsightConsole($console) { - if(is_string($console)) { - if(get_class($this)!='FirePHP_Insight' && !is_subclass_of($this, 'FirePHP_Insight')) { + if (is_string($console)) { + if (get_class($this) != 'FirePHP_Insight' && !is_subclass_of($this, 'FirePHP_Insight')) { throw new Exception('FirePHP instance not an instance or subclass of FirePHP_Insight!'); } $this->logToInsightConsole = $this->to('request')->console($console); @@ -603,30 +615,30 @@ public function setLogToInsightConsole($console) /** * Enable and disable logging to Firebug - * + * * @param boolean $Enabled TRUE to enable, FALSE to disable * @return void */ public function setEnabled($Enabled) { - $this->enabled = $Enabled; + $this->enabled = $Enabled; } - + /** * Check if logging is enabled - * + * * @return boolean TRUE if enabled */ public function getEnabled() { return $this->enabled; } - + /** * Specify a filter to be used when encoding an object - * + * * Filters are used to exclude object members. - * + * * @param string $Class The class name of the object * @param array $Filter An array of members to exclude * @return void @@ -635,23 +647,23 @@ public function setObjectFilter($Class, $Filter) { $this->objectFilters[strtolower($Class)] = $Filter; } - + /** * Set some options for the library - * + * * Options: * - maxDepth: The maximum depth to traverse (default: 10) * - maxObjectDepth: The maximum depth to traverse objects (default: 5) * - maxArrayDepth: The maximum depth to traverse arrays (default: 5) * - useNativeJsonEncode: If true will use json_encode() (default: true) * - includeLineNumbers: If true will include line numbers and filenames (default: true) - * + * * @param array $Options The options to be set * @return void */ public function setOptions($Options) { - $this->options = array_merge($this->options,$Options); + $this->options = array_merge($this->options, $Options); } /** @@ -666,12 +678,12 @@ public function getOptions() /** * Set an option for the library - * + * * @param string $Name * @param mixed $Value * @throws Exception * @return void - */ + */ public function setOption($Name, $Value) { if (!isset($this->options[$Name])) { @@ -697,9 +709,9 @@ public function getOption($Name) /** * Register FirePHP as your error handler - * + * * Will throw exceptions for each php error. - * + * * @return mixed Returns a string containing the previously defined error handler (if any) */ public function registerErrorHandler($throwErrorExceptions = false) @@ -708,15 +720,15 @@ public function registerErrorHandler($throwErrorExceptions = false) // E_ERROR, E_PARSE, E_CORE_ERROR, // E_CORE_WARNING, E_COMPILE_ERROR, // E_COMPILE_WARNING, E_STRICT - + $this->throwErrorExceptions = $throwErrorExceptions; - - return set_error_handler(array($this,'errorHandler')); + + return set_error_handler(array($this, 'errorHandler')); } /** * FirePHP's error handler - * + * * Throws exception for each php error that will occur. * * @param int $errno @@ -742,34 +754,34 @@ public function errorHandler($errno, $errstr, $errfile, $errline, $errcontext) } } } - + /** * Register FirePHP as your exception handler - * + * * @return mixed Returns the name of the previously defined exception handler, * or NULL on error. * If no previous handler was defined, NULL is also returned. */ public function registerExceptionHandler() { - return set_exception_handler(array($this,'exceptionHandler')); + return set_exception_handler(array($this, 'exceptionHandler')); } - + /** * FirePHP's exception handler - * + * * Logs all exceptions to your firebug console and then stops the script. * * @param Exception $Exception * @throws Exception */ - function exceptionHandler($Exception) + public function exceptionHandler($Exception) { - + $this->inExceptionHandler = true; - + header('HTTP/1.1 500 Internal Server Error'); - + try { $this->fb($Exception); } catch (Exception $e) { @@ -777,10 +789,10 @@ function exceptionHandler($Exception) } $this->inExceptionHandler = false; } - + /** * Register FirePHP driver as your assert callback - * + * * @param boolean $convertAssertionErrorsToExceptions * @param boolean $throwAssertionExceptions * @return mixed Returns the original setting or FALSE on errors @@ -788,15 +800,15 @@ function exceptionHandler($Exception) public function registerAssertionHandler($convertAssertionErrorsToExceptions = true, $throwAssertionExceptions = false) { $this->convertAssertionErrorsToExceptions = $convertAssertionErrorsToExceptions; - $this->throwAssertionExceptions = $throwAssertionExceptions; - + $this->throwAssertionExceptions = $throwAssertionExceptions; + if ($throwAssertionExceptions && !$convertAssertionErrorsToExceptions) { throw $this->newException('Cannot throw assertion exceptions as assertion errors are not being converted to exceptions!'); } - + return assert_options(ASSERT_CALLBACK, array($this, 'assertionHandler')); } - + /** * FirePHP's assertion handler * @@ -809,23 +821,23 @@ public function registerAssertionHandler($convertAssertionErrorsToExceptions = t public function assertionHandler($file, $line, $code) { if ($this->convertAssertionErrorsToExceptions) { - - $exception = new ErrorException('Assertion Failed - Code[ '.$code.' ]', 0, null, $file, $line); - - if ($this->throwAssertionExceptions) { - throw $exception; - } else { - $this->fb($exception); - } - + + $exception = new ErrorException('Assertion Failed - Code[ ' . $code . ' ]', 0, null, $file, $line); + + if ($this->throwAssertionExceptions) { + throw $exception; + } else { + $this->fb($exception); + } + } else { - $this->fb($code, 'Assertion Failed', FirePHP::ERROR, array('File'=>$file,'Line'=>$line)); + $this->fb($code, 'Assertion Failed', FirePHP::ERROR, array('File' => $file, 'Line' => $line)); } } - + /** * Start a group for following messages. - * + * * Options: * Collapsed: [true|false] * Color: [#RRGGBB|ColorName] @@ -837,23 +849,23 @@ public function assertionHandler($file, $line, $code) */ public function group($Name, $Options = null) { - + if (!$Name) { throw $this->newException('You must specify a label for the group!'); } - + if ($Options) { if (!is_array($Options)) { throw $this->newException('Options must be defined as an array!'); } if (array_key_exists('Collapsed', $Options)) { - $Options['Collapsed'] = ($Options['Collapsed'])?'true':'false'; + $Options['Collapsed'] = ($Options['Collapsed']) ? 'true' : 'false'; } } - + return $this->fb(null, $Name, FirePHP::GROUP_START, $Options); } - + /** * Ends a group you have started before * @@ -877,7 +889,7 @@ public function groupEnd() public function log($Object, $Label = null, $Options = array()) { return $this->fb($Object, $Label, FirePHP::LOG, $Options); - } + } /** * Log object with label to firebug console @@ -891,7 +903,7 @@ public function log($Object, $Label = null, $Options = array()) public function info($Object, $Label = null, $Options = array()) { return $this->fb($Object, $Label, FirePHP::INFO, $Options); - } + } /** * Log object with label to firebug console @@ -905,7 +917,7 @@ public function info($Object, $Label = null, $Options = array()) public function warn($Object, $Label = null, $Options = array()) { return $this->fb($Object, $Label, FirePHP::WARN, $Options); - } + } /** * Log object with label to firebug console @@ -919,7 +931,7 @@ public function warn($Object, $Label = null, $Options = array()) public function error($Object, $Label = null, $Options = array()) { return $this->fb($Object, $Label, FirePHP::ERROR, $Options); - } + } /** * Dumps key and variable to firebug server panel @@ -935,7 +947,7 @@ public function dump($Key, $Variable, $Options = array()) if (!is_string($Key)) { throw $this->newException('Key passed to dump() is not a string'); } - if (strlen($Key)>100) { + if (strlen($Key) > 100) { throw $this->newException('Key passed to dump() is longer than 100 characters'); } if (!preg_match_all('/^[a-zA-Z0-9-_\.:]*$/', $Key, $m)) { @@ -943,7 +955,7 @@ public function dump($Key, $Variable, $Options = array()) } return $this->fb($Variable, $Key, FirePHP::DUMP, $Options); } - + /** * Log a trace in the firebug console * @@ -955,7 +967,7 @@ public function dump($Key, $Variable, $Options = array()) public function trace($Label) { return $this->fb($Label, FirePHP::TRACE); - } + } /** * Log a table in the firebug console @@ -973,7 +985,7 @@ public function table($Label, $Table, $Options = array()) /** * Insight API wrapper - * + * * @see Insight_Helper::to() */ public static function to() @@ -988,7 +1000,7 @@ public static function to() /** * Insight API wrapper - * + * * @see Insight_Helper::plugin() */ public static function plugin() @@ -1009,21 +1021,21 @@ public static function plugin() public function detectClientExtension() { // Check if FirePHP is installed on client via User-Agent header - if (@preg_match_all('/\sFirePHP\/([\.\d]*)\s?/si',$this->getUserAgent(),$m) && - version_compare($m[1][0],'0.0.6','>=')) { + if (@preg_match_all('/\sFirePHP\/([\.\d]*)\s?/si', $this->getUserAgent(), $m) && + version_compare($m[1][0], '0.0.6', '>=')) { return true; } else // Check if FirePHP is installed on client via X-FirePHP-Version header - if (@preg_match_all('/^([\.\d]*)$/si',$this->getRequestHeader("X-FirePHP-Version"),$m) && - version_compare($m[1][0],'0.0.6','>=')) { + if (@preg_match_all('/^([\.\d]*)$/si', $this->getRequestHeader("X-FirePHP-Version"), $m) && + version_compare($m[1][0], '0.0.6', '>=')) { return true; } return false; } - + /** * Log varible to Firebug - * + * * @see http://www.firephp.org/Wiki/Reference/Fb * @param mixed $Object The variable to be logged * @return true Return TRUE if message was added to headers, FALSE otherwise @@ -1031,8 +1043,9 @@ public function detectClientExtension() */ public function fb($Object) { - if($this instanceof FirePHP_Insight && method_exists($this, '_logUpgradeClientMessage')) { - if(!FirePHP_Insight::$upgradeClientMessageLogged) { // avoid infinite recursion as _logUpgradeClientMessage() logs a message + if ($this instanceof FirePHP_Insight && method_exists($this, '_logUpgradeClientMessage')) { + if (!FirePHP_Insight::$upgradeClientMessageLogged) { + // avoid infinite recursion as _logUpgradeClientMessage() logs a message $this->_logUpgradeClientMessage(); } } @@ -1047,20 +1060,20 @@ public function fb($Object) // If we are logging from within the exception handler we cannot throw another exception if ($this->inExceptionHandler) { // Simply echo the error out to the page - echo '
FirePHP ERROR: Headers already sent in '.$filename.' on line '.$linenum.'. Cannot send log data to FirePHP. You must have Output Buffering enabled via ob_start() or output_buffering ini directive.
'; + echo '
FirePHP ERROR: Headers already sent in ' . $filename . ' on line ' . $linenum . '. Cannot send log data to FirePHP. You must have Output Buffering enabled via ob_start() or output_buffering ini directive.
'; } else { - throw $this->newException('Headers already sent in '.$filename.' on line '.$linenum.'. Cannot send log data to FirePHP. You must have Output Buffering enabled via ob_start() or output_buffering ini directive.'); + throw $this->newException('Headers already sent in ' . $filename . ' on line ' . $linenum . '. Cannot send log data to FirePHP. You must have Output Buffering enabled via ob_start() or output_buffering ini directive.'); } } - - $Type = null; - $Label = null; + + $Type = null; + $Label = null; $Options = array(); - - if (func_num_args()==1) { + + if (func_num_args() == 1) { } else - if (func_num_args()==2) { - switch(func_get_arg(1)) { + if (func_num_args() == 2) { + switch (func_get_arg(1)) { case self::LOG: case self::INFO: case self::WARN: @@ -1078,27 +1091,27 @@ public function fb($Object) break; } } else - if (func_num_args()==3) { - $Type = func_get_arg(2); + if (func_num_args() == 3) { + $Type = func_get_arg(2); $Label = func_get_arg(1); } else - if (func_num_args()==4) { - $Type = func_get_arg(2); - $Label = func_get_arg(1); + if (func_num_args() == 4) { + $Type = func_get_arg(2); + $Label = func_get_arg(1); $Options = func_get_arg(3); } else { throw $this->newException('Wrong number of arguments to fb() function!'); } - if($this->logToInsightConsole!==null && (get_class($this)=='FirePHP_Insight' || is_subclass_of($this, 'FirePHP_Insight'))) { + if (null !== $this->logToInsightConsole && (get_class($this) == 'FirePHP_Insight' || is_subclass_of($this, 'FirePHP_Insight'))) { $msg = $this->logToInsightConsole; if ($Object instanceof Exception) { $Type = self::EXCEPTION; } - if($Label && $Type!=self::TABLE && $Type!=self::GROUP_START) { + if ($Label && self::TABLE != $Type && self::GROUP_START != $Type) { $msg = $msg->label($Label); } - switch($Type) { + switch ($Type) { case self::DUMP: case self::LOG: return $msg->log($Object); @@ -1116,12 +1129,12 @@ public function fb($Object) if (isset($Object[0]) && !is_string($Object[0]) && $Label) { $Object = array($Label, $Object); } - return $msg->table($Object[0], array_slice($Object[1],1), $Object[1][0]); + return $msg->table($Object[0], array_slice($Object[1], 1), $Object[1][0]); case self::GROUP_START: $insightGroupStack[] = $msg->group(md5($Label))->open(); return $msg->log($Label); case self::GROUP_END: - if(count($insightGroupStack)==0) { + if (count($insightGroupStack) == 0) { throw new Error('Too many groupEnd() as opposed to group() calls!'); } $group = array_pop($insightGroupStack); @@ -1134,170 +1147,175 @@ public function fb($Object) if (!$this->detectClientExtension()) { return false; } - - $meta = array(); + + $meta = array(); $skipFinalObjectEncode = false; - + if ($Object instanceof Exception) { - + $meta['file'] = $this->_escapeTraceFile($Object->getFile()); $meta['line'] = $Object->getLine(); - + $trace = $Object->getTrace(); if ($Object instanceof ErrorException - && isset($trace[0]['function']) - && $trace[0]['function']=='errorHandler' - && isset($trace[0]['class']) - && $trace[0]['class']=='FirePHP') { - + && isset($trace[0]['function']) + && 'errorHandler' == $trace[0]['function'] && isset($trace[0]['class']) + && 'FirePHP' == $trace[0]['class']) { + $severity = false; - switch($Object->getSeverity()) { - case E_WARNING: $severity = 'E_WARNING'; break; - case E_NOTICE: $severity = 'E_NOTICE'; break; - case E_USER_ERROR: $severity = 'E_USER_ERROR'; break; - case E_USER_WARNING: $severity = 'E_USER_WARNING'; break; - case E_USER_NOTICE: $severity = 'E_USER_NOTICE'; break; - case E_STRICT: $severity = 'E_STRICT'; break; - case E_RECOVERABLE_ERROR: $severity = 'E_RECOVERABLE_ERROR'; break; - case E_DEPRECATED: $severity = 'E_DEPRECATED'; break; - case E_USER_DEPRECATED: $severity = 'E_USER_DEPRECATED'; break; + switch ($Object->getSeverity()) { + case E_WARNING:$severity = 'E_WARNING'; + break; + case E_NOTICE:$severity = 'E_NOTICE'; + break; + case E_USER_ERROR:$severity = 'E_USER_ERROR'; + break; + case E_USER_WARNING:$severity = 'E_USER_WARNING'; + break; + case E_USER_NOTICE:$severity = 'E_USER_NOTICE'; + break; + case E_STRICT:$severity = 'E_STRICT'; + break; + case E_RECOVERABLE_ERROR:$severity = 'E_RECOVERABLE_ERROR'; + break; + case E_DEPRECATED:$severity = 'E_DEPRECATED'; + break; + case E_USER_DEPRECATED:$severity = 'E_USER_DEPRECATED'; + break; } - - $Object = array('Class'=>get_class($Object), - 'Message'=>$severity.': '.$Object->getMessage(), - 'File'=>$this->_escapeTraceFile($Object->getFile()), - 'Line'=>$Object->getLine(), - 'Type'=>'trigger', - 'Trace'=>$this->_escapeTrace(array_splice($trace,2))); + + $Object = array('Class' => get_class($Object), + 'Message' => $severity . ': ' . $Object->getMessage(), + 'File' => $this->_escapeTraceFile($Object->getFile()), + 'Line' => $Object->getLine(), + 'Type' => 'trigger', + 'Trace' => $this->_escapeTrace(array_splice($trace, 2))); $skipFinalObjectEncode = true; } else { - $Object = array('Class'=>get_class($Object), - 'Message'=>$Object->getMessage(), - 'File'=>$this->_escapeTraceFile($Object->getFile()), - 'Line'=>$Object->getLine(), - 'Type'=>'throw', - 'Trace'=>$this->_escapeTrace($trace)); + $Object = array('Class' => get_class($Object), + 'Message' => $Object->getMessage(), + 'File' => $this->_escapeTraceFile($Object->getFile()), + 'Line' => $Object->getLine(), + 'Type' => 'throw', + 'Trace' => $this->_escapeTrace($trace)); $skipFinalObjectEncode = true; } $Type = self::EXCEPTION; - + } else - if ($Type==self::TRACE) { - + if (self::TRACE == $Type) { + $trace = debug_backtrace(); - if (!$trace) return false; - for( $i=0 ; $i_standardizePath($trace[$i]['file']),-18,18)=='FirePHPCore/fb.php' - || substr($this->_standardizePath($trace[$i]['file']),-29,29)=='FirePHPCore/FirePHP.class.php')) { + && isset($trace[$i]['file']) + && ('FirePHP' == $trace[$i]['class'] || 'FB' == $trace[$i]['class']) + && (substr($this->_standardizePath($trace[$i]['file']), -18, 18) == 'FirePHPCore/fb.php' + || substr($this->_standardizePath($trace[$i]['file']), -29, 29) == 'FirePHPCore/FirePHP.class.php')) { /* Skip - FB::trace(), FB::send(), $firephp->trace(), $firephp->fb() */ } else if (isset($trace[$i]['class']) - && isset($trace[$i+1]['file']) - && $trace[$i]['class']=='FirePHP' - && substr($this->_standardizePath($trace[$i+1]['file']),-18,18)=='FirePHPCore/fb.php') { + && isset($trace[$i + 1]['file']) + && 'FirePHP' == $trace[$i]['class'] && substr($this->_standardizePath($trace[$i + 1]['file']), -18, 18) == 'FirePHPCore/fb.php') { /* Skip fb() */ } else - if ($trace[$i]['function']=='fb' - || $trace[$i]['function']=='trace' - || $trace[$i]['function']=='send') { - - $Object = array('Class'=>isset($trace[$i]['class'])?$trace[$i]['class']:'', - 'Type'=>isset($trace[$i]['type'])?$trace[$i]['type']:'', - 'Function'=>isset($trace[$i]['function'])?$trace[$i]['function']:'', - 'Message'=>$trace[$i]['args'][0], - 'File'=>isset($trace[$i]['file'])?$this->_escapeTraceFile($trace[$i]['file']):'', - 'Line'=>isset($trace[$i]['line'])?$trace[$i]['line']:'', - 'Args'=>isset($trace[$i]['args'])?$this->encodeObject($trace[$i]['args']):'', - 'Trace'=>$this->_escapeTrace(array_splice($trace,$i+1))); - + if ('fb' == $trace[$i]['function'] || 'trace' == $trace[$i]['function'] || 'send' == $trace[$i]['function']) { + + $Object = array('Class' => isset($trace[$i]['class']) ? $trace[$i]['class'] : '', + 'Type' => isset($trace[$i]['type']) ? $trace[$i]['type'] : '', + 'Function' => isset($trace[$i]['function']) ? $trace[$i]['function'] : '', + 'Message' => $trace[$i]['args'][0], + 'File' => isset($trace[$i]['file']) ? $this->_escapeTraceFile($trace[$i]['file']) : '', + 'Line' => isset($trace[$i]['line']) ? $trace[$i]['line'] : '', + 'Args' => isset($trace[$i]['args']) ? $this->encodeObject($trace[$i]['args']) : '', + 'Trace' => $this->_escapeTrace(array_splice($trace, $i + 1))); + $skipFinalObjectEncode = true; - $meta['file'] = isset($trace[$i]['file'])?$this->_escapeTraceFile($trace[$i]['file']):''; - $meta['line'] = isset($trace[$i]['line'])?$trace[$i]['line']:''; + $meta['file'] = isset($trace[$i]['file']) ? $this->_escapeTraceFile($trace[$i]['file']) : ''; + $meta['line'] = isset($trace[$i]['line']) ? $trace[$i]['line'] : ''; break; } } - + } else - if ($Type==self::TABLE) { - + if (self::TABLE == $Type) { + if (isset($Object[0]) && is_string($Object[0])) { $Object[1] = $this->encodeTable($Object[1]); } else { $Object = $this->encodeTable($Object); } - + $skipFinalObjectEncode = true; - + } else - if ($Type==self::GROUP_START) { - + if (self::GROUP_START == $Type) { + if (!$Label) { throw $this->newException('You must specify a label for the group!'); } - + } else { - if ($Type===null) { + if (null === $Type) { $Type = self::LOG; } } - + if ($this->options['includeLineNumbers']) { if (!isset($meta['file']) || !isset($meta['line'])) { - + $trace = debug_backtrace(); - for( $i=0 ; $trace && $i_standardizePath($trace[$i]['file']),-18,18)=='FirePHPCore/fb.php' - || substr($this->_standardizePath($trace[$i]['file']),-29,29)=='FirePHPCore/FirePHP.class.php')) { + && isset($trace[$i]['file']) + && ('FirePHP' == $trace[$i]['class'] || 'FB' == $trace[$i]['class']) + && (substr($this->_standardizePath($trace[$i]['file']), -18, 18) == 'FirePHPCore/fb.php' + || substr($this->_standardizePath($trace[$i]['file']), -29, 29) == 'FirePHPCore/FirePHP.class.php')) { /* Skip - FB::trace(), FB::send(), $firephp->trace(), $firephp->fb() */ } else if (isset($trace[$i]['class']) - && isset($trace[$i+1]['file']) - && $trace[$i]['class']=='FirePHP' - && substr($this->_standardizePath($trace[$i+1]['file']),-18,18)=='FirePHPCore/fb.php') { + && isset($trace[$i + 1]['file']) + && 'FirePHP' == $trace[$i]['class'] && substr($this->_standardizePath($trace[$i + 1]['file']), -18, 18) == 'FirePHPCore/fb.php') { /* Skip fb() */ } else if (isset($trace[$i]['file']) - && substr($this->_standardizePath($trace[$i]['file']),-18,18)=='FirePHPCore/fb.php') { + && substr($this->_standardizePath($trace[$i]['file']), -18, 18) == 'FirePHPCore/fb.php') { /* Skip FB::fb() */ } else { - $meta['file'] = isset($trace[$i]['file'])?$this->_escapeTraceFile($trace[$i]['file']):''; - $meta['line'] = isset($trace[$i]['line'])?$trace[$i]['line']:''; + $meta['file'] = isset($trace[$i]['file']) ? $this->_escapeTraceFile($trace[$i]['file']) : ''; + $meta['line'] = isset($trace[$i]['line']) ? $trace[$i]['line'] : ''; break; } - } + } } } else { unset($meta['file']); unset($meta['line']); } - $this->setHeader('X-Wf-Protocol-1','http://meta.wildfirehq.org/Protocol/JsonStream/0.2'); - $this->setHeader('X-Wf-1-Plugin-1','http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/'.self::VERSION); - + $this->setHeader('X-Wf-Protocol-1', 'http://meta.wildfirehq.org/Protocol/JsonStream/0.2'); + $this->setHeader('X-Wf-1-Plugin-1', 'http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/' . self::VERSION); + $structure_index = 1; - if ($Type==self::DUMP) { + if (self::DUMP == $Type) { $structure_index = 2; - $this->setHeader('X-Wf-1-Structure-2','http://meta.firephp.org/Wildfire/Structure/FirePHP/Dump/0.1'); + $this->setHeader('X-Wf-1-Structure-2', 'http://meta.firephp.org/Wildfire/Structure/FirePHP/Dump/0.1'); } else { - $this->setHeader('X-Wf-1-Structure-1','http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1'); + $this->setHeader('X-Wf-1-Structure-1', 'http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1'); } - - if ($Type==self::DUMP) { - $msg = '{"'.$Label.'":'.$this->jsonEncode($Object, $skipFinalObjectEncode).'}'; + + if (self::DUMP == $Type) { + $msg = '{"' . $Label . '":' . $this->jsonEncode($Object, $skipFinalObjectEncode) . '}'; } else { - $msg_meta = $Options; + $msg_meta = $Options; $msg_meta['Type'] = $Type; - if ($Label!==null) { + if (null !== $Label) { $msg_meta['Label'] = $Label; } if (isset($meta['file']) && !isset($msg_meta['File'])) { @@ -1306,40 +1324,40 @@ public function fb($Object) if (isset($meta['line']) && !isset($msg_meta['Line'])) { $msg_meta['Line'] = $meta['line']; } - $msg = '['.$this->jsonEncode($msg_meta).','.$this->jsonEncode($Object, $skipFinalObjectEncode).']'; + $msg = '[' . $this->jsonEncode($msg_meta) . ',' . $this->jsonEncode($Object, $skipFinalObjectEncode) . ']'; } - - $parts = explode("\n",chunk_split($msg, 5000, "\n")); - - for( $i=0 ; $i2) { + + if (count($parts) > 2) { // Message needs to be split into multiple parts - $this->setHeader('X-Wf-1-'.$structure_index.'-'.'1-'.$this->messageIndex, - (($i==0)?strlen($msg):'') - . '|' . $part . '|' - . (($isetHeader('X-Wf-1-' . $structure_index . '-' . '1-' . $this->messageIndex, + ((0 == $i) ? strlen($msg) : '') + . '|' . $part . '|' + . (($i < count($parts) - 2) ? '\\' : '')); } else { - $this->setHeader('X-Wf-1-'.$structure_index.'-'.'1-'.$this->messageIndex, - strlen($part) . '|' . $part . '|'); + $this->setHeader('X-Wf-1-' . $structure_index . '-' . '1-' . $this->messageIndex, + strlen($part) . '|' . $part . '|'); } - + $this->messageIndex++; - + if ($this->messageIndex > 99999) { - throw $this->newException('Maximum number (99,999) of messages reached!'); + throw $this->newException('Maximum number (99,999) of messages reached!'); } } } - - $this->setHeader('X-Wf-1-Index',$this->messageIndex-1); - + + $this->setHeader('X-Wf-1-Index', $this->messageIndex - 1); + return true; } - + /** * Standardizes path for windows systems. * @@ -1348,9 +1366,9 @@ public function fb($Object) */ protected function _standardizePath($Path) { - return preg_replace('/\\\\+/','/',$Path); + return preg_replace('/\\\\+/', '/', $Path); } - + /** * Escape trace path for windows systems * @@ -1359,8 +1377,11 @@ protected function _standardizePath($Path) */ protected function _escapeTrace($Trace) { - if (!$Trace) return $Trace; - for( $i=0 ; $i_escapeTraceFile($Trace[$i]['file']); } @@ -1368,9 +1389,9 @@ protected function _escapeTrace($Trace) $Trace[$i]['args'] = $this->encodeObject($Trace[$i]['args']); } } - return $Trace; + return $Trace; } - + /** * Escape file information of trace for windows systems * @@ -1380,11 +1401,11 @@ protected function _escapeTrace($Trace) protected function _escapeTraceFile($File) { /* Check if we have a windows filepath */ - if (strpos($File,'\\')) { + if (strpos($File, '\\')) { /* First strip down to single \ */ - - $file = preg_replace('/\\\\+/','\\',$File); - + + $file = preg_replace('/\\\\+/', '\\', $File); + return $file; } return $File; @@ -1409,7 +1430,7 @@ protected function headersSent(&$Filename, &$Linenum) */ protected function setHeader($Name, $Value) { - return header($Name.': '.$Value); + return header($Name . ': ' . $Value); } /** @@ -1419,28 +1440,32 @@ protected function setHeader($Name, $Value) */ protected function getUserAgent() { - if (!isset($_SERVER['HTTP_USER_AGENT'])) return false; + if (!isset($_SERVER['HTTP_USER_AGENT'])) { + return false; + } + return $_SERVER['HTTP_USER_AGENT']; } /** * Get all request headers - * + * * @return array */ - public static function getAllRequestHeaders() { + public static function getAllRequestHeaders() + { static $_cached_headers = false; - if($_cached_headers!==false) { + if (false !== $_cached_headers) { return $_cached_headers; } $headers = array(); - if(function_exists('getallheaders')) { - foreach( getallheaders() as $name => $value ) { + if (function_exists('getallheaders')) { + foreach (getallheaders() as $name => $value) { $headers[strtolower($name)] = $value; } } else { - foreach($_SERVER as $name => $value) { - if(substr($name, 0, 5) == 'HTTP_') { + foreach ($_SERVER as $name => $value) { + if (substr($name, 0, 5) == 'HTTP_') { $headers[strtolower(str_replace(' ', '-', str_replace('_', ' ', substr($name, 5))))] = $value; } } @@ -1472,12 +1497,12 @@ protected function newException($Message) { return new Exception($Message); } - + /** * Encode an object into a JSON string - * + * * Uses PHP's jeson_encode() if available - * + * * @param object $Object The object to be encoded * @return string The JSON string */ @@ -1486,48 +1511,50 @@ public function jsonEncode($Object, $skipObjectEncode = false) if (!$skipObjectEncode) { $Object = $this->encodeObject($Object); } - + if (function_exists('json_encode') - && $this->options['useNativeJsonEncode']!=false) { - - return json_encode($Object); + && false != $this->options['useNativeJsonEncode']) { + + return jsonEncode($Object); } else { - return $this->json_encode($Object); + return $this->jsonEncode($Object); } } /** * Encodes a table by encoding each row and column with encodeObject() - * + * * @param array $Table The table to be encoded * @return array - */ + */ protected function encodeTable($Table) { - - if (!$Table) return $Table; - + + if (!$Table) { + return $Table; + } + $new_table = array(); - foreach($Table as $row) { - + foreach ($Table as $row) { + if (is_array($row)) { $new_row = array(); - - foreach($row as $item) { + + foreach ($row as $item) { $new_row[] = $this->encodeObject($item); } - + $new_table[] = $new_row; } } - + return $new_table; } /** * Encodes an object including members with * protected and private visibility - * + * * @param Object $Object The object to be encoded * @param int $Depth The current traversal depth * @return array All members of the object @@ -1535,69 +1562,69 @@ protected function encodeTable($Table) protected function encodeObject($Object, $ObjectDepth = 1, $ArrayDepth = 1, $MaxDepth = 1) { if ($MaxDepth > $this->options['maxDepth']) { - return '** Max Depth ('.$this->options['maxDepth'].') **'; + return '** Max Depth (' . $this->options['maxDepth'] . ') **'; } $return = array(); - + if (is_resource($Object)) { - - return '** '.(string)$Object.' **'; - - } else + + return '** ' . (string) $Object . ' **'; + + } else if (is_object($Object)) { - + if ($ObjectDepth > $this->options['maxObjectDepth']) { - return '** Max Object Depth ('.$this->options['maxObjectDepth'].') **'; + return '** Max Object Depth (' . $this->options['maxObjectDepth'] . ') **'; } - + foreach ($this->objectStack as $refVal) { if ($refVal === $Object) { - return '** Recursion ('.get_class($Object).') **'; + return '** Recursion (' . get_class($Object) . ') **'; } } array_push($this->objectStack, $Object); - + $return['__className'] = $class = get_class($Object); - $class_lower = strtolower($class); - - $reflectionClass = new ReflectionClass($class); - $properties = array(); - foreach( $reflectionClass->getProperties() as $property) { + $class_lower = strtolower($class); + + $reflectionClass = new ReflectionClass($class); + $properties = array(); + foreach ($reflectionClass->getProperties() as $property) { $properties[$property->getName()] = $property; } - - $members = (array)$Object; - - foreach( $properties as $plain_name => $property ) { - + + $members = (array) $Object; + + foreach ($properties as $plain_name => $property) { + $name = $raw_name = $plain_name; if ($property->isStatic()) { - $name = 'static:'.$name; + $name = 'static:' . $name; } if ($property->isPublic()) { - $name = 'public:'.$name; + $name = 'public:' . $name; } else if ($property->isPrivate()) { - $name = 'private:'.$name; - $raw_name = "\0".$class."\0".$raw_name; + $name = 'private:' . $name; + $raw_name = "\0" . $class . "\0" . $raw_name; } else if ($property->isProtected()) { - $name = 'protected:'.$name; - $raw_name = "\0".'*'."\0".$raw_name; + $name = 'protected:' . $name; + $raw_name = "\0" . '*' . "\0" . $raw_name; } - + if (!(isset($this->objectFilters[$class_lower]) - && is_array($this->objectFilters[$class_lower]) - && in_array($plain_name,$this->objectFilters[$class_lower]))) { - - if (array_key_exists($raw_name,$members) - && !$property->isStatic()) { - - $return[$name] = $this->encodeObject($members[$raw_name], $ObjectDepth + 1, 1, $MaxDepth + 1); - + && is_array($this->objectFilters[$class_lower]) + && in_array($plain_name, $this->objectFilters[$class_lower]))) { + + if (array_key_exists($raw_name, $members) + && !$property->isStatic()) { + + $return[$name] = $this->encodeObject($members[$raw_name], $ObjectDepth + 1, 1, $MaxDepth + 1); + } else { - if (method_exists($property,'setAccessible')) { + if (method_exists($property, 'setAccessible')) { $property->setAccessible(true); $return[$name] = $this->encodeObject($property->getValue($Object), $ObjectDepth + 1, 1, $MaxDepth + 1); } else @@ -1611,58 +1638,57 @@ protected function encodeObject($Object, $ObjectDepth = 1, $ArrayDepth = 1, $Max $return[$name] = '** Excluded by Filter **'; } } - + // Include all members that are not defined in the class // but exist in the object - foreach( $members as $raw_name => $value ) { - + foreach ($members as $raw_name => $value) { + $name = $raw_name; - - if ($name{0} == "\0") { + + if ("\0" == $name{0}) { $parts = explode("\0", $name); - $name = $parts[2]; + $name = $parts[2]; } - + $plain_name = $name; - + if (!isset($properties[$name])) { - $name = 'undeclared:'.$name; - + $name = 'undeclared:' . $name; + if (!(isset($this->objectFilters[$class_lower]) - && is_array($this->objectFilters[$class_lower]) - && in_array($plain_name,$this->objectFilters[$class_lower]))) { - + && is_array($this->objectFilters[$class_lower]) + && in_array($plain_name, $this->objectFilters[$class_lower]))) { + $return[$name] = $this->encodeObject($value, $ObjectDepth + 1, 1, $MaxDepth + 1); } else { $return[$name] = '** Excluded by Filter **'; } } } - + array_pop($this->objectStack); - + } elseif (is_array($Object)) { - + if ($ArrayDepth > $this->options['maxArrayDepth']) { - return '** Max Array Depth ('.$this->options['maxArrayDepth'].') **'; + return '** Max Array Depth (' . $this->options['maxArrayDepth'] . ') **'; } - + foreach ($Object as $key => $val) { - + // Encoding the $GLOBALS PHP array causes an infinite loop // if the recursion is not reset here as it contains // a reference to itself. This is the only way I have come up // with to stop infinite recursion in this case. - if ($key=='GLOBALS' - && is_array($val) - && array_key_exists('GLOBALS',$val)) { + if ('GLOBALS' == $key && is_array($val) + && array_key_exists('GLOBALS', $val)) { $val['GLOBALS'] = '** Recursion (GLOBALS) **'; } - + $return[$key] = $this->encodeObject($val, 1, $ArrayDepth + 1, $MaxDepth + 1); } } else { - if (self::is_utf8($Object)) { + if (self::isUtf8($Object)) { return $Object; } else { return utf8_encode($Object); @@ -1677,35 +1703,51 @@ protected function encodeObject($Object, $ObjectDepth = 1, $ArrayDepth = 1, $Max * @param mixed $str String to be tested * @return boolean */ - protected static function is_utf8($str) + protected static function isUtf8($str) { - if(function_exists('mb_detect_encoding')) { + if (function_exists('mb_detect_encoding')) { return (mb_detect_encoding($str) == 'UTF-8'); } - $c=0; $b=0; - $bits=0; - $len=strlen($str); - for($i=0; $i<$len; $i++){ - $c=ord($str[$i]); - if ($c > 128){ - if (($c >= 254)) return false; - elseif ($c >= 252) $bits=6; - elseif ($c >= 248) $bits=5; - elseif ($c >= 240) $bits=4; - elseif ($c >= 224) $bits=3; - elseif ($c >= 192) $bits=2; - else return false; - if (($i+$bits) > $len) return false; - while($bits > 1){ + $c = 0; + $b = 0; + $bits = 0; + $len = strlen($str); + for ($i = 0; $i < $len; $i++) { + $c = ord($str[$i]); + if ($c > 128) { + if (($c >= 254)) { + return false; + } elseif ($c >= 252) { + $bits = 6; + } elseif ($c >= 248) { + $bits = 5; + } elseif ($c >= 240) { + $bits = 4; + } elseif ($c >= 224) { + $bits = 3; + } elseif ($c >= 192) { + $bits = 2; + } else { + return false; + } + + if (($i + $bits) > $len) { + return false; + } + + while ($bits > 1) { $i++; - $b=ord($str[$i]); - if ($b < 128 || $b > 191) return false; + $b = ord($str[$i]); + if ($b < 128 || $b > 191) { + return false; + } + $bits--; } } } return true; - } + } /** * Converts to and from JSON format. @@ -1762,33 +1804,31 @@ protected static function is_utf8($str) * @license http://www.opensource.org/licenses/bsd-license.php * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198 */ - - + /** * Keep a list of objects as we descend into the array so we can detect recursion. */ private $json_objectStack = array(); - - /** - * convert a string from one UTF-8 char to one UTF-16 char - * - * Normally should be handled by mb_convert_encoding, but - * provides a slower PHP-only method for installations - * that lack the multibye string extension. - * - * @param string $utf8 UTF-8 character - * @return string UTF-16 character - * @access private - */ - private function json_utf82utf16($utf8) + /** + * convert a string from one UTF-8 char to one UTF-16 char + * + * Normally should be handled by mb_convert_encoding, but + * provides a slower PHP-only method for installations + * that lack the multibye string extension. + * + * @param string $utf8 UTF-8 character + * @return string UTF-16 character + * @access private + */ + private function jsonUtf82utf16($utf8) { // oh please oh please oh please oh please oh please if (function_exists('mb_convert_encoding')) { return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8'); } - switch(strlen($utf8)) { + switch (strlen($utf8)) { case 1: // this case should never be reached, because we are in ASCII range // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 @@ -1798,42 +1838,42 @@ private function json_utf82utf16($utf8) // return a UTF-16 character from a 2-byte UTF-8 char // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 return chr(0x07 & (ord($utf8{0}) >> 2)) - . chr((0xC0 & (ord($utf8{0}) << 6)) - | (0x3F & ord($utf8{1}))); + . chr((0xC0 & (ord($utf8{0}) << 6)) + | (0x3F & ord($utf8{1}))); case 3: // return a UTF-16 character from a 3-byte UTF-8 char // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 return chr((0xF0 & (ord($utf8{0}) << 4)) - | (0x0F & (ord($utf8{1}) >> 2))) - . chr((0xC0 & (ord($utf8{1}) << 6)) - | (0x7F & ord($utf8{2}))); + | (0x0F & (ord($utf8{1}) >> 2))) + . chr((0xC0 & (ord($utf8{1}) << 6)) + | (0x7F & ord($utf8{2}))); } // ignoring UTF-32 for now, sorry return ''; } - /** - * encodes an arbitrary variable into JSON format - * - * @param mixed $var any number, boolean, string, array, or object to be encoded. - * see argument 1 to Services_JSON() above for array-parsing behavior. - * if var is a strng, note that encode() always expects it - * to be in ASCII or UTF-8 format! - * - * @return mixed JSON string representation of input var or an error if a problem occurs - * @access public - */ - private function json_encode($var) - { - + /** + * encodes an arbitrary variable into JSON format + * + * @param mixed $var any number, boolean, string, array, or object to be encoded. + * see argument 1 to Services_JSON() above for array-parsing behavior. + * if var is a strng, note that encode() always expects it + * to be in ASCII or UTF-8 format! + * + * @return mixed JSON string representation of input var or an error if a problem occurs + * @access public + */ + private function jsonEncode($var) + { + if (is_object($var)) { - if (in_array($var,$this->json_objectStack)) { + if (in_array($var, $this->json_objectStack)) { return '"** Recursion **"'; } } - + switch (gettype($var)) { case 'boolean': return $var ? 'true' : 'false'; @@ -1850,39 +1890,39 @@ private function json_encode($var) case 'string': // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT - $ascii = ''; + $ascii = ''; $strlen_var = strlen($var); - /* - * Iterate over every character in the string, - * escaping with a slash or encoding to UTF-8 where necessary - */ + /* + * Iterate over every character in the string, + * escaping with a slash or encoding to UTF-8 where necessary + */ for ($c = 0; $c < $strlen_var; ++$c) { $ord_var_c = ord($var{$c}); switch (true) { - case $ord_var_c == 0x08: + case 0x08 == $ord_var_c: $ascii .= '\b'; break; - case $ord_var_c == 0x09: + case 0x09 == $ord_var_c: $ascii .= '\t'; break; - case $ord_var_c == 0x0A: + case 0x0A == $ord_var_c: $ascii .= '\n'; break; - case $ord_var_c == 0x0C: + case 0x0C == $ord_var_c: $ascii .= '\f'; break; - case $ord_var_c == 0x0D: + case 0x0D == $ord_var_c: $ascii .= '\r'; break; - case $ord_var_c == 0x22: - case $ord_var_c == 0x2F: - case $ord_var_c == 0x5C: + case 0x22 == $ord_var_c: + case 0x2F == $ord_var_c: + case 0x5C == $ord_var_c: // double quote, slash, slosh - $ascii .= '\\'.$var{$c}; + $ascii .= '\\' . $var{$c}; break; case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)): @@ -1895,7 +1935,7 @@ private function json_encode($var) // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $char = pack('C*', $ord_var_c, ord($var{$c + 1})); $c += 1; - $utf16 = $this->json_utf82utf16($char); + $utf16 = $this->jsonUtf82utf16($char); $ascii .= sprintf('\u%04s', bin2hex($utf16)); break; @@ -1903,10 +1943,10 @@ private function json_encode($var) // characters U-00000800 - U-0000FFFF, mask 1110XXXX // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $char = pack('C*', $ord_var_c, - ord($var{$c + 1}), - ord($var{$c + 2})); + ord($var{$c + 1}), + ord($var{$c + 2})); $c += 2; - $utf16 = $this->json_utf82utf16($char); + $utf16 = $this->jsonUtf82utf16($char); $ascii .= sprintf('\u%04s', bin2hex($utf16)); break; @@ -1914,11 +1954,11 @@ private function json_encode($var) // characters U-00010000 - U-001FFFFF, mask 11110XXX // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $char = pack('C*', $ord_var_c, - ord($var{$c + 1}), - ord($var{$c + 2}), - ord($var{$c + 3})); + ord($var{$c + 1}), + ord($var{$c + 2}), + ord($var{$c + 3})); $c += 3; - $utf16 = $this->json_utf82utf16($char); + $utf16 = $this->jsonUtf82utf16($char); $ascii .= sprintf('\u%04s', bin2hex($utf16)); break; @@ -1926,12 +1966,12 @@ private function json_encode($var) // characters U-00200000 - U-03FFFFFF, mask 111110XX // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $char = pack('C*', $ord_var_c, - ord($var{$c + 1}), - ord($var{$c + 2}), - ord($var{$c + 3}), - ord($var{$c + 4})); + ord($var{$c + 1}), + ord($var{$c + 2}), + ord($var{$c + 3}), + ord($var{$c + 4})); $c += 4; - $utf16 = $this->json_utf82utf16($char); + $utf16 = $this->jsonUtf82utf16($char); $ascii .= sprintf('\u%04s', bin2hex($utf16)); break; @@ -1939,19 +1979,19 @@ private function json_encode($var) // characters U-04000000 - U-7FFFFFFF, mask 1111110X // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $char = pack('C*', $ord_var_c, - ord($var{$c + 1}), - ord($var{$c + 2}), - ord($var{$c + 3}), - ord($var{$c + 4}), - ord($var{$c + 5})); + ord($var{$c + 1}), + ord($var{$c + 2}), + ord($var{$c + 3}), + ord($var{$c + 4}), + ord($var{$c + 5})); $c += 5; - $utf16 = $this->json_utf82utf16($char); + $utf16 = $this->jsonUtf82utf16($char); $ascii .= sprintf('\u%04s', bin2hex($utf16)); break; } } - return '"'.$ascii.'"'; + return '"' . $ascii . '"'; case 'array': /* @@ -1974,16 +2014,16 @@ private function json_encode($var) // treat as a JSON object if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) { - + $this->json_objectStack[] = $var; $properties = array_map(array($this, 'json_name_value'), - array_keys($var), - array_values($var)); + array_keys($var), + array_values($var)); array_pop($this->json_objectStack); - foreach($properties as $property) { + foreach ($properties as $property) { if ($property instanceof Exception) { return $property; } @@ -1999,7 +2039,7 @@ private function json_encode($var) array_pop($this->json_objectStack); - foreach($elements as $element) { + foreach ($elements as $element) { if ($element instanceof Exception) { return $element; } @@ -2013,17 +2053,17 @@ private function json_encode($var) $this->json_objectStack[] = $var; $properties = array_map(array($this, 'json_name_value'), - array_keys($vars), - array_values($vars)); + array_keys($vars), + array_values($vars)); array_pop($this->json_objectStack); - - foreach($properties as $property) { + + foreach ($properties as $property) { if ($property instanceof Exception) { return $property; } } - + return '{' . join(',', $properties) . '}'; default: @@ -2031,39 +2071,38 @@ private function json_encode($var) } } - /** - * array-walking function for use in generating JSON-formatted name-value pairs - * - * @param string $name name of key to use - * @param mixed $value reference to an array element to be encoded - * - * @return string JSON-formatted name-value pair, like '"name":value' - * @access private - */ - private function json_name_value($name, $value) + /** + * array-walking function for use in generating JSON-formatted name-value pairs + * + * @param string $name name of key to use + * @param mixed $value reference to an array element to be encoded + * + * @return string JSON-formatted name-value pair, like '"name":value' + * @access private + */ + private function jsonNameValue($name, $value) { // Encoding the $GLOBALS PHP array causes an infinite loop // if the recursion is not reset here as it contains // a reference to itself. This is the only way I have come up // with to stop infinite recursion in this case. - if ($name=='GLOBALS' - && is_array($value) - && array_key_exists('GLOBALS',$value)) { + if ('GLOBALS' == $name && is_array($value) + && array_key_exists('GLOBALS', $value)) { $value['GLOBALS'] = '** Recursion **'; } - - $encoded_value = $this->json_encode($value); + + $encoded_value = $this->jsonEncode($value); if ($encoded_value instanceof Exception) { return $encoded_value; } - return $this->json_encode(strval($name)) . ':' . $encoded_value; + return $this->jsonEncode(strval($name)) . ':' . $encoded_value; } /** * @deprecated - */ + */ public function setProcessorUrl($URL) { trigger_error("The FirePHP::setProcessorUrl() method is no longer supported", E_USER_DEPRECATED); @@ -2075,5 +2114,5 @@ public function setProcessorUrl($URL) public function setRendererUrl($URL) { trigger_error("The FirePHP::setRendererUrl() method is no longer supported", E_USER_DEPRECATED); - } + } } diff --git a/ThinkPHP/Library/Behavior/ParseTemplateBehavior.class.php b/ThinkPHP/Library/Behavior/ParseTemplateBehavior.class.php index 21b6853e0..32f80579b 100644 --- a/ThinkPHP/Library/Behavior/ParseTemplateBehavior.class.php +++ b/ThinkPHP/Library/Behavior/ParseTemplateBehavior.class.php @@ -9,40 +9,47 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Behavior; + use Think\Storage; use Think\Think; + /** * 系统行为扩展:模板解析 */ -class ParseTemplateBehavior { +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'])) { // 缓存有效 + 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{ + 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']); + $tpl->fetch($_content, $_data['var'], $_data['prefix']); } - }else{ + } 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); + 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); } } } @@ -54,23 +61,27 @@ public function run(&$_data){ * @param string $tmplTemplateFile 模板文件名 * @return boolean */ - protected function checkCache($tmplTemplateFile,$prefix='') { + 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)){ + } + + $tmplCacheFile = C('CACHE_PATH') . $prefix . md5($tmplTemplateFile) . C('TMPL_CACHFILE_SUFFIX'); + if (!Storage::has($tmplCacheFile)) { return false; - }elseif (filemtime($tmplTemplateFile) > Storage::get($tmplCacheFile,'mtime')) { + } elseif (filemtime($tmplTemplateFile) > Storage::get($tmplCacheFile, 'mtime')) { // 模板文件如果有更新则缓存需要更新 return false; - }elseif (C('TMPL_CACHE_TIME') != 0 && time() > Storage::get($tmplCacheFile,'mtime')+C('TMPL_CACHE_TIME')) { + } 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')) { + if (C('LAYOUT_ON')) { + $layoutFile = THEME_PATH . C('LAYOUT_NAME') . C('TMPL_TEMPLATE_SUFFIX'); + if (filemtime($layoutFile) > Storage::get($tmplCacheFile, 'mtime')) { return false; } } @@ -85,11 +96,12 @@ protected function checkCache($tmplTemplateFile,$prefix='') { * @param string $tmplContent 模板内容 * @return boolean */ - protected function checkContentCache($tmplContent,$prefix='') { - if(Storage::has(C('CACHE_PATH').$prefix.md5($tmplContent).C('TMPL_CACHFILE_SUFFIX'))){ + protected function checkContentCache($tmplContent, $prefix = '') + { + if (Storage::has(C('CACHE_PATH') . $prefix . md5($tmplContent) . C('TMPL_CACHFILE_SUFFIX'))) { return true; - }else{ + } else { return false; } - } + } } diff --git a/ThinkPHP/Library/Behavior/ReadHtmlCacheBehavior.class.php b/ThinkPHP/Library/Behavior/ReadHtmlCacheBehavior.class.php index ce167daa4..cb05c44a6 100644 --- a/ThinkPHP/Library/Behavior/ReadHtmlCacheBehavior.class.php +++ b/ThinkPHP/Library/Behavior/ReadHtmlCacheBehavior.class.php @@ -9,80 +9,96 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Behavior; + use Think\Storage; + /** * 系统行为扩展:静态缓存读取 */ -class ReadHtmlCacheBehavior { +class ReadHtmlCacheBehavior +{ // 行为扩展的执行入口必须是run - public function run(&$params){ + public function run(&$params) + { // 开启静态缓存 - if(IS_GET && C('HTML_CACHE_ON')) { + if (IS_GET && C('HTML_CACHE_ON')) { $cacheTime = $this->requireHtmlCache(); - if( false !== $cacheTime && $this->checkHTMLCache(HTML_FILE_NAME,$cacheTime)) { //静态页面有效 + if (false !== $cacheTime && $this->checkHTMLCache(HTML_FILE_NAME, $cacheTime)) { + //静态页面有效 // 读取静态页面输出 - echo Storage::read(HTML_FILE_NAME,'html'); + echo Storage::read(HTML_FILE_NAME, 'html'); exit(); } } } // 判断是否需要静态缓存 - static private function requireHtmlCache() { + private static function requireHtmlCache() + { // 分析当前的静态规则 - $htmls = C('HTML_CACHE_RULES'); // 读取静态规则 - if(!empty($htmls)) { + $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 (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)) { + if (!empty($html)) { // 解读静态规则 - $rule = is_array($html)?$html[0]:$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; + $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); + $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 = 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 = 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; + $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')); + define('HTML_FILE_NAME', HTML_PATH . $rule . C('HTML_FILE_SUFFIX', null, '.html')); return $cacheTime; } } @@ -98,15 +114,16 @@ static private function requireHtmlCache() { * @param integer $cacheTime 缓存有效期 * @return boolean */ - static public function checkHTMLCache($cacheFile='',$cacheTime='') { - if(!is_file($cacheFile) && 'sae' != APP_MODE ){ + public static 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')) { + } elseif (filemtime(\Think\Think::instance('Think\View')->parseTemplate()) > Storage::get($cacheFile, 'mtime', 'html')) { // 模板文件如果更新静态文件需要更新 return false; - }elseif(!is_numeric($cacheTime) && function_exists($cacheTime)){ + } elseif (!is_numeric($cacheTime) && function_exists($cacheTime)) { return $cacheTime($cacheFile); - }elseif ($cacheTime != 0 && NOW_TIME > Storage::get($cacheFile,'mtime','html')+$cacheTime) { + } elseif (0 != $cacheTime && NOW_TIME > Storage::get($cacheFile, 'mtime', 'html') + $cacheTime) { // 文件是否在有效期 return false; } @@ -114,4 +131,4 @@ static public function checkHTMLCache($cacheFile='',$cacheTime='') { return true; } -} \ No newline at end of file +} diff --git a/ThinkPHP/Library/Behavior/RobotCheckBehavior.class.php b/ThinkPHP/Library/Behavior/RobotCheckBehavior.class.php index 77242db1c..cf698ee19 100644 --- a/ThinkPHP/Library/Behavior/RobotCheckBehavior.class.php +++ b/ThinkPHP/Library/Behavior/RobotCheckBehavior.class.php @@ -9,33 +9,37 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Behavior; + /** * 机器人检测 * @author liu21st */ -class RobotCheckBehavior { - - public function run(&$params) { +class RobotCheckBehavior +{ + + public function run(&$params) + { // 机器人访问检测 - if(C('LIMIT_ROBOT_VISIT',null,true) && self::isRobot()) { + if (C('LIMIT_ROBOT_VISIT', null, true) && self::isRobot()) { // 禁止机器人访问 exit('Access Denied'); } } - static private function isRobot() { + private static function isRobot() + { static $_robot = null; - if(is_null($_robot)) { - $spiders = 'Bot|Crawl|Spider|slurp|sohu-search|lycos|robozilla'; + 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; + if (preg_match("/($browsers)/", $_SERVER['HTTP_USER_AGENT'])) { + $_robot = false; + } elseif (preg_match("/($spiders)/", $_SERVER['HTTP_USER_AGENT'])) { + $_robot = true; } else { - $_robot = false; + $_robot = false; } } return $_robot; } -} \ No newline at end of file +} diff --git a/ThinkPHP/Library/Behavior/ShowPageTraceBehavior.class.php b/ThinkPHP/Library/Behavior/ShowPageTraceBehavior.class.php index 4fc119783..8ee712128 100644 --- a/ThinkPHP/Library/Behavior/ShowPageTraceBehavior.class.php +++ b/ThinkPHP/Library/Behavior/ShowPageTraceBehavior.class.php @@ -9,16 +9,18 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Behavior; -use Think\Log; + /** * 系统行为扩展:页面Trace显示输出 */ -class ShowPageTraceBehavior { - protected $tracePageTabs = array('BASE'=>'基本','FILE'=>'文件','INFO'=>'流程','ERR|NOTIC'=>'错误','SQL'=>'SQL','DEBUG'=>'调试'); +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')) { + public function run(&$params) + { + if (!IS_AJAX && !IS_CLI && C('SHOW_PAGE_TRACE')) { echo $this->showTrace(); } } @@ -27,93 +29,97 @@ public function run(&$params){ * 显示页面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 )'; + 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 = 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); + $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; + $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; + $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(); + 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]:''; + $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]; + 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"; + $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"; + } else { + $content .= print_r($val, true) . "\r\n"; } $content .= "\r\n"; } } - error_log(str_replace('
',"\r\n",$content), 3,C('LOG_PATH').date('y_m_d').'_trace.log'); + error_log(str_replace('
', "\r\n", $content), 3, C('LOG_PATH') . date('y_m_d') . '_trace.log'); } - unset($files,$info,$base); + unset($files, $info, $base); // 调用Trace页面模板 ob_start(); - include C('TMPL_TRACE_FILE')?C('TMPL_TRACE_FILE'):THINK_PATH.'Tpl/page_trace.tpl'; + include C('TMPL_TRACE_FILE') ? C('TMPL_TRACE_FILE') : THINK_PATH . 'Tpl/page_trace.tpl'; return ob_get_clean(); } /** * 获取运行时间 */ - private function showTime() { + private function showTime() + { // 显示运行时间 - G('beginTime',$GLOBALS['_beginTime']); + 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 )'; + 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 )'; } } diff --git a/ThinkPHP/Library/Behavior/ShowRuntimeBehavior.class.php b/ThinkPHP/Library/Behavior/ShowRuntimeBehavior.class.php index 66360d3c4..6f62361da 100644 --- a/ThinkPHP/Library/Behavior/ShowRuntimeBehavior.class.php +++ b/ThinkPHP/Library/Behavior/ShowRuntimeBehavior.class.php @@ -9,25 +9,30 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Behavior; + /** * 系统行为扩展:运行时间信息显示 */ -class ShowRuntimeBehavior { +class ShowRuntimeBehavior +{ // 行为扩展的执行入口必须是run - public function run(&$content){ - if(C('SHOW_RUN_TIME')){ - if(false !== strpos($content,'{__NORUNTIME__}')) { - $content = str_replace('{__NORUNTIME__}','',$content); - }else{ + 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; + if (strpos($content, '{__RUNTIME__}')) { + $content = str_replace('{__RUNTIME__}', $runtime, $content); + } else { + $content .= $runtime; + } + } - }else{ - $content = str_replace(array('{__NORUNTIME__}','{__RUNTIME__}'),'',$content); + } else { + $content = str_replace(array('{__NORUNTIME__}', '{__RUNTIME__}'), '', $content); } } @@ -36,34 +41,35 @@ public function run(&$content){ * @access private * @return string */ - private function showTime() { + private function showTime() + { // 显示运行时间 - G('beginTime',$GLOBALS['_beginTime']); + G('beginTime', $GLOBALS['_beginTime']); G('viewEndTime'); - $showTime = 'Process: '.G('beginTime','viewEndTime').'s '; - if(C('SHOW_ADV_TIME')) { + $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 )'; + $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') ) { + if (C('SHOW_DB_TIMES')) { // 显示数据库操作次数 - $showTime .= ' | DB :'.N('db_query').' queries '.N('db_write').' writes '; + $showTime .= ' | DB :' . N('db_query') . ' queries ' . N('db_write') . ' writes '; } - if(C('SHOW_CACHE_TIMES') ) { + if (C('SHOW_CACHE_TIMES')) { // 显示缓存读写次数 - $showTime .= ' | Cache :'.N('cache_read').' gets '.N('cache_write').' writes '; + $showTime .= ' | Cache :' . N('cache_read') . ' gets ' . N('cache_write') . ' writes '; } - if(MEMORY_LIMIT_ON && C('SHOW_USE_MEM')) { + if (MEMORY_LIMIT_ON && C('SHOW_USE_MEM')) { // 显示内存开销 - $showTime .= ' | UseMem:'. number_format((memory_get_usage() - $GLOBALS['_startUseMems'])/1024).' kb'; + $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_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']); + if (C('SHOW_FUN_TIMES')) { + $fun = get_defined_functions(); + $showTime .= ' | CallFun:' . count($fun['user']) . ',' . count($fun['internal']); } return $showTime; } -} \ No newline at end of file +} diff --git a/ThinkPHP/Library/Behavior/TokenBuildBehavior.class.php b/ThinkPHP/Library/Behavior/TokenBuildBehavior.class.php index 6e7888a6f..796ecfadf 100644 --- a/ThinkPHP/Library/Behavior/TokenBuildBehavior.class.php +++ b/ThinkPHP/Library/Behavior/TokenBuildBehavior.class.php @@ -9,46 +9,53 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Behavior; + /** * 系统行为扩展:表单令牌生成 */ -class TokenBuildBehavior { +class TokenBuildBehavior +{ - public function run(&$content){ - if(C('TOKEN_ON')) { - list($tokenName,$tokenKey,$tokenValue)=$this->getToken(); - $input_token = ''; - $meta_token = ''; - if(strpos($content,'{__TOKEN__}')) { + public function run(&$content) + { + if (C('TOKEN_ON')) { + list($tokenName, $tokenKey, $tokenValue) = $this->getToken(); + $input_token = ''; + $meta_token = ''; + if (strpos($content, '{__TOKEN__}')) { // 指定表单令牌隐藏域位置 - $content = str_replace('{__TOKEN__}',$input_token,$content); - }elseif(preg_match('/<\/form(\s*)>/is',$content,$match)) { + $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_replace($match[0], $input_token . $match[0], $content); } - $content = str_ireplace('',$meta_token.'',$content); - }else{ - $content = str_replace('{__TOKEN__}','',$content); + $content = str_ireplace('', $meta_token . '', $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(); + 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 + $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值 + } 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); + return array($tokenName, $tokenKey, $tokenValue); } -} \ No newline at end of file +} diff --git a/ThinkPHP/Library/Behavior/UpgradeNoticeBehavior.class.php b/ThinkPHP/Library/Behavior/UpgradeNoticeBehavior.class.php index d9c67d098..0a191de64 100644 --- a/ThinkPHP/Library/Behavior/UpgradeNoticeBehavior.class.php +++ b/ThinkPHP/Library/Behavior/UpgradeNoticeBehavior.class.php @@ -7,6 +7,7 @@ // | Author: luofei614 // +---------------------------------------------------------------------- namespace Behavior; + /** * 升级短信通知, 如果有ThinkPHP新版升级,或者重要的更新,会发送短信通知你。 * 需要使用SAE的短信服务。请先找一个SAE的应用开通短信服务。 @@ -20,9 +21,9 @@ *
* * 2,将此文件放在应用的Lib/Behavior文件夹下。 - *注:在SAE上面使用时,以上两步可以省略 + *注:在SAE上面使用时,以上两步可以省略 * 3,在config.php中配置: - * 'UPGRADE_NOTICE_ON'=>true,//开启短信升级提醒功能 + * 'UPGRADE_NOTICE_ON'=>true,//开启短信升级提醒功能 * 'UPGRADE_NOTICE_AKEY'=>'your akey',//SAE应用的AKEY,如果在SAE上使用可以不填 * 'UPGRADE_NOTICE_SKEY'=>'your skey',//SAE应用的SKEY,如果在SAE上使用可以不填 *'UPGRADE_NOTICE_MOBILE'=>'136456789',//接受短信的手机号 @@ -32,86 +33,96 @@ * */ -class UpgradeNoticeBehavior { +class UpgradeNoticeBehavior +{ protected $header_ = ''; protected $httpCode_; protected $httpDesc_; protected $accesskey_; protected $secretkey_; - public function run(&$params) { + 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); + 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 ; + return; } - $akey = C('UPGRADE_NOTICE_AKEY',null,''); - $skey = C('UPGRADE_NOTICE_SKEY',null,''); + $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); + $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); //发送升级短信 + if ($info['version'] != $current_version) { + if ($this->sendSms($info['msg'])) { + trace($info['msg'], '升级通知成功', 'NOTIC', true); + } + //发送升级短信 } - S('think_upgrade_interval', true, C('UPGRADE_NOTICE_CHECK_INTERVAL',null,604800)); + 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_; + private function sendSms($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( + $headers = array( "FetchUrl: $url", - "AccessKey: ".$this->accesskey_, + "AccessKey: " . $this->accesskey_, "TimeStamp: " . $timestamp, - "Signature: $signature" + "Signature: $signature", ); $data = array( - 'mobile' => C('UPGRADE_NOTICE_MOBILE',null,'') , - 'msg' => $msg, - 'encoding' => 'UTF-8' + 'mobile' => C('UPGRADE_NOTICE_MOBILE', null, ''), + 'msg' => $msg, + 'encoding' => 'UTF-8', ); - if(!$ret = $this->send('http://g.apibus.io', $data, $headers)){ + 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()) { + 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); + 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); - + 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; } } diff --git a/ThinkPHP/Library/Behavior/WriteHtmlCacheBehavior.class.php b/ThinkPHP/Library/Behavior/WriteHtmlCacheBehavior.class.php index 6248867cc..a9d5a0bec 100644 --- a/ThinkPHP/Library/Behavior/WriteHtmlCacheBehavior.class.php +++ b/ThinkPHP/Library/Behavior/WriteHtmlCacheBehavior.class.php @@ -9,21 +9,25 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Behavior; + use Think\Storage; + /** * 系统行为扩展:静态缓存写入 */ -class WriteHtmlCacheBehavior { +class WriteHtmlCacheBehavior +{ // 行为扩展的执行入口必须是run - public function run(&$content) { + 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)) { + && !preg_match('/(-[a-z0-9]{2}){3,}/i', HTML_FILE_NAME)) { //静态文件写入 Storage::put(HTML_FILE_NAME, $content, 'html'); } } -} \ No newline at end of file +} diff --git a/ThinkPHP/Library/Org/Net/Http.class.php b/ThinkPHP/Library/Org/Net/Http.class.php index 7fe2c2b14..94b509715 100644 --- a/ThinkPHP/Library/Org/Net/Http.class.php +++ b/ThinkPHP/Library/Org/Net/Http.class.php @@ -9,12 +9,14 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Org\Net; + /** * Http 工具类 * 提供一系列的Http方法 * @author liu21st */ -class Http { +class Http +{ /** * 采集远程文件 @@ -23,9 +25,10 @@ class Http { * @param string $local 本地保存文件名 * @return mixed */ - static public function curlDownload($remote,$local) { + public static function curlDownload($remote, $local) + { $cp = curl_init($remote); - $fp = fopen($local,"w"); + $fp = fopen($local, "w"); curl_setopt($cp, CURLOPT_FILE, $fp); curl_setopt($cp, CURLOPT_HEADER, 0); curl_exec($cp); @@ -33,65 +36,69 @@ static public function curlDownload($remote,$local) { 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()) { + /** + * 使用 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 + */ + public static function fsockopenDownload($url, $conf = array()) + { $return = ''; - if(!is_array($conf)) return $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; + $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, - ); + 'limit' => 0, + 'post' => '', + 'cookie' => '', + 'ip' => '', + 'timeout' => 15, + 'block' => true, + ); - foreach (array_merge($conf_arr, $conf) as $k=>$v) ${$k} = $v; + foreach (array_merge($conf_arr, $conf) as $k => $v) { + ${$k} = $v; + } - if($post) { - if(is_array($post)) - { + if ($post) { + if (is_array($post)) { $post = http_build_query($post); } - $out = "POST $path HTTP/1.0\r\n"; + $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 .= '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 = "GET $path HTTP/1.0\r\n"; $out .= "Accept: */*\r\n"; //$out .= "Referer: $boardurl\r\n"; $out .= "Accept-Language: zh-cn\r\n"; @@ -101,25 +108,25 @@ static public function fsockopenDownload($url, $conf = array()) { $out .= "Cookie: $cookie\r\n\r\n"; } $fp = @fsockopen(($ip ? $ip : $host), $port, $errno, $errstr, $timeout); - if(!$fp) { + 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']) { + if (!$status['timed_out']) { while (!feof($fp)) { - if(($header = @fgets($fp)) && ($header == "\r\n" || $header == "\n")) { + if (($header = @fgets($fp)) && ("\r\n" == $header || "\n" == $header)) { break; } } $stop = false; - while(!feof($fp) && !$stop) { - $data = fread($fp, ($limit == 0 || $limit > 8192 ? 8192 : $limit)); + while (!feof($fp) && !$stop) { + $data = fread($fp, (0 == $limit || $limit > 8192 ? 8192 : $limit)); $return .= $data; - if($limit) { + if ($limit) { $limit -= strlen($data); $stop = $limit <= 0; } @@ -142,42 +149,43 @@ static public function fsockopenDownload($url, $conf = array()) { * @param integer $expire 下载内容浏览器缓存时间 * @return void */ - static public function download ($filename, $showname='',$content='',$expire=180) { - if(is_file($filename)) { + public static 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 != '') { + } elseif (is_file(UPLOAD_PATH . $filename)) { + $filename = UPLOAD_PATH . $filename; + $length = filesize($filename); + } elseif ('' != $content) { $length = strlen($content); - }else { - E($filename.L('下载文件不存在!')); + } else { + E($filename . L('下载文件不存在!')); } - if(empty($showname)) { + 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"; - } + 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: 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("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 == '' ) { + header("Content-Transfer-Encoding: binary"); + if ('' == $content) { readfile($filename); - }else { - echo($content); + } else { + echo ($content); } exit(); } @@ -186,21 +194,22 @@ static public function download ($filename, $showname='',$content='',$expire=180 * 显示HTTP Header 信息 * @return string */ - static function getHeaderInfo($header='',$echo=true) { + public 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"); + $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(); + $output = ob_get_clean(); if ($echo) { echo (nl2br($output)); - }else { + } else { return $output; } @@ -210,62 +219,63 @@ static function getHeaderInfo($header='',$echo=true) { * HTTP Protocol defined status codes * @param int $num */ - static function sendHttpStatus($code) { - static $_status = array( - // Informational 1xx - 100 => 'Continue', - 101 => 'Switching Protocols', + public 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', + // 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', + // 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', + // 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]); - } - } -}//类定义结束 \ No newline at end of file + // 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]); + } + } +} //类定义结束 diff --git a/ThinkPHP/Library/Org/Net/IpLocation.class.php b/ThinkPHP/Library/Org/Net/IpLocation.class.php index 1d5730740..bf7c70347 100644 --- a/ThinkPHP/Library/Org/Net/IpLocation.class.php +++ b/ThinkPHP/Library/Org/Net/IpLocation.class.php @@ -9,12 +9,14 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Org\Net; + /** * IP 地理位置查询类 修改自 CoolCode.CN * 由于使用UTF8编码 如果使用纯真IP地址库的话 需要对返回结果进行编码转换 * @author liu21st */ -class IpLocation { +class IpLocation +{ /** * QQWry.Dat文件指针 * @@ -49,12 +51,13 @@ class IpLocation { * @param string $filename * @return IpLocation */ - public function __construct($filename = "UTFWry.dat") { + 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; + if (($this->fp = fopen(dirname(__FILE__) . '/' . $filename, 'rb')) !== false) { + $this->firstip = $this->getlong(); + $this->lastip = $this->getlong(); + $this->totalip = ($this->lastip - $this->firstip) / 7; } } @@ -64,7 +67,8 @@ public function __construct($filename = "UTFWry.dat") { * @access private * @return int */ - private function getlong() { + private function getlong() + { //将读取的little-endian编码的4个字节转化为长整型数 $result = unpack('Vlong', fread($this->fp, 4)); return $result['long']; @@ -76,9 +80,10 @@ private function getlong() { * @access private * @return int */ - private function getlong3() { + private function getlong3() + { //将读取的little-endian编码的3个字节转化为长整型数 - $result = unpack('Vlong', fread($this->fp, 3).chr(0)); + $result = unpack('Vlong', fread($this->fp, 3) . chr(0)); return $result['long']; } @@ -89,7 +94,8 @@ private function getlong3() { * @param string $ip * @return string */ - private function packip($ip) { + private function packip($ip) + { // 将IP地址转化为长整型数,如果在PHP5中,IP地址错误,则返回False, // 这时intval将Flase转化为整数-1,之后压缩成big-endian编码的字符串 return pack('N', intval(ip2long($ip))); @@ -102,11 +108,13 @@ private function packip($ip) { * @param string $data * @return string */ - private function getstring($data = "") { + private function getstring($data = "") + { $char = fread($this->fp, 1); - while (ord($char) > 0) { // 字符串按照C格式保存,以\0结束 - $data .= $char; // 将读取的字符连接到给定字符串之后 - $char = fread($this->fp, 1); + while (ord($char) > 0) { + // 字符串按照C格式保存,以\0结束 + $data .= $char; // 将读取的字符连接到给定字符串之后 + $char = fread($this->fp, 1); } return $data; } @@ -117,18 +125,19 @@ private function getstring($data = "") { * @access private * @return string */ - private function getarea() { - $byte = fread($this->fp, 1); // 标志字节 + private function getarea() + { + $byte = fread($this->fp, 1); // 标志字节 switch (ord($byte)) { - case 0: // 没有区域信息 + case 0: // 没有区域信息 $area = ""; break; case 1: - case 2: // 标志字节为1或2,表示区域信息被重定向 + case 2: // 标志字节为1或2,表示区域信息被重定向 fseek($this->fp, $this->getlong3()); $area = $this->getstring(); break; - default: // 否则,表示区域信息没有被重定向 + default: // 否则,表示区域信息没有被重定向 $area = $this->getstring($byte); break; } @@ -142,75 +151,83 @@ private function getarea() { * @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 + 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); // 计算近似中间记录 + $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地址 + $beginip = strrev(fread($this->fp, 4)); // 获取中间记录的开始IP地址 // strrev函数在这里的作用是将little-endian的压缩IP地址转化为big-endian的格式 // 以便用于比较,后面相同。 - if ($ip < $beginip) { // 用户的IP小于中间记录的开始IP地址时 - $u = $i - 1; // 将搜索的上边界修改为中间记录减一 - } - else { + 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范围内时 + $endip = strrev(fread($this->fp, 4)); // 获取中间记录的结束IP地址 + if ($ip > $endip) { // 用户的IP大于中间记录的结束IP地址时 + $l = $i + 1; // 将搜索的下边界修改为中间记录加一 + } else { + // 用户的IP在中间记录的IP范围内时 $findip = $this->firstip + $i * 7; - break; // 则表示找到结果,退出循环 + break; // 则表示找到结果,退出循环 } } } //获取查找到的IP地理位置信息 fseek($this->fp, $findip); - $location['beginip'] = long2ip($this->getlong()); // 用户IP所在范围的开始地址 - $offset = $this->getlong3(); + $location['beginip'] = long2ip($this->getlong()); // 用户IP所在范围的开始地址 + $offset = $this->getlong3(); fseek($this->fp, $offset); - $location['endip'] = long2ip($this->getlong()); // 用户IP所在范围的结束地址 - $byte = fread($this->fp, 1); // 标志字节 + $location['endip'] = long2ip($this->getlong()); // 用户IP所在范围的结束地址 + $byte = fread($this->fp, 1); // 标志字节 switch (ord($byte)) { - case 1: // 标志字节为1,表示国家和区域信息都被同时重定向 - $countryOffset = $this->getlong3(); // 重定向地址 + case 1: // 标志字节为1,表示国家和区域信息都被同时重定向 + $countryOffset = $this->getlong3(); // 重定向地址 fseek($this->fp, $countryOffset); - $byte = fread($this->fp, 1); // 标志字节 + $byte = fread($this->fp, 1); // 标志字节 switch (ord($byte)) { - case 2: // 标志字节为2,表示国家信息又被重定向 + case 2: // 标志字节为2,表示国家信息又被重定向 fseek($this->fp, $this->getlong3()); - $location['country'] = $this->getstring(); + $location['country'] = $this->getstring(); fseek($this->fp, $countryOffset + 4); - $location['area'] = $this->getarea(); + $location['area'] = $this->getarea(); break; - default: // 否则,表示国家信息没有被重定向 - $location['country'] = $this->getstring($byte); - $location['area'] = $this->getarea(); + default: // 否则,表示国家信息没有被重定向 + $location['country'] = $this->getstring($byte); + $location['area'] = $this->getarea(); break; } break; - case 2: // 标志字节为2,表示国家信息被重定向 + case 2: // 标志字节为2,表示国家信息被重定向 fseek($this->fp, $this->getlong3()); - $location['country'] = $this->getstring(); + $location['country'] = $this->getstring(); fseek($this->fp, $offset + 8); - $location['area'] = $this->getarea(); + $location['area'] = $this->getarea(); break; - default: // 否则,表示国家信息没有被重定向 - $location['country'] = $this->getstring($byte); - $location['area'] = $this->getarea(); + default: // 否则,表示国家信息没有被重定向 + $location['country'] = $this->getstring($byte); + $location['area'] = $this->getarea(); break; } - if (trim($location['country']) == 'CZ88.NET') { // CZ88.NET表示没有有效信息 + if (trim($location['country']) == 'CZ88.NET') { + // CZ88.NET表示没有有效信息 $location['country'] = '未知'; } if (trim($location['area']) == 'CZ88.NET') { @@ -223,11 +240,12 @@ public function getlocation($ip='') { * 析构函数,用于在页面执行结束后自动关闭打开的文件。 * */ - public function __destruct() { + public function __destruct() + { if ($this->fp) { fclose($this->fp); } $this->fp = 0; } -} \ No newline at end of file +} diff --git a/ThinkPHP/Library/Org/Util/ArrayList.class.php b/ThinkPHP/Library/Org/Util/ArrayList.class.php index 4aae88984..a353e9daa 100644 --- a/ThinkPHP/Library/Org/Util/ArrayList.class.php +++ b/ThinkPHP/Library/Org/Util/ArrayList.class.php @@ -9,6 +9,7 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Org\Util; + /** * ArrayList实现类 * @category Think @@ -16,7 +17,8 @@ * @subpackage Util * @author liu21st */ -class ArrayList implements \IteratorAggregate { +class ArrayList implements \IteratorAggregate +{ /** * 集合元素 @@ -30,7 +32,8 @@ class ArrayList implements \IteratorAggregate { * @access public * @param string $elements 初始化数组元素 */ - public function __construct($elements = array()) { + public function __construct($elements = array()) + { if (!empty($elements)) { $this->_elements = $elements; } @@ -41,7 +44,8 @@ public function __construct($elements = array()) { * @access public * @return ArrayObject */ - public function getIterator() { + public function getIterator() + { return new ArrayObject($this->_elements); } @@ -51,17 +55,20 @@ public function getIterator() { * @param mixed $element 要添加的元素 * @return boolean */ - public function add($element) { + 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 unshift($element) + { + return (array_unshift($this->_elements, $element)) ? true : false; } // - public function pop() { + public function pop() + { return array_pop($this->_elements); } @@ -71,9 +78,10 @@ public function pop() { * @param ArrayList $list 元素列表 * @return boolean */ - public function addAll($list) { + public function addAll($list) + { $before = $this->size(); - foreach( $list as $element) { + foreach ($list as $element) { $this->add($element); } $after = $this->size(); @@ -84,7 +92,8 @@ public function addAll($list) { * 清除所有元素 * @access public */ - public function clear() { + public function clear() + { $this->_elements = array(); } @@ -94,8 +103,9 @@ public function clear() { * @param mixed $element 查找元素 * @return string */ - public function contains($element) { - return (array_search($element, $this->_elements) !== false ); + public function contains($element) + { + return (array_search($element, $this->_elements) !== false); } /** @@ -104,7 +114,8 @@ public function contains($element) { * @param integer $index 索引 * @return mixed */ - public function get($index) { + public function get($index) + { return $this->_elements[$index]; } @@ -115,7 +126,8 @@ public function get($index) { * @param mixed $element 查找元素 * @return integer */ - public function indexOf($element) { + public function indexOf($element) + { return array_search($element, $this->_elements); } @@ -124,7 +136,8 @@ public function indexOf($element) { * @access public * @return boolean */ - public function isEmpty() { + public function isEmpty() + { return empty($this->_elements); } @@ -134,13 +147,15 @@ public function isEmpty() { * @param mixed $element 查找元素 * @return integer */ - public function lastIndexOf($element) { + public function lastIndexOf($element) + { for ($i = (count($this->_elements) - 1); $i > 0; $i--) { - if ($element == $this->get($i)) { return $i; } + if ($this->get($i) == $element) {return $i;} } } - public function toJson() { + public function toJson() + { return json_encode($this->_elements); } @@ -151,9 +166,10 @@ public function toJson() { * @param integer $index 索引 * @return mixed */ - public function remove($index) { + public function remove($index) + { $element = $this->get($index); - if (!is_null($element)) { array_splice($this->_elements, $index, 1); } + if (!is_null($element)) {array_splice($this->_elements, $index, 1);} return $element; } @@ -163,15 +179,17 @@ public function remove($index) { * @param integer $offset 开始移除位置 * @param integer $length 移除长度 */ - public function removeRange($offset , $length) { - array_splice($this->_elements, $offset , $length); + public function removeRange($offset, $length) + { + array_splice($this->_elements, $offset, $length); } /** * 移出重复的值 * @access public */ - public function unique() { + public function unique() + { $this->_elements = array_unique($this->_elements); } @@ -181,8 +199,9 @@ public function unique() { * @param integer $offset 开始位置 * @param integer $length 长度 */ - public function range($offset,$length=null) { - return array_slice($this->_elements,$offset,$length); + public function range($offset, $length = null) + { + return array_slice($this->_elements, $offset, $length); } /** @@ -193,8 +212,9 @@ public function range($offset,$length=null) { * @param mixed $element 元素 * @return mixed */ - public function set($index, $element) { - $previous = $this->get($index); + public function set($index, $element) + { + $previous = $this->get($index); $this->_elements[$index] = $element; return $previous; } @@ -204,7 +224,8 @@ public function set($index, $element) { * @access public * @return integer */ - public function size() { + public function size() + { return count($this->_elements); } @@ -213,27 +234,32 @@ public function size() { * @access public * @return array */ - public function toArray() { + public function toArray() + { return $this->_elements; } // 列表排序 - public function ksort() { + public function ksort() + { ksort($this->_elements); } // 列表排序 - public function asort() { + public function asort() + { asort($this->_elements); } // 逆向排序 - public function rsort() { + public function rsort() + { rsort($this->_elements); } // 自然排序 - public function natsort() { + public function natsort() + { natsort($this->_elements); } diff --git a/ThinkPHP/Library/Org/Util/CodeSwitch.class.php b/ThinkPHP/Library/Org/Util/CodeSwitch.class.php index ee728c85f..73907b1c0 100644 --- a/ThinkPHP/Library/Org/Util/CodeSwitch.class.php +++ b/ThinkPHP/Library/Org/Util/CodeSwitch.class.php @@ -9,192 +9,213 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Org\Util; -class CodeSwitch { + +class CodeSwitch +{ // 错误信息 - static private $error = array(); + private static $error = array(); // 提示信息 - static private $info = array(); + private static $info = array(); // 记录错误 - static private function error($msg) { - self::$error[] = $msg; + private static function error($msg) + { + self::$error[] = $msg; } // 记录信息 - static private function info($info) { - self::$info[] = $info; + private static function info($info) + { + self::$info[] = $info; } - /** + /** * 编码转换函数,对整个文件进行编码转换 - * 支持以下转换 - * GB2312、UTF-8 WITH BOM转换为UTF-8 - * UTF-8、UTF-8 WITH BOM转换为GB2312 + * 支持以下转换 + * GB2312、UTF-8 WITH BOM转换为UTF-8 + * UTF-8、UTF-8 WITH BOM转换为GB2312 * @access public - * @param string $filename 文件名 - * @param string $out_charset 转换后的文件编码,与iconv使用的参数一致 + * @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编码,没有进行编码转换,不影响使用"); - } - } - - /** + public static function DetectAndSwitch($filename, $out_charset) + { + $fpr = fopen($filename, "r"); + $char1 = fread($fpr, 1); + $char2 = fread($fpr, 1); + $char3 = fread($fpr, 1); + + $originEncoding = ""; + + if (chr(239) == $char1 && chr(187) == $char2 && chr(191) == $char3) //UTF-8 WITH BOM + { + $originEncoding = "UTF-8 WITH BOM"; + } elseif (chr(255) == $char1 && chr(254) == $char2) //UNICODE LE + { + self::error("不支持从UNICODE LE转换到UTF-8或GB编码"); + fclose($fpr); + return; + } elseif (chr(254) == $char1 && chr(255) == $char2) { +//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 ("UTF-8 WITH BOM" == $originEncoding) { + //跳过三个字节,把后面的内容复制一遍得到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表示遍历到最底层 + * @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) ; - } - - /** + public 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 ("FILES" != $mode) { + $dirlist[] = $path; + } + + if ($handle = @opendir($path)) { + while (false !== ($file = readdir($handle))) { + if ('.' != $file && '..' != $file) { + $file = $path . $file; + if (!is_dir($file)) { + if ("DIRS" != $mode) { + $extension = ""; + $extpos = strrpos($file, '.'); + if (false !== $extpos) { + $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 (0 == $d) { + natcasesort($dirlist); + } + + return ($dirlist); + } + + /** * 对整个项目目录中的PHP和HTML文件行进编码转换 * @access public - * @param string $app 要遍历的项目路径 - * @param string $mode 遍历模式,一般取FILES,这样只返回带路径的文件名 - * @param array $file_types 文件后缀过滤数组 + * @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() { + public 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); + } + + } + + public static function getError() + { return self::$error; } - static public function getInfo() { + public static function getInfo() + { return self::$info; } -} \ No newline at end of file +} diff --git a/ThinkPHP/Library/Org/Util/Date.class.php b/ThinkPHP/Library/Org/Util/Date.class.php index 42346a7d6..3e1d099be 100644 --- a/ThinkPHP/Library/Org/Util/Date.class.php +++ b/ThinkPHP/Library/Org/Util/Date.class.php @@ -10,6 +10,7 @@ // +---------------------------------------------------------------------- namespace Org\Util; + /** * 日期时间操作类 * @category ORG @@ -18,115 +19,117 @@ * @author liu21st * @version $Id: Date.class.php 2662 2012-01-26 06:32:50Z liu21st $ */ -class Date { +use Org\Util\Date as Date; +class Date +{ /** * 日期的时间戳 * @var integer * @access protected */ - protected $date; + protected $date; /** * 时区 * @var integer * @access protected */ - protected $timezone; + protected $timezone; /** * 年 * @var integer * @access protected */ - protected $year; + protected $year; /** * 月 * @var integer * @access protected */ - protected $month; + protected $month; /** * 日 * @var integer * @access protected */ - protected $day; + protected $day; /** * 时 * @var integer * @access protected */ - protected $hour; + protected $hour; /** * 分 * @var integer * @access protected */ - protected $minute; + protected $minute; /** * 秒 * @var integer * @access protected */ - protected $second; + protected $second; /** * 星期的数字表示 * @var integer * @access protected */ - protected $weekday; + protected $weekday; /** * 星期的完整表示 * @var string * @access protected */ - protected $cWeekday; + protected $cWeekday; /** * 一年中的天数 0-365 * @var integer * @access protected */ - protected $yDay; + protected $yDay; /** * 月份的完整表示 * @var string * @access protected */ - protected $cMonth; + protected $cMonth; /** * 日期CDATE表示 * @var string * @access protected */ - protected $CDATE; + protected $CDATE; /** * 日期的YMD表示 * @var string * @access protected */ - protected $YMD; + protected $YMD; /** * 时间的输出表示 * @var string * @access protected */ - protected $CTIME; + protected $CTIME; - // 星期的输出 - protected $Week = array("日","一","二","三","四","五","六"); + // 星期的输出 + protected $Week = array("日", "一", "二", "三", "四", "五", "六"); /** * 架构函数 @@ -135,9 +138,10 @@ class Date { * @static * @access public */ - public function __construct($date='') { + public function __construct($date = '') + { //分析日期 - $this->date = $this->parse($date); + $this->date = $this->parse($date); $this->setDate($this->date); } @@ -149,16 +153,17 @@ public function __construct($date='') { * @param mixed $date 日期 * @return string */ - public function parse($date) { + public function parse($date) + { if (is_string($date)) { - if (($date == "") || strtotime($date) == -1) { + if (("" == $date) || strtotime($date) == -1) { //为空默认取得当前时间戳 $tmpdate = time(); } else { //把字符串转换成UNIX时间戳 $tmpdate = strtotime($date); } - } elseif (is_null($date)) { + } elseif (is_null($date)) { //为空默认取得当前时间戳 $tmpdate = time(); @@ -184,7 +189,8 @@ public function parse($date) { * @param mixed $date 日期数据 * @return string */ - public function valid($date) { + public function valid($date) + { } @@ -195,26 +201,27 @@ public function valid($date) { * @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 ; + 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; } /** @@ -224,7 +231,8 @@ public function setDate($date) { * @param string $format 格式化参数 * @return string */ - public function format($format = "%Y-%m-%d %H:%M:%S") { + public function format($format = "%Y-%m-%d %H:%M:%S") + { return strftime($format, $this->date); } @@ -234,8 +242,9 @@ public function format($format = "%Y-%m-%d %H:%M:%S") { * @access public * @return string */ - public function isLeapYear($year='') { - if(empty($year)) { + public function isLeapYear($year = '') + { + if (empty($year)) { $year = $this->year; } return ((($year % 4) == 0) && (($year % 100) != 0) || (($year % 400) == 0)); @@ -255,33 +264,34 @@ public function isLeapYear($year='') { * @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); + 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__ ; + $__DAYSELAPS = ($this->parse($date) - $this->date) / $__SECONDS_IN_A_DAY__; switch ($elaps) { - case "y"://转换成年 - $__DAYSELAPS = $__DAYSELAPS / $__DAYS_PER_YEAR__; + case "y": //转换成年 + $__DAYSELAPS = $__DAYSELAPS / $__DAYS_PER_YEAR__; break; - case "M"://转换成月 - $__DAYSELAPS = $__DAYSELAPS / $__DAYS_PER_MONTH__; + case "M": //转换成月 + $__DAYSELAPS = $__DAYSELAPS / $__DAYS_PER_MONTH__; break; - case "w"://转换成星期 - $__DAYSELAPS = $__DAYSELAPS / $__DAYS_PER_WEEK__; + case "w": //转换成星期 + $__DAYSELAPS = $__DAYSELAPS / $__DAYS_PER_WEEK__; break; - case "h"://转换成小时 - $__DAYSELAPS = $__DAYSELAPS * $__HOURS_IN_A_DAY__; + case "h": //转换成小时 + $__DAYSELAPS = $__DAYSELAPS * $__HOURS_IN_A_DAY__; break; - case "m"://转换成分钟 - $__DAYSELAPS = $__DAYSELAPS * $__MINUTES_IN_A_DAY__; + case "m": //转换成分钟 + $__DAYSELAPS = $__DAYSELAPS * $__MINUTES_IN_A_DAY__; break; - case "s"://转换成秒 - $__DAYSELAPS = $__DAYSELAPS * $__SECONDS_IN_A_DAY__; + case "s": //转换成秒 + $__DAYSELAPS = $__DAYSELAPS * $__SECONDS_IN_A_DAY__; break; } return $__DAYSELAPS; @@ -295,27 +305,28 @@ public function dateDiff($date, $elaps = "d") { * @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].'前'; + 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=$chunks[$i][0]) { - $num = floor($diff/$chunks[$i][0]); - $since .= sprintf('%d'.$chunks[$i][1],$num); - $diff = (int)($diff-$chunks[$i][0]*$num); + $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) { + if (!$precision || $count >= $precision) { break; } } - } - return $since.'前'; + } + return $since . '前'; } /** @@ -323,8 +334,9 @@ public function timeDiff( $time ,$precision=false) { * @access public * @return Date */ - public function getDayOfWeek($n){ - $week = array(0=>'sunday',1=>'monday',2=>'tuesday',3=>'wednesday',4=>'thursday',5=>'friday',6=>'saturday'); + 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])); } @@ -333,7 +345,8 @@ public function getDayOfWeek($n){ * @access public * @return Date */ - public function firstDayOfWeek() { + public function firstDayOfWeek() + { return $this->getDayOfWeek(1); } @@ -342,8 +355,9 @@ public function firstDayOfWeek() { * @access public * @return Date */ - public function firstDayOfMonth() { - return (new Date(mktime(0, 0, 0,$this->month,1,$this->year ))); + public function firstDayOfMonth() + { + return (new Date(mktime(0, 0, 0, $this->month, 1, $this->year))); } /** @@ -351,7 +365,8 @@ public function firstDayOfMonth() { * @access public * @return Date */ - public function firstDayOfYear() { + public function firstDayOfYear() + { return (new Date(mktime(0, 0, 0, 1, 1, $this->year))); } @@ -360,7 +375,8 @@ public function firstDayOfYear() { * @access public * @return Date */ - public function lastDayOfWeek() { + public function lastDayOfWeek() + { return $this->getDayOfWeek(0); } @@ -369,8 +385,9 @@ public function lastDayOfWeek() { * @access public * @return Date */ - public function lastDayOfMonth() { - return (new Date(mktime(0, 0, 0, $this->month + 1, 0, $this->year ))); + public function lastDayOfMonth() + { + return (new Date(mktime(0, 0, 0, $this->month + 1, 0, $this->year))); } /** @@ -378,7 +395,8 @@ public function lastDayOfMonth() { * @access public * @return Date */ - public function lastDayOfYear() { + public function lastDayOfYear() + { return (new Date(mktime(0, 0, 0, 1, 0, $this->year + 1))); } @@ -387,8 +405,9 @@ public function lastDayOfYear() { * @access public * @return integer */ - public function maxDayOfMonth() { - $result = $this->dateDiff(strtotime($this->dateAdd(1,'m')),'d'); + public function maxDayOfMonth() + { + $result = $this->dateDiff(strtotime($this->dateAdd(1, 'm')), 'd'); return $result; } @@ -410,13 +429,14 @@ public function maxDayOfMonth() { * @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; + 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": @@ -426,7 +446,7 @@ public function dateAdd($number = 0, $interval = "d") { case "q": //---Add $number to quarter - $month += ($number*3); + $month += ($number * 3); break; case "m": @@ -443,7 +463,7 @@ public function dateAdd($number = 0, $interval = "d") { case "ww": //---Add $number to week - $day += ($number*7); + $day += ($number * 7); break; case "h": @@ -463,11 +483,11 @@ public function dateAdd($number = 0, $interval = "d") { } return (new Date(mktime($hours, - $minutes, - $seconds, - $month, - $day, - $year))); + $minutes, + $seconds, + $month, + $day, + $year))); } @@ -479,22 +499,20 @@ public function dateAdd($number = 0, $interval = "d") { * @param integer $number 日期数字 * @return string */ - public function numberToCh($number) { + 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]; + $array = array('一', '二', '三', '四', '五', '六', '七', '八', '九', '十'); + $str = ''; + if (0 == $number) {$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; } @@ -507,11 +525,12 @@ public function numberToCh($number) { * @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)]; + public function yearToCh($yearStr, $flag = false) + { + $array = array('零', '一', '二', '三', '四', '五', '六', '七', '八', '九'); + $str = $flag ? '公元' : ''; + for ($i = 0; $i < 4; $i++) { + $str .= $array[substr($yearStr, $i, 1)]; } return $str; } @@ -525,45 +544,51 @@ public function yearToCh( $yearStr ,$flag=false ) { * @param string $type 获取信息类型 * @return string */ - public function magicInfo($type) { + public function magicInfo($type) + { $result = ''; - $m = $this->month; - $y = $this->year; - $d = $this->day; + $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; + 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; + + $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() { + public function __toString() + { return $this->format(); } -} \ No newline at end of file +} diff --git a/ThinkPHP/Library/Org/Util/Rbac.class.php b/ThinkPHP/Library/Org/Util/Rbac.class.php index b9c18e8b9..51bd8f797 100644 --- a/ThinkPHP/Library/Org/Util/Rbac.class.php +++ b/ThinkPHP/Library/Org/Util/Rbac.class.php @@ -9,11 +9,11 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Org\Util; + use Think\Db; + /** - +------------------------------------------------------------------------------ * 基于角色的数据库方式验证类 - +------------------------------------------------------------------------------ */ // 配置文件增加设置 // USER_AUTH_ON 是否需要认证 @@ -30,256 +30,277 @@ /* -- -------------------------------------------------------- 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`) +`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`) +`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`) +`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`) +`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 { + */ +class Rbac +{ // 认证方法 - static public function authenticate($map,$model='') { - if(empty($model)) $model = C('USER_AUTH_MODEL'); + public static 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')]; + public 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 ; + 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; + // 取得模块的所属记录访问权限列表 返回有权限的记录ID数组 + public 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); + $accessList = self::getModuleAccessList($authId, $module); return $accessList; - } + } //检查当前操作是否需要认证 - static function checkAccess() { + public static function checkAccess() + { //如果项目要求认证,并且当前模块需要认证,则进行权限认证 - if( C('USER_AUTH_ON') ){ - $_module = array(); - $_action = array(); - if("" != C('REQUIRE_AUTH_MODULE')) { + if (C('USER_AUTH_ON')) { + $_module = array(); + $_action = array(); + if ("" != C('REQUIRE_AUTH_MODULE')) { //需要认证的模块 - $_module['yes'] = explode(',',strtoupper(C('REQUIRE_AUTH_MODULE'))); - }else { + $_module['yes'] = explode(',', strtoupper(C('REQUIRE_AUTH_MODULE'))); + } else { //无需认证的模块 - $_module['no'] = explode(',',strtoupper(C('NOT_AUTH_MODULE'))); + $_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 { + 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() { + // 登录检查 + public static function checkLogin() + { //检查当前操作是否需要认证 - if(self::checkAccess()) { + if (self::checkAccess()) { //检查认证识别号 - if(!$_SESSION[C('USER_AUTH_KEY')]) { - if(C('GUEST_AUTH_ON')) { + if (!$_SESSION[C('USER_AUTH_KEY')]) { + if (C('GUEST_AUTH_ON')) { // 开启游客授权访问 - if(!isset($_SESSION['_ACCESS_LIST'])) - // 保存游客权限 + if (!isset($_SESSION['_ACCESS_LIST'])) + // 保存游客权限 + { self::saveAccessList(C('GUEST_AUTH_ID')); - }else{ + } + + } else { // 禁止游客访问跳转到认证网关 - redirect(PHP_FILE.C('USER_AUTH_GATEWAY')); + redirect(PHP_FILE . C('USER_AUTH_GATEWAY')); } } } return true; - } + } //权限认证的过滤器方法 - static public function AccessDecision($appName=MODULE_NAME) { + public static function AccessDecision($appName = MODULE_NAME) + { //检查是否需要认证 - if(self::checkAccess()) { + if (self::checkAccess()) { //存在认证识别号,则进行进一步的访问决策 - $accessGuid = md5($appName.CONTROLLER_NAME.ACTION_NAME); - if(empty($_SESSION[C('ADMIN_AUTH_KEY')])) { - if(C('USER_AUTH_TYPE')==2) { + $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 { + } else { // 如果是管理员或者当前操作已经认证过,无需再次认证 - if( $_SESSION[$accessGuid]) { + if ($_SESSION[$accessGuid]) { return true; } //登录验证模式,比较登录后保存的权限访问列表 $accessList = $_SESSION['_ACCESS_LIST']; } //判断是否为组件化模式,如果是,验证其全模块名 - if(!isset($accessList[strtoupper($appName)][strtoupper(CONTROLLER_NAME)][strtoupper(ACTION_NAME)])) { - $_SESSION[$accessGuid] = false; + if (!isset($accessList[strtoupper($appName)][strtoupper(CONTROLLER_NAME)][strtoupper(ACTION_NAME)])) { + $_SESSION[$accessGuid] = false; return false; + } else { + $_SESSION[$accessGuid] = true; } - else { - $_SESSION[$accessGuid] = true; - } - }else{ + } else { //管理员无需认证 - return true; - } + return true; + } } return true; } /** - +---------------------------------------------------------- * 取得当前认证号的所有权限列表 - +---------------------------------------------------------- * @param integer $authId 用户ID - +---------------------------------------------------------- * @access public - +---------------------------------------------------------- */ - static public function getAccessList($authId) { + public static 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']; + $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); + $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']; + $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 ". + 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']; + $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']; + 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); + $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']; + foreach ($rs as $a) { + $action[$a['name']] = $a['id']; } // 和公共模块的操作权限合并 $action += $publicAction; - $access[strtoupper($appName)][strtoupper($moduleName)] = array_change_key_case($action,CASE_UPPER); + $access[strtoupper($appName)][strtoupper($moduleName)] = array_change_key_case($action, CASE_UPPER); } } return $access; } - // 读取模块所属的记录访问权限 - static public function getModuleAccessList($authId,$module) { + // 读取模块所属的记录访问权限 + public static 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']; + $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; - } -} \ No newline at end of file + return $access; + } +} diff --git a/ThinkPHP/Library/Org/Util/Stack.class.php b/ThinkPHP/Library/Org/Util/Stack.class.php index 51045e030..2a1412ca0 100644 --- a/ThinkPHP/Library/Org/Util/Stack.class.php +++ b/ThinkPHP/Library/Org/Util/Stack.class.php @@ -17,14 +17,16 @@ * @subpackage Util * @author liu21st */ -class Stack extends ArrayList { +class Stack extends ArrayList +{ /** * 架构函数 * @access public * @param array $values 初始化数组元素 */ - public function __construct($values = array()) { + public function __construct($values = array()) + { parent::__construct($values); } @@ -33,7 +35,8 @@ public function __construct($values = array()) { * @access public * @return mixed */ - public function peek() { + public function peek() + { return reset($this->toArray()); } @@ -43,7 +46,8 @@ public function peek() { * @param mixed $value * @return mixed */ - public function push($value) { + public function push($value) + { $this->add($value); return $value; } diff --git a/ThinkPHP/Library/Org/Util/String.class.php b/ThinkPHP/Library/Org/Util/String.class.php index 64078f49b..87b97a2ce 100644 --- a/ThinkPHP/Library/Org/Util/String.class.php +++ b/ThinkPHP/Library/Org/Util/String.class.php @@ -9,23 +9,26 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Org\Util; -class String { + +class String +{ /** * 生成UUID 单机使用 * @access public * @return string */ - static public function uuid() { + public static function uuid() + { $charid = md5(uniqid(mt_rand(), true)); - $hyphen = chr(45);// "-" - $uuid = chr(123)// "{" - .substr($charid, 0, 8).$hyphen - .substr($charid, 8, 4).$hyphen - .substr($charid,12, 4).$hyphen - .substr($charid,16, 4).$hyphen - .substr($charid,20,12) - .chr(125);// "}" + $hyphen = chr(45); // "-" + $uuid = chr(123) // "{" + . substr($charid, 0, 8) . $hyphen + . substr($charid, 8, 4) . $hyphen + . substr($charid, 12, 4) . $hyphen + . substr($charid, 16, 4) . $hyphen + . substr($charid, 20, 12) + . chr(125); // "}" return $uuid; } @@ -33,8 +36,9 @@ static public function uuid() { * 生成Guid主键 * @return Boolean */ - static public function keyGen() { - return str_replace('-','',substr(String::uuid(),1,-1)); + public static function keyGen() + { + return str_replace('-', '', substr(String::uuid(), 1, -1)); } /** @@ -42,25 +46,42 @@ static public function keyGen() { * @param string $string 字符串 * @return Boolean */ - static public function isUtf8($str) { - $c=0; $b=0; - $bits=0; - $len=strlen($str); - for($i=0; $i<$len; $i++){ - $c=ord($str[$i]); - if($c > 128){ - if(($c >= 254)) return false; - elseif($c >= 252) $bits=6; - elseif($c >= 248) $bits=5; - elseif($c >= 240) $bits=4; - elseif($c >= 224) $bits=3; - elseif($c >= 192) $bits=2; - else return false; - if(($i+$bits) > $len) return false; - while($bits > 1){ + public static function isUtf8($str) + { + $c = 0; + $b = 0; + $bits = 0; + $len = strlen($str); + for ($i = 0; $i < $len; $i++) { + $c = ord($str[$i]); + if ($c > 128) { + if (($c >= 254)) { + return false; + } elseif ($c >= 252) { + $bits = 6; + } elseif ($c >= 248) { + $bits = 5; + } elseif ($c >= 240) { + $bits = 4; + } elseif ($c >= 224) { + $bits = 3; + } elseif ($c >= 192) { + $bits = 2; + } else { + return false; + } + + if (($i + $bits) > $len) { + return false; + } + + while ($bits > 1) { $i++; - $b=ord($str[$i]); - if($b < 128 || $b > 191) return false; + $b = ord($str[$i]); + if ($b < 128 || $b > 191) { + return false; + } + $bits--; } } @@ -79,20 +100,21 @@ static public function isUtf8($str) { * @param string $suffix 截断显示字符 * @return string */ - static public function msubstr($str, $start=0, $length, $charset="utf-8", $suffix=true) { - if(function_exists("mb_substr")) + public static function msubstr($str, $start = 0, $length, $charset = "utf-8", $suffix = true) + { + if (function_exists("mb_substr")) { $slice = mb_substr($str, $start, $length, $charset); - elseif(function_exists('iconv_substr')) { - $slice = iconv_substr($str,$start,$length,$charset); - }else{ - $re['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/"; + } elseif (function_exists('iconv_substr')) { + $slice = iconv_substr($str, $start, $length, $charset); + } else { + $re['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/"; $re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/"; $re['gbk'] = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/"; $re['big5'] = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/"; preg_match_all($re[$charset], $str, $match); - $slice = join("",array_slice($match[0], $start, $length)); + $slice = join("", array_slice($match[0], $start, $length)); } - return $suffix ? $slice.'...' : $slice; + return $suffix ? $slice . '...' : $slice; } /** @@ -104,39 +126,41 @@ static public function msubstr($str, $start=0, $length, $charset="utf-8", $suffi * @param string $addChars 额外字符 * @return string */ - static public function randString($len=6,$type='',$addChars='') { - $str =''; - switch($type) { + public static function randString($len = 6, $type = '', $addChars = '') + { + $str = ''; + switch ($type) { case 0: - $chars='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.$addChars; + $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' . $addChars; break; case 1: - $chars= str_repeat('0123456789',3); + $chars = str_repeat('0123456789', 3); break; case 2: - $chars='ABCDEFGHIJKLMNOPQRSTUVWXYZ'.$addChars; + $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' . $addChars; break; case 3: - $chars='abcdefghijklmnopqrstuvwxyz'.$addChars; + $chars = 'abcdefghijklmnopqrstuvwxyz' . $addChars; break; case 4: - $chars = "们以我到他会作时要动国产的一是工就年阶义发成部民可出能方进在了不和有大这主中人上为来分生对于学下级地个用同行面说种过命度革而多子后自社加小机也经力线本电高量长党得实家定深法表着水理化争现所二起政三好十战无农使性前等反体合斗路图把结第里正新开论之物从当两些还天资事队批点育重其思与间内去因件日利相由压员气业代全组数果期导平各基或月毛然如应形想制心样干都向变关问比展那它最及外没看治提五解系林者米群头意只明四道马认次文通但条较克又公孔领军流入接席位情运器并飞原油放立题质指建区验活众很教决特此常石强极土少已根共直团统式转别造切九你取西持总料连任志观调七么山程百报更见必真保热委手改管处己将修支识病象几先老光专什六型具示复安带每东增则完风回南广劳轮科北打积车计给节做务被整联步类集号列温装即毫知轴研单色坚据速防史拉世设达尔场织历花受求传口断况采精金界品判参层止边清至万确究书术状厂须离再目海交权且儿青才证低越际八试规斯近注办布门铁需走议县兵固除般引齿千胜细影济白格效置推空配刀叶率述今选养德话查差半敌始片施响收华觉备名红续均药标记难存测士身紧液派准斤角降维板许破述技消底床田势端感往神便贺村构照容非搞亚磨族火段算适讲按值美态黄易彪服早班麦削信排台声该击素张密害侯草何树肥继右属市严径螺检左页抗苏显苦英快称坏移约巴材省黑武培著河帝仅针怎植京助升王眼她抓含苗副杂普谈围食射源例致酸旧却充足短划剂宣环落首尺波承粉践府鱼随考刻靠够满夫失包住促枝局菌杆周护岩师举曲春元超负砂封换太模贫减阳扬江析亩木言球朝医校古呢稻宋听唯输滑站另卫字鼓刚写刘微略范供阿块某功套友限项余倒卷创律雨让骨远帮初皮播优占死毒圈伟季训控激找叫云互跟裂粮粒母练塞钢顶策双留误础吸阻故寸盾晚丝女散焊功株亲院冷彻弹错散商视艺灭版烈零室轻血倍缺厘泵察绝富城冲喷壤简否柱李望盘磁雄似困巩益洲脱投送奴侧润盖挥距触星松送获兴独官混纪依未突架宽冬章湿偏纹吃执阀矿寨责熟稳夺硬价努翻奇甲预职评读背协损棉侵灰虽矛厚罗泥辟告卵箱掌氧恩爱停曾溶营终纲孟钱待尽俄缩沙退陈讨奋械载胞幼哪剥迫旋征槽倒握担仍呀鲜吧卡粗介钻逐弱脚怕盐末阴丰雾冠丙街莱贝辐肠付吉渗瑞惊顿挤秒悬姆烂森糖圣凹陶词迟蚕亿矩康遵牧遭幅园腔订香肉弟屋敏恢忘编印蜂急拿扩伤飞露核缘游振操央伍域甚迅辉异序免纸夜乡久隶缸夹念兰映沟乙吗儒杀汽磷艰晶插埃燃欢铁补咱芽永瓦倾阵碳演威附牙芽永瓦斜灌欧献顺猪洋腐请透司危括脉宜笑若尾束壮暴企菜穗楚汉愈绿拖牛份染既秋遍锻玉夏疗尖殖井费州访吹荣铜沿替滚客召旱悟刺脑措贯藏敢令隙炉壳硫煤迎铸粘探临薄旬善福纵择礼愿伏残雷延烟句纯渐耕跑泽慢栽鲁赤繁境潮横掉锥希池败船假亮谓托伙哲怀割摆贡呈劲财仪沉炼麻罪祖息车穿货销齐鼠抽画饲龙库守筑房歌寒喜哥洗蚀废纳腹乎录镜妇恶脂庄擦险赞钟摇典柄辩竹谷卖乱虚桥奥伯赶垂途额壁网截野遗静谋弄挂课镇妄盛耐援扎虑键归符庆聚绕摩忙舞遇索顾胶羊湖钉仁音迹碎伸灯避泛亡答勇频皇柳哈揭甘诺概宪浓岛袭谁洪谢炮浇斑讯懂灵蛋闭孩释乳巨徒私银伊景坦累匀霉杜乐勒隔弯绩招绍胡呼痛峰零柴簧午跳居尚丁秦稍追梁折耗碱殊岗挖氏刃剧堆赫荷胸衡勤膜篇登驻案刊秧缓凸役剪川雪链渔啦脸户洛孢勃盟买杨宗焦赛旗滤硅炭股坐蒸凝竟陷枪黎救冒暗洞犯筒您宋弧爆谬涂味津臂障褐陆啊健尊豆拔莫抵桑坡缝警挑污冰柬嘴啥饭塑寄赵喊垫丹渡耳刨虎笔稀昆浪萨茶滴浅拥穴覆伦娘吨浸袖珠雌妈紫戏塔锤震岁貌洁剖牢锋疑霸闪埔猛诉刷狠忽灾闹乔唐漏闻沈熔氯荒茎男凡抢像浆旁玻亦忠唱蒙予纷捕锁尤乘乌智淡允叛畜俘摸锈扫毕璃宝芯爷鉴秘净蒋钙肩腾枯抛轨堂拌爸循诱祝励肯酒绳穷塘燥泡袋朗喂铝软渠颗惯贸粪综墙趋彼届墨碍启逆卸航衣孙龄岭骗休借".$addChars; + $chars = "们以我到他会作时要动国产的一是工就年阶义发成部民可出能方进在了不和有大这主中人上为来分生对于学下级地个用同行面说种过命度革而多子后自社加小机也经力线本电高量长党得实家定深法表着水理化争现所二起政三好十战无农使性前等反体合斗路图把结第里正新开论之物从当两些还天资事队批点育重其思与间内去因件日利相由压员气业代全组数果期导平各基或月毛然如应形想制心样干都向变关问比展那它最及外没看治提五解系林者米群头意只明四道马认次文通但条较克又公孔领军流入接席位情运器并飞原油放立题质指建区验活众很教决特此常石强极土少已根共直团统式转别造切九你取西持总料连任志观调七么山程百报更见必真保热委手改管处己将修支识病象几先老光专什六型具示复安带每东增则完风回南广劳轮科北打积车计给节做务被整联步类集号列温装即毫知轴研单色坚据速防史拉世设达尔场织历花受求传口断况采精金界品判参层止边清至万确究书术状厂须离再目海交权且儿青才证低越际八试规斯近注办布门铁需走议县兵固除般引齿千胜细影济白格效置推空配刀叶率述今选养德话查差半敌始片施响收华觉备名红续均药标记难存测士身紧液派准斤角降维板许破述技消底床田势端感往神便贺村构照容非搞亚磨族火段算适讲按值美态黄易彪服早班麦削信排台声该击素张密害侯草何树肥继右属市严径螺检左页抗苏显苦英快称坏移约巴材省黑武培著河帝仅针怎植京助升王眼她抓含苗副杂普谈围食射源例致酸旧却充足短划剂宣环落首尺波承粉践府鱼随考刻靠够满夫失包住促枝局菌杆周护岩师举曲春元超负砂封换太模贫减阳扬江析亩木言球朝医校古呢稻宋听唯输滑站另卫字鼓刚写刘微略范供阿块某功套友限项余倒卷创律雨让骨远帮初皮播优占死毒圈伟季训控激找叫云互跟裂粮粒母练塞钢顶策双留误础吸阻故寸盾晚丝女散焊功株亲院冷彻弹错散商视艺灭版烈零室轻血倍缺厘泵察绝富城冲喷壤简否柱李望盘磁雄似困巩益洲脱投送奴侧润盖挥距触星松送获兴独官混纪依未突架宽冬章湿偏纹吃执阀矿寨责熟稳夺硬价努翻奇甲预职评读背协损棉侵灰虽矛厚罗泥辟告卵箱掌氧恩爱停曾溶营终纲孟钱待尽俄缩沙退陈讨奋械载胞幼哪剥迫旋征槽倒握担仍呀鲜吧卡粗介钻逐弱脚怕盐末阴丰雾冠丙街莱贝辐肠付吉渗瑞惊顿挤秒悬姆烂森糖圣凹陶词迟蚕亿矩康遵牧遭幅园腔订香肉弟屋敏恢忘编印蜂急拿扩伤飞露核缘游振操央伍域甚迅辉异序免纸夜乡久隶缸夹念兰映沟乙吗儒杀汽磷艰晶插埃燃欢铁补咱芽永瓦倾阵碳演威附牙芽永瓦斜灌欧献顺猪洋腐请透司危括脉宜笑若尾束壮暴企菜穗楚汉愈绿拖牛份染既秋遍锻玉夏疗尖殖井费州访吹荣铜沿替滚客召旱悟刺脑措贯藏敢令隙炉壳硫煤迎铸粘探临薄旬善福纵择礼愿伏残雷延烟句纯渐耕跑泽慢栽鲁赤繁境潮横掉锥希池败船假亮谓托伙哲怀割摆贡呈劲财仪沉炼麻罪祖息车穿货销齐鼠抽画饲龙库守筑房歌寒喜哥洗蚀废纳腹乎录镜妇恶脂庄擦险赞钟摇典柄辩竹谷卖乱虚桥奥伯赶垂途额壁网截野遗静谋弄挂课镇妄盛耐援扎虑键归符庆聚绕摩忙舞遇索顾胶羊湖钉仁音迹碎伸灯避泛亡答勇频皇柳哈揭甘诺概宪浓岛袭谁洪谢炮浇斑讯懂灵蛋闭孩释乳巨徒私银伊景坦累匀霉杜乐勒隔弯绩招绍胡呼痛峰零柴簧午跳居尚丁秦稍追梁折耗碱殊岗挖氏刃剧堆赫荷胸衡勤膜篇登驻案刊秧缓凸役剪川雪链渔啦脸户洛孢勃盟买杨宗焦赛旗滤硅炭股坐蒸凝竟陷枪黎救冒暗洞犯筒您宋弧爆谬涂味津臂障褐陆啊健尊豆拔莫抵桑坡缝警挑污冰柬嘴啥饭塑寄赵喊垫丹渡耳刨虎笔稀昆浪萨茶滴浅拥穴覆伦娘吨浸袖珠雌妈紫戏塔锤震岁貌洁剖牢锋疑霸闪埔猛诉刷狠忽灾闹乔唐漏闻沈熔氯荒茎男凡抢像浆旁玻亦忠唱蒙予纷捕锁尤乘乌智淡允叛畜俘摸锈扫毕璃宝芯爷鉴秘净蒋钙肩腾枯抛轨堂拌爸循诱祝励肯酒绳穷塘燥泡袋朗喂铝软渠颗惯贸粪综墙趋彼届墨碍启逆卸航衣孙龄岭骗休借" . $addChars; break; - default : + default: // 默认去掉了容易混淆的字符oOLl和数字01,要添加请使用addChars参数 - $chars='ABCDEFGHIJKMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz23456789'.$addChars; + $chars = 'ABCDEFGHIJKMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz23456789' . $addChars; break; } - if($len>10 ) {//位数过长重复字符串一定次数 - $chars= $type==1? str_repeat($chars,$len) : str_repeat($chars,5); + if ($len > 10) { +//位数过长重复字符串一定次数 + $chars = 1 == $type ? str_repeat($chars, $len) : str_repeat($chars, 5); } - if($type!=4) { - $chars = str_shuffle($chars); - $str = substr($chars,0,$len); - }else{ + if (4 != $type) { + $chars = str_shuffle($chars); + $str = substr($chars, 0, $len); + } else { // 中文随机字 - for($i=0;$i<$len;$i++){ - $str.= self::msubstr($chars, floor(mt_rand(0,mb_strlen($chars,'utf-8')-1)),1,'utf-8',false); + for ($i = 0; $i < $len; $i++) { + $str .= self::msubstr($chars, floor(mt_rand(0, mb_strlen($chars, 'utf-8') - 1)), 1, 'utf-8', false); } } return $str; @@ -150,25 +174,26 @@ static public function randString($len=6,$type='',$addChars='') { * 0 字母 1 数字 其它 混合 * @return string */ - static public function buildCountRand ($number,$length=4,$mode=1) { - if($mode==1 && $length $val) { - $_key = self::autoCharset($key, $from, $to); + $_key = self::autoCharset($key, $from, $to); $string[$_key] = self::autoCharset($val, $from, $to); - if ($key != $_key) + if ($key != $_key) { unset($string[$key]); + } + } return $string; - } - else { + } else { return $string; } } -} \ No newline at end of file +} diff --git a/ThinkPHP/Library/Think/App.class.php b/ThinkPHP/Library/Think/App.class.php index be153948a..fedf108bf 100644 --- a/ThinkPHP/Library/Think/App.class.php +++ b/ThinkPHP/Library/Think/App.class.php @@ -9,49 +9,53 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think; + /** * ThinkPHP 应用程序类 执行应用过程管理 */ -class App { + +class App +{ /** * 应用程序初始化 * @access public * @return void */ - static public function init() { + public static function init() + { // 加载动态应用公共文件和配置 load_ext_file(COMMON_PATH); // 日志目录转换为绝对路径 默认情况下存储到公共模块下面 - C('LOG_PATH', realpath(LOG_PATH).'/Common/'); + C('LOG_PATH', realpath(LOG_PATH) . '/Common/'); // 定义当前请求的系统常量 - define('NOW_TIME', $_SERVER['REQUEST_TIME']); - define('REQUEST_METHOD',$_SERVER['REQUEST_METHOD']); - define('IS_GET', REQUEST_METHOD =='GET' ? true : false); - define('IS_POST', REQUEST_METHOD =='POST' ? true : false); - define('IS_PUT', REQUEST_METHOD =='PUT' ? true : false); - define('IS_DELETE', REQUEST_METHOD =='DELETE' ? true : false); + define('NOW_TIME', $_SERVER['REQUEST_TIME']); + define('REQUEST_METHOD', $_SERVER['REQUEST_METHOD']); + define('IS_GET', REQUEST_METHOD == 'GET' ? true : false); + define('IS_POST', REQUEST_METHOD == 'POST' ? true : false); + define('IS_PUT', REQUEST_METHOD == 'PUT' ? true : false); + define('IS_DELETE', REQUEST_METHOD == 'DELETE' ? true : false); // URL调度 Dispatcher::dispatch(); - if(C('REQUEST_VARS_FILTER')){ - // 全局安全过滤 - array_walk_recursive($_GET, 'think_filter'); - array_walk_recursive($_POST, 'think_filter'); - array_walk_recursive($_REQUEST, 'think_filter'); - } + if (C('REQUEST_VARS_FILTER')) { + // 全局安全过滤 + array_walk_recursive($_GET, 'think_filter'); + array_walk_recursive($_POST, 'think_filter'); + array_walk_recursive($_REQUEST, 'think_filter'); + } // URL调度结束标签 - Hook::listen('url_dispatch'); + Hook::listen('url_dispatch'); - define('IS_AJAX', ((isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') || !empty($_POST[C('VAR_AJAX_SUBMIT')]) || !empty($_GET[C('VAR_AJAX_SUBMIT')])) ? true : false); + define('IS_AJAX', ((isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') || !empty($_POST[C('VAR_AJAX_SUBMIT')]) || !empty($_GET[C('VAR_AJAX_SUBMIT')])) ? true : false); // TMPL_EXCEPTION_FILE 改为绝对地址 - C('TMPL_EXCEPTION_FILE',realpath(C('TMPL_EXCEPTION_FILE'))); - return ; + C('TMPL_EXCEPTION_FILE', realpath(C('TMPL_EXCEPTION_FILE'))); + return; } /** @@ -59,144 +63,148 @@ static public function init() { * @access public * @return void */ - static public function exec() { - - if(!preg_match('/^[A-Za-z](\/|\w)*$/',CONTROLLER_NAME)){ // 安全检测 - $module = false; - }elseif(C('ACTION_BIND_CLASS')){ + public static function exec() + { + + if (!preg_match('/^[A-Za-z](\/|\w)*$/', CONTROLLER_NAME)) { + // 安全检测 + $module = false; + } elseif (C('ACTION_BIND_CLASS')) { // 操作绑定到类:模块\Controller\控制器\操作 - $layer = C('DEFAULT_C_LAYER'); - if(is_dir(MODULE_PATH.$layer.'/'.CONTROLLER_NAME)){ - $namespace = MODULE_NAME.'\\'.$layer.'\\'.CONTROLLER_NAME.'\\'; - }else{ + $layer = C('DEFAULT_C_LAYER'); + if (is_dir(MODULE_PATH . $layer . '/' . CONTROLLER_NAME)) { + $namespace = MODULE_NAME . '\\' . $layer . '\\' . CONTROLLER_NAME . '\\'; + } else { // 空控制器 - $namespace = MODULE_NAME.'\\'.$layer.'\\_empty\\'; + $namespace = MODULE_NAME . '\\' . $layer . '\\_empty\\'; } - $actionName = strtolower(ACTION_NAME); - if(class_exists($namespace.$actionName)){ - $class = $namespace.$actionName; - }elseif(class_exists($namespace.'_empty')){ + $actionName = strtolower(ACTION_NAME); + if (class_exists($namespace . $actionName)) { + $class = $namespace . $actionName; + } elseif (class_exists($namespace . '_empty')) { // 空操作 - $class = $namespace.'_empty'; - }else{ - E(L('_ERROR_ACTION_').':'.ACTION_NAME); + $class = $namespace . '_empty'; + } else { + E(L('_ERROR_ACTION_') . ':' . ACTION_NAME); } - $module = new $class; + $module = new $class; // 操作绑定到类后 固定执行run入口 - $action = 'run'; - }else{ + $action = 'run'; + } else { //创建控制器实例 - $module = controller(CONTROLLER_NAME,CONTROLLER_PATH); + $module = controller(CONTROLLER_NAME, CONTROLLER_PATH); } - if(!$module) { - if('4e5e5d7364f443e28fbf0d3ae744a59a' == CONTROLLER_NAME) { + if (!$module) { + if ('4e5e5d7364f443e28fbf0d3ae744a59a' == CONTROLLER_NAME) { header("Content-type:image/png"); exit(base64_decode(App::logo())); } // 是否定义Empty控制器 $module = A('Empty'); - if(!$module){ - E(L('_CONTROLLER_NOT_EXIST_').':'.CONTROLLER_NAME); + if (!$module) { + E(L('_CONTROLLER_NOT_EXIST_') . ':' . CONTROLLER_NAME); } } // 获取当前操作名 支持动态路由 - if(!isset($action)){ - $action = ACTION_NAME.C('ACTION_SUFFIX'); + if (!isset($action)) { + $action = ACTION_NAME . C('ACTION_SUFFIX'); } - try{ - self::invokeAction($module,$action); - } catch (\ReflectionException $e) { + try { + self::invokeAction($module, $action); + } catch (\ReflectionException $e) { // 方法调用发生异常后 引导到__call方法处理 - $method = new \ReflectionMethod($module,'__call'); - $method->invokeArgs($module,array($action,'')); + $method = new \ReflectionMethod($module, '__call'); + $method->invokeArgs($module, array($action, '')); } - return ; + return; } - public static function invokeAction($module,$action){ - if(!preg_match('/^[A-Za-z](\w)*$/',$action)){ - // 非法操作 - throw new \ReflectionException(); - } - //执行当前操作 - $method = new \ReflectionMethod($module, $action); - if($method->isPublic() && !$method->isStatic()) { - $class = new \ReflectionClass($module); - // 前置操作 - if($class->hasMethod('_before_'.$action)) { - $before = $class->getMethod('_before_'.$action); - if($before->isPublic()) { - $before->invoke($module); - } - } - // URL参数绑定检测 - if($method->getNumberOfParameters()>0 && C('URL_PARAMS_BIND')){ - switch($_SERVER['REQUEST_METHOD']) { - case 'POST': - $vars = array_merge($_GET,$_POST); - break; - case 'PUT': - parse_str(file_get_contents('php://input'), $vars); - break; - default: - $vars = $_GET; - } - $params = $method->getParameters(); - $paramsBindType = C('URL_PARAMS_BIND_TYPE'); - foreach ($params as $param){ - $name = $param->getName(); - if( 1 == $paramsBindType && !empty($vars) ){ - $args[] = array_shift($vars); - }elseif( 0 == $paramsBindType && isset($vars[$name])){ - $args[] = $vars[$name]; - }elseif($param->isDefaultValueAvailable()){ - $args[] = $param->getDefaultValue(); - }else{ - E(L('_PARAM_ERROR_').':'.$name); - } - } - // 开启绑定参数过滤机制 - if(C('URL_PARAMS_SAFE')){ - $filters = C('URL_PARAMS_FILTER')?:C('DEFAULT_FILTER'); - if($filters) { - $filters = explode(',',$filters); - foreach($filters as $filter){ - $args = array_map_recursive($filter,$args); // 参数过滤 - } - } - } - array_walk_recursive($args,'think_filter'); - $method->invokeArgs($module,$args); - }else{ - $method->invoke($module); - } - // 后置操作 - if($class->hasMethod('_after_'.$action)) { - $after = $class->getMethod('_after_'.$action); - if($after->isPublic()) { - $after->invoke($module); - } - } - }else{ - // 操作方法不是Public 抛出异常 - throw new \ReflectionException(); - } + public static function invokeAction($module, $action) + { + if (!preg_match('/^[A-Za-z](\w)*$/', $action)) { + // 非法操作 + throw new \ReflectionException(); + } + //执行当前操作 + $method = new \ReflectionMethod($module, $action); + if ($method->isPublic() && !$method->isStatic()) { + $class = new \ReflectionClass($module); + // 前置操作 + if ($class->hasMethod('_before_' . $action)) { + $before = $class->getMethod('_before_' . $action); + if ($before->isPublic()) { + $before->invoke($module); + } + } + // URL参数绑定检测 + if ($method->getNumberOfParameters() > 0 && C('URL_PARAMS_BIND')) { + switch ($_SERVER['REQUEST_METHOD']) { + case 'POST': + $vars = array_merge($_GET, $_POST); + break; + case 'PUT': + parse_str(file_get_contents('php://input'), $vars); + break; + default: + $vars = $_GET; + } + $params = $method->getParameters(); + $paramsBindType = C('URL_PARAMS_BIND_TYPE'); + foreach ($params as $param) { + $name = $param->getName(); + if (1 == $paramsBindType && !empty($vars)) { + $args[] = array_shift($vars); + } elseif (0 == $paramsBindType && isset($vars[$name])) { + $args[] = $vars[$name]; + } elseif ($param->isDefaultValueAvailable()) { + $args[] = $param->getDefaultValue(); + } else { + E(L('_PARAM_ERROR_') . ':' . $name); + } + } + // 开启绑定参数过滤机制 + if (C('URL_PARAMS_SAFE')) { + $filters = C('URL_PARAMS_FILTER') ?: C('DEFAULT_FILTER'); + if ($filters) { + $filters = explode(',', $filters); + foreach ($filters as $filter) { + $args = array_map_recursive($filter, $args); // 参数过滤 + } + } + } + array_walk_recursive($args, 'think_filter'); + $method->invokeArgs($module, $args); + } else { + $method->invoke($module); + } + // 后置操作 + if ($class->hasMethod('_after_' . $action)) { + $after = $class->getMethod('_after_' . $action); + if ($after->isPublic()) { + $after->invoke($module); + } + } + } else { + // 操作方法不是Public 抛出异常 + throw new \ReflectionException(); + } } /** * 运行应用实例 入口文件使用的快捷方法 * @access public * @return void */ - static public function run() { + public static function run() + { // 应用初始化标签 Hook::listen('app_init'); App::init(); // 应用开始标签 Hook::listen('app_begin'); // Session初始化 - if(!IS_CLI){ + if (!IS_CLI) { session(C('SESSION_OPTIONS')); } // 记录应用初始化时间 @@ -204,10 +212,11 @@ static public function run() { App::exec(); // 应用结束标签 Hook::listen('app_end'); - return ; + return; } - static public function logo(){ + public static function logo() + { return 'iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyBpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBXaW5kb3dzIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjVERDVENkZGQjkyNDExRTE5REY3RDQ5RTQ2RTRDQUJCIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjVERDVENzAwQjkyNDExRTE5REY3RDQ5RTQ2RTRDQUJCIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6NURENUQ2RkRCOTI0MTFFMTlERjdENDlFNDZFNENBQkIiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NURENUQ2RkVCOTI0MTFFMTlERjdENDlFNDZFNENBQkIiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz5fx6IRAAAMCElEQVR42sxae3BU1Rk/9+69+8xuNtkHJAFCSIAkhMgjCCJQUi0GtEIVbP8Qq9LH2No6TmfaztjO2OnUdvqHFMfOVFTqIK0vUEEeqUBARCsEeYQkEPJoEvIiELLvvc9z+p27u2F3s5tsBB1OZiebu5dzf7/v/L7f952zMM8cWIwY+Mk2ulCp92Fnq3XvnzArr2NZnYNldDp0Gw+/OEQ4+obQn5D+4Ubb22+YOGsWi/Todh8AHglKEGkEsnHBQ162511GZFgW6ZCBM9/W4H3iNSQqIe09O196dLKX7d1O39OViP/wthtkND62if/wj/DbMpph8BY/m9xy8BoBmQk+mHqZQGNy4JYRwCoRbwa8l4JXw6M+orJxpU0U6ToKy/5bQsAiTeokGKkTx46RRxxEUgrwGgF4MWNNEJCGgYTvpgnY1IJWg5RzfqLgvcIgktX0i8dmMlFA8qCQ5L0Z/WObPLUxT1i4lWSYDISoEfBYGvM+LlMQQdkLHoWRRZ8zYQI62Thswe5WTORGwNXDcGjqeOA9AF7B8rhzsxMBEoJ8oJKaqPu4hblHMCMPwl9XeNWyb8xkB/DDGYKfMAE6aFL7xesZ389JlgG3XHEMI6UPDOP6JHHu67T2pwNPI69mCP4rEaBDUAJaKc/AOuXiwH07VCS3w5+UQMAuF/WqGI+yFIwVNBwemBD4r0wgQiKoFZa00sEYTwss32lA1tPwVxtc8jQ5/gWCwmGCyUD8vRT0sHBFW4GJDvZmrJFWRY1EkrGA6ZB8/10fOZSSj0E6F+BSP7xidiIzhBmKB09lEwHPkG+UQIyEN44EBiT5vrv2uJXyPQqSqO930fxvcvwbR/+JAkD9EfASgI9EHlp6YiHO4W+cAB20SnrFqxBbNljiXf1Pl1K2S0HCWfiog3YlAD5RGwwxK6oUjTweuVigLjyB0mX410mAFnMoVK1lvvUvgt8fUJH0JVyjuvcmg4dE5mUiFtD24AZ4qBVELxXKS+pMxN43kSdzNwudJ+bQbLlmnxvPOQoCugSap1GnSRoG8KOiKbH+rIA0lEeSAg3y6eeQ6XI2nrYnrPM89bUTgI0Pdqvl50vlNbtZxDUBcLBK0kPd5jPziyLdojJIN0pq5/mdzwL4UVvVInV5ncQEPNOUxa9d0TU+CW5l+FoI0GSDKHVVSOs+0KOsZoxwOzSZNFGv0mQ9avyLCh2Hpm+70Y0YJoJVgmQv822wnDC8Miq6VjJ5IFed0QD1YiAbT+nQE8v/RMZfmgmcCRHIIu7Bmcp39oM9fqEychcA747KxQ/AEyqQonl7hATtJmnhO2XYtgcia01aSbVMenAXrIomPcLgEBA4liGBzFZAT8zBYqW6brI67wg8sFVhxBhwLwBP2+tqBQqqK7VJKGh/BRrfTr6nWL7nYBaZdBJHqrX3kPEPap56xwE/GvjJTRMADeMCdcGpGXL1Xh4ZL8BDOlWkUpegfi0CeDzeA5YITzEnddv+IXL+UYCmqIvqC9UlUC/ki9FipwVjunL3yX7dOTLeXmVMAhbsGporPfyOBTm/BJ23gTVehsvXRnSewagUfpBXF3p5pygKS7OceqTjb7h2vjr/XKm0ZofKSI2Q/J102wHzatZkJPYQ5JoKsuK+EoHJakVzubzuLQDepCKllTZi9AG0DYg9ZLxhFaZsOu7bvlmVI5oPXJMQJcHxHClSln1apFTvAimeg48u0RWFeZW4lVcjbQWZuIQK1KozZfIDO6CSQmQQXdpBaiKZyEWThVK1uEc6v7V7uK0ysduExPZx4vysDR+4SelhBYm0R6LBuR4PXts8MYMcJPsINo4YZCDLj0sgB0/vLpPXvA2Tn42Cv5rsLulGubzW0sEd3d4W/mJt2Kck+DzDMijfPLOjyrDhXSh852B+OvflqAkoyXO1cYfujtc/i3jJSAwhgfFlp20laMLOku/bC7prgqW7lCn4auE5NhcXPd3M7x70+IceSgZvNljCd9k3fLjYsPElqLR14PXQZqD2ZNkkrAB79UeJUebFQmXpf8ZcAQt2XrMQdyNUVBqZoUzAFyp3V3xi/MubUA/mCT4Fhf038PC8XplhWnCmnK/ZzyC2BSTRSqKVOuY2kB8Jia0lvvRIVoP+vVWJbYarf6p655E2/nANBMCWkgD49DA0VAMyI1OLFMYCXiU9bmzi9/y5i/vsaTpHPHidTofzLbM65vMPva9HlovgXp0AvjtaqYMfDD0/4mAsYE92pxa+9k1QgCnRVObCpojpzsKTPvayPetTEgBdwnssjuc0kOBFX+q3HwRQxdrOLAqeYRjkMk/trTSu2Z9Lik7CfF0AvjtqAhS4NHobGXUnB5DQs8hG8p/wMX1r4+8xkmyvQ50JVq72TVeXbz3HvpWaQJi57hJYTw4kGbtS+C2TigQUtZUX+X27QQq2ePBZBru/0lxTm8fOOQ5yaZOZMAV+he4FqIMB+LQB0UgMSajANX29j+vbmly8ipRvHeSQoQOkM5iFXcPQCVwDMs5RBCQmaPOyvbNd6uwvQJ183BZQG3Zc+Eiv7vQOKu8YeDmMcJlt2ckyftVeMIGLBCmdMHl/tFILYwGPjXWO3zOfSq/+om+oa7Mlh2fpSsRGLp7RAW3FUVjNHgiMhyE6zBFjM2BdkdJGO7nP1kJXWAtBuBpPIAu7f+hhu7bFXIuC5xWrf0X2xreykOsUyKkF2gwadbrXDcXrfKxR43zGcSj4t/cCgr+a1iy6EjE5GYktUCl9fwfMeylyooGF48bN2IGLTw8x7StS7sj8TF9FmPGWQhm3rRR+o9lhvjJvSYAdfDUevI1M6bnX/OwWaDMOQ8RPgKRo0eulBTdT8AW2kl8e9L7UHghHwMfLiZPNoSpx0yugpQZaFqKWqxVSM3a2pN1SAhC2jf94I7ybBI7EL5A2Wvu5ht3xsoEt4+Ay/abXgCQAxyOeDsDlTCQzy75ohcGgv9Tra9uiymRUYTLrswOLlCdfAQf7HPDQQ4ErAH5EDXB9cMxWYpjtXApRncojS0sbV/cCgHTHwGNBJy+1PQE2x56FpaVR7wfQGZ37V+V+19EiHNvR6q1fRUjqvbjbMq1/qfHxbTrE10ePY2gPFk48D2CVMTf1AF4PXvyYR9dV6Wf7H413m3xTWQvYGhQ7mfYwA5mAX+18Vue05v/8jG/fZX/IW5MKPKtjSYlt0ellxh+/BOCPAwYaeVr0QofZFxJWVWC8znG70au6llVmktsF0bfHF6k8fvZ5esZJbwHwwnjg59tXz6sL/P0NUZDuSNu1mnJ8Vab17+cy005A9wtOpp3i0bZdpJLUil00semAwN45LgEViZYe3amNye0B6A9chviSlzXVsFtyN5/1H3gaNmMpn8Fz0GpYFp6Zw615H/LpUuRQQDMCL82n5DpBSawkvzIdN2ypiT8nSLth8Pk9jnjwdFzH3W4XW6KMBfwB569NdcGX93mC16tTflcArcYUc/mFuYbV+8zY0SAjAVoNErNgWjtwumJ3wbn/HlBFYdxHvSkJJEc+Ngal9opSwyo9YlITX2C/P/+gf8sxURSLR+mcZUmeqaS9wrh6vxW5zxFCOqFi90RbDWq/YwZmnu1+a6OvdpvRqkNxxe44lyl4OobEnpKA6Uox5EfH9xzPs/HRKrTPWdIQrK1VZDU7ETiD3Obpl+8wPPCRBbkbwNtpW9AbBe5L1SMlj3tdTxk/9W47JUmqS5HU+JzYymUKXjtWVmT9RenIhgXc+nroWLyxXJhmL112OdB8GCsk4f8oZJucnvmmtR85mBn10GZ0EKSCMUSAR3ukcXd5s7LvLD3me61WkuTCpJzYAyRurMB44EdEJzTfU271lUJC03YjXJXzYOGZwN4D8eB5jlfLrdWfzGRW7icMPfiSO6Oe7s20bmhdgLX4Z23B+s3JgQESzUDiMboSzDMHFpNMwccGePauhfwjzwnI2wu9zKGgEFg80jcZ7MHllk07s1H+5yojtUQTlH4nFdLKTGwDmPbIklOb1L1zO4T6N8NCuDLFLS/C63c0eNRimZ++s5BMBHxU11jHchI9oFVUxRh/eMDzHEzGYu0Lg8gJ7oS/tFCwoic44fyUtix0n/46vP4bf+//BRgAYwDDar4ncHIAAAAASUVORK5CYII='; } } diff --git a/ThinkPHP/Library/Think/Auth.class.php b/ThinkPHP/Library/Think/Auth.class.php index 4c1dea1cd..d5aca936a 100644 --- a/ThinkPHP/Library/Think/Auth.class.php +++ b/ThinkPHP/Library/Think/Auth.class.php @@ -6,19 +6,20 @@ // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- -// | Author: luofei614   +// | Author: luofei614 // +---------------------------------------------------------------------- namespace Think; + /** * 权限认证类 * 功能特性: * 1,是对规则进行认证,不是对节点进行认证。用户可以把节点当作规则名称实现对节点进行认证。 * $auth=new Auth(); $auth->check('规则名称','用户id') * 2,可以同时对多条规则进行认证,并设置多条规则的关系(or或者and) - * $auth=new Auth(); $auth->check('规则1,规则2','用户id','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之间时这条规则才会通过。 */ @@ -29,61 +30,63 @@ -- 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`) +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 用户组表, +-- 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`) +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`) +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{ +class Auth +{ //默认配置 protected $_config = array( - 'AUTH_ON' => true, // 认证开关 - 'AUTH_TYPE' => 1, // 认证方式,1为实时认证;2为登录认证。 - 'AUTH_GROUP' => 'auth_group', // 用户组数据表名 + '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' // 用户信息表 + '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']; + 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')); @@ -91,17 +94,20 @@ public function __construct() { } /** - * 检查权限 - * @param name string|array 需要验证的规则列表,支持逗号分隔的权限规则或索引数组 - * @param uid int 认证用户的id - * @param string mode 执行check的模式 - * @param relation string 如果为 'or' 表示满足任一条规则即通过验证;如果为 'and'则表示需满足所有规则才能通过验证 - * @return boolean 通过验证返回true;失败返回false + * 检查权限 + * @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']) + public function check($name, $uid, $type = 1, $mode = 'url', $relation = 'or') + { + if (!$this->_config['AUTH_ON']) { return true; - $authList = $this->getAuthList($uid,$type); //获取用户需要验证的所有有效规则列表 + } + + $authList = $this->getAuthList($uid, $type); //获取用户需要验证的所有有效规则列表 if (is_string($name)) { $name = strtolower($name); if (strpos($name, ',') !== false) { @@ -111,27 +117,28 @@ public function check($name, $uid, $type=1, $mode='url', $relation='or') { } } $list = array(); //保存验证通过的规则名 - if ($mode=='url') { - $REQUEST = unserialize( strtolower(serialize($_REQUEST)) ); + if ('url' == $mode) { + $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 ; + foreach ($authList as $auth) { + $query = preg_replace('/^.+\?/U', '', $auth); + if ('url' == $mode && $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 ; + } else if (in_array($auth, $name)) { + $list[] = $auth; } } - if ($relation == 'or' and !empty($list)) { + if ('or' == $relation and !empty($list)) { return true; } $diff = array_diff($name, $list); - if ($relation == 'and' and empty($diff)) { + if ('and' == $relation and empty($diff)) { return true; } return false; @@ -142,61 +149,66 @@ public function check($name, $uid, $type=1, $mode='url', $relation='or') { * @param uid int 用户id * @return array 用户所属的用户组 array( * array('uid'=>'用户id','group_id'=>'用户组id','title'=>'用户组名称','rules'=>'用户组拥有的规则id,多个,号隔开'), - * ...) + * ...) */ - public function getGroups($uid) { + public function getGroups($uid) + { static $groups = array(); - if (isset($groups[$uid])) + 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") + ->join($this->_config['AUTH_GROUP'] . " g on a.group_id=g.id") ->field('uid,group_id,title,rules')->select(); - $groups[$uid]=$user_groups?:array(); + $groups[$uid] = $user_groups ?: array(); return $groups[$uid]; } /** * 获得权限列表 * @param integer $uid 用户id - * @param integer $type + * @param integer $type */ - protected function getAuthList($uid,$type) { + protected function getAuthList($uid, $type) + { static $_authList = array(); //保存用户验证通过的权限列表 - $t = implode(',',(array)$type); - if (isset($_authList[$uid.$t])) { - return $_authList[$uid.$t]; + $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]; + if (2 == $this->_config['AUTH_TYPE'] && isset($_SESSION['_AUTH_LIST_' . $uid . $t])) { + return $_SESSION['_AUTH_LIST_' . $uid . $t]; } //读取用户所属用户组 $groups = $this->getGroups($uid); - $ids = array();//保存用户所属用户组设置的所有权限规则id + $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(); + $_authList[$uid . $t] = array(); return array(); } - $map=array( - 'id'=>array('in',$ids), - 'type'=>$type, - 'status'=>1, + $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(); // + $authList = array(); // foreach ($rules as $rule) { - if (!empty($rule['condition'])) { //根据condition进行验证 - $user = $this->getUserInfo($uid);//获取用户信息,一维数组 + if (!empty($rule['condition'])) { + //根据condition进行验证 + $user = $this->getUserInfo($uid); //获取用户信息,一维数组 $command = preg_replace('/\{(\w*?)\}/', '$user[\'\\1\']', $rule['condition']); //dump($command);//debug @@ -209,10 +221,10 @@ protected function getAuthList($uid,$type) { $authList[] = strtolower($rule['name']); } } - $_authList[$uid.$t] = $authList; - if($this->_config['AUTH_TYPE']==2){ + $_authList[$uid . $t] = $authList; + if (2 == $this->_config['AUTH_TYPE']) { //规则列表结果保存到session - $_SESSION['_AUTH_LIST_'.$uid.$t]=$authList; + $_SESSION['_AUTH_LIST_' . $uid . $t] = $authList; } return array_unique($authList); } @@ -220,10 +232,11 @@ protected function getAuthList($uid,$type) { /** * 获得用户资料,根据自己的情况读取数据库 */ - protected function getUserInfo($uid) { - static $userinfo=array(); - if(!isset($userinfo[$uid])){ - $userinfo[$uid]=M()->where(array('uid'=>$uid))->table($this->_config['AUTH_USER'])->find(); + 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]; } diff --git a/ThinkPHP/Library/Think/Behavior.class.php b/ThinkPHP/Library/Think/Behavior.class.php index a467b9d74..624a76d12 100644 --- a/ThinkPHP/Library/Think/Behavior.class.php +++ b/ThinkPHP/Library/Think/Behavior.class.php @@ -9,10 +9,12 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think; + /** * ThinkPHP Behavior基础类 */ -abstract class Behavior { +abstract class Behavior +{ /** * 执行行为 run方法是Behavior唯一的接口 * @access public @@ -21,4 +23,4 @@ abstract class Behavior { */ abstract public function run(&$params); -} \ No newline at end of file +} diff --git a/ThinkPHP/Library/Think/Build.class.php b/ThinkPHP/Library/Think/Build.class.php index 65281070c..f0503d373 100644 --- a/ThinkPHP/Library/Think/Build.class.php +++ b/ThinkPHP/Library/Think/Build.class.php @@ -9,12 +9,14 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think; + /** * 用于ThinkPHP的自动生成 */ -class Build { +class Build +{ - static protected $controller = ''配置值'\n);":''); + if (!is_file(CONF_PATH . 'config' . CONF_EXT)) { + file_put_contents(CONF_PATH . 'config' . CONF_EXT, '.php' == CONF_EXT ? "'配置值'\n);" : ''); + } + // 写入模块配置文件 - if(!is_file(APP_PATH.$module.'/Conf/config'.CONF_EXT)) - file_put_contents(APP_PATH.$module.'/Conf/config'.CONF_EXT,'.php' == CONF_EXT ? "'配置值'\n);":''); + if (!is_file(APP_PATH . $module . '/Conf/config' . CONF_EXT)) { + file_put_contents(APP_PATH . $module . '/Conf/config' . CONF_EXT, '.php' == CONF_EXT ? "'配置值'\n);" : ''); + } + // 生成模块的测试控制器 - if(defined('BUILD_CONTROLLER_LIST')){ + if (defined('BUILD_CONTROLLER_LIST')) { // 自动生成的控制器列表(注意大小写) - $list = explode(',',BUILD_CONTROLLER_LIST); - foreach($list as $controller){ - self::buildController($module,$controller); + $list = explode(',', BUILD_CONTROLLER_LIST); + foreach ($list as $controller) { + self::buildController($module, $controller); } - }else{ + } else { // 生成默认的控制器 self::buildController($module); } // 生成模块的模型 - if(defined('BUILD_MODEL_LIST')){ + if (defined('BUILD_MODEL_LIST')) { // 自动生成的控制器列表(注意大小写) - $list = explode(',',BUILD_MODEL_LIST); - foreach($list as $model){ - self::buildModel($module,$model); + $list = explode(',', BUILD_MODEL_LIST); + foreach ($list as $model) { + self::buildModel($module, $model); } - } - }else{ + } + } else { header('Content-Type:text/html; charset=utf-8'); - exit('应用目录['.APP_PATH.']不可写,目录无法自动生成!
请手动生成项目目录~'); + exit('应用目录[' . APP_PATH . ']不可写,目录无法自动生成!
请手动生成项目目录~'); } } // 检查缓存目录(Runtime) 如果不存在则自动创建 - static public function buildRuntime() { - if(!is_dir(RUNTIME_PATH)) { + public static function buildRuntime() + { + if (!is_dir(RUNTIME_PATH)) { mkdir(RUNTIME_PATH); - }elseif(!is_writeable(RUNTIME_PATH)) { + } elseif (!is_writeable(RUNTIME_PATH)) { header('Content-Type:text/html; charset=utf-8'); - exit('目录 [ '.RUNTIME_PATH.' ] 不可写!'); + exit('目录 [ ' . RUNTIME_PATH . ' ] 不可写!'); + } + mkdir(CACHE_PATH); // 模板缓存目录 + if (!is_dir(LOG_PATH)) { + mkdir(LOG_PATH); + } + // 日志目录 + if (!is_dir(TEMP_PATH)) { + mkdir(TEMP_PATH); } - mkdir(CACHE_PATH); // 模板缓存目录 - if(!is_dir(LOG_PATH)) mkdir(LOG_PATH); // 日志目录 - if(!is_dir(TEMP_PATH)) mkdir(TEMP_PATH); // 数据缓存目录 - if(!is_dir(DATA_PATH)) mkdir(DATA_PATH); // 数据文件目录 + // 数据缓存目录 + if (!is_dir(DATA_PATH)) { + mkdir(DATA_PATH); + } + // 数据文件目录 return true; } // 创建控制器类 - static public function buildController($module,$controller='Index') { - $file = APP_PATH.$module.'/Controller/'.$controller.'Controller'.EXT; - if(!is_file($file)){ - $content = str_replace(array('[MODULE]','[CONTROLLER]'),array($module,$controller),self::$controller); - if(!C('APP_USE_NAMESPACE')){ - $content = preg_replace('/namespace\s(.*?);/','',$content,1); + public static function buildController($module, $controller = 'Index') + { + $file = APP_PATH . $module . '/Controller/' . $controller . 'Controller' . EXT; + if (!is_file($file)) { + $content = str_replace(array('[MODULE]', '[CONTROLLER]'), array($module, $controller), self::$controller); + if (!C('APP_USE_NAMESPACE')) { + $content = preg_replace('/namespace\s(.*?);/', '', $content, 1); } $dir = dirname($file); - if(!is_dir($dir)){ + if (!is_dir($dir)) { mkdir($dir, 0755, true); } - file_put_contents($file,$content); + file_put_contents($file, $content); } } // 创建模型类 - static public function buildModel($module,$model) { - $file = APP_PATH.$module.'/Model/'.$model.'Model'.EXT; - if(!is_file($file)){ - $content = str_replace(array('[MODULE]','[MODEL]'),array($module,$model),self::$model); - if(!C('APP_USE_NAMESPACE')){ - $content = preg_replace('/namespace\s(.*?);/','',$content,1); + public static function buildModel($module, $model) + { + $file = APP_PATH . $module . '/Model/' . $model . 'Model' . EXT; + if (!is_file($file)) { + $content = str_replace(array('[MODULE]', '[MODEL]'), array($module, $model), self::$model); + if (!C('APP_USE_NAMESPACE')) { + $content = preg_replace('/namespace\s(.*?);/', '', $content, 1); } $dir = dirname($file); - if(!is_dir($dir)){ + if (!is_dir($dir)) { mkdir($dir, 0755, true); } - file_put_contents($file,$content); + file_put_contents($file, $content); } } // 生成目录安全文件 - static public function buildDirSecure($dirs=array()) { + public static function buildDirSecure($dirs = array()) + { // 目录安全写入(默认开启) - defined('BUILD_DIR_SECURE') or define('BUILD_DIR_SECURE', true); - if(BUILD_DIR_SECURE) { - defined('DIR_SECURE_FILENAME') or define('DIR_SECURE_FILENAME', 'index.html'); - defined('DIR_SECURE_CONTENT') or define('DIR_SECURE_CONTENT', ' '); + defined('BUILD_DIR_SECURE') or define('BUILD_DIR_SECURE', true); + if (BUILD_DIR_SECURE) { + defined('DIR_SECURE_FILENAME') or define('DIR_SECURE_FILENAME', 'index.html'); + defined('DIR_SECURE_CONTENT') or define('DIR_SECURE_CONTENT', ' '); // 自动写入目录安全文件 $content = DIR_SECURE_CONTENT; - $files = explode(',', DIR_SECURE_FILENAME); - foreach ($files as $filename){ - foreach ($dirs as $dir) - file_put_contents($dir.$filename,$content); + $files = explode(',', DIR_SECURE_FILENAME); + foreach ($files as $filename) { + foreach ($dirs as $dir) { + file_put_contents($dir . $filename, $content); + } + } } } diff --git a/ThinkPHP/Library/Think/Cache.class.php b/ThinkPHP/Library/Think/Cache.class.php index b098261c2..c8c59b9c0 100644 --- a/ThinkPHP/Library/Think/Cache.class.php +++ b/ThinkPHP/Library/Think/Cache.class.php @@ -9,17 +9,19 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think; + /** * 缓存管理类 */ -class Cache { +class Cache +{ /** * 操作句柄 * @var string * @access protected */ - protected $handler ; + protected $handler; /** * 缓存连接参数 @@ -35,13 +37,19 @@ class Cache { * @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)) + 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); + } else { + E(L('_CACHE_TYPE_INVALID_') . ':' . $type); + } + return $cache; } @@ -51,32 +59,38 @@ public function connect($type='',$options=array()) { * @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 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) { + public function __get($name) + { return $this->get($name); } - public function __set($name,$value) { - return $this->set($name,$value); + public function __set($name, $value) + { + return $this->set($name, $value); } - public function __unset($name) { + public function __unset($name) + { $this->rm($name); } - public function setOptions($name,$value) { - $this->options[$name] = $value; + public function setOptions($name, $value) + { + $this->options[$name] = $value; } - public function getOptions($name) { + public function getOptions($name) + { return $this->options[$name]; } @@ -86,42 +100,47 @@ public function getOptions($name) { * @param string $key 队列名 * @return mixed */ - // - protected function queue($key) { + // + protected function queue($key) + { static $_handler = array( - 'file' => array('F','F'), - 'xcache'=> array('xcache_get','xcache_set'), - 'apc' => array('apc_fetch','apc_store'), + '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(); + $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']) { + if (false === array_search($key, $value)) { + array_push($value, $key); + } + + if (count($value) > $this->options['length']) { // 出列 - $key = array_shift($value); + $key = array_shift($value); // 删除缓存 $this->rm($key); - if(APP_DEBUG){ + if (APP_DEBUG) { //调试模式下,记录出列次数 - N($queue_name.'_out_times',1); + N($queue_name . '_out_times', 1); } } - return $fun[1]($queue_name,$value); + return $fun[1]($queue_name, $value); } - - public function __call($method,$args){ + + 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_')); + 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; } } -} \ No newline at end of file +} diff --git a/ThinkPHP/Library/Think/Cache/Driver/Apachenote.class.php b/ThinkPHP/Library/Think/Cache/Driver/Apachenote.class.php index 4ad3fd736..125f5a536 100644 --- a/ThinkPHP/Library/Think/Cache/Driver/Apachenote.class.php +++ b/ThinkPHP/Library/Think/Cache/Driver/Apachenote.class.php @@ -9,33 +9,36 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think\Cache\Driver; + use Think\Cache; -defined('THINK_PATH') or exit(); + /** * Apachenote缓存驱动 */ -class Apachenote extends Cache { +class Apachenote extends Cache +{ /** * 架构函数 * @param array $options 缓存参数 * @access public */ - public function __construct($options=array()) { - if(!empty($options)) { - $this->options = $options; + 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, + 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->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(); } @@ -45,19 +48,20 @@ public function __construct($options=array()) { * @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); + 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); - } + for ($data = '';!feof($this->handler);) { + $data .= fread($this->handler, 4096); + } + N('cache_read', 1); + $this->close(); + return '' === $data ? '' : unserialize($data); + } /** * 写入缓存 @@ -66,18 +70,19 @@ public function get($name) { * @param mixed $value 存储数据 * @return boolean */ - public function set($name, $value) { - N('cache_write',1); + 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; + $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) { + if ("OK\n" === $ret) { + if ($this->options['length'] > 0) { // 记录缓存队列 $this->queue($name); } @@ -92,33 +97,36 @@ public function set($name, $value) { * @param string $name 缓存变量名 * @return boolean */ - public function rm($name) { + public function rm($name) + { $this->open(); - $name = $this->options['prefix'].$name; - $s = 'D' . pack('N', strlen($name)) . $name; + $name = $this->options['prefix'] . $name; + $s = 'D' . pack('N', strlen($name)) . $name; fwrite($this->handler, $s); - $ret = fgets($this->handler); + $ret = fgets($this->handler); $this->close(); - return $ret === "OK\n"; - } + return "OK\n" === $ret; + } /** * 关闭缓存 * @access private */ - private function close() { - fclose($this->handler); - $this->handler = false; - } + 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']); - } - } + private function open() + { + if (!is_resource($this->handler)) { + $this->handler = fsockopen($this->options['host'], $this->options['port'], $_, $_, $this->options['timeout']); + } + } -} \ No newline at end of file +} diff --git a/ThinkPHP/Library/Think/Cache/Driver/Apc.class.php b/ThinkPHP/Library/Think/Cache/Driver/Apc.class.php index 4ccb94124..5135d00ee 100644 --- a/ThinkPHP/Library/Think/Cache/Driver/Apc.class.php +++ b/ThinkPHP/Library/Think/Cache/Driver/Apc.class.php @@ -9,25 +9,28 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think\Cache\Driver; + use Think\Cache; -defined('THINK_PATH') or exit(); + /** * Apc缓存驱动 */ -class Apc extends Cache { +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'); + 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'); + $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'); } /** @@ -36,10 +39,11 @@ public function __construct($options=array()) { * @param string $name 缓存变量名 * @return mixed */ - public function get($name) { - N('cache_read',1); - return apc_fetch($this->options['prefix'].$name); - } + public function get($name) + { + N('cache_read', 1); + return apc_fetch($this->options['prefix'] . $name); + } /** * 写入缓存 @@ -49,20 +53,21 @@ public function get($name) { * @param integer $expire 有效时间(秒) * @return boolean */ - public function set($name, $value, $expire = null) { - N('cache_write',1); - if(is_null($expire)) { - $expire = $this->options['expire']; + 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) { + $name = $this->options['prefix'] . $name; + if ($result = apc_store($name, $value, $expire)) { + if ($this->options['length'] > 0) { // 记录缓存队列 $this->queue($name); } } return $result; - } + } /** * 删除缓存 @@ -70,16 +75,18 @@ public function set($name, $value, $expire = null) { * @param string $name 缓存变量名 * @return boolean */ - public function rm($name) { - return apc_delete($this->options['prefix'].$name); - } + public function rm($name) + { + return apc_delete($this->options['prefix'] . $name); + } /** * 清除缓存 * @access public * @return boolean */ - public function clear() { + public function clear() + { return apc_clear_cache(); } diff --git a/ThinkPHP/Library/Think/Cache/Driver/Db.class.php b/ThinkPHP/Library/Think/Cache/Driver/Db.class.php index fc2f21021..cb319baee 100644 --- a/ThinkPHP/Library/Think/Cache/Driver/Db.class.php +++ b/ThinkPHP/Library/Think/Cache/Driver/Db.class.php @@ -9,8 +9,9 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think\Cache\Driver; + use Think\Cache; -defined('THINK_PATH') or exit(); + /** * 数据库方式缓存驱动 * CREATE TABLE think_cache ( @@ -21,24 +22,26 @@ * UNIQUE KEY `cachekey` (`cachekey`) * ); */ -class Db extends Cache { +class Db extends Cache +{ /** * 架构函数 * @param array $options 缓存参数 * @access public */ - public function __construct($options=array()) { - if(empty($options)) { - $options = array ( - 'table' => C('DATA_CACHE_TABLE'), + 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(); + $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(); } /** @@ -47,26 +50,27 @@ public function __construct($options=array()) { * @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'])) {//校验错误 + 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 (md5($result['data']) != $result['datacrc']) { //校验错误 return false; } } - $content = $result['data']; - if(C('DATA_CACHE_COMPRESS') && function_exists('gzcompress')) { + $content = $result['data']; + if (C('DATA_CACHE_COMPRESS') && function_exists('gzcompress')) { //启用数据压缩 - $content = gzuncompress($content); + $content = gzuncompress($content); } - $content = unserialize($content); + $content = unserialize($content); return $content; - } - else { + } else { return false; } } @@ -79,38 +83,40 @@ public function get($name) { * @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')) { + 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); + $data = gzcompress($data, 3); } - if(C('DATA_CACHE_CHECK')) {//开启数据校验 - $crc = md5($data); - }else { - $crc = ''; + if (C('DATA_CACHE_CHECK')) { +//开启数据校验 + $crc = md5($data); + } else { + $crc = ''; } - if(is_null($expire)) { - $expire = $this->options['expire']; + 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.')'); + $expire = (0 == $expire) ? 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) { + if ($result) { + if ($this->options['length'] > 0) { // 记录缓存队列 $this->queue($name); } return true; - }else { + } else { return false; } } @@ -121,9 +127,10 @@ public function set($name, $value,$expire=null) { * @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.'\''); + public function rm($name) + { + $name = $this->options['prefix'] . addslashes($name); + return $this->handler->execute('DELETE FROM `' . $this->options['table'] . '` WHERE `cachekey`=\'' . $name . '\''); } /** @@ -131,8 +138,9 @@ public function rm($name) { * @access public * @return boolean */ - public function clear() { - return $this->handler->execute('TRUNCATE TABLE `'.$this->options['table'].'`'); + public function clear() + { + return $this->handler->execute('TRUNCATE TABLE `' . $this->options['table'] . '`'); } -} \ No newline at end of file +} diff --git a/ThinkPHP/Library/Think/Cache/Driver/Eaccelerator.class.php b/ThinkPHP/Library/Think/Cache/Driver/Eaccelerator.class.php index 751ef248f..6cd7d4c0b 100644 --- a/ThinkPHP/Library/Think/Cache/Driver/Eaccelerator.class.php +++ b/ThinkPHP/Library/Think/Cache/Driver/Eaccelerator.class.php @@ -9,22 +9,25 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think\Cache\Driver; + use Think\Cache; -defined('THINK_PATH') or exit(); + /** * Eaccelerator缓存驱动 */ -class Eaccelerator extends Cache { +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; + 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; } /** @@ -33,10 +36,11 @@ public function __construct($options=array()) { * @param string $name 缓存变量名 * @return mixed */ - public function get($name) { - N('cache_read',1); - return eaccelerator_get($this->options['prefix'].$name); - } + public function get($name) + { + N('cache_read', 1); + return eaccelerator_get($this->options['prefix'] . $name); + } /** * 写入缓存 @@ -46,23 +50,23 @@ public function get($name) { * @param integer $expire 有效时间(秒) * @return boolean */ - public function set($name, $value, $expire = null) { - N('cache_write',1); - if(is_null($expire)) { - $expire = $this->options['expire']; + public function set($name, $value, $expire = null) + { + N('cache_write', 1); + if (is_null($expire)) { + $expire = $this->options['expire']; } - $name = $this->options['prefix'].$name; + $name = $this->options['prefix'] . $name; eaccelerator_lock($name); - if(eaccelerator_put($name, $value, $expire)) { - if($this->options['length']>0) { + if (eaccelerator_put($name, $value, $expire)) { + if ($this->options['length'] > 0) { // 记录缓存队列 $this->queue($name); } return true; } return false; - } - + } /** * 删除缓存 @@ -70,8 +74,9 @@ public function set($name, $value, $expire = null) { * @param string $name 缓存变量名 * @return boolean */ - public function rm($name) { - return eaccelerator_rm($this->options['prefix'].$name); - } + public function rm($name) + { + return eaccelerator_rm($this->options['prefix'] . $name); + } -} \ No newline at end of file +} diff --git a/ThinkPHP/Library/Think/Cache/Driver/File.class.php b/ThinkPHP/Library/Think/Cache/Driver/File.class.php index c5c64efc1..54d8fd664 100644 --- a/ThinkPHP/Library/Think/Cache/Driver/File.class.php +++ b/ThinkPHP/Library/Think/Cache/Driver/File.class.php @@ -9,26 +9,32 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think\Cache\Driver; + use Think\Cache; -defined('THINK_PATH') or exit(); + /** * 文件类型缓存类 */ -class File extends Cache { +class File extends Cache +{ /** * 架构函数 * @access public */ - public function __construct($options=array()) { - if(!empty($options)) { - $this->options = $options; + 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->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(); } @@ -37,7 +43,8 @@ public function __construct($options=array()) { * @access private * @return boolean */ - private function init() { + private function init() + { // 创建应用缓存目录 if (!is_dir($this->options['temp'])) { mkdir($this->options['temp']); @@ -50,22 +57,23 @@ private function init() { * @param string $name 缓存变量名 * @return string */ - private function filename($name) { - $name = md5(C('DATA_CACHE_KEY').$name); - if(C('DATA_CACHE_SUBDIR')) { + private function filename($name) + { + $name = md5(C('DATA_CACHE_KEY') . $name); + if (C('DATA_CACHE_SUBDIR')) { // 使用子目录 - $dir =''; - for($i=0;$ioptions['temp'].$dir)) { - mkdir($this->options['temp'].$dir,0755,true); + 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'; + $filename = $dir . $this->options['prefix'] . $name . '.php'; + } else { + $filename = $this->options['prefix'] . $name . '.php'; } - return $this->options['temp'].$filename; + return $this->options['temp'] . $filename; } /** @@ -74,37 +82,39 @@ private function filename($name) { * @param string $name 缓存变量名 * @return mixed */ - public function get($name) { - $filename = $this->filename($name); + public function get($name) + { + $filename = $this->filename($name); if (!is_file($filename)) { - return false; + 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) { + N('cache_read', 1); + $content = file_get_contents($filename); + if (false !== $content) { + $expire = (int) substr($content, 8, 12); + if (0 != $expire && 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)) {//校验错误 + if (C('DATA_CACHE_CHECK')) { +//开启数据校验 + $check = substr($content, 20, 32); + $content = substr($content, 52, -3); + if (md5($content) != $check) { +//校验错误 return false; } - }else { - $content = substr($content,20, -3); + } else { + $content = substr($content, 20, -3); } - if(C('DATA_CACHE_COMPRESS') && function_exists('gzcompress')) { + if (C('DATA_CACHE_COMPRESS') && function_exists('gzcompress')) { //启用数据压缩 - $content = gzuncompress($content); + $content = gzuncompress($content); } - $content = unserialize($content); + $content = unserialize($content); return $content; - } - else { + } else { return false; } } @@ -117,32 +127,34 @@ public function get($name) { * @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']; + 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')) { + $filename = $this->filename($name); + $data = serialize($value); + if (C('DATA_CACHE_COMPRESS') && function_exists('gzcompress')) { //数据压缩 - $data = gzcompress($data,3); + $data = gzcompress($data, 3); } - if(C('DATA_CACHE_CHECK')) {//开启数据校验 - $check = md5($data); - }else { - $check = ''; + if (C('DATA_CACHE_CHECK')) { +//开启数据校验 + $check = md5($data); + } else { + $check = ''; } - $data = ""; - $result = file_put_contents($filename,$data); - if($result) { - if($this->options['length']>0) { + $data = ""; + $result = file_put_contents($filename, $data); + if ($result) { + if ($this->options['length'] > 0) { // 记录缓存队列 $this->queue($name); } clearstatcache(); return true; - }else { + } else { return false; } } @@ -153,7 +165,8 @@ public function set($name,$value,$expire=null) { * @param string $name 缓存变量名 * @return boolean */ - public function rm($name) { + public function rm($name) + { return unlink($this->filename($name)); } @@ -163,19 +176,20 @@ public function rm($name) { * @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 ); + 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; } -} \ No newline at end of file +} diff --git a/ThinkPHP/Library/Think/Cache/Driver/Memcache.class.php b/ThinkPHP/Library/Think/Cache/Driver/Memcache.class.php index ff53ebe1e..b7e7b046e 100644 --- a/ThinkPHP/Library/Think/Cache/Driver/Memcache.class.php +++ b/ThinkPHP/Library/Think/Cache/Driver/Memcache.class.php @@ -9,39 +9,41 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think\Cache\Driver; + use Think\Cache; -defined('THINK_PATH') or exit(); + /** * Memcache缓存驱动 */ -class Memcache extends Cache { +class Memcache extends Cache +{ /** * 架构函数 * @param array $options 缓存参数 * @access public */ - function __construct($options=array()) { - if ( !extension_loaded('memcache') ) { - E(L('_NOT_SUPPORT_').':memcache'); + 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); + $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']); + $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; false === $options['timeout'] ? + $this->handler->$func($options['host'], $options['port']) : + $this->handler->$func($options['host'], $options['port'], $options['timeout']); } /** @@ -50,9 +52,10 @@ function __construct($options=array()) { * @param string $name 缓存变量名 * @return mixed */ - public function get($name) { - N('cache_read',1); - return $this->handler->get($this->options['prefix'].$name); + public function get($name) + { + N('cache_read', 1); + return $this->handler->get($this->options['prefix'] . $name); } /** @@ -63,14 +66,15 @@ public function get($name) { * @param integer $expire 有效时间(秒) * @return boolean */ - public function set($name, $value, $expire = null) { - N('cache_write',1); - if(is_null($expire)) { - $expire = $this->options['expire']; + 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) { + $name = $this->options['prefix'] . $name; + if ($this->handler->set($name, $value, 0, $expire)) { + if ($this->options['length'] > 0) { // 记录缓存队列 $this->queue($name); } @@ -85,11 +89,12 @@ public function set($name, $value, $expire = null) { * @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); + public function rm($name, $ttl = false) + { + $name = $this->options['prefix'] . $name; + return false === $ttl ? + $this->handler->delete($name) : + $this->handler->delete($name, $ttl); } /** @@ -97,7 +102,8 @@ public function rm($name, $ttl = false) { * @access public * @return boolean */ - public function clear() { + public function clear() + { return $this->handler->flush(); } } diff --git a/ThinkPHP/Library/Think/Cache/Driver/Memcached.class.php b/ThinkPHP/Library/Think/Cache/Driver/Memcached.class.php index 929bdcaea..5cf08faf1 100644 --- a/ThinkPHP/Library/Think/Cache/Driver/Memcached.class.php +++ b/ThinkPHP/Library/Think/Cache/Driver/Memcached.class.php @@ -17,28 +17,30 @@ /** * Memcached缓存驱动 */ -class Memcached extends Cache { +class Memcached extends Cache +{ /** * * @param array $options */ - public function __construct($options = array()) { - if ( !extension_loaded('memcached') ) { - E(L('_NOT_SUPPORT_').':memcached'); + 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 + '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->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; + $this->handler = new MemcachedResource; $options['servers'] && $this->handler->addServers($options['servers']); $options['lib_options'] && $this->handler->setOptions($options['lib_options']); } @@ -49,9 +51,10 @@ public function __construct($options = array()) { * @param string $name 缓存变量名 * @return mixed */ - public function get($name) { - N('cache_read',1); - return $this->handler->get($this->options['prefix'].$name); + public function get($name) + { + N('cache_read', 1); + return $this->handler->get($this->options['prefix'] . $name); } /** @@ -62,14 +65,15 @@ public function get($name) { * @param integer $expire 有效时间(秒) * @return boolean */ - public function set($name, $value, $expire = null) { - N('cache_write',1); - if(is_null($expire)) { - $expire = $this->options['expire']; + 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) { + $name = $this->options['prefix'] . $name; + if ($this->handler->set($name, $value, time() + $expire)) { + if ($this->options['length'] > 0) { // 记录缓存队列 $this->queue($name); } @@ -84,9 +88,10 @@ public function set($name, $value, $expire = null) { * @param string $name 缓存变量名 * @return boolean */ - public function rm($name, $ttl = false) { - $name = $this->options['prefix'].$name; - return $ttl === false ? + public function rm($name, $ttl = false) + { + $name = $this->options['prefix'] . $name; + return false === $ttl ? $this->handler->delete($name) : $this->handler->delete($name, $ttl); } @@ -96,7 +101,8 @@ public function rm($name, $ttl = false) { * @access public * @return boolean */ - public function clear() { + public function clear() + { return $this->handler->flush(); } } diff --git a/ThinkPHP/Library/Think/Cache/Driver/Memcachesae.class.php b/ThinkPHP/Library/Think/Cache/Driver/Memcachesae.class.php index a1d1c5641..576e5822b 100644 --- a/ThinkPHP/Library/Think/Cache/Driver/Memcachesae.class.php +++ b/ThinkPHP/Library/Think/Cache/Driver/Memcachesae.class.php @@ -9,9 +9,9 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think\Cache\Driver; + use Think\Cache; -defined('THINK_PATH') or exit(); /** * Memcache缓存驱动 * @category Extend @@ -19,28 +19,30 @@ * @subpackage Driver.Cache * @author liu21st */ -class Memcachesae extends Cache { +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); + 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] 下实例化 + $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; + $this->connected = true; } /** @@ -48,7 +50,8 @@ function __construct($options=array()) { * @access private * @return boolean */ - private function isConnected() { + private function isConnected() + { return $this->connected; } @@ -58,9 +61,10 @@ private function isConnected() { * @param string $name 缓存变量名 * @return mixed */ - public function get($name) { - N('cache_read',1); - return $this->handler->get($_SERVER['HTTP_APPVERSION'].'/'.$this->options['prefix'].$name); + public function get($name) + { + N('cache_read', 1); + return $this->handler->get($_SERVER['HTTP_APPVERSION'] . '/' . $this->options['prefix'] . $name); } /** @@ -71,14 +75,15 @@ public function get($name) { * @param integer $expire 有效时间(秒) * @return boolean */ - public function set($name, $value, $expire = null) { - N('cache_write',1); - if(is_null($expire)) { - $expire = $this->options['expire']; + 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) { + $name = $this->options['prefix'] . $name; + if ($this->handler->set($_SERVER['HTTP_APPVERSION'] . '/' . $name, $value, 0, $expire)) { + if ($this->options['length'] > 0) { // 记录缓存队列 $this->queue($name); } @@ -93,11 +98,12 @@ public function set($name, $value, $expire = null) { * @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); + public function rm($name, $ttl = false) + { + $name = $_SERVER['HTTP_APPVERSION'] . '/' . $this->options['prefix'] . $name; + return false === $ttl ? + $this->handler->delete($name) : + $this->handler->delete($name, $ttl); } /** @@ -105,7 +111,8 @@ public function rm($name, $ttl = false) { * @access public * @return boolean */ - public function clear() { + public function clear() + { return $this->handler->flush(); } @@ -116,29 +123,35 @@ public function clear() { * @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(); + 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']) { + if (false === array_search($key, $value)) { + array_push($value, $key); + } + + if (count($value) > $this->options['length']) { // 出列 - $key = array_shift($value); + $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); - } + //调试模式下记录出队次数 + $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); + return F($queue_name, $value); } } diff --git a/ThinkPHP/Library/Think/Cache/Driver/Redis.class.php b/ThinkPHP/Library/Think/Cache/Driver/Redis.class.php index 132cefb66..eaca5ee3f 100644 --- a/ThinkPHP/Library/Think/Cache/Driver/Redis.class.php +++ b/ThinkPHP/Library/Think/Cache/Driver/Redis.class.php @@ -9,39 +9,40 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think\Cache\Driver; + use Think\Cache; -defined('THINK_PATH') or exit(); /** - * Redis缓存驱动 + * Redis缓存驱动 * 要求安装phpredis扩展:https://github.com/nicolasff/phpredis */ -class Redis extends Cache { - /** - * 架构函数 +class Redis extends Cache +{ + /** + * 架构函数 * @param array $options 缓存参数 * @access public */ - public function __construct($options=array()) { - if ( !extension_loaded('redis') ) { - E(L('_NOT_SUPPORT_').':redis'); + 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); + $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']); + $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; false === $options['timeout'] ? + $this->handler->$func($options['host'], $options['port']) : + $this->handler->$func($options['host'], $options['port'], $options['timeout']); } /** @@ -50,11 +51,12 @@ public function __construct($options=array()) { * @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返回源数据 + public function get($name) + { + N('cache_read', 1); + $value = $this->handler->get($this->options['prefix'] . $name); + $jsonData = json_decode($value, true); + return (null === $jsonData) ? $value : $jsonData; //检测是否为JSON数据 true 返回JSON解析数组, false返回源数据 } /** @@ -65,20 +67,21 @@ public function get($name) { * @param integer $expire 有效时间(秒) * @return boolean */ - public function set($name, $value, $expire = null) { - N('cache_write',1); - if(is_null($expire)) { - $expire = $this->options['expire']; + public function set($name, $value, $expire = null) + { + N('cache_write', 1); + if (is_null($expire)) { + $expire = $this->options['expire']; } - $name = $this->options['prefix'].$name; + $name = $this->options['prefix'] . $name; //对数组/对象数据进行缓存处理,保证数据完整性 - $value = (is_object($value) || is_array($value)) ? json_encode($value) : $value; - if(is_int($expire) && $expire) { + $value = (is_object($value) || is_array($value)) ? json_encode($value) : $value; + if (is_int($expire) && $expire) { $result = $this->handler->setex($name, $expire, $value); - }else{ + } else { $result = $this->handler->set($name, $value); } - if($result && $this->options['length']>0) { + if ($result && $this->options['length'] > 0) { // 记录缓存队列 $this->queue($name); } @@ -91,8 +94,9 @@ public function set($name, $value, $expire = null) { * @param string $name 缓存变量名 * @return boolean */ - public function rm($name) { - return $this->handler->delete($this->options['prefix'].$name); + public function rm($name) + { + return $this->handler->delete($this->options['prefix'] . $name); } /** @@ -100,7 +104,8 @@ public function rm($name) { * @access public * @return boolean */ - public function clear() { + public function clear() + { return $this->handler->flushDB(); } diff --git a/ThinkPHP/Library/Think/Cache/Driver/Shmop.class.php b/ThinkPHP/Library/Think/Cache/Driver/Shmop.class.php index 60927c3ee..be0c02610 100644 --- a/ThinkPHP/Library/Think/Cache/Driver/Shmop.class.php +++ b/ThinkPHP/Library/Think/Cache/Driver/Shmop.class.php @@ -9,34 +9,37 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think\Cache\Driver; + use Think\Cache; -defined('THINK_PATH') or exit(); + /** - * Shmop缓存驱动 + * Shmop缓存驱动 */ -class Shmop extends Cache { +class Shmop extends Cache +{ /** * 架构函数 * @param array $options 缓存参数 * @access public */ - public function __construct($options=array()) { - if ( !extension_loaded('shmop') ) { - E(L('_NOT_SUPPORT_').':shmop'); + public function __construct($options = array()) + { + if (!extension_loaded('shmop')) { + E(L('_NOT_SUPPORT_') . ':shmop'); } - if(!empty($options)){ + if (!empty($options)) { $options = array( - 'size' => C('SHARE_MEM_SIZE'), - 'temp' => TEMP_PATH, - 'project' => 's', - 'length' => 0, - ); + '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']); + $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']); } /** @@ -45,28 +48,29 @@ public function __construct($options=array()) { * @param string $name 缓存变量名 * @return mixed */ - public function get($name = false) { - N('cache_read',1); + public function get($name = false) + { + N('cache_read', 1); $id = shmop_open($this->handler, 'c', 0600, 0); - if ($id !== false) { + if (false !== $id) { $ret = unserialize(shmop_read($id, 0, shmop_size($id))); shmop_close($id); - if ($name === false) { + if (false === $name) { return $ret; } - $name = $this->options['prefix'].$name; - if(isset($ret[$name])) { - $content = $ret[$name]; - if(C('DATA_CACHE_COMPRESS') && function_exists('gzcompress')) { + $name = $this->options['prefix'] . $name; + if (isset($ret[$name])) { + $content = $ret[$name]; + if (C('DATA_CACHE_COMPRESS') && function_exists('gzcompress')) { //启用数据压缩 - $content = gzuncompress($content); + $content = gzuncompress($content); } return $content; - }else { + } else { return null; } - }else { + } else { return false; } } @@ -78,20 +82,24 @@ public function get($name = false) { * @param mixed $value 存储数据 * @return boolean */ - public function set($name, $value) { - N('cache_write',1); - $lh = $this->_lock(); + 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')) { + if (!is_array($val)) { + $val = array(); + } + + if (C('DATA_CACHE_COMPRESS') && function_exists('gzcompress')) { //数据压缩 - $value = gzcompress($value,3); + $value = gzcompress($value, 3); } - $name = $this->options['prefix'].$name; + $name = $this->options['prefix'] . $name; $val[$name] = $value; - $val = serialize($val); - if($this->_write($val, $lh)) { - if($this->options['length']>0) { + $val = serialize($val); + if ($this->_write($val, $lh)) { + if ($this->options['length'] > 0) { // 记录缓存队列 $this->queue($name); } @@ -106,11 +114,15 @@ public function set($name, $value) { * @param string $name 缓存变量名 * @return boolean */ - public function rm($name) { - $lh = $this->_lock(); + public function rm($name) + { + $lh = $this->_lock(); $val = $this->get(); - if (!is_array($val)) $val = array(); - $name = $this->options['prefix'].$name; + if (!is_array($val)) { + $val = array(); + } + + $name = $this->options['prefix'] . $name; unset($val[$name]); $val = serialize($val); return $this->_write($val, $lh); @@ -122,15 +134,19 @@ public function rm($name) { * @param string $project 项目标识名 * @return integer */ - private function _ftok($project) { - if (function_exists('ftok')) return ftok(__FILE__, $project); - if(strtoupper(PHP_OS) == 'WINNT'){ + 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 { + (($project & 0xff) << 24))); + } else { $filename = __FILE__ . (string) $project; - for($key = array(); sizeof($key) < strlen($filename); $key[] = ord(substr($filename, sizeof($key), 1))); + for ($key = array(); sizeof($key) < strlen($filename); $key[] = ord(substr($filename, sizeof($key), 1))); return dechex(array_sum($key)); } } @@ -141,13 +157,14 @@ private function _ftok($project) { * @param string $name 缓存变量名 * @return integer|boolean */ - private function _write(&$val, &$lh) { - $id = shmop_open($this->handler, 'c', 0600, $this->options['size']); + 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; + $ret = shmop_write($id, $val, 0) == strlen($val); + shmop_close($id); + $this->_unlock($lh); + return $ret; } $this->_unlock($lh); return false; @@ -159,12 +176,13 @@ private function _write(&$val, &$lh) { * @param string $name 缓存变量名 * @return boolean */ - private function _lock() { + private function _lock() + { if (function_exists('sem_get')) { $fp = sem_get($this->handler, 1, 0600, 1); - sem_acquire ($fp); + sem_acquire($fp); } else { - $fp = fopen($this->options['temp'].$this->options['prefix'].md5($this->handler), 'w'); + $fp = fopen($this->options['temp'] . $this->options['prefix'] . md5($this->handler), 'w'); flock($fp, LOCK_EX); } return $fp; @@ -176,7 +194,8 @@ private function _lock() { * @param string $name 缓存变量名 * @return boolean */ - private function _unlock(&$fp) { + private function _unlock(&$fp) + { if (function_exists('sem_release')) { sem_release($fp); } else { diff --git a/ThinkPHP/Library/Think/Cache/Driver/Sqlite.class.php b/ThinkPHP/Library/Think/Cache/Driver/Sqlite.class.php index 33bd222f9..2b89deb58 100644 --- a/ThinkPHP/Library/Think/Cache/Driver/Sqlite.class.php +++ b/ThinkPHP/Library/Think/Cache/Driver/Sqlite.class.php @@ -9,35 +9,38 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think\Cache\Driver; + use Think\Cache; -defined('THINK_PATH') or exit(); + /** * Sqlite缓存驱动 */ -class Sqlite extends Cache { +class Sqlite extends Cache +{ /** * 架构函数 * @param array $options 缓存参数 * @access public */ - public function __construct($options=array()) { - if ( !extension_loaded('sqlite') ) { - E(L('_NOT_SUPPORT_').':sqlite'); + public function __construct($options = array()) + { + if (!extension_loaded('sqlite')) { + E(L('_NOT_SUPPORT_') . ':sqlite'); } - if(empty($options)) { - $options = array ( - 'db' => ':memory:', - 'table' => 'sharedmemory', + 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']); + $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']); } /** @@ -46,16 +49,17 @@ public function __construct($options=array()) { * @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'; + 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 = sqlite_fetch_single($result); + if (C('DATA_CACHE_COMPRESS') && function_exists('gzcompress')) { //启用数据压缩 - $content = gzuncompress($content); + $content = gzuncompress($content); } return unserialize($content); } @@ -70,21 +74,22 @@ public function get($name) { * @param integer $expire 有效时间(秒) * @return boolean */ - public function set($name, $value,$expire=null) { - N('cache_write',1); - $name = $this->options['prefix'].sqlite_escape_string($name); + 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']; + if (is_null($expire)) { + $expire = $this->options['expire']; } - $expire = ($expire==0)?0: (time()+$expire) ;//缓存有效期为0表示永久缓存 - if( C('DATA_CACHE_COMPRESS') && function_exists('gzcompress')) { + $expire = (0 == $expire) ? 0 : (time() + $expire); //缓存有效期为0表示永久缓存 + if (C('DATA_CACHE_COMPRESS') && function_exists('gzcompress')) { //数据压缩 - $value = gzcompress($value,3); + $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) { + $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); } @@ -99,9 +104,10 @@ public function set($name, $value,$expire=null) { * @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.'\''; + 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; } @@ -111,9 +117,10 @@ public function rm($name) { * @access public * @return boolean */ - public function clear() { - $sql = 'DELETE FROM '.$this->options['table']; + public function clear() + { + $sql = 'DELETE FROM ' . $this->options['table']; sqlite_query($this->handler, $sql); - return ; + return; } } diff --git a/ThinkPHP/Library/Think/Cache/Driver/Wincache.class.php b/ThinkPHP/Library/Think/Cache/Driver/Wincache.class.php index 9d118e999..a21ddd402 100644 --- a/ThinkPHP/Library/Think/Cache/Driver/Wincache.class.php +++ b/ThinkPHP/Library/Think/Cache/Driver/Wincache.class.php @@ -9,25 +9,28 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think\Cache\Driver; + use Think\Cache; -defined('THINK_PATH') or exit(); + /** * Wincache缓存驱动 */ -class Wincache extends Cache { +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'); + 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; + $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; } /** @@ -36,10 +39,11 @@ public function __construct($options=array()) { * @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; + public function get($name) + { + N('cache_read', 1); + $name = $this->options['prefix'] . $name; + return wincache_ucache_exists($name) ? wincache_ucache_get($name) : false; } /** @@ -50,14 +54,15 @@ public function get($name) { * @param integer $expire 有效时间(秒) * @return boolean */ - public function set($name, $value,$expire=null) { - N('cache_write',1); - if(is_null($expire)) { - $expire = $this->options['expire']; + 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) { + $name = $this->options['prefix'] . $name; + if (wincache_ucache_set($name, $value, $expire)) { + if ($this->options['length'] > 0) { // 记录缓存队列 $this->queue($name); } @@ -72,8 +77,9 @@ public function set($name, $value,$expire=null) { * @param string $name 缓存变量名 * @return boolean */ - public function rm($name) { - return wincache_ucache_delete($this->options['prefix'].$name); + public function rm($name) + { + return wincache_ucache_delete($this->options['prefix'] . $name); } /** @@ -81,8 +87,9 @@ public function rm($name) { * @access public * @return boolean */ - public function clear() { + public function clear() + { return wincache_ucache_clear(); - } + } } diff --git a/ThinkPHP/Library/Think/Cache/Driver/Xcache.class.php b/ThinkPHP/Library/Think/Cache/Driver/Xcache.class.php index ccb1fdded..151f6a769 100644 --- a/ThinkPHP/Library/Think/Cache/Driver/Xcache.class.php +++ b/ThinkPHP/Library/Think/Cache/Driver/Xcache.class.php @@ -9,25 +9,28 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think\Cache\Driver; + use Think\Cache; -defined('THINK_PATH') or exit(); + /** * Xcache缓存驱动 */ -class Xcache extends Cache { +class Xcache extends Cache +{ /** * 架构函数 * @param array $options 缓存参数 * @access public */ - public function __construct($options=array()) { - if ( !function_exists('xcache_info') ) { - E(L('_NOT_SUPPORT_').':Xcache'); + 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; + $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; } /** @@ -36,9 +39,10 @@ public function __construct($options=array()) { * @param string $name 缓存变量名 * @return mixed */ - public function get($name) { - N('cache_read',1); - $name = $this->options['prefix'].$name; + public function get($name) + { + N('cache_read', 1); + $name = $this->options['prefix'] . $name; if (xcache_isset($name)) { return xcache_get($name); } @@ -53,14 +57,15 @@ public function get($name) { * @param integer $expire 有效时间(秒) * @return boolean */ - public function set($name, $value,$expire=null) { - N('cache_write',1); - if(is_null($expire)) { - $expire = $this->options['expire'] ; + 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) { + $name = $this->options['prefix'] . $name; + if (xcache_set($name, $value, $expire)) { + if ($this->options['length'] > 0) { // 记录缓存队列 $this->queue($name); } @@ -75,8 +80,9 @@ public function set($name, $value,$expire=null) { * @param string $name 缓存变量名 * @return boolean */ - public function rm($name) { - return xcache_unset($this->options['prefix'].$name); + public function rm($name) + { + return xcache_unset($this->options['prefix'] . $name); } /** @@ -84,7 +90,8 @@ public function rm($name) { * @access public * @return boolean */ - public function clear() { + public function clear() + { return xcache_clear_cache(1, -1); } } diff --git a/ThinkPHP/Library/Think/Controller.class.php b/ThinkPHP/Library/Think/Controller.class.php index ce0f2a1f3..77883f7c6 100644 --- a/ThinkPHP/Library/Think/Controller.class.php +++ b/ThinkPHP/Library/Think/Controller.class.php @@ -9,36 +9,39 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think; + /** * ThinkPHP 控制器基类 抽象类 */ -abstract class Controller { - +class Controller +{ /** * 视图实例对象 * @var view * @access protected - */ - protected $view = null; + */abstract protected $view = null; /** * 控制器参数 * @var config * @access protected - */ - protected $config = array(); + */ + protected $config = array(); - /** + /** * 架构函数 取得模板对象实例 * @access public */ - public function __construct() { - Hook::listen('action_begin',$this->config); + public function __construct() + { + Hook::listen('action_begin', $this->config); //实例化视图类 - $this->view = Think::instance('Think\View'); + $this->view = Think::instance('Think\View'); //控制器初始化 - if(method_exists($this,'_initialize')) + if (method_exists($this, '_initialize')) { $this->_initialize(); + } + } /** @@ -52,8 +55,9 @@ public function __construct() { * @param string $prefix 模板缓存前缀 * @return void */ - protected function display($templateFile='',$charset='',$contentType='',$content='',$prefix='') { - $this->view->display($templateFile,$charset,$contentType,$content,$prefix); + protected function display($templateFile = '', $charset = '', $contentType = '', $content = '', $prefix = '') + { + $this->view->display($templateFile, $charset, $contentType, $content, $prefix); } /** @@ -65,8 +69,9 @@ protected function display($templateFile='',$charset='',$contentType='',$content * @param string $prefix 模板缓存前缀 * @return mixed */ - protected function show($content,$charset='',$contentType='',$prefix='') { - $this->view->display('',$charset,$contentType,$content,$prefix); + protected function show($content, $charset = '', $contentType = '', $prefix = '') + { + $this->view->display('', $charset, $contentType, $content, $prefix); } /** @@ -76,11 +81,12 @@ protected function show($content,$charset='',$contentType='',$prefix='') { * @param string $templateFile 指定要调用的模板文件 * 默认为空 由系统自动定位模板文件 * @param string $content 模板输出内容 - * @param string $prefix 模板缓存前缀* + * @param string $prefix 模板缓存前缀* * @return string */ - protected function fetch($templateFile='',$content='',$prefix='') { - return $this->view->fetch($templateFile,$content,$prefix); + protected function fetch($templateFile = '', $content = '', $prefix = '') + { + return $this->view->fetch($templateFile, $content, $prefix); } /** @@ -92,11 +98,12 @@ protected function fetch($templateFile='',$content='',$prefix='') { * 默认为空 由系统自动定位模板文件 * @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'); + 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; } @@ -106,7 +113,8 @@ protected function buildHtml($htmlfile='',$htmlpath='',$templateFile='') { * @param string $theme 模版主题 * @return Action */ - protected function theme($theme){ + protected function theme($theme) + { $this->view->theme($theme); return $this; } @@ -118,13 +126,15 @@ protected function theme($theme){ * @param mixed $value 变量的值 * @return Action */ - protected function assign($name,$value='') { - $this->view->assign($name,$value); + protected function assign($name, $value = '') + { + $this->view->assign($name, $value); return $this; } - public function __set($name,$value) { - $this->assign($name,$value); + public function __set($name, $value) + { + $this->assign($name, $value); } /** @@ -133,11 +143,13 @@ public function __set($name,$value) { * @param string $name 模板显示变量 * @return mixed */ - public function get($name='') { - return $this->view->get($name); + public function get($name = '') + { + return $this->view->get($name); } - public function __get($name) { + public function __get($name) + { return $this->get($name); } @@ -147,7 +159,8 @@ public function __get($name) { * @param string $name 名称 * @return boolean */ - public function __isset($name) { + public function __isset($name) + { return $this->get($name); } @@ -158,19 +171,20 @@ public function __isset($name) { * @param array $args 参数 * @return mixed */ - public function __call($method,$args) { - if( 0 === strcasecmp($method,ACTION_NAME.C('ACTION_SUFFIX'))) { - if(method_exists($this,'_empty')) { + 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->_empty($method, $args); + } elseif (file_exists_case($this->view->parseTemplate())) { // 检查是否存在默认模版 如果有直接输出模版 $this->display(); - }else{ - E(L('_ERROR_ACTION_').':'.ACTION_NAME); + } else { + E(L('_ERROR_ACTION_') . ':' . ACTION_NAME); } - }else{ - E(__CLASS__.':'.$method.L('_METHOD_NOT_EXIST_')); + } else { + E(__CLASS__ . ':' . $method . L('_METHOD_NOT_EXIST_')); return; } } @@ -183,8 +197,9 @@ public function __call($method,$args) { * @param mixed $ajax 是否为Ajax方式 当数字时指定跳转时间 * @return void */ - protected function error($message='',$jumpUrl='',$ajax=false) { - $this->dispatchJump($message,0,$jumpUrl,$ajax); + protected function error($message = '', $jumpUrl = '', $ajax = false) + { + $this->dispatchJump($message, 0, $jumpUrl, $ajax); } /** @@ -195,8 +210,9 @@ protected function error($message='',$jumpUrl='',$ajax=false) { * @param mixed $ajax 是否为Ajax方式 当数字时指定跳转时间 * @return void */ - protected function success($message='',$jumpUrl='',$ajax=false) { - $this->dispatchJump($message,1,$jumpUrl,$ajax); + protected function success($message = '', $jumpUrl = '', $ajax = false) + { + $this->dispatchJump($message, 1, $jumpUrl, $ajax); } /** @@ -207,29 +223,33 @@ protected function success($message='',$jumpUrl='',$ajax=false) { * @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' : + 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' : + 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' : + $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 : + exit($data); + default: // 用于扩展其他返回格式数据 - Hook::listen('ajax_return',$data); + Hook::listen('ajax_return', $data); } } @@ -242,9 +262,10 @@ protected function ajaxReturn($data,$type='',$json_option=0) { * @param string $msg 跳转提示信息 * @return void */ - protected function redirect($url,$params=array(),$delay=0,$msg='') { - $url = U($url,$params); - redirect($url,$delay,$msg); + protected function redirect($url, $params = array(), $delay = 0, $msg = '') + { + $url = U($url, $params); + redirect($url, $delay, $msg); } /** @@ -258,50 +279,75 @@ protected function redirect($url,$params=array(),$delay=0,$msg='') { * @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; + 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); + 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_')); + $this->assign('msgTitle', $status ? L('_OPERATION_SUCCESS_') : L('_OPERATION_FAIL_')); //如果设置了关闭窗口,则提示完毕后自动关闭窗口 - if($this->get('closeWin')) $this->assign('jumpUrl','javascript:window.close();'); - $this->assign('status',$status); // 状态 + 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);// 提示信息 + C('HTML_CACHE_ON', false); + if ($status) { + //发送成功信息 + $this->assign('message', $message); // 提示信息 // 成功操作后默认停留1秒 - if(!isset($this->waitSecond)) $this->assign('waitSecond','1'); + if (!isset($this->waitSecond)) { + $this->assign('waitSecond', '1'); + } + // 默认操作成功自动返回操作前页面 - if(!isset($this->jumpUrl)) $this->assign("jumpUrl",$_SERVER["HTTP_REFERER"]); + if (!isset($this->jumpUrl)) { + $this->assign("jumpUrl", $_SERVER["HTTP_REFERER"]); + } + $this->display(C('TMPL_ACTION_SUCCESS')); - }else{ - $this->assign('error',$message);// 提示信息 + } else { + $this->assign('error', $message); // 提示信息 //发生错误时候默认停留3秒 - if(!isset($this->waitSecond)) $this->assign('waitSecond','3'); + if (!isset($this->waitSecond)) { + $this->assign('waitSecond', '3'); + } + // 默认发生错误的话自动返回上页 - if(!isset($this->jumpUrl)) $this->assign('jumpUrl',"javascript:history.back(-1);"); + if (!isset($this->jumpUrl)) { + $this->assign('jumpUrl', "javascript:history.back(-1);"); + } + $this->display(C('TMPL_ACTION_ERROR')); // 中止执行 避免出错后继续执行 - exit ; + exit; } } - /** + /** * 析构方法 * @access public */ - public function __destruct() { + public function __destruct() + { // 执行后续操作 Hook::listen('action_end'); } } // 设置控制器别名 便于升级 -class_alias('Think\Controller','Think\Action'); +class_alias('Think\Controller', 'Think\Action'); diff --git a/ThinkPHP/Library/Think/Controller/HproseController.class.php b/ThinkPHP/Library/Think/Controller/HproseController.class.php index 88d3a1c36..3ce92d6c9 100644 --- a/ThinkPHP/Library/Think/Controller/HproseController.class.php +++ b/ThinkPHP/Library/Think/Controller/HproseController.class.php @@ -9,37 +9,42 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think\Controller; + /** * ThinkPHP Hprose控制器类 */ -class HproseController { +class HproseController +{ - protected $allowMethodList = ''; - protected $crossDomain = false; - protected $P3P = false; - protected $get = true; - protected $debug = false; + protected $allowMethodList = ''; + protected $crossDomain = false; + protected $P3P = false; + protected $get = true; + protected $debug = false; - /** + /** * 架构函数 * @access public */ - public function __construct() { + public function __construct() + { //控制器初始化 - if(method_exists($this,'_initialize')) + 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 = 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->addMethods($methods, $this); + if (APP_DEBUG || $this->debug) { $server->setDebugEnabled(true); } // Hprose设置 @@ -57,5 +62,6 @@ public function __construct() { * @param array $args 参数 * @return mixed */ - public function __call($method,$args){} + public function __call($method, $args) + {} } diff --git a/ThinkPHP/Library/Think/Controller/JsonRpcController.class.php b/ThinkPHP/Library/Think/Controller/JsonRpcController.class.php index a73ca5c28..b34b98070 100644 --- a/ThinkPHP/Library/Think/Controller/JsonRpcController.class.php +++ b/ThinkPHP/Library/Think/Controller/JsonRpcController.class.php @@ -9,19 +9,25 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think\Controller; + /** * ThinkPHP JsonRPC控制器类 */ -class JsonRpcController { +use jsonRPCServer as jsonRPCServer; +class JsonRpcController +{ - /** + /** * 架构函数 * @access public */ - public function __construct() { + public function __construct() + { //控制器初始化 - if(method_exists($this,'_initialize')) + if (method_exists($this, '_initialize')) { $this->_initialize(); + } + //导入类库 Vendor('jsonRPC.jsonRPCServer'); // 启动server @@ -35,5 +41,6 @@ public function __construct() { * @param array $args 参数 * @return mixed */ - public function __call($method,$args){} + public function __call($method, $args) + {} } diff --git a/ThinkPHP/Library/Think/Controller/RestController.class.php b/ThinkPHP/Library/Think/Controller/RestController.class.php index 2a6266275..63233ebc8 100644 --- a/ThinkPHP/Library/Think/Controller/RestController.class.php +++ b/ThinkPHP/Library/Think/Controller/RestController.class.php @@ -9,54 +9,59 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think\Controller; -use Think\Controller; + use Think\App; +use Think\Controller; + /** * ThinkPHP REST控制器类 */ -class RestController extends Controller { +class RestController extends Controller +{ // 当前请求类型 - protected $_method = ''; + protected $_method = ''; // 当前请求的资源类型 - protected $_type = ''; + protected $_type = ''; // REST允许的请求类型列表 - protected $allowMethod = array('get','post','put','delete'); + protected $allowMethod = array('get', 'post', 'put', 'delete'); // REST默认请求类型 - protected $defaultMethod = 'get'; + protected $defaultMethod = 'get'; // REST允许请求的资源类型列表 - protected $allowType = array('html','xml','json','rss'); + protected $allowType = array('html', 'xml', 'json', 'rss'); // 默认的资源类型 - protected $defaultType = 'html'; + protected $defaultType = 'html'; // REST允许输出的资源类型列表 - protected $allowOutputType= array( - 'xml' => 'application/xml', - 'json' => 'application/json', - 'html' => 'text/html', - ); + protected $allowOutputType = array( + 'xml' => 'application/xml', + 'json' => 'application/json', + 'html' => 'text/html', + ); - /** + /** * 架构函数 * @access public */ - public function __construct() { + public function __construct() + { // 资源类型检测 - if(''==__EXT__) { // 自动检测资源类型 - $this->_type = $this->getAcceptType(); - }elseif(!in_array(__EXT__,$this->allowType)) { + if ('' == __EXT__) { + // 自动检测资源类型 + $this->_type = $this->getAcceptType(); + } elseif (!in_array(__EXT__, $this->allowType)) { // 资源类型非法 则用默认资源类型访问 - $this->_type = $this->defaultType; - }else{ - $this->_type = __EXT__ ; + $this->_type = $this->defaultType; + } else { + $this->_type = __EXT__; } // 请求方式检测 - $method = strtolower(REQUEST_METHOD); - if(!in_array($method,$this->allowMethod)) { + $method = strtolower(REQUEST_METHOD); + if (!in_array($method, $this->allowMethod)) { // 请求方式非法 则用默认请求方法 $method = $this->defaultMethod; } $this->_method = $method; - + parent::__construct(); } @@ -67,25 +72,27 @@ public function __construct() { * @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; - App::invokeAction($this,$fun); - }elseif($this->_method == $this->defaultMethod && method_exists($this,$method.'_'.$this->_type) ){ - $fun = $method.'_'.$this->_type; - App::invokeAction($this,$fun); - }elseif($this->_type == $this->defaultType && method_exists($this,$method.'_'.$this->_method) ){ - $fun = $method.'_'.$this->_method; - App::invokeAction($this,$fun); - }elseif(method_exists($this,'_empty')) { + 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; + App::invokeAction($this, $fun); + } elseif ($this->_method == $this->defaultMethod && method_exists($this, $method . '_' . $this->_type)) { + $fun = $method . '_' . $this->_type; + App::invokeAction($this, $fun); + } elseif ($this->_type == $this->defaultType && method_exists($this, $method . '_' . $this->_method)) { + $fun = $method . '_' . $this->_method; + App::invokeAction($this, $fun); + } elseif (method_exists($this, '_empty')) { // 如果定义了_empty操作 则调用 - $this->_empty($method,$args); - }elseif(file_exists_case($this->view->parseTemplate())){ + $this->_empty($method, $args); + } elseif (file_exists_case($this->view->parseTemplate())) { // 检查是否存在默认模版 如果有直接输出模版 $this->display(); - }else{ - E(L('_ERROR_ACTION_').':'.ACTION_NAME); + } else { + E(L('_ERROR_ACTION_') . ':' . ACTION_NAME); } } } @@ -94,28 +101,29 @@ public function __call($method,$args) { * 获取当前请求的Accept头信息 * @return string */ - protected function getAcceptType(){ + 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,*/*' + '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)) { + + foreach ($type as $key => $val) { + $array = explode(',', $val); + foreach ($array as $k => $v) { + if (stristr($_SERVER['HTTP_ACCEPT'], $v)) { return $key; } } @@ -124,7 +132,8 @@ protected function getAcceptType(){ } // 发送Http状态信息 - protected function sendHttpStatus($code) { + protected function sendHttpStatus($code) + { static $_status = array( // Informational 1xx 100 => 'Continue', @@ -140,7 +149,7 @@ protected function sendHttpStatus($code) { // Redirection 3xx 300 => 'Multiple Choices', 301 => 'Moved Permanently', - 302 => 'Moved Temporarily ', // 1.1 + 302 => 'Moved Temporarily ', // 1.1 303 => 'See Other', 304 => 'Not Modified', 305 => 'Use Proxy', @@ -172,12 +181,12 @@ protected function sendHttpStatus($code) { 503 => 'Service Unavailable', 504 => 'Gateway Timeout', 505 => 'HTTP Version Not Supported', - 509 => 'Bandwidth Limit Exceeded' + 509 => 'Bandwidth Limit Exceeded', ); - if(isset($_status[$code])) { - header('HTTP/1.1 '.$code.' '.$_status[$code]); + if (isset($_status[$code])) { + header('HTTP/1.1 ' . $code . ' ' . $_status[$code]); // 确保FastCGI模式下正常 - header('Status:'.$code.' '.$_status[$code]); + header('Status:' . $code . ' ' . $_status[$code]); } } @@ -188,17 +197,21 @@ protected function sendHttpStatus($code) { * @param String $type 返回类型 JSON XML * @return string */ - protected function encodeData($data,$type='') { - if(empty($data)) return ''; - if('json' == $type) { + protected function encodeData($data, $type = '') + { + if (empty($data)) { + return ''; + } + + if ('json' == $type) { // 返回JSON数据格式到客户端 包含状态信息 $data = json_encode($data); - }elseif('xml' == $type){ + } elseif ('xml' == $type) { // 返回xml格式数据 $data = xml_encode($data); - }elseif('php'==$type){ + } elseif ('php' == $type) { $data = serialize($data); - }// 默认直接输出 + } // 默认直接输出 $this->setContentType($type); //header('Content-Length: ' . strlen($data)); return $data; @@ -211,12 +224,22 @@ protected function encodeData($data,$type='') { * @param string $charset 页面输出编码 * @return void */ - public function setContentType($type, $charset=''){ - if(headers_sent()) return; - if(empty($charset)) $charset = C('DEFAULT_CHARSET'); + 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); + if (isset($this->allowOutputType[$type])) //过滤content_type + { + header('Content-Type: ' . $this->allowOutputType[$type] . '; charset=' . $charset); + } + } /** @@ -227,8 +250,9 @@ public function setContentType($type, $charset=''){ * @param integer $code HTTP状态 * @return void */ - protected function response($data,$type='',$code=200) { + protected function response($data, $type = '', $code = 200) + { $this->sendHttpStatus($code); - exit($this->encodeData($data,strtolower($type))); + exit($this->encodeData($data, strtolower($type))); } } diff --git a/ThinkPHP/Library/Think/Controller/RpcController.class.php b/ThinkPHP/Library/Think/Controller/RpcController.class.php index 737e7374b..c25167205 100644 --- a/ThinkPHP/Library/Think/Controller/RpcController.class.php +++ b/ThinkPHP/Library/Think/Controller/RpcController.class.php @@ -9,35 +9,40 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think\Controller; + /** * ThinkPHP RPC控制器类 */ -class RpcController { +class RpcController +{ - protected $allowMethodList = ''; - protected $debug = false; + protected $allowMethodList = ''; + protected $debug = false; - /** + /** * 架构函数 * @access public */ - public function __construct() { + public function __construct() + { //控制器初始化 - if(method_exists($this,'_initialize')) + 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 = 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); + $server->add($methods, $this); - if(APP_DEBUG || $this->debug ) { + if (APP_DEBUG || $this->debug) { $server->setDebugMode(true); } $server->setEnableGZIP(true); @@ -52,5 +57,6 @@ public function __construct() { * @param array $args 参数 * @return mixed */ - public function __call($method,$args){} + public function __call($method, $args) + {} } diff --git a/ThinkPHP/Library/Think/Controller/YarController.class.php b/ThinkPHP/Library/Think/Controller/YarController.class.php index 40245b41e..7860331d6 100644 --- a/ThinkPHP/Library/Think/Controller/YarController.class.php +++ b/ThinkPHP/Library/Think/Controller/YarController.class.php @@ -9,24 +9,31 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think\Controller; + /** * ThinkPHP Yar控制器类 */ -class YarController { +class YarController +{ - /** + /** * 架构函数 * @access public */ - public function __construct() { + public function __construct() + { //控制器初始化 - if(method_exists($this,'_initialize')) + if (method_exists($this, '_initialize')) { $this->_initialize(); + } + //判断扩展是否存在 - if(!extension_loaded('yar')) - E(L('_NOT_SUPPORT_').':yar'); + if (!extension_loaded('yar')) { + E(L('_NOT_SUPPORT_') . ':yar'); + } + //实例化Yar_Server - $server = new \Yar_Server($this); + $server = new \Yar_Server($this); // 启动server $server->handle(); } @@ -38,5 +45,6 @@ public function __construct() { * @param array $args 参数 * @return mixed */ - public function __call($method,$args){} + public function __call($method, $args) + {} } diff --git a/ThinkPHP/Library/Think/Crypt.class.php b/ThinkPHP/Library/Think/Crypt.class.php index ee7bafafb..6a81cdaa5 100644 --- a/ThinkPHP/Library/Think/Crypt.class.php +++ b/ThinkPHP/Library/Think/Crypt.class.php @@ -9,17 +9,20 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think; + /** * 加密解密类 */ -class Crypt { +class Crypt +{ - private static $handler = ''; + 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; + public static function init($type = '') + { + $type = $type ?: C('DATA_CRYPT_TYPE'); + $class = strpos($type, '\\') ? $type : 'Think\\Crypt\\Driver\\' . ucwords(strtolower($type)); + self::$handler = $class; } /** @@ -29,12 +32,13 @@ public static function init($type=''){ * @param integer $expire 有效期(秒) 0 为永久有效 * @return string */ - public static function encrypt($data,$key,$expire=0){ - if(empty(self::$handler)){ + public static function encrypt($data, $key, $expire = 0) + { + if (empty(self::$handler)) { self::init(); } - $class = self::$handler; - return $class::encrypt($data,$key,$expire); + $class = self::$handler; + return $class::encrypt($data, $key, $expire); } /** @@ -43,11 +47,12 @@ public static function encrypt($data,$key,$expire=0){ * @param string $key 加密key * @return string */ - public static function decrypt($data,$key){ - if(empty(self::$handler)){ + public static function decrypt($data, $key) + { + if (empty(self::$handler)) { self::init(); } - $class = self::$handler; - return $class::decrypt($data,$key); + $class = self::$handler; + return $class::decrypt($data, $key); } -} \ No newline at end of file +} diff --git a/ThinkPHP/Library/Think/Crypt/Driver/Base64.class.php b/ThinkPHP/Library/Think/Crypt/Driver/Base64.class.php index 44f6014db..a54ff8786 100644 --- a/ThinkPHP/Library/Think/Crypt/Driver/Base64.class.php +++ b/ThinkPHP/Library/Think/Crypt/Driver/Base64.class.php @@ -9,33 +9,39 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think\Crypt\Driver; + /** * Base64 加密实现类 */ -class Base64 { +class Base64 +{ /** * 加密字符串 * @param string $str 字符串 * @param string $key 加密key - * @param integer $expire 有效期(秒) + * @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); + 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); + for ($i = 0; $i < $len; $i++) { + $str .= chr(ord(substr($data, $i, 1)) + (ord(substr($char, $i, 1))) % 256); } return $str; } @@ -46,29 +52,33 @@ public static function encrypt($data,$key,$expire=0) { * @param string $key 加密key * @return string */ - public static function decrypt($data,$key) { - $key = md5($key); - $x=0; + 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); + $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)) 0 && $expire < time()) { + $data = base64_decode($str); + $expire = substr($data, 0, 10); + if ($expire > 0 && $expire < time()) { return ''; } - $data = substr($data,10); + $data = substr($data, 10); return $data; } -} \ No newline at end of file +} diff --git a/ThinkPHP/Library/Think/Crypt/Driver/Crypt.class.php b/ThinkPHP/Library/Think/Crypt/Driver/Crypt.class.php index 382425fed..cf6939033 100644 --- a/ThinkPHP/Library/Think/Crypt/Driver/Crypt.class.php +++ b/ThinkPHP/Library/Think/Crypt/Driver/Crypt.class.php @@ -9,6 +9,7 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think\Crypt\Driver; + /** * Crypt 加密实现类 * @category ORG @@ -16,30 +17,35 @@ * @subpackage Crypt * @author liu21st */ -class Crypt { +class Crypt +{ /** * 加密字符串 * @param string $str 字符串 * @param string $key 加密key - * @param integer $expire 有效期(秒) + * @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++; + 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); + return self::ed($v, $key); } /** @@ -48,36 +54,40 @@ public static function encrypt($str,$key,$expire=0){ * @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); + 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()) { + $data = $v; + $expire = substr($data, 0, 10); + if ($expire > 0 && $expire < time()) { return ''; } - $data = substr($data,10); + $data = substr($data, 10); return $data; } + private static 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; + } - static private 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; - } -} \ No newline at end of file + $v .= substr($str, $i, 1) ^ substr($r, $c, 1); + $c++; + } + return $v; + } +} diff --git a/ThinkPHP/Library/Think/Crypt/Driver/Des.class.php b/ThinkPHP/Library/Think/Crypt/Driver/Des.class.php index db1bad61e..4deba6bb3 100644 --- a/ThinkPHP/Library/Think/Crypt/Driver/Des.class.php +++ b/ThinkPHP/Library/Think/Crypt/Driver/Des.class.php @@ -9,6 +9,7 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think\Crypt\Driver; + /** * Des 加密实现类 * Converted from JavaScript to PHP by Jim Gibbs, June 2004 Paul Tero, July 2001 @@ -16,22 +17,24 @@ * http://www.netdealing.com */ -class Des { +class Des +{ /** * 加密字符串 * @param string $str 字符串 * @param string $key 加密key - * @param integer $expire 有效期(秒) + * @param integer $expire 有效期(秒) * @return string */ - public static function encrypt($str, $key,$expire=0) { - if ($str == "") { + public static function encrypt($str, $key, $expire = 0) + { + if ("" == $str) { return ""; } - $expire = sprintf('%010d', $expire ? $expire + time():0); - $str = $expire.$str; - return self::_des($key,$str,1); + $expire = sprintf('%010d', $expire ? $expire + time() : 0); + $str = $expire . $str; + return self::_des($key, $str, 1); } /** @@ -40,16 +43,17 @@ public static function encrypt($str, $key,$expire=0) { * @param string $key 加密key * @return string */ - public static function decrypt($str, $key) { - if ($str == "") { + public static function decrypt($str, $key) + { + if ("" == $str) { return ""; } - $data = self::_des($key,$str,0); - $expire = substr($data,0,10); - if($expire > 0 && $expire < time()) { + $data = self::_des($key, $str, 0); + $expire = substr($data, 0, 10); + if ($expire > 0 && $expire < time()) { return ''; } - $data = substr($data,10); + $data = substr($data, 10); return $data; } @@ -59,97 +63,134 @@ public static function decrypt($str, $key) { * @param string $key 加密key * @return string */ - private static function _des($key, $message, $encrypt, $mode=0, $iv=null) { - //declaring this locally speeds things up a bit - $spfunction1 = array (0x1010400,0,0x10000,0x1010404,0x1010004,0x10404,0x4,0x10000,0x400,0x1010400,0x1010404,0x400,0x1000404,0x1010004,0x1000000,0x4,0x404,0x1000400,0x1000400,0x10400,0x10400,0x1010000,0x1010000,0x1000404,0x10004,0x1000004,0x1000004,0x10004,0,0x404,0x10404,0x1000000,0x10000,0x1010404,0x4,0x1010000,0x1010400,0x1000000,0x1000000,0x400,0x1010004,0x10000,0x10400,0x1000004,0x400,0x4,0x1000404,0x10404,0x1010404,0x10004,0x1010000,0x1000404,0x1000004,0x404,0x10404,0x1010400,0x404,0x1000400,0x1000400,0,0x10004,0x10400,0,0x1010004); - $spfunction2 = array (-0x7fef7fe0,-0x7fff8000,0x8000,0x108020,0x100000,0x20,-0x7fefffe0,-0x7fff7fe0,-0x7fffffe0,-0x7fef7fe0,-0x7fef8000,-0x80000000,-0x7fff8000,0x100000,0x20,-0x7fefffe0,0x108000,0x100020,-0x7fff7fe0,0,-0x80000000,0x8000,0x108020,-0x7ff00000,0x100020,-0x7fffffe0,0,0x108000,0x8020,-0x7fef8000,-0x7ff00000,0x8020,0,0x108020,-0x7fefffe0,0x100000,-0x7fff7fe0,-0x7ff00000,-0x7fef8000,0x8000,-0x7ff00000,-0x7fff8000,0x20,-0x7fef7fe0,0x108020,0x20,0x8000,-0x80000000,0x8020,-0x7fef8000,0x100000,-0x7fffffe0,0x100020,-0x7fff7fe0,-0x7fffffe0,0x100020,0x108000,0,-0x7fff8000,0x8020,-0x80000000,-0x7fefffe0,-0x7fef7fe0,0x108000); - $spfunction3 = array (0x208,0x8020200,0,0x8020008,0x8000200,0,0x20208,0x8000200,0x20008,0x8000008,0x8000008,0x20000,0x8020208,0x20008,0x8020000,0x208,0x8000000,0x8,0x8020200,0x200,0x20200,0x8020000,0x8020008,0x20208,0x8000208,0x20200,0x20000,0x8000208,0x8,0x8020208,0x200,0x8000000,0x8020200,0x8000000,0x20008,0x208,0x20000,0x8020200,0x8000200,0,0x200,0x20008,0x8020208,0x8000200,0x8000008,0x200,0,0x8020008,0x8000208,0x20000,0x8000000,0x8020208,0x8,0x20208,0x20200,0x8000008,0x8020000,0x8000208,0x208,0x8020000,0x20208,0x8,0x8020008,0x20200); - $spfunction4 = array (0x802001,0x2081,0x2081,0x80,0x802080,0x800081,0x800001,0x2001,0,0x802000,0x802000,0x802081,0x81,0,0x800080,0x800001,0x1,0x2000,0x800000,0x802001,0x80,0x800000,0x2001,0x2080,0x800081,0x1,0x2080,0x800080,0x2000,0x802080,0x802081,0x81,0x800080,0x800001,0x802000,0x802081,0x81,0,0,0x802000,0x2080,0x800080,0x800081,0x1,0x802001,0x2081,0x2081,0x80,0x802081,0x81,0x1,0x2000,0x800001,0x2001,0x802080,0x800081,0x2001,0x2080,0x800000,0x802001,0x80,0x800000,0x2000,0x802080); - $spfunction5 = array (0x100,0x2080100,0x2080000,0x42000100,0x80000,0x100,0x40000000,0x2080000,0x40080100,0x80000,0x2000100,0x40080100,0x42000100,0x42080000,0x80100,0x40000000,0x2000000,0x40080000,0x40080000,0,0x40000100,0x42080100,0x42080100,0x2000100,0x42080000,0x40000100,0,0x42000000,0x2080100,0x2000000,0x42000000,0x80100,0x80000,0x42000100,0x100,0x2000000,0x40000000,0x2080000,0x42000100,0x40080100,0x2000100,0x40000000,0x42080000,0x2080100,0x40080100,0x100,0x2000000,0x42080000,0x42080100,0x80100,0x42000000,0x42080100,0x2080000,0,0x40080000,0x42000000,0x80100,0x2000100,0x40000100,0x80000,0,0x40080000,0x2080100,0x40000100); - $spfunction6 = array (0x20000010,0x20400000,0x4000,0x20404010,0x20400000,0x10,0x20404010,0x400000,0x20004000,0x404010,0x400000,0x20000010,0x400010,0x20004000,0x20000000,0x4010,0,0x400010,0x20004010,0x4000,0x404000,0x20004010,0x10,0x20400010,0x20400010,0,0x404010,0x20404000,0x4010,0x404000,0x20404000,0x20000000,0x20004000,0x10,0x20400010,0x404000,0x20404010,0x400000,0x4010,0x20000010,0x400000,0x20004000,0x20000000,0x4010,0x20000010,0x20404010,0x404000,0x20400000,0x404010,0x20404000,0,0x20400010,0x10,0x4000,0x20400000,0x404010,0x4000,0x400010,0x20004010,0,0x20404000,0x20000000,0x400010,0x20004010); - $spfunction7 = array (0x200000,0x4200002,0x4000802,0,0x800,0x4000802,0x200802,0x4200800,0x4200802,0x200000,0,0x4000002,0x2,0x4000000,0x4200002,0x802,0x4000800,0x200802,0x200002,0x4000800,0x4000002,0x4200000,0x4200800,0x200002,0x4200000,0x800,0x802,0x4200802,0x200800,0x2,0x4000000,0x200800,0x4000000,0x200800,0x200000,0x4000802,0x4000802,0x4200002,0x4200002,0x2,0x200002,0x4000000,0x4000800,0x200000,0x4200800,0x802,0x200802,0x4200800,0x802,0x4000002,0x4200802,0x4200000,0x200800,0,0x2,0x4200802,0,0x200802,0x4200000,0x800,0x4000002,0x4000800,0x800,0x200002); - $spfunction8 = array (0x10001040,0x1000,0x40000,0x10041040,0x10000000,0x10001040,0x40,0x10000000,0x40040,0x10040000,0x10041040,0x41000,0x10041000,0x41040,0x1000,0x40,0x10040000,0x10000040,0x10001000,0x1040,0x41000,0x40040,0x10040040,0x10041000,0x1040,0,0,0x10040040,0x10000040,0x10001000,0x41040,0x40000,0x41040,0x40000,0x10041000,0x1000,0x40,0x10040040,0x1000,0x41040,0x10001000,0x40,0x10000040,0x10040000,0x10040040,0x10000000,0x40000,0x10001040,0,0x10041040,0x40040,0x10000040,0x10040000,0x10001000,0x10001040,0,0x10041040,0x41000,0x41000,0x1040,0x1040,0x40040,0x10000000,0x10041000); - $masks = array (4294967295,2147483647,1073741823,536870911,268435455,134217727,67108863,33554431,16777215,8388607,4194303,2097151,1048575,524287,262143,131071,65535,32767,16383,8191,4095,2047,1023,511,255,127,63,31,15,7,3,1,0); - - //create the 16 or 48 subkeys we will need - $keys = self::_createKeys ($key); - $m=0; - $len = strlen($message); - $chunk = 0; - //set up the loops for single and triple des - $iterations = ((count($keys) == 32) ? 3 : 9); //single or triple des - if ($iterations == 3) {$looping = (($encrypt) ? array (0, 32, 2) : array (30, -2, -2));} - else {$looping = (($encrypt) ? array (0, 32, 2, 62, 30, -2, 64, 96, 2) : array (94, 62, -2, 32, 64, 2, 30, -2, -2));} - - $message .= (chr(0) . chr(0) . chr(0) . chr(0) . chr(0) . chr(0) . chr(0) . chr(0)); //pad the message out with null bytes - //store the result here - $result = ""; - $tempresult = ""; - - if ($mode == 1) { //CBC mode - $cbcleft = (ord($iv{$m++}) << 24) | (ord($iv{$m++}) << 16) | (ord($iv{$m++}) << 8) | ord($iv{$m++}); - $cbcright = (ord($iv{$m++}) << 24) | (ord($iv{$m++}) << 16) | (ord($iv{$m++}) << 8) | ord($iv{$m++}); - $m=0; - } - - //loop through each 64 bit chunk of the message - while ($m < $len) { - $left = (ord($message{$m++}) << 24) | (ord($message{$m++}) << 16) | (ord($message{$m++}) << 8) | ord($message{$m++}); - $right = (ord($message{$m++}) << 24) | (ord($message{$m++}) << 16) | (ord($message{$m++}) << 8) | ord($message{$m++}); - - //for Cipher Block Chaining mode, xor the message with the previous result - if ($mode == 1) {if ($encrypt) {$left ^= $cbcleft; $right ^= $cbcright;} else {$cbcleft2 = $cbcleft; $cbcright2 = $cbcright; $cbcleft = $left; $cbcright = $right;}} - - //first each 64 but chunk of the message must be permuted according to IP - $temp = (($left >> 4 & $masks[4]) ^ $right) & 0x0f0f0f0f; $right ^= $temp; $left ^= ($temp << 4); - $temp = (($left >> 16 & $masks[16]) ^ $right) & 0x0000ffff; $right ^= $temp; $left ^= ($temp << 16); - $temp = (($right >> 2 & $masks[2]) ^ $left) & 0x33333333; $left ^= $temp; $right ^= ($temp << 2); - $temp = (($right >> 8 & $masks[8]) ^ $left) & 0x00ff00ff; $left ^= $temp; $right ^= ($temp << 8); - $temp = (($left >> 1 & $masks[1]) ^ $right) & 0x55555555; $right ^= $temp; $left ^= ($temp << 1); - - $left = (($left << 1) | ($left >> 31 & $masks[31])); - $right = (($right << 1) | ($right >> 31 & $masks[31])); - - //do this either 1 or 3 times for each chunk of the message - for ($j=0; $j<$iterations; $j+=3) { - $endloop = $looping[$j+1]; - $loopinc = $looping[$j+2]; - //now go through and perform the encryption or decryption - for ($i=$looping[$j]; $i!=$endloop; $i+=$loopinc) { //for efficiency - $right1 = $right ^ $keys[$i]; - $right2 = (($right >> 4 & $masks[4]) | ($right << 28)) ^ $keys[$i+1]; - //the result is attained by passing these bytes through the S selection functions - $temp = $left; - $left = $right; - $right = $temp ^ ($spfunction2[($right1 >> 24 & $masks[24]) & 0x3f] | $spfunction4[($right1 >> 16 & $masks[16]) & 0x3f] - | $spfunction6[($right1 >> 8 & $masks[8]) & 0x3f] | $spfunction8[$right1 & 0x3f] - | $spfunction1[($right2 >> 24 & $masks[24]) & 0x3f] | $spfunction3[($right2 >> 16 & $masks[16]) & 0x3f] - | $spfunction5[($right2 >> 8 & $masks[8]) & 0x3f] | $spfunction7[$right2 & 0x3f]); - } - $temp = $left; $left = $right; $right = $temp; //unreverse left and right - } //for either 1 or 3 iterations - - //move then each one bit to the right - $left = (($left >> 1 & $masks[1]) | ($left << 31)); - $right = (($right >> 1 & $masks[1]) | ($right << 31)); - - //now perform IP-1, which is IP in the opposite direction - $temp = (($left >> 1 & $masks[1]) ^ $right) & 0x55555555; $right ^= $temp; $left ^= ($temp << 1); - $temp = (($right >> 8 & $masks[8]) ^ $left) & 0x00ff00ff; $left ^= $temp; $right ^= ($temp << 8); - $temp = (($right >> 2 & $masks[2]) ^ $left) & 0x33333333; $left ^= $temp; $right ^= ($temp << 2); - $temp = (($left >> 16 & $masks[16]) ^ $right) & 0x0000ffff; $right ^= $temp; $left ^= ($temp << 16); - $temp = (($left >> 4 & $masks[4]) ^ $right) & 0x0f0f0f0f; $right ^= $temp; $left ^= ($temp << 4); - - //for Cipher Block Chaining mode, xor the message with the previous result - if ($mode == 1) {if ($encrypt) {$cbcleft = $left; $cbcright = $right;} else {$left ^= $cbcleft2; $right ^= $cbcright2;}} - $tempresult .= (chr($left>>24 & $masks[24]) . chr(($left>>16 & $masks[16]) & 0xff) . chr(($left>>8 & $masks[8]) & 0xff) . chr($left & 0xff) . chr($right>>24 & $masks[24]) . chr(($right>>16 & $masks[16]) & 0xff) . chr(($right>>8 & $masks[8]) & 0xff) . chr($right & 0xff)); - - $chunk += 8; - if ($chunk == 512) {$result .= $tempresult; $tempresult = ""; $chunk = 0;} - } //for every 8 characters, or 64 bits in the message - - //return the result as an array - return ($result . $tempresult); + private static function _des($key, $message, $encrypt, $mode = 0, $iv = null) + { + //declaring this locally speeds things up a bit + $spfunction1 = array(0x1010400, 0, 0x10000, 0x1010404, 0x1010004, 0x10404, 0x4, 0x10000, 0x400, 0x1010400, 0x1010404, 0x400, 0x1000404, 0x1010004, 0x1000000, 0x4, 0x404, 0x1000400, 0x1000400, 0x10400, 0x10400, 0x1010000, 0x1010000, 0x1000404, 0x10004, 0x1000004, 0x1000004, 0x10004, 0, 0x404, 0x10404, 0x1000000, 0x10000, 0x1010404, 0x4, 0x1010000, 0x1010400, 0x1000000, 0x1000000, 0x400, 0x1010004, 0x10000, 0x10400, 0x1000004, 0x400, 0x4, 0x1000404, 0x10404, 0x1010404, 0x10004, 0x1010000, 0x1000404, 0x1000004, 0x404, 0x10404, 0x1010400, 0x404, 0x1000400, 0x1000400, 0, 0x10004, 0x10400, 0, 0x1010004); + $spfunction2 = array(-0x7fef7fe0, -0x7fff8000, 0x8000, 0x108020, 0x100000, 0x20, -0x7fefffe0, -0x7fff7fe0, -0x7fffffe0, -0x7fef7fe0, -0x7fef8000, -0x80000000, -0x7fff8000, 0x100000, 0x20, -0x7fefffe0, 0x108000, 0x100020, -0x7fff7fe0, 0, -0x80000000, 0x8000, 0x108020, -0x7ff00000, 0x100020, -0x7fffffe0, 0, 0x108000, 0x8020, -0x7fef8000, -0x7ff00000, 0x8020, 0, 0x108020, -0x7fefffe0, 0x100000, -0x7fff7fe0, -0x7ff00000, -0x7fef8000, 0x8000, -0x7ff00000, -0x7fff8000, 0x20, -0x7fef7fe0, 0x108020, 0x20, 0x8000, -0x80000000, 0x8020, -0x7fef8000, 0x100000, -0x7fffffe0, 0x100020, -0x7fff7fe0, -0x7fffffe0, 0x100020, 0x108000, 0, -0x7fff8000, 0x8020, -0x80000000, -0x7fefffe0, -0x7fef7fe0, 0x108000); + $spfunction3 = array(0x208, 0x8020200, 0, 0x8020008, 0x8000200, 0, 0x20208, 0x8000200, 0x20008, 0x8000008, 0x8000008, 0x20000, 0x8020208, 0x20008, 0x8020000, 0x208, 0x8000000, 0x8, 0x8020200, 0x200, 0x20200, 0x8020000, 0x8020008, 0x20208, 0x8000208, 0x20200, 0x20000, 0x8000208, 0x8, 0x8020208, 0x200, 0x8000000, 0x8020200, 0x8000000, 0x20008, 0x208, 0x20000, 0x8020200, 0x8000200, 0, 0x200, 0x20008, 0x8020208, 0x8000200, 0x8000008, 0x200, 0, 0x8020008, 0x8000208, 0x20000, 0x8000000, 0x8020208, 0x8, 0x20208, 0x20200, 0x8000008, 0x8020000, 0x8000208, 0x208, 0x8020000, 0x20208, 0x8, 0x8020008, 0x20200); + $spfunction4 = array(0x802001, 0x2081, 0x2081, 0x80, 0x802080, 0x800081, 0x800001, 0x2001, 0, 0x802000, 0x802000, 0x802081, 0x81, 0, 0x800080, 0x800001, 0x1, 0x2000, 0x800000, 0x802001, 0x80, 0x800000, 0x2001, 0x2080, 0x800081, 0x1, 0x2080, 0x800080, 0x2000, 0x802080, 0x802081, 0x81, 0x800080, 0x800001, 0x802000, 0x802081, 0x81, 0, 0, 0x802000, 0x2080, 0x800080, 0x800081, 0x1, 0x802001, 0x2081, 0x2081, 0x80, 0x802081, 0x81, 0x1, 0x2000, 0x800001, 0x2001, 0x802080, 0x800081, 0x2001, 0x2080, 0x800000, 0x802001, 0x80, 0x800000, 0x2000, 0x802080); + $spfunction5 = array(0x100, 0x2080100, 0x2080000, 0x42000100, 0x80000, 0x100, 0x40000000, 0x2080000, 0x40080100, 0x80000, 0x2000100, 0x40080100, 0x42000100, 0x42080000, 0x80100, 0x40000000, 0x2000000, 0x40080000, 0x40080000, 0, 0x40000100, 0x42080100, 0x42080100, 0x2000100, 0x42080000, 0x40000100, 0, 0x42000000, 0x2080100, 0x2000000, 0x42000000, 0x80100, 0x80000, 0x42000100, 0x100, 0x2000000, 0x40000000, 0x2080000, 0x42000100, 0x40080100, 0x2000100, 0x40000000, 0x42080000, 0x2080100, 0x40080100, 0x100, 0x2000000, 0x42080000, 0x42080100, 0x80100, 0x42000000, 0x42080100, 0x2080000, 0, 0x40080000, 0x42000000, 0x80100, 0x2000100, 0x40000100, 0x80000, 0, 0x40080000, 0x2080100, 0x40000100); + $spfunction6 = array(0x20000010, 0x20400000, 0x4000, 0x20404010, 0x20400000, 0x10, 0x20404010, 0x400000, 0x20004000, 0x404010, 0x400000, 0x20000010, 0x400010, 0x20004000, 0x20000000, 0x4010, 0, 0x400010, 0x20004010, 0x4000, 0x404000, 0x20004010, 0x10, 0x20400010, 0x20400010, 0, 0x404010, 0x20404000, 0x4010, 0x404000, 0x20404000, 0x20000000, 0x20004000, 0x10, 0x20400010, 0x404000, 0x20404010, 0x400000, 0x4010, 0x20000010, 0x400000, 0x20004000, 0x20000000, 0x4010, 0x20000010, 0x20404010, 0x404000, 0x20400000, 0x404010, 0x20404000, 0, 0x20400010, 0x10, 0x4000, 0x20400000, 0x404010, 0x4000, 0x400010, 0x20004010, 0, 0x20404000, 0x20000000, 0x400010, 0x20004010); + $spfunction7 = array(0x200000, 0x4200002, 0x4000802, 0, 0x800, 0x4000802, 0x200802, 0x4200800, 0x4200802, 0x200000, 0, 0x4000002, 0x2, 0x4000000, 0x4200002, 0x802, 0x4000800, 0x200802, 0x200002, 0x4000800, 0x4000002, 0x4200000, 0x4200800, 0x200002, 0x4200000, 0x800, 0x802, 0x4200802, 0x200800, 0x2, 0x4000000, 0x200800, 0x4000000, 0x200800, 0x200000, 0x4000802, 0x4000802, 0x4200002, 0x4200002, 0x2, 0x200002, 0x4000000, 0x4000800, 0x200000, 0x4200800, 0x802, 0x200802, 0x4200800, 0x802, 0x4000002, 0x4200802, 0x4200000, 0x200800, 0, 0x2, 0x4200802, 0, 0x200802, 0x4200000, 0x800, 0x4000002, 0x4000800, 0x800, 0x200002); + $spfunction8 = array(0x10001040, 0x1000, 0x40000, 0x10041040, 0x10000000, 0x10001040, 0x40, 0x10000000, 0x40040, 0x10040000, 0x10041040, 0x41000, 0x10041000, 0x41040, 0x1000, 0x40, 0x10040000, 0x10000040, 0x10001000, 0x1040, 0x41000, 0x40040, 0x10040040, 0x10041000, 0x1040, 0, 0, 0x10040040, 0x10000040, 0x10001000, 0x41040, 0x40000, 0x41040, 0x40000, 0x10041000, 0x1000, 0x40, 0x10040040, 0x1000, 0x41040, 0x10001000, 0x40, 0x10000040, 0x10040000, 0x10040040, 0x10000000, 0x40000, 0x10001040, 0, 0x10041040, 0x40040, 0x10000040, 0x10040000, 0x10001000, 0x10001040, 0, 0x10041040, 0x41000, 0x41000, 0x1040, 0x1040, 0x40040, 0x10000000, 0x10041000); + $masks = array(4294967295, 2147483647, 1073741823, 536870911, 268435455, 134217727, 67108863, 33554431, 16777215, 8388607, 4194303, 2097151, 1048575, 524287, 262143, 131071, 65535, 32767, 16383, 8191, 4095, 2047, 1023, 511, 255, 127, 63, 31, 15, 7, 3, 1, 0); + + //create the 16 or 48 subkeys we will need + $keys = self::_createKeys($key); + $m = 0; + $len = strlen($message); + $chunk = 0; + //set up the loops for single and triple des + $iterations = ((count($keys) == 32) ? 3 : 9); //single or triple des + if (3 == $iterations) {$looping = (($encrypt) ? array(0, 32, 2) : array(30, -2, -2));} else { $looping = (($encrypt) ? array(0, 32, 2, 62, 30, -2, 64, 96, 2) : array(94, 62, -2, 32, 64, 2, 30, -2, -2));} + + $message .= (chr(0) . chr(0) . chr(0) . chr(0) . chr(0) . chr(0) . chr(0) . chr(0)); //pad the message out with null bytes + //store the result here + $result = ""; + $tempresult = ""; + + if (1 == $mode) { + //CBC mode + $cbcleft = (ord($iv{$m++}) << 24) | (ord($iv{$m++}) << 16) | (ord($iv{$m++}) << 8) | ord($iv{$m++}); + $cbcright = (ord($iv{$m++}) << 24) | (ord($iv{$m++}) << 16) | (ord($iv{$m++}) << 8) | ord($iv{$m++}); + $m = 0; + } + + //loop through each 64 bit chunk of the message + while ($m < $len) { + $left = (ord($message{$m++}) << 24) | (ord($message{$m++}) << 16) | (ord($message{$m++}) << 8) | ord($message{$m++}); + $right = (ord($message{$m++}) << 24) | (ord($message{$m++}) << 16) | (ord($message{$m++}) << 8) | ord($message{$m++}); + + //for Cipher Block Chaining mode, xor the message with the previous result + if (1 == $mode) { + if ($encrypt) {$left ^= $cbcleft; + $right ^= $cbcright;} else { + $cbcleft2 = $cbcleft; + $cbcright2 = $cbcright; + $cbcleft = $left; + $cbcright = $right;}} + + //first each 64 but chunk of the message must be permuted according to IP + $temp = (($left >> 4 & $masks[4]) ^ $right) & 0x0f0f0f0f; + $right ^= $temp; + $left ^= ($temp << 4); + $temp = (($left >> 16 & $masks[16]) ^ $right) & 0x0000ffff; + $right ^= $temp; + $left ^= ($temp << 16); + $temp = (($right >> 2 & $masks[2]) ^ $left) & 0x33333333; + $left ^= $temp; + $right ^= ($temp << 2); + $temp = (($right >> 8 & $masks[8]) ^ $left) & 0x00ff00ff; + $left ^= $temp; + $right ^= ($temp << 8); + $temp = (($left >> 1 & $masks[1]) ^ $right) & 0x55555555; + $right ^= $temp; + $left ^= ($temp << 1); + + $left = (($left << 1) | ($left >> 31 & $masks[31])); + $right = (($right << 1) | ($right >> 31 & $masks[31])); + + //do this either 1 or 3 times for each chunk of the message + for ($j = 0; $j < $iterations; $j += 3) { + $endloop = $looping[$j + 1]; + $loopinc = $looping[$j + 2]; + //now go through and perform the encryption or decryption + for ($i = $looping[$j]; $i != $endloop; $i += $loopinc) { + //for efficiency + $right1 = $right ^ $keys[$i]; + $right2 = (($right >> 4 & $masks[4]) | ($right << 28)) ^ $keys[$i + 1]; + //the result is attained by passing these bytes through the S selection functions + $temp = $left; + $left = $right; + $right = $temp ^ ($spfunction2[($right1 >> 24 & $masks[24]) & 0x3f] | $spfunction4[($right1 >> 16 & $masks[16]) & 0x3f] + | $spfunction6[($right1 >> 8 & $masks[8]) & 0x3f] | $spfunction8[$right1 & 0x3f] + | $spfunction1[($right2 >> 24 & $masks[24]) & 0x3f] | $spfunction3[($right2 >> 16 & $masks[16]) & 0x3f] + | $spfunction5[($right2 >> 8 & $masks[8]) & 0x3f] | $spfunction7[$right2 & 0x3f]); + } + $temp = $left; + $left = $right; + $right = $temp; //unreverse left and right + } //for either 1 or 3 iterations + + //move then each one bit to the right + $left = (($left >> 1 & $masks[1]) | ($left << 31)); + $right = (($right >> 1 & $masks[1]) | ($right << 31)); + + //now perform IP-1, which is IP in the opposite direction + $temp = (($left >> 1 & $masks[1]) ^ $right) & 0x55555555; + $right ^= $temp; + $left ^= ($temp << 1); + $temp = (($right >> 8 & $masks[8]) ^ $left) & 0x00ff00ff; + $left ^= $temp; + $right ^= ($temp << 8); + $temp = (($right >> 2 & $masks[2]) ^ $left) & 0x33333333; + $left ^= $temp; + $right ^= ($temp << 2); + $temp = (($left >> 16 & $masks[16]) ^ $right) & 0x0000ffff; + $right ^= $temp; + $left ^= ($temp << 16); + $temp = (($left >> 4 & $masks[4]) ^ $right) & 0x0f0f0f0f; + $right ^= $temp; + $left ^= ($temp << 4); + + //for Cipher Block Chaining mode, xor the message with the previous result + if (1 == $mode) { + if ($encrypt) {$cbcleft = $left; + $cbcright = $right;} else { + $left ^= $cbcleft2; + $right ^= $cbcright2;}} + $tempresult .= (chr($left >> 24 & $masks[24]) . chr(($left >> 16 & $masks[16]) & 0xff) . chr(($left >> 8 & $masks[8]) & 0xff) . chr($left & 0xff) . chr($right >> 24 & $masks[24]) . chr(($right >> 16 & $masks[16]) & 0xff) . chr(($right >> 8 & $masks[8]) & 0xff) . chr($right & 0xff)); + + $chunk += 8; + if (512 == $chunk) { + $result .= $tempresult; + $tempresult = ""; + $chunk = 0;} + } //for every 8 characters, or 64 bits in the message + + //return the result as an array + return ($result . $tempresult); } //end of des /** @@ -159,83 +200,100 @@ private static function _des($key, $message, $encrypt, $mode=0, $iv=null) { * @param string $key 加密key * @return string */ - private static function _createKeys ($key) { - //declaring this locally speeds things up a bit - $pc2bytes0 = array (0,0x4,0x20000000,0x20000004,0x10000,0x10004,0x20010000,0x20010004,0x200,0x204,0x20000200,0x20000204,0x10200,0x10204,0x20010200,0x20010204); - $pc2bytes1 = array (0,0x1,0x100000,0x100001,0x4000000,0x4000001,0x4100000,0x4100001,0x100,0x101,0x100100,0x100101,0x4000100,0x4000101,0x4100100,0x4100101); - $pc2bytes2 = array (0,0x8,0x800,0x808,0x1000000,0x1000008,0x1000800,0x1000808,0,0x8,0x800,0x808,0x1000000,0x1000008,0x1000800,0x1000808); - $pc2bytes3 = array (0,0x200000,0x8000000,0x8200000,0x2000,0x202000,0x8002000,0x8202000,0x20000,0x220000,0x8020000,0x8220000,0x22000,0x222000,0x8022000,0x8222000); - $pc2bytes4 = array (0,0x40000,0x10,0x40010,0,0x40000,0x10,0x40010,0x1000,0x41000,0x1010,0x41010,0x1000,0x41000,0x1010,0x41010); - $pc2bytes5 = array (0,0x400,0x20,0x420,0,0x400,0x20,0x420,0x2000000,0x2000400,0x2000020,0x2000420,0x2000000,0x2000400,0x2000020,0x2000420); - $pc2bytes6 = array (0,0x10000000,0x80000,0x10080000,0x2,0x10000002,0x80002,0x10080002,0,0x10000000,0x80000,0x10080000,0x2,0x10000002,0x80002,0x10080002); - $pc2bytes7 = array (0,0x10000,0x800,0x10800,0x20000000,0x20010000,0x20000800,0x20010800,0x20000,0x30000,0x20800,0x30800,0x20020000,0x20030000,0x20020800,0x20030800); - $pc2bytes8 = array (0,0x40000,0,0x40000,0x2,0x40002,0x2,0x40002,0x2000000,0x2040000,0x2000000,0x2040000,0x2000002,0x2040002,0x2000002,0x2040002); - $pc2bytes9 = array (0,0x10000000,0x8,0x10000008,0,0x10000000,0x8,0x10000008,0x400,0x10000400,0x408,0x10000408,0x400,0x10000400,0x408,0x10000408); - $pc2bytes10 = array (0,0x20,0,0x20,0x100000,0x100020,0x100000,0x100020,0x2000,0x2020,0x2000,0x2020,0x102000,0x102020,0x102000,0x102020); - $pc2bytes11 = array (0,0x1000000,0x200,0x1000200,0x200000,0x1200000,0x200200,0x1200200,0x4000000,0x5000000,0x4000200,0x5000200,0x4200000,0x5200000,0x4200200,0x5200200); - $pc2bytes12 = array (0,0x1000,0x8000000,0x8001000,0x80000,0x81000,0x8080000,0x8081000,0x10,0x1010,0x8000010,0x8001010,0x80010,0x81010,0x8080010,0x8081010); - $pc2bytes13 = array (0,0x4,0x100,0x104,0,0x4,0x100,0x104,0x1,0x5,0x101,0x105,0x1,0x5,0x101,0x105); - $masks = array (4294967295,2147483647,1073741823,536870911,268435455,134217727,67108863,33554431,16777215,8388607,4194303,2097151,1048575,524287,262143,131071,65535,32767,16383,8191,4095,2047,1023,511,255,127,63,31,15,7,3,1,0); - - //how many iterations (1 for des, 3 for triple des) - $iterations = ((strlen($key) >= 24) ? 3 : 1); - //stores the return keys - $keys = array (); // size = 32 * iterations but you don't specify this in php - //now define the left shifts which need to be done - $shifts = array (0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0); - //other variables - $m=0; - $n=0; - - for ($j=0; $j<$iterations; $j++) { //either 1 or 3 iterations - $left = (ord($key{$m++}) << 24) | (ord($key{$m++}) << 16) | (ord($key{$m++}) << 8) | ord($key{$m++}); - $right = (ord($key{$m++}) << 24) | (ord($key{$m++}) << 16) | (ord($key{$m++}) << 8) | ord($key{$m++}); - - $temp = (($left >> 4 & $masks[4]) ^ $right) & 0x0f0f0f0f; $right ^= $temp; $left ^= ($temp << 4); - $temp = (($right >> 16 & $masks[16]) ^ $left) & 0x0000ffff; $left ^= $temp; $right ^= ($temp << -16); - $temp = (($left >> 2 & $masks[2]) ^ $right) & 0x33333333; $right ^= $temp; $left ^= ($temp << 2); - $temp = (($right >> 16 & $masks[16]) ^ $left) & 0x0000ffff; $left ^= $temp; $right ^= ($temp << -16); - $temp = (($left >> 1 & $masks[1]) ^ $right) & 0x55555555; $right ^= $temp; $left ^= ($temp << 1); - $temp = (($right >> 8 & $masks[8]) ^ $left) & 0x00ff00ff; $left ^= $temp; $right ^= ($temp << 8); - $temp = (($left >> 1 & $masks[1]) ^ $right) & 0x55555555; $right ^= $temp; $left ^= ($temp << 1); - - //the right side needs to be shifted and to get the last four bits of the left side - $temp = ($left << 8) | (($right >> 20 & $masks[20]) & 0x000000f0); - //left needs to be put upside down - $left = ($right << 24) | (($right << 8) & 0xff0000) | (($right >> 8 & $masks[8]) & 0xff00) | (($right >> 24 & $masks[24]) & 0xf0); - $right = $temp; - - //now go through and perform these shifts on the left and right keys - for ($i=0; $i < count($shifts); $i++) { - //shift the keys either one or two bits to the left - if ($shifts[$i] > 0) { - $left = (($left << 2) | ($left >> 26 & $masks[26])); - $right = (($right << 2) | ($right >> 26 & $masks[26])); - } else { - $left = (($left << 1) | ($left >> 27 & $masks[27])); - $right = (($right << 1) | ($right >> 27 & $masks[27])); - } - $left = $left & -0xf; - $right = $right & -0xf; - - //now apply PC-2, in such a way that E is easier when encrypting or decrypting - //this conversion will look like PC-2 except only the last 6 bits of each byte are used - //rather than 48 consecutive bits and the order of lines will be according to - //how the S selection functions will be applied: S2, S4, S6, S8, S1, S3, S5, S7 - $lefttemp = $pc2bytes0[$left >> 28 & $masks[28]] | $pc2bytes1[($left >> 24 & $masks[24]) & 0xf] - | $pc2bytes2[($left >> 20 & $masks[20]) & 0xf] | $pc2bytes3[($left >> 16 & $masks[16]) & 0xf] - | $pc2bytes4[($left >> 12 & $masks[12]) & 0xf] | $pc2bytes5[($left >> 8 & $masks[8]) & 0xf] - | $pc2bytes6[($left >> 4 & $masks[4]) & 0xf]; - $righttemp = $pc2bytes7[$right >> 28 & $masks[28]] | $pc2bytes8[($right >> 24 & $masks[24]) & 0xf] - | $pc2bytes9[($right >> 20 & $masks[20]) & 0xf] | $pc2bytes10[($right >> 16 & $masks[16]) & 0xf] - | $pc2bytes11[($right >> 12 & $masks[12]) & 0xf] | $pc2bytes12[($right >> 8 & $masks[8]) & 0xf] - | $pc2bytes13[($right >> 4 & $masks[4]) & 0xf]; - $temp = (($righttemp >> 16 & $masks[16]) ^ $lefttemp) & 0x0000ffff; - $keys[$n++] = $lefttemp ^ $temp; $keys[$n++] = $righttemp ^ ($temp << 16); - } - } //for each iterations - //return the keys we've created - return $keys; + private static function _createKeys($key) + { + //declaring this locally speeds things up a bit + $pc2bytes0 = array(0, 0x4, 0x20000000, 0x20000004, 0x10000, 0x10004, 0x20010000, 0x20010004, 0x200, 0x204, 0x20000200, 0x20000204, 0x10200, 0x10204, 0x20010200, 0x20010204); + $pc2bytes1 = array(0, 0x1, 0x100000, 0x100001, 0x4000000, 0x4000001, 0x4100000, 0x4100001, 0x100, 0x101, 0x100100, 0x100101, 0x4000100, 0x4000101, 0x4100100, 0x4100101); + $pc2bytes2 = array(0, 0x8, 0x800, 0x808, 0x1000000, 0x1000008, 0x1000800, 0x1000808, 0, 0x8, 0x800, 0x808, 0x1000000, 0x1000008, 0x1000800, 0x1000808); + $pc2bytes3 = array(0, 0x200000, 0x8000000, 0x8200000, 0x2000, 0x202000, 0x8002000, 0x8202000, 0x20000, 0x220000, 0x8020000, 0x8220000, 0x22000, 0x222000, 0x8022000, 0x8222000); + $pc2bytes4 = array(0, 0x40000, 0x10, 0x40010, 0, 0x40000, 0x10, 0x40010, 0x1000, 0x41000, 0x1010, 0x41010, 0x1000, 0x41000, 0x1010, 0x41010); + $pc2bytes5 = array(0, 0x400, 0x20, 0x420, 0, 0x400, 0x20, 0x420, 0x2000000, 0x2000400, 0x2000020, 0x2000420, 0x2000000, 0x2000400, 0x2000020, 0x2000420); + $pc2bytes6 = array(0, 0x10000000, 0x80000, 0x10080000, 0x2, 0x10000002, 0x80002, 0x10080002, 0, 0x10000000, 0x80000, 0x10080000, 0x2, 0x10000002, 0x80002, 0x10080002); + $pc2bytes7 = array(0, 0x10000, 0x800, 0x10800, 0x20000000, 0x20010000, 0x20000800, 0x20010800, 0x20000, 0x30000, 0x20800, 0x30800, 0x20020000, 0x20030000, 0x20020800, 0x20030800); + $pc2bytes8 = array(0, 0x40000, 0, 0x40000, 0x2, 0x40002, 0x2, 0x40002, 0x2000000, 0x2040000, 0x2000000, 0x2040000, 0x2000002, 0x2040002, 0x2000002, 0x2040002); + $pc2bytes9 = array(0, 0x10000000, 0x8, 0x10000008, 0, 0x10000000, 0x8, 0x10000008, 0x400, 0x10000400, 0x408, 0x10000408, 0x400, 0x10000400, 0x408, 0x10000408); + $pc2bytes10 = array(0, 0x20, 0, 0x20, 0x100000, 0x100020, 0x100000, 0x100020, 0x2000, 0x2020, 0x2000, 0x2020, 0x102000, 0x102020, 0x102000, 0x102020); + $pc2bytes11 = array(0, 0x1000000, 0x200, 0x1000200, 0x200000, 0x1200000, 0x200200, 0x1200200, 0x4000000, 0x5000000, 0x4000200, 0x5000200, 0x4200000, 0x5200000, 0x4200200, 0x5200200); + $pc2bytes12 = array(0, 0x1000, 0x8000000, 0x8001000, 0x80000, 0x81000, 0x8080000, 0x8081000, 0x10, 0x1010, 0x8000010, 0x8001010, 0x80010, 0x81010, 0x8080010, 0x8081010); + $pc2bytes13 = array(0, 0x4, 0x100, 0x104, 0, 0x4, 0x100, 0x104, 0x1, 0x5, 0x101, 0x105, 0x1, 0x5, 0x101, 0x105); + $masks = array(4294967295, 2147483647, 1073741823, 536870911, 268435455, 134217727, 67108863, 33554431, 16777215, 8388607, 4194303, 2097151, 1048575, 524287, 262143, 131071, 65535, 32767, 16383, 8191, 4095, 2047, 1023, 511, 255, 127, 63, 31, 15, 7, 3, 1, 0); + + //how many iterations (1 for des, 3 for triple des) + $iterations = ((strlen($key) >= 24) ? 3 : 1); + //stores the return keys + $keys = array(); // size = 32 * iterations but you don't specify this in php + //now define the left shifts which need to be done + $shifts = array(0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0); + //other variables + $m = 0; + $n = 0; + + for ($j = 0; $j < $iterations; $j++) { + //either 1 or 3 iterations + $left = (ord($key{$m++}) << 24) | (ord($key{$m++}) << 16) | (ord($key{$m++}) << 8) | ord($key{$m++}); + $right = (ord($key{$m++}) << 24) | (ord($key{$m++}) << 16) | (ord($key{$m++}) << 8) | ord($key{$m++}); + + $temp = (($left >> 4 & $masks[4]) ^ $right) & 0x0f0f0f0f; + $right ^= $temp; + $left ^= ($temp << 4); + $temp = (($right >> 16 & $masks[16]) ^ $left) & 0x0000ffff; + $left ^= $temp; + $right ^= ($temp << -16); + $temp = (($left >> 2 & $masks[2]) ^ $right) & 0x33333333; + $right ^= $temp; + $left ^= ($temp << 2); + $temp = (($right >> 16 & $masks[16]) ^ $left) & 0x0000ffff; + $left ^= $temp; + $right ^= ($temp << -16); + $temp = (($left >> 1 & $masks[1]) ^ $right) & 0x55555555; + $right ^= $temp; + $left ^= ($temp << 1); + $temp = (($right >> 8 & $masks[8]) ^ $left) & 0x00ff00ff; + $left ^= $temp; + $right ^= ($temp << 8); + $temp = (($left >> 1 & $masks[1]) ^ $right) & 0x55555555; + $right ^= $temp; + $left ^= ($temp << 1); + + //the right side needs to be shifted and to get the last four bits of the left side + $temp = ($left << 8) | (($right >> 20 & $masks[20]) & 0x000000f0); + //left needs to be put upside down + $left = ($right << 24) | (($right << 8) & 0xff0000) | (($right >> 8 & $masks[8]) & 0xff00) | (($right >> 24 & $masks[24]) & 0xf0); + $right = $temp; + + //now go through and perform these shifts on the left and right keys + for ($i = 0; $i < count($shifts); $i++) { + //shift the keys either one or two bits to the left + if ($shifts[$i] > 0) { + $left = (($left << 2) | ($left >> 26 & $masks[26])); + $right = (($right << 2) | ($right >> 26 & $masks[26])); + } else { + $left = (($left << 1) | ($left >> 27 & $masks[27])); + $right = (($right << 1) | ($right >> 27 & $masks[27])); + } + $left = $left & -0xf; + $right = $right & -0xf; + + //now apply PC-2, in such a way that E is easier when encrypting or decrypting + //this conversion will look like PC-2 except only the last 6 bits of each byte are used + //rather than 48 consecutive bits and the order of lines will be according to + //how the S selection functions will be applied: S2, S4, S6, S8, S1, S3, S5, S7 + $lefttemp = $pc2bytes0[$left >> 28 & $masks[28]] | $pc2bytes1[($left >> 24 & $masks[24]) & 0xf] + | $pc2bytes2[($left >> 20 & $masks[20]) & 0xf] | $pc2bytes3[($left >> 16 & $masks[16]) & 0xf] + | $pc2bytes4[($left >> 12 & $masks[12]) & 0xf] | $pc2bytes5[($left >> 8 & $masks[8]) & 0xf] + | $pc2bytes6[($left >> 4 & $masks[4]) & 0xf]; + $righttemp = $pc2bytes7[$right >> 28 & $masks[28]] | $pc2bytes8[($right >> 24 & $masks[24]) & 0xf] + | $pc2bytes9[($right >> 20 & $masks[20]) & 0xf] | $pc2bytes10[($right >> 16 & $masks[16]) & 0xf] + | $pc2bytes11[($right >> 12 & $masks[12]) & 0xf] | $pc2bytes12[($right >> 8 & $masks[8]) & 0xf] + | $pc2bytes13[($right >> 4 & $masks[4]) & 0xf]; + $temp = (($righttemp >> 16 & $masks[16]) ^ $lefttemp) & 0x0000ffff; + $keys[$n++] = $lefttemp ^ $temp; + $keys[$n++] = $righttemp ^ ($temp << 16); + } + } //for each iterations + //return the keys we've created + return $keys; } //end of des_createKeys -} \ No newline at end of file +} diff --git a/ThinkPHP/Library/Think/Crypt/Driver/Think.class.php b/ThinkPHP/Library/Think/Crypt/Driver/Think.class.php index f8ae9e15c..9a65a3a1b 100644 --- a/ThinkPHP/Library/Think/Crypt/Driver/Think.class.php +++ b/ThinkPHP/Library/Think/Crypt/Driver/Think.class.php @@ -9,37 +9,43 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think\Crypt\Driver; + /** * Base64 加密实现类 */ -class Think { +class Think +{ /** * 加密字符串 * @param string $str 字符串 * @param string $key 加密key - * @param integer $expire 有效期(秒) + * @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 = ''; + 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; + 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); + $str .= chr(ord(substr($data, $i, 1)) + (ord(substr($char, $i, 1))) % 256); } - return str_replace(array('+','/','='),array('-','_',''),base64_encode($str)); + return str_replace(array('+', '/', '='), array('-', '_', ''), base64_encode($str)); } /** @@ -48,39 +54,43 @@ public static function encrypt($data,$key,$expire=0) { * @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; + 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 .= substr('====', $mod4); } - $data = base64_decode($data); + $data = base64_decode($data); - $x = 0; - $len = strlen($data); - $l = strlen($key); - $char = $str = ''; + $x = 0; + $len = strlen($data); + $l = strlen($key); + $char = $str = ''; for ($i = 0; $i < $len; $i++) { - if ($x == $l) $x = 0; + if ($x == $l) { + $x = 0; + } + $char .= substr($key, $x, 1); $x++; } for ($i = 0; $i < $len; $i++) { - if (ord(substr($data, $i, 1)) 0 && $expire < time()) { + $expire = substr($data, 0, 10); + if ($expire > 0 && $expire < time()) { return ''; } - $data = substr($data,10); + $data = substr($data, 10); return $data; } -} \ No newline at end of file +} diff --git a/ThinkPHP/Library/Think/Crypt/Driver/Xxtea.class.php b/ThinkPHP/Library/Think/Crypt/Driver/Xxtea.class.php index 3f506a196..9677b339e 100644 --- a/ThinkPHP/Library/Think/Crypt/Driver/Xxtea.class.php +++ b/ThinkPHP/Library/Think/Crypt/Driver/Xxtea.class.php @@ -9,41 +9,44 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think\Crypt\Driver; + /** * Xxtea 加密实现类 */ -class Xxtea { +class Xxtea +{ /** * 加密字符串 * @param string $str 字符串 * @param string $key 加密key - * @param integer $expire 有效期(秒) + * @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; + 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]; + $z = $v[$n]; + $y = $v[0]; $delta = 0x9E3779B9; - $q = floor(6 + 52 / ($n + 1)); - $sum = 0; + $q = floor(6 + 52 / ($n + 1)); + $sum = 0; while (0 < $q--) { $sum = self::int32($sum + $delta); - $e = $sum >> 2 & 3; + $e = $sum >> 2 & 3; for ($p = 0; $p < $n; $p++) { - $y = $v[$p + 1]; + $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); + $z = $v[$p] = self::int32($v[$p] + $mx); } - $y = $v[0]; + $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); + $z = $v[$n] = self::int32($v[$n] + $mx); } return self::long2str($v, false); } @@ -54,52 +57,55 @@ public static function encrypt($str, $key,$expire=0) { * @param string $key 加密key * @return string */ - public static function decrypt($str, $key) { + 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]; + $z = $v[$n]; + $y = $v[0]; $delta = 0x9E3779B9; - $q = floor(6 + 52 / ($n + 1)); - $sum = self::int32($q * $delta); - while ($sum != 0) { + $q = floor(6 + 52 / ($n + 1)); + $sum = self::int32($q * $delta); + while (0 != $sum) { $e = $sum >> 2 & 3; for ($p = $n; $p > 0; $p--) { - $z = $v[$p - 1]; + $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); + $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); + $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()) { + $expire = substr($data, 0, 10); + if ($expire > 0 && $expire < time()) { return ''; } - $data = substr($data,10); + $data = substr($data, 10); return $data; } - private static function long2str($v, $w) { + private static function long2str($v, $w) + { $len = count($v); - $s = array(); + $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{ + } else { return join('', $s); } } - private static function str2long($s, $w) { - $v = unpack("V*", $s. str_repeat("\0", (4 - strlen($s) % 4) & 3)); + 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); @@ -107,10 +113,17 @@ private static function str2long($s, $w) { return $v; } - private static function int32($n) { - while ($n >= 2147483648) $n -= 4294967296; - while ($n <= -2147483649) $n += 4294967296; - return (int)$n; + private static function int32($n) + { + while ($n >= 2147483648) { + $n -= 4294967296; + } + + while ($n <= -2147483649) { + $n += 4294967296; + } + + return (int) $n; } -} \ No newline at end of file +} diff --git a/ThinkPHP/Library/Think/Db.class.php b/ThinkPHP/Library/Think/Db.class.php index 5c46e2ff7..39f12b965 100644 --- a/ThinkPHP/Library/Think/Db.class.php +++ b/ThinkPHP/Library/Think/Db.class.php @@ -14,10 +14,11 @@ /** * ThinkPHP 数据库中间层实现类 */ -class Db { +class Db +{ - static private $instance = array(); // 数据库连接实例 - static private $_instance = null; // 当前数据库连接实例 + private static $instance = array(); // 数据库连接实例 + private static $_instance = null; // 当前数据库连接实例 /** * 取得数据库类实例 @@ -26,23 +27,27 @@ class Db { * @param mixed $config 连接配置 * @return Object 返回数据库驱动类 */ - static public function getInstance($config=array()) { - $md5 = md5(serialize($config)); - if(!isset(self::$instance[$md5])) { + public static function getInstance($config = array()) + { + $md5 = md5(serialize($config)); + if (!isset(self::$instance[$md5])) { // 解析连接参数 支持数组和字符串 - $options = self::parseConfig($config); + $options = self::parseConfig($config); // 兼容mysqli - if('mysqli' == $options['type']) $options['type'] = 'mysql'; + if ('mysqli' == $options['type']) { + $options['type'] = 'mysql'; + } + // 如果采用lite方式 仅支持原生SQL 包括query和execute方法 - $class = !empty($options['lite'])? 'Think\Db\Lite' : 'Think\\Db\\Driver\\'.ucwords(strtolower($options['type'])); - if(class_exists($class)){ - self::$instance[$md5] = new $class($options); - }else{ + $class = !empty($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); + E(L('_NO_DB_DRIVER_') . ': ' . $class); } } - self::$_instance = self::$instance[$md5]; + self::$_instance = self::$instance[$md5]; return self::$_instance; } @@ -53,46 +58,47 @@ static public function getInstance($config=array()) { * @param mixed $config * @return array */ - static private function parseConfig($config){ - if(!empty($config)){ - if(is_string($config)) { + private static 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, + $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'), + } 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; @@ -106,32 +112,34 @@ static private function parseConfig($config){ * @param string $dsnStr * @return array */ - static private function parseDsn($dsnStr) { - if( empty($dsnStr) ){return false;} + private static function parseDsn($dsnStr) + { + if (empty($dsnStr)) {return false;} $info = parse_url($dsnStr); - if(!$info) { + 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', + '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(); + + if (isset($info['query'])) { + parse_str($info['query'], $dsn['params']); + } else { + $dsn['params'] = array(); } return $dsn; - } + } // 调用驱动类的方法 - static public function __callStatic($method, $params){ + public static function __callStatic($method, $params) + { return call_user_func_array(array(self::$_instance, $method), $params); } } diff --git a/ThinkPHP/Library/Think/Db/Driver.class.php b/ThinkPHP/Library/Think/Db/Driver.class.php index fb46bebc1..820ecc16f 100644 --- a/ThinkPHP/Library/Think/Db/Driver.class.php +++ b/ThinkPHP/Library/Think/Db/Driver.class.php @@ -10,77 +10,79 @@ // +---------------------------------------------------------------------- namespace Think\Db; + +use PDO; use Think\Config; use Think\Debug; -use Think\Log; -use PDO; -abstract class Driver { +abstract class Driver +{ // PDO操作实例 protected $PDOStatement = null; // 当前操作所属的模型名 - protected $model = '_think_'; + protected $model = '_think_'; // 当前SQL指令 - protected $queryStr = ''; - protected $modelSql = array(); + protected $queryStr = ''; + protected $modelSql = array(); // 最后插入ID - protected $lastInsID = null; + protected $lastInsID = null; // 返回或者影响记录数 - protected $numRows = 0; + protected $numRows = 0; // 事务指令数 protected $transTimes = 0; // 错误信息 - protected $error = ''; + protected $error = ''; // 数据库连接ID 支持多个连接 - protected $linkID = array(); + protected $linkID = array(); // 当前连接ID - protected $_linkID = null; + protected $_linkID = null; // 数据库连接参数配置 - protected $config = array( - 'type' => '', // 数据库类型 - 'hostname' => '127.0.0.1', // 服务器地址 - 'database' => '', // 数据库名 - 'username' => '', // 用户名 - 'password' => '', // 密码 - 'hostport' => '', // 端口 - 'dsn' => '', // - 'params' => array(), // 数据库连接参数 - 'charset' => 'utf8', // 数据库编码默认采用utf8 - 'prefix' => '', // 数据库表前缀 - 'debug' => false, // 数据库调试模式 - 'deploy' => 0, // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器) - 'rw_separate' => false, // 数据库读写是否分离 主从式有效 - 'master_num' => 1, // 读写分离后 主服务器数量 - 'slave_no' => '', // 指定从服务器序号 - 'db_like_fields' => '', + protected $config = array( + 'type' => '', // 数据库类型 + 'hostname' => '127.0.0.1', // 服务器地址 + 'database' => '', // 数据库名 + 'username' => '', // 用户名 + 'password' => '', // 密码 + 'hostport' => '', // 端口 + 'dsn' => '', // + 'params' => array(), // 数据库连接参数 + 'charset' => 'utf8', // 数据库编码默认采用utf8 + 'prefix' => '', // 数据库表前缀 + 'debug' => false, // 数据库调试模式 + 'deploy' => 0, // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器) + 'rw_separate' => false, // 数据库读写是否分离 主从式有效 + 'master_num' => 1, // 读写分离后 主服务器数量 + 'slave_no' => '', // 指定从服务器序号 + 'db_like_fields' => '', ); // 数据库表达式 - protected $exp = array('eq'=>'=','neq'=>'<>','gt'=>'>','egt'=>'>=','lt'=>'<','elt'=>'<=','notlike'=>'NOT LIKE','like'=>'LIKE','in'=>'IN','notin'=>'NOT IN','not in'=>'NOT IN','between'=>'BETWEEN','not between'=>'NOT BETWEEN','notbetween'=>'NOT BETWEEN'); + protected $exp = array('eq' => '=', 'neq' => '<>', 'gt' => '>', 'egt' => '>=', 'lt' => '<', 'elt' => '<=', 'notlike' => 'NOT LIKE', 'like' => 'LIKE', 'in' => 'IN', 'notin' => 'NOT IN', 'not in' => 'NOT IN', 'between' => 'BETWEEN', 'not between' => 'NOT BETWEEN', 'notbetween' => 'NOT BETWEEN'); // 查询表达式 - protected $selectSql = 'SELECT%DISTINCT% %FIELD% FROM %TABLE%%FORCE%%JOIN%%WHERE%%GROUP%%HAVING%%ORDER%%LIMIT% %UNION%%LOCK%%COMMENT%'; + protected $selectSql = 'SELECT%DISTINCT% %FIELD% FROM %TABLE%%FORCE%%JOIN%%WHERE%%GROUP%%HAVING%%ORDER%%LIMIT% %UNION%%LOCK%%COMMENT%'; // 查询次数 - protected $queryTimes = 0; + protected $queryTimes = 0; // 执行次数 - protected $executeTimes = 0; + protected $executeTimes = 0; // PDO连接参数 protected $options = array( - PDO::ATTR_CASE => PDO::CASE_LOWER, - PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, - PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL, - PDO::ATTR_STRINGIFY_FETCHES => false, + PDO::ATTR_CASE => PDO::CASE_LOWER, + PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, + PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL, + PDO::ATTR_STRINGIFY_FETCHES => false, ); - protected $bind = array(); // 参数绑定 + protected $bind = array(); // 参数绑定 /** * 架构函数 读取数据库配置信息 * @access public * @param array $config 数据库配置数组 */ - public function __construct($config=''){ - if(!empty($config)) { - $this->config = array_merge($this->config,$config); - if(is_array($this->config['params'])){ - $this->options = $this->config['params'] + $this->options; + public function __construct($config = '') + { + if (!empty($config)) { + $this->config = array_merge($this->config, $config); + if (is_array($this->config['params'])) { + $this->options = $this->config['params'] + $this->options; } } } @@ -89,23 +91,27 @@ public function __construct($config=''){ * 连接数据库方法 * @access public */ - public function connect($config='',$linkNum=0,$autoConnection=false) { - if ( !isset($this->linkID[$linkNum]) ) { - if(empty($config)) $config = $this->config; - try{ - if(empty($config['dsn'])) { - $config['dsn'] = $this->parseDsn($config); + public function connect($config = '', $linkNum = 0, $autoConnection = false) + { + if (!isset($this->linkID[$linkNum])) { + if (empty($config)) { + $config = $this->config; + } + + try { + if (empty($config['dsn'])) { + $config['dsn'] = $this->parseDsn($config); } - if(version_compare(PHP_VERSION,'5.3.6','<=')){ + if (version_compare(PHP_VERSION, '5.3.6', '<=')) { // 禁用模拟预处理语句 - $this->options[PDO::ATTR_EMULATE_PREPARES] = false; + $this->options[PDO::ATTR_EMULATE_PREPARES] = false; } - $this->linkID[$linkNum] = new PDO( $config['dsn'], $config['username'], $config['password'],$this->options); - }catch (\PDOException $e) { - if($autoConnection){ - trace($e->getMessage(),'','ERR'); - return $this->connect($autoConnection,$linkNum); - }elseif($config['debug']){ + $this->linkID[$linkNum] = new PDO($config['dsn'], $config['username'], $config['password'], $this->options); + } catch (\PDOException $e) { + if ($autoConnection) { + trace($e->getMessage(), '', 'ERR'); + return $this->connect($autoConnection, $linkNum); + } elseif ($config['debug']) { E($e->getMessage()); } } @@ -119,13 +125,15 @@ public function connect($config='',$linkNum=0,$autoConnection=false) { * @param array $config 连接信息 * @return string */ - protected function parseDsn($config){} + protected function parseDsn($config) + {} /** * 释放查询结果 * @access public */ - public function free() { + public function free() + { $this->PDOStatement = null; } @@ -136,47 +144,54 @@ public function free() { * @param boolean $fetchSql 不执行只是获取SQL * @return mixed */ - public function query($str,$fetchSql=false) { + public function query($str, $fetchSql = false) + { $this->initConnect(false); - 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 (!$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){ + if ($fetchSql) { return $this->queryStr; } //释放前次的查询结果 - if ( !empty($this->PDOStatement) ) $this->free(); + if (!empty($this->PDOStatement)) { + $this->free(); + } + $this->queryTimes++; - N('db_query',1); // 兼容代码 + N('db_query', 1); // 兼容代码 // 调试开始 $this->debug(true); $this->PDOStatement = $this->_linkID->prepare($str); - if(false === $this->PDOStatement){ + if (false === $this->PDOStatement) { $this->error(); return false; } foreach ($this->bind as $key => $val) { - if(is_array($val)){ + if (is_array($val)) { $this->PDOStatement->bindValue($key, $val[0], $val[1]); - }else{ + } else { $this->PDOStatement->bindValue($key, $val); } } - $this->bind = array(); - try{ - $result = $this->PDOStatement->execute(); + $this->bind = array(); + try { + $result = $this->PDOStatement->execute(); // 调试结束 $this->debug(false); - if ( false === $result ) { + if (false === $result) { $this->error(); return false; } else { return $this->getResult(); } - }catch (\PDOException $e) { + } catch (\PDOException $e) { $this->error(); return false; } @@ -189,51 +204,58 @@ public function query($str,$fetchSql=false) { * @param boolean $fetchSql 不执行只是获取SQL * @return mixed */ - public function execute($str,$fetchSql=false) { + public function execute($str, $fetchSql = false) + { $this->initConnect(true); - if ( !$this->_linkID ) return false; + 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 (!empty($this->bind)) { + $that = $this; + $this->queryStr = strtr($this->queryStr, array_map(function ($val) use ($that) {return '\'' . $that->escapeString($val) . '\'';}, $this->bind)); } - if($fetchSql){ + if ($fetchSql) { return $this->queryStr; } //释放前次的查询结果 - if ( !empty($this->PDOStatement) ) $this->free(); + if (!empty($this->PDOStatement)) { + $this->free(); + } + $this->executeTimes++; - N('db_write',1); // 兼容代码 + N('db_write', 1); // 兼容代码 // 记录开始执行时间 $this->debug(true); - $this->PDOStatement = $this->_linkID->prepare($str); - if(false === $this->PDOStatement) { + $this->PDOStatement = $this->_linkID->prepare($str); + if (false === $this->PDOStatement) { $this->error(); return false; } foreach ($this->bind as $key => $val) { - if(is_array($val)){ + if (is_array($val)) { $this->PDOStatement->bindValue($key, $val[0], $val[1]); - }else{ + } else { $this->PDOStatement->bindValue($key, $val); } } - $this->bind = array(); - try{ - $result = $this->PDOStatement->execute(); + $this->bind = array(); + try { + $result = $this->PDOStatement->execute(); // 调试结束 $this->debug(false); - if ( false === $result) { + if (false === $result) { $this->error(); return false; } else { $this->numRows = $this->PDOStatement->rowCount(); - if(preg_match("/^\s*(INSERT\s+INTO|REPLACE\s+INTO)\s+/i", $str)) { + if (preg_match("/^\s*(INSERT\s+INTO|REPLACE\s+INTO)\s+/i", $str)) { $this->lastInsID = $this->_linkID->lastInsertId(); } return $this->numRows; } - }catch (\PDOException $e) { + } catch (\PDOException $e) { $this->error(); return false; } @@ -244,15 +266,19 @@ public function execute($str,$fetchSql=false) { * @access public * @return void */ - public function startTrans() { + public function startTrans() + { $this->initConnect(true); - if ( !$this->_linkID ) return false; + if (!$this->_linkID) { + return false; + } + //数据rollback 支持 - if ($this->transTimes == 0) { + if (0 == $this->transTimes) { $this->_linkID->beginTransaction(); } $this->transTimes++; - return ; + return; } /** @@ -260,11 +286,12 @@ public function startTrans() { * @access public * @return boolean */ - public function commit() { + public function commit() + { if ($this->transTimes > 0) { - $result = $this->_linkID->commit(); + $result = $this->_linkID->commit(); $this->transTimes = 0; - if(!$result){ + if (!$result) { $this->error(); return false; } @@ -277,11 +304,12 @@ public function commit() { * @access public * @return boolean */ - public function rollback() { + public function rollback() + { if ($this->transTimes > 0) { - $result = $this->_linkID->rollback(); + $result = $this->_linkID->rollback(); $this->transTimes = 0; - if(!$result){ + if (!$result) { $this->error(); return false; } @@ -294,10 +322,11 @@ public function rollback() { * @access private * @return array */ - private function getResult() { + private function getResult() + { //返回数据集 - $result = $this->PDOStatement->fetchAll(PDO::FETCH_ASSOC); - $this->numRows = count( $result ); + $result = $this->PDOStatement->fetchAll(PDO::FETCH_ASSOC); + $this->numRows = count($result); return $result; } @@ -307,8 +336,9 @@ private function getResult() { * @param boolean $execute 是否包含所有查询 * @return integer */ - public function getQueryTimes($execute=false){ - return $execute?$this->queryTimes+$this->executeTimes:$this->queryTimes; + public function getQueryTimes($execute = false) + { + return $execute ? $this->queryTimes + $this->executeTimes : $this->queryTimes; } /** @@ -316,7 +346,8 @@ public function getQueryTimes($execute=false){ * @access public * @return integer */ - public function getExecuteTimes(){ + public function getExecuteTimes() + { return $this->executeTimes; } @@ -324,7 +355,8 @@ public function getExecuteTimes(){ * 关闭数据库 * @access public */ - public function close() { + public function close() + { $this->_linkID = null; } @@ -334,21 +366,23 @@ public function close() { * @access public * @return string */ - public function error() { - if($this->PDOStatement) { - $error = $this->PDOStatement->errorInfo(); - $this->error = $error[1].':'.$error[2]; - }else{ + public function error() + { + if ($this->PDOStatement) { + $error = $this->PDOStatement->errorInfo(); + $this->error = $error[1] . ':' . $error[2]; + } else { $this->error = ''; } - if('' != $this->queryStr){ - $this->error .= "\n [ SQL语句 ] : ".$this->queryStr; + if ('' != $this->queryStr) { + $this->error .= "\n [ SQL语句 ] : " . $this->queryStr; } // 记录错误日志 - trace($this->error,'','ERR'); - if($this->config['debug']) {// 开启数据库调试模式 + trace($this->error, '', 'ERR'); + if ($this->config['debug']) { +// 开启数据库调试模式 E($this->error); - }else{ + } else { return $this->error; } } @@ -358,8 +392,9 @@ public function error() { * @access protected * @return string */ - protected function parseLock($lock=false) { - return $lock? ' FOR UPDATE ' : ''; + protected function parseLock($lock = false) + { + return $lock ? ' FOR UPDATE ' : ''; } /** @@ -368,23 +403,25 @@ protected function parseLock($lock=false) { * @param array $data * @return string */ - protected function parseSet($data) { - foreach ($data as $key=>$val){ - if(is_array($val) && 'exp' == $val[0]){ - $set[] = $this->parseKey($key).'='.$val[1]; - }elseif(is_null($val)){ - $set[] = $this->parseKey($key).'=NULL'; - }elseif(is_scalar($val)) {// 过滤非标量数据 - if(0===strpos($val,':') && in_array($val,array_keys($this->bind)) ){ - $set[] = $this->parseKey($key).'='.$this->escapeString($val); - }else{ - $name = count($this->bind); - $set[] = $this->parseKey($key).'=:'.$name; - $this->bindParam($name,$val); + protected function parseSet($data) + { + foreach ($data as $key => $val) { + if (is_array($val) && 'exp' == $val[0]) { + $set[] = $this->parseKey($key) . '=' . $val[1]; + } elseif (is_null($val)) { + $set[] = $this->parseKey($key) . '=NULL'; + } elseif (is_scalar($val)) { +// 过滤非标量数据 + if (0 === strpos($val, ':') && in_array($val, array_keys($this->bind))) { + $set[] = $this->parseKey($key) . '=' . $this->escapeString($val); + } else { + $name = count($this->bind); + $set[] = $this->parseKey($key) . '=:' . $name; + $this->bindParam($name, $val); } } } - return ' SET '.implode(',',$set); + return ' SET ' . implode(',', $set); } /** @@ -394,8 +431,9 @@ protected function parseSet($data) { * @param mixed $value 绑定值 * @return void */ - protected function bindParam($name,$value){ - $this->bind[':'.$name] = $value; + protected function bindParam($name, $value) + { + $this->bind[':' . $name] = $value; } /** @@ -404,27 +442,29 @@ protected function bindParam($name,$value){ * @param string $key * @return string */ - protected function parseKey(&$key) { + protected function parseKey(&$key) + { return $key; } - + /** * value分析 * @access protected * @param mixed $value * @return string */ - protected function parseValue($value) { - if(is_string($value)) { - $value = strpos($value,':') === 0 && in_array($value,array_keys($this->bind))? $this->escapeString($value) : '\''.$this->escapeString($value).'\''; - }elseif(isset($value[0]) && is_string($value[0]) && strtolower($value[0]) == 'exp'){ - $value = $this->escapeString($value[1]); - }elseif(is_array($value)) { - $value = array_map(array($this, 'parseValue'),$value); - }elseif(is_bool($value)){ - $value = $value ? '1' : '0'; - }elseif(is_null($value)){ - $value = 'null'; + protected function parseValue($value) + { + if (is_string($value)) { + $value = strpos($value, ':') === 0 && in_array($value, array_keys($this->bind)) ? $this->escapeString($value) : '\'' . $this->escapeString($value) . '\''; + } elseif (isset($value[0]) && is_string($value[0]) && strtolower($value[0]) == 'exp') { + $value = $this->escapeString($value[1]); + } elseif (is_array($value)) { + $value = array_map(array($this, 'parseValue'), $value); + } elseif (is_bool($value)) { + $value = $value ? '1' : '0'; + } elseif (is_null($value)) { + $value = 'null'; } return $value; } @@ -435,22 +475,25 @@ protected function parseValue($value) { * @param mixed $fields * @return string */ - protected function parseField($fields) { - if(is_string($fields) && '' !== $fields) { - $fields = explode(',',$fields); + protected function parseField($fields) + { + if (is_string($fields) && '' !== $fields) { + $fields = explode(',', $fields); } - if(is_array($fields)) { + if (is_array($fields)) { // 完善数组方式传字段名的支持 // 支持 'field1'=>'field2' 这样的字段别名定义 - $array = array(); - foreach ($fields as $key=>$field){ - if(!is_numeric($key)) - $array[] = $this->parseKey($key).' AS '.$this->parseKey($field); - else - $array[] = $this->parseKey($field); + $array = array(); + foreach ($fields as $key => $field) { + if (!is_numeric($key)) { + $array[] = $this->parseKey($key) . ' AS ' . $this->parseKey($field); + } else { + $array[] = $this->parseKey($field); + } + } $fieldsStr = implode(',', $array); - }else{ + } else { $fieldsStr = '*'; } //TODO 如果是查询全部字段,并且是join的方式,那么就把要查的表加个别名,以免字段被覆盖 @@ -463,21 +506,25 @@ protected function parseField($fields) { * @param mixed $table * @return string */ - protected function parseTable($tables) { - if(is_array($tables)) {// 支持别名定义 - $array = array(); - foreach ($tables as $table=>$alias){ - if(!is_numeric($table)) - $array[] = $this->parseKey($table).' '.$this->parseKey($alias); - else - $array[] = $this->parseKey($alias); + protected function parseTable($tables) + { + if (is_array($tables)) { +// 支持别名定义 + $array = array(); + foreach ($tables as $table => $alias) { + if (!is_numeric($table)) { + $array[] = $this->parseKey($table) . ' ' . $this->parseKey($alias); + } else { + $array[] = $this->parseKey($alias); + } + } - $tables = $array; - }elseif(is_string($tables)){ - $tables = explode(',',$tables); + $tables = $array; + } elseif (is_string($tables)) { + $tables = explode(',', $tables); array_walk($tables, array(&$this, 'parseKey')); } - return implode(',',$tables); + return implode(',', $tables); } /** @@ -486,129 +533,139 @@ protected function parseTable($tables) { * @param mixed $where * @return string */ - protected function parseWhere($where) { + protected function parseWhere($where) + { $whereStr = ''; - if(is_string($where)) { + if (is_string($where)) { // 直接使用字符串条件 $whereStr = $where; - }else{ // 使用数组表达式 - $operate = isset($where['_logic'])?strtoupper($where['_logic']):''; - if(in_array($operate,array('AND','OR','XOR'))){ + } else { + // 使用数组表达式 + $operate = isset($where['_logic']) ? strtoupper($where['_logic']) : ''; + if (in_array($operate, array('AND', 'OR', 'XOR'))) { // 定义逻辑运算规则 例如 OR XOR AND NOT - $operate = ' '.$operate.' '; + $operate = ' ' . $operate . ' '; unset($where['_logic']); - }else{ + } else { // 默认进行 AND 运算 - $operate = ' AND '; + $operate = ' AND '; } - foreach ($where as $key=>$val){ - if(is_numeric($key)){ - $key = '_complex'; + foreach ($where as $key => $val) { + if (is_numeric($key)) { + $key = '_complex'; } - if(0===strpos($key,'_')) { + if (0 === strpos($key, '_')) { // 解析特殊条件表达式 - $whereStr .= $this->parseThinkWhere($key,$val); - }else{ + $whereStr .= $this->parseThinkWhere($key, $val); + } else { // 查询字段的安全过滤 // if(!preg_match('/^[A-Z_\|\&\-.a-z0-9\(\)\,]+$/',trim($key))){ // E(L('_EXPRESS_ERROR_').':'.$key); // } // 多条件支持 - $multi = is_array($val) && isset($val['_multi']); - $key = trim($key); - if(strpos($key,'|')) { // 支持 name|title|nickname 方式定义查询字段 - $array = explode('|',$key); - $str = array(); - foreach ($array as $m=>$k){ - $v = $multi?$val[$m]:$val; - $str[] = $this->parseWhereItem($this->parseKey($k),$v); + $multi = is_array($val) && isset($val['_multi']); + $key = trim($key); + if (strpos($key, '|')) { + // 支持 name|title|nickname 方式定义查询字段 + $array = explode('|', $key); + $str = array(); + foreach ($array as $m => $k) { + $v = $multi ? $val[$m] : $val; + $str[] = $this->parseWhereItem($this->parseKey($k), $v); } - $whereStr .= '( '.implode(' OR ',$str).' )'; - }elseif(strpos($key,'&')){ - $array = explode('&',$key); - $str = array(); - foreach ($array as $m=>$k){ - $v = $multi?$val[$m]:$val; - $str[] = '('.$this->parseWhereItem($this->parseKey($k),$v).')'; + $whereStr .= '( ' . implode(' OR ', $str) . ' )'; + } elseif (strpos($key, '&')) { + $array = explode('&', $key); + $str = array(); + foreach ($array as $m => $k) { + $v = $multi ? $val[$m] : $val; + $str[] = '(' . $this->parseWhereItem($this->parseKey($k), $v) . ')'; } - $whereStr .= '( '.implode(' AND ',$str).' )'; - }else{ - $whereStr .= $this->parseWhereItem($this->parseKey($key),$val); + $whereStr .= '( ' . implode(' AND ', $str) . ' )'; + } else { + $whereStr .= $this->parseWhereItem($this->parseKey($key), $val); } } $whereStr .= $operate; } - $whereStr = substr($whereStr,0,-strlen($operate)); + $whereStr = substr($whereStr, 0, -strlen($operate)); } - return empty($whereStr)?'':' WHERE '.$whereStr; + return empty($whereStr) ? '' : ' WHERE ' . $whereStr; } // where子单元分析 - protected function parseWhereItem($key,$val) { + protected function parseWhereItem($key, $val) + { $whereStr = ''; - if(is_array($val)) { - if(is_string($val[0])) { - $exp = strtolower($val[0]); - if(preg_match('/^(eq|neq|gt|egt|lt|elt)$/',$exp)) { // 比较运算 - $whereStr .= $key.' '.$this->exp[$exp].' '.$this->parseValue($val[1]); - }elseif(preg_match('/^(notlike|like)$/',$exp)){// 模糊查找 - if(is_array($val[1])) { - $likeLogic = isset($val[2])?strtoupper($val[2]):'OR'; - if(in_array($likeLogic,array('AND','OR','XOR'))){ - $like = array(); - foreach ($val[1] as $item){ - $like[] = $key.' '.$this->exp[$exp].' '.$this->parseValue($item); + if (is_array($val)) { + if (is_string($val[0])) { + $exp = strtolower($val[0]); + if (preg_match('/^(eq|neq|gt|egt|lt|elt)$/', $exp)) { + // 比较运算 + $whereStr .= $key . ' ' . $this->exp[$exp] . ' ' . $this->parseValue($val[1]); + } elseif (preg_match('/^(notlike|like)$/', $exp)) { +// 模糊查找 + if (is_array($val[1])) { + $likeLogic = isset($val[2]) ? strtoupper($val[2]) : 'OR'; + if (in_array($likeLogic, array('AND', 'OR', 'XOR'))) { + $like = array(); + foreach ($val[1] as $item) { + $like[] = $key . ' ' . $this->exp[$exp] . ' ' . $this->parseValue($item); } - $whereStr .= '('.implode(' '.$likeLogic.' ',$like).')'; + $whereStr .= '(' . implode(' ' . $likeLogic . ' ', $like) . ')'; } - }else{ - $whereStr .= $key.' '.$this->exp[$exp].' '.$this->parseValue($val[1]); + } else { + $whereStr .= $key . ' ' . $this->exp[$exp] . ' ' . $this->parseValue($val[1]); } - }elseif('bind' == $exp ){ // 使用表达式 - $whereStr .= $key.' = :'.$val[1]; - }elseif('exp' == $exp ){ // 使用表达式 - $whereStr .= $key.' '.$val[1]; - }elseif(preg_match('/^(notin|not in|in)$/',$exp)){ // IN 运算 - if(isset($val[2]) && 'exp'==$val[2]) { - $whereStr .= $key.' '.$this->exp[$exp].' '.$val[1]; - }else{ - if(is_string($val[1])) { - $val[1] = explode(',',$val[1]); + } elseif ('bind' == $exp) { + // 使用表达式 + $whereStr .= $key . ' = :' . $val[1]; + } elseif ('exp' == $exp) { + // 使用表达式 + $whereStr .= $key . ' ' . $val[1]; + } elseif (preg_match('/^(notin|not in|in)$/', $exp)) { + // IN 运算 + if (isset($val[2]) && 'exp' == $val[2]) { + $whereStr .= $key . ' ' . $this->exp[$exp] . ' ' . $val[1]; + } else { + if (is_string($val[1])) { + $val[1] = explode(',', $val[1]); } - $zone = implode(',',$this->parseValue($val[1])); - $whereStr .= $key.' '.$this->exp[$exp].' ('.$zone.')'; + $zone = implode(',', $this->parseValue($val[1])); + $whereStr .= $key . ' ' . $this->exp[$exp] . ' (' . $zone . ')'; } - }elseif(preg_match('/^(notbetween|not between|between)$/',$exp)){ // BETWEEN运算 - $data = is_string($val[1])? explode(',',$val[1]):$val[1]; - $whereStr .= $key.' '.$this->exp[$exp].' '.$this->parseValue($data[0]).' AND '.$this->parseValue($data[1]); - }else{ - E(L('_EXPRESS_ERROR_').':'.$val[0]); + } elseif (preg_match('/^(notbetween|not between|between)$/', $exp)) { + // BETWEEN运算 + $data = is_string($val[1]) ? explode(',', $val[1]) : $val[1]; + $whereStr .= $key . ' ' . $this->exp[$exp] . ' ' . $this->parseValue($data[0]) . ' AND ' . $this->parseValue($data[1]); + } else { + E(L('_EXPRESS_ERROR_') . ':' . $val[0]); } - }else { + } else { $count = count($val); - $rule = isset($val[$count-1]) ? (is_array($val[$count-1]) ? strtoupper($val[$count-1][0]) : strtoupper($val[$count-1]) ) : '' ; - if(in_array($rule,array('AND','OR','XOR'))) { - $count = $count -1; - }else{ - $rule = 'AND'; + $rule = isset($val[$count - 1]) ? (is_array($val[$count - 1]) ? strtoupper($val[$count - 1][0]) : strtoupper($val[$count - 1])) : ''; + if (in_array($rule, array('AND', 'OR', 'XOR'))) { + $count = $count - 1; + } else { + $rule = 'AND'; } - for($i=0;$i<$count;$i++) { - $data = is_array($val[$i])?$val[$i][1]:$val[$i]; - if('exp'==strtolower($val[$i][0])) { - $whereStr .= $key.' '.$data.' '.$rule.' '; - }else{ - $whereStr .= $this->parseWhereItem($key,$val[$i]).' '.$rule.' '; + for ($i = 0; $i < $count; $i++) { + $data = is_array($val[$i]) ? $val[$i][1] : $val[$i]; + if ('exp' == strtolower($val[$i][0])) { + $whereStr .= $key . ' ' . $data . ' ' . $rule . ' '; + } else { + $whereStr .= $this->parseWhereItem($key, $val[$i]) . ' ' . $rule . ' '; } } - $whereStr = '( '.substr($whereStr,0,-4).' )'; + $whereStr = '( ' . substr($whereStr, 0, -4) . ' )'; } - }else { + } else { //对字符串类型字段采用模糊匹配 - $likeFields = $this->config['db_like_fields']; - if($likeFields && preg_match('/^('.$likeFields.')$/i',$key)) { - $whereStr .= $key.' LIKE '.$this->parseValue('%'.$val.'%'); - }else { - $whereStr .= $key.' = '.$this->parseValue($val); + $likeFields = $this->config['db_like_fields']; + if ($likeFields && preg_match('/^(' . $likeFields . ')$/i', $key)) { + $whereStr .= $key . ' LIKE ' . $this->parseValue('%' . $val . '%'); + } else { + $whereStr .= $key . ' = ' . $this->parseValue($val); } } return $whereStr; @@ -621,33 +678,36 @@ protected function parseWhereItem($key,$val) { * @param mixed $val * @return string */ - protected function parseThinkWhere($key,$val) { - $whereStr = ''; - switch($key) { + protected function parseThinkWhere($key, $val) + { + $whereStr = ''; + switch ($key) { case '_string': // 字符串模式查询条件 $whereStr = $val; break; case '_complex': // 复合查询条件 - $whereStr = substr($this->parseWhere($val),6); + $whereStr = substr($this->parseWhere($val), 6); break; case '_query': // 字符串模式查询条件 - parse_str($val,$where); - if(isset($where['_logic'])) { - $op = ' '.strtoupper($where['_logic']).' '; + parse_str($val, $where); + if (isset($where['_logic'])) { + $op = ' ' . strtoupper($where['_logic']) . ' '; unset($where['_logic']); - }else{ - $op = ' AND '; + } else { + $op = ' AND '; + } + $array = array(); + foreach ($where as $field => $data) { + $array[] = $this->parseKey($field) . ' = ' . $this->parseValue($data); } - $array = array(); - foreach ($where as $field=>$data) - $array[] = $this->parseKey($field).' = '.$this->parseValue($data); - $whereStr = implode($op,$array); + + $whereStr = implode($op, $array); break; } - return '( '.$whereStr.' )'; + return '( ' . $whereStr . ' )'; } /** @@ -656,8 +716,9 @@ protected function parseThinkWhere($key,$val) { * @param mixed $lmit * @return string */ - protected function parseLimit($limit) { - return !empty($limit)? ' LIMIT '.$limit.' ':''; + protected function parseLimit($limit) + { + return !empty($limit) ? ' LIMIT ' . $limit . ' ' : ''; } /** @@ -666,10 +727,11 @@ protected function parseLimit($limit) { * @param mixed $join * @return string */ - protected function parseJoin($join) { + protected function parseJoin($join) + { $joinStr = ''; - if(!empty($join)) { - $joinStr = ' '.implode(' ',$join).' '; + if (!empty($join)) { + $joinStr = ' ' . implode(' ', $join) . ' '; } return $joinStr; } @@ -680,19 +742,20 @@ protected function parseJoin($join) { * @param mixed $order * @return string */ - protected function parseOrder($order) { - if(is_array($order)) { - $array = array(); - foreach ($order as $key=>$val){ - if(is_numeric($key)) { - $array[] = $this->parseKey($val); - }else{ - $array[] = $this->parseKey($key).' '.$val; + protected function parseOrder($order) + { + if (is_array($order)) { + $array = array(); + foreach ($order as $key => $val) { + if (is_numeric($key)) { + $array[] = $this->parseKey($val); + } else { + $array[] = $this->parseKey($key) . ' ' . $val; } } - $order = implode(',',$array); + $order = implode(',', $array); } - return !empty($order)? ' ORDER BY '.$order:''; + return !empty($order) ? ' ORDER BY ' . $order : ''; } /** @@ -701,8 +764,9 @@ protected function parseOrder($order) { * @param mixed $group * @return string */ - protected function parseGroup($group) { - return !empty($group)? ' GROUP BY '.$group:''; + protected function parseGroup($group) + { + return !empty($group) ? ' GROUP BY ' . $group : ''; } /** @@ -711,8 +775,9 @@ protected function parseGroup($group) { * @param string $having * @return string */ - protected function parseHaving($having) { - return !empty($having)? ' HAVING '.$having:''; + protected function parseHaving($having) + { + return !empty($having) ? ' HAVING ' . $having : ''; } /** @@ -721,8 +786,9 @@ protected function parseHaving($having) { * @param string $comment * @return string */ - protected function parseComment($comment) { - return !empty($comment)? ' /* '.$comment.' */':''; + protected function parseComment($comment) + { + return !empty($comment) ? ' /* ' . $comment . ' */' : ''; } /** @@ -731,8 +797,9 @@ protected function parseComment($comment) { * @param mixed $distinct * @return string */ - protected function parseDistinct($distinct) { - return !empty($distinct)? ' DISTINCT ' :''; + protected function parseDistinct($distinct) + { + return !empty($distinct) ? ' DISTINCT ' : ''; } /** @@ -741,18 +808,22 @@ protected function parseDistinct($distinct) { * @param mixed $union * @return string */ - protected function parseUnion($union) { - if(empty($union)) return ''; - if(isset($union['_all'])) { - $str = 'UNION ALL '; + protected function parseUnion($union) + { + if (empty($union)) { + return ''; + } + + if (isset($union['_all'])) { + $str = 'UNION ALL '; unset($union['_all']); - }else{ - $str = 'UNION '; + } else { + $str = 'UNION '; } - foreach ($union as $u){ - $sql[] = $str.(is_array($u)?$this->buildSelectSql($u):$u); + foreach ($union as $u) { + $sql[] = $str . (is_array($u) ? $this->buildSelectSql($u) : $u); } - return implode(' ',$sql); + return implode(' ', $sql); } /** @@ -761,8 +832,9 @@ protected function parseUnion($union) { * @param array $bind * @return array */ - protected function parseBind($bind){ - $this->bind = array_merge($this->bind,$bind); + protected function parseBind($bind) + { + $this->bind = array_merge($this->bind, $bind); } /** @@ -771,19 +843,27 @@ protected function parseBind($bind){ * @param mixed $index * @return string */ - protected function parseForce($index) { - if(empty($index)) return ''; - if(is_array($index)) $index = join(",", $index); + protected function parseForce($index) + { + if (empty($index)) { + return ''; + } + + if (is_array($index)) { + $index = join(",", $index); + } + return sprintf(" FORCE INDEX ( %s ) ", $index); } /** * ON DUPLICATE KEY UPDATE 分析 * @access protected - * @param mixed $duplicate + * @param mixed $duplicate * @return string */ - protected function parseDuplicate($duplicate){ + protected function parseDuplicate($duplicate) + { return ''; } @@ -795,36 +875,37 @@ protected function parseDuplicate($duplicate){ * @param boolean $replace 是否replace * @return false | integer */ - public function insert($data,$options=array(),$replace=false) { - $values = $fields = array(); - $this->model = $options['model']; - $this->parseBind(!empty($options['bind'])?$options['bind']:array()); - foreach ($data as $key=>$val){ - if(is_array($val) && 'exp' == $val[0]){ - $fields[] = $this->parseKey($key); - $values[] = $val[1]; - }elseif(is_null($val)){ - $fields[] = $this->parseKey($key); - $values[] = 'NULL'; - }elseif(is_scalar($val)) { // 过滤非标量数据 - $fields[] = $this->parseKey($key); - if(0===strpos($val,':') && in_array($val,array_keys($this->bind))){ - $values[] = $this->parseValue($val); - }else{ - $name = count($this->bind); - $values[] = ':'.$name; - $this->bindParam($name,$val); + public function insert($data, $options = array(), $replace = false) + { + $values = $fields = array(); + $this->model = $options['model']; + $this->parseBind(!empty($options['bind']) ? $options['bind'] : array()); + foreach ($data as $key => $val) { + if (is_array($val) && 'exp' == $val[0]) { + $fields[] = $this->parseKey($key); + $values[] = $val[1]; + } elseif (is_null($val)) { + $fields[] = $this->parseKey($key); + $values[] = 'NULL'; + } elseif (is_scalar($val)) { + // 过滤非标量数据 + $fields[] = $this->parseKey($key); + if (0 === strpos($val, ':') && in_array($val, array_keys($this->bind))) { + $values[] = $this->parseValue($val); + } else { + $name = count($this->bind); + $values[] = ':' . $name; + $this->bindParam($name, $val); } } } // 兼容数字传入方式 - $replace= (is_numeric($replace) && $replace>0)?true:$replace; - $sql = (true===$replace?'REPLACE':'INSERT').' INTO '.$this->parseTable($options['table']).' ('.implode(',', $fields).') VALUES ('.implode(',', $values).')'.$this->parseDuplicate($replace); - $sql .= $this->parseComment(!empty($options['comment'])?$options['comment']:''); - return $this->execute($sql,!empty($options['fetch_sql']) ? true : false); + $replace = (is_numeric($replace) && $replace > 0) ? true : $replace; + $sql = (true === $replace ? 'REPLACE' : 'INSERT') . ' INTO ' . $this->parseTable($options['table']) . ' (' . implode(',', $fields) . ') VALUES (' . implode(',', $values) . ')' . $this->parseDuplicate($replace); + $sql .= $this->parseComment(!empty($options['comment']) ? $options['comment'] : ''); + return $this->execute($sql, !empty($options['fetch_sql']) ? true : false); } - /** * 批量插入记录 * @access public @@ -833,34 +914,38 @@ public function insert($data,$options=array(),$replace=false) { * @param boolean $replace 是否replace * @return false | integer */ - public function insertAll($dataSet,$options=array(),$replace=false) { - $values = array(); - $this->model = $options['model']; - if(!is_array($dataSet[0])) return false; - $this->parseBind(!empty($options['bind'])?$options['bind']:array()); - $fields = array_map(array($this,'parseKey'),array_keys($dataSet[0])); - foreach ($dataSet as $data){ - $value = array(); - foreach ($data as $key=>$val){ - if(is_array($val) && 'exp' == $val[0]){ - $value[] = $val[1]; - }elseif(is_null($val)){ - $value[] = 'NULL'; - }elseif(is_scalar($val)){ - if(0===strpos($val,':') && in_array($val,array_keys($this->bind))){ - $value[] = $this->parseValue($val); - }else{ - $name = count($this->bind); - $value[] = ':'.$name; - $this->bindParam($name,$val); + public function insertAll($dataSet, $options = array(), $replace = false) + { + $values = array(); + $this->model = $options['model']; + if (!is_array($dataSet[0])) { + return false; + } + + $this->parseBind(!empty($options['bind']) ? $options['bind'] : array()); + $fields = array_map(array($this, 'parseKey'), array_keys($dataSet[0])); + foreach ($dataSet as $data) { + $value = array(); + foreach ($data as $key => $val) { + if (is_array($val) && 'exp' == $val[0]) { + $value[] = $val[1]; + } elseif (is_null($val)) { + $value[] = 'NULL'; + } elseif (is_scalar($val)) { + if (0 === strpos($val, ':') && in_array($val, array_keys($this->bind))) { + $value[] = $this->parseValue($val); + } else { + $name = count($this->bind); + $value[] = ':' . $name; + $this->bindParam($name, $val); } } } - $values[] = 'SELECT '.implode(',', $value); + $values[] = 'SELECT ' . implode(',', $value); } - $sql = 'INSERT INTO '.$this->parseTable($options['table']).' ('.implode(',', $fields).') '.implode(' UNION ALL ',$values); - $sql .= $this->parseComment(!empty($options['comment'])?$options['comment']:''); - return $this->execute($sql,!empty($options['fetch_sql']) ? true : false); + $sql = 'INSERT INTO ' . $this->parseTable($options['table']) . ' (' . implode(',', $fields) . ') ' . implode(' UNION ALL ', $values); + $sql .= $this->parseComment(!empty($options['comment']) ? $options['comment'] : ''); + return $this->execute($sql, !empty($options['fetch_sql']) ? true : false); } /** @@ -871,14 +956,18 @@ public function insertAll($dataSet,$options=array(),$replace=false) { * @param array $option 查询数据参数 * @return false | integer */ - public function selectInsert($fields,$table,$options=array()) { - $this->model = $options['model']; - $this->parseBind(!empty($options['bind'])?$options['bind']:array()); - if(is_string($fields)) $fields = explode(',',$fields); + public function selectInsert($fields, $table, $options = array()) + { + $this->model = $options['model']; + $this->parseBind(!empty($options['bind']) ? $options['bind'] : array()); + if (is_string($fields)) { + $fields = explode(',', $fields); + } + array_walk($fields, array($this, 'parseKey')); - $sql = 'INSERT INTO '.$this->parseTable($table).' ('.implode(',', $fields).') '; - $sql .= $this->buildSelectSql($options); - return $this->execute($sql,!empty($options['fetch_sql']) ? true : false); + $sql = 'INSERT INTO ' . $this->parseTable($table) . ' (' . implode(',', $fields) . ') '; + $sql .= $this->buildSelectSql($options); + return $this->execute($sql, !empty($options['fetch_sql']) ? true : false); } /** @@ -888,22 +977,24 @@ public function selectInsert($fields,$table,$options=array()) { * @param array $options 表达式 * @return false | integer */ - public function update($data,$options) { - $this->model = $options['model']; - $this->parseBind(!empty($options['bind'])?$options['bind']:array()); - $table = $this->parseTable($options['table']); + public function update($data, $options) + { + $this->model = $options['model']; + $this->parseBind(!empty($options['bind']) ? $options['bind'] : array()); + $table = $this->parseTable($options['table']); $sql = 'UPDATE ' . $table . $this->parseSet($data); - if(strpos($table,',')){// 多表更新支持JOIN操作 - $sql .= $this->parseJoin(!empty($options['join'])?$options['join']:''); + if (strpos($table, ',')) { +// 多表更新支持JOIN操作 + $sql .= $this->parseJoin(!empty($options['join']) ? $options['join'] : ''); } - $sql .= $this->parseWhere(!empty($options['where'])?$options['where']:''); - if(!strpos($table,',')){ + $sql .= $this->parseWhere(!empty($options['where']) ? $options['where'] : ''); + if (!strpos($table, ',')) { // 单表更新支持order和lmit - $sql .= $this->parseOrder(!empty($options['order'])?$options['order']:'') - .$this->parseLimit(!empty($options['limit'])?$options['limit']:''); + $sql .= $this->parseOrder(!empty($options['order']) ? $options['order'] : '') + . $this->parseLimit(!empty($options['limit']) ? $options['limit'] : ''); } - $sql .= $this->parseComment(!empty($options['comment'])?$options['comment']:''); - return $this->execute($sql,!empty($options['fetch_sql']) ? true : false); + $sql .= $this->parseComment(!empty($options['comment']) ? $options['comment'] : ''); + return $this->execute($sql, !empty($options['fetch_sql']) ? true : false); } /** @@ -912,25 +1003,27 @@ public function update($data,$options) { * @param array $options 表达式 * @return false | integer */ - public function delete($options=array()) { - $this->model = $options['model']; - $this->parseBind(!empty($options['bind'])?$options['bind']:array()); - $table = $this->parseTable($options['table']); - $sql = 'DELETE FROM '.$table; - if(strpos($table,',')){// 多表删除支持USING和JOIN操作 - if(!empty($options['using'])){ - $sql .= ' USING '.$this->parseTable($options['using']).' '; + public function delete($options = array()) + { + $this->model = $options['model']; + $this->parseBind(!empty($options['bind']) ? $options['bind'] : array()); + $table = $this->parseTable($options['table']); + $sql = 'DELETE FROM ' . $table; + if (strpos($table, ',')) { +// 多表删除支持USING和JOIN操作 + if (!empty($options['using'])) { + $sql .= ' USING ' . $this->parseTable($options['using']) . ' '; } - $sql .= $this->parseJoin(!empty($options['join'])?$options['join']:''); + $sql .= $this->parseJoin(!empty($options['join']) ? $options['join'] : ''); } - $sql .= $this->parseWhere(!empty($options['where'])?$options['where']:''); - if(!strpos($table,',')){ + $sql .= $this->parseWhere(!empty($options['where']) ? $options['where'] : ''); + if (!strpos($table, ',')) { // 单表删除支持order和limit - $sql .= $this->parseOrder(!empty($options['order'])?$options['order']:'') - .$this->parseLimit(!empty($options['limit'])?$options['limit']:''); + $sql .= $this->parseOrder(!empty($options['order']) ? $options['order'] : '') + . $this->parseLimit(!empty($options['limit']) ? $options['limit'] : ''); } - $sql .= $this->parseComment(!empty($options['comment'])?$options['comment']:''); - return $this->execute($sql,!empty($options['fetch_sql']) ? true : false); + $sql .= $this->parseComment(!empty($options['comment']) ? $options['comment'] : ''); + return $this->execute($sql, !empty($options['fetch_sql']) ? true : false); } /** @@ -939,11 +1032,12 @@ public function delete($options=array()) { * @param array $options 表达式 * @return mixed */ - public function select($options=array()) { - $this->model = $options['model']; - $this->parseBind(!empty($options['bind'])?$options['bind']:array()); + public function select($options = array()) + { + $this->model = $options['model']; + $this->parseBind(!empty($options['bind']) ? $options['bind'] : array()); $sql = $this->buildSelectSql($options); - $result = $this->query($sql,!empty($options['fetch_sql']) ? true : false); + $result = $this->query($sql, !empty($options['fetch_sql']) ? true : false); return $result; } @@ -953,16 +1047,17 @@ public function select($options=array()) { * @param array $options 表达式 * @return string */ - public function buildSelectSql($options=array()) { - if(isset($options['page'])) { + public function buildSelectSql($options = array()) + { + if (isset($options['page'])) { // 根据页数计算limit - list($page,$listRows) = $options['page']; - $page = $page>0 ? $page : 1; - $listRows= $listRows>0 ? $listRows : (is_numeric($options['limit'])?$options['limit']:20); - $offset = $listRows*($page-1); - $options['limit'] = $offset.','.$listRows; + list($page, $listRows) = $options['page']; + $page = $page > 0 ? $page : 1; + $listRows = $listRows > 0 ? $listRows : (is_numeric($options['limit']) ? $options['limit'] : 20); + $offset = $listRows * ($page - 1); + $options['limit'] = $offset . ',' . $listRows; } - $sql = $this->parseSql($this->selectSql,$options); + $sql = $this->parseSql($this->selectSql, $options); return $sql; } @@ -972,35 +1067,37 @@ public function buildSelectSql($options=array()) { * @param array $options 表达式 * @return string */ - public function parseSql($sql,$options=array()){ - $sql = str_replace( - array('%TABLE%','%DISTINCT%','%FIELD%','%JOIN%','%WHERE%','%GROUP%','%HAVING%','%ORDER%','%LIMIT%','%UNION%','%LOCK%','%COMMENT%','%FORCE%'), + public function parseSql($sql, $options = array()) + { + $sql = str_replace( + array('%TABLE%', '%DISTINCT%', '%FIELD%', '%JOIN%', '%WHERE%', '%GROUP%', '%HAVING%', '%ORDER%', '%LIMIT%', '%UNION%', '%LOCK%', '%COMMENT%', '%FORCE%'), array( $this->parseTable($options['table']), - $this->parseDistinct(isset($options['distinct'])?$options['distinct']:false), - $this->parseField(!empty($options['field'])?$options['field']:'*'), - $this->parseJoin(!empty($options['join'])?$options['join']:''), - $this->parseWhere(!empty($options['where'])?$options['where']:''), - $this->parseGroup(!empty($options['group'])?$options['group']:''), - $this->parseHaving(!empty($options['having'])?$options['having']:''), - $this->parseOrder(!empty($options['order'])?$options['order']:''), - $this->parseLimit(!empty($options['limit'])?$options['limit']:''), - $this->parseUnion(!empty($options['union'])?$options['union']:''), - $this->parseLock(isset($options['lock'])?$options['lock']:false), - $this->parseComment(!empty($options['comment'])?$options['comment']:''), - $this->parseForce(!empty($options['force'])?$options['force']:'') - ),$sql); + $this->parseDistinct(isset($options['distinct']) ? $options['distinct'] : false), + $this->parseField(!empty($options['field']) ? $options['field'] : '*'), + $this->parseJoin(!empty($options['join']) ? $options['join'] : ''), + $this->parseWhere(!empty($options['where']) ? $options['where'] : ''), + $this->parseGroup(!empty($options['group']) ? $options['group'] : ''), + $this->parseHaving(!empty($options['having']) ? $options['having'] : ''), + $this->parseOrder(!empty($options['order']) ? $options['order'] : ''), + $this->parseLimit(!empty($options['limit']) ? $options['limit'] : ''), + $this->parseUnion(!empty($options['union']) ? $options['union'] : ''), + $this->parseLock(isset($options['lock']) ? $options['lock'] : false), + $this->parseComment(!empty($options['comment']) ? $options['comment'] : ''), + $this->parseForce(!empty($options['force']) ? $options['force'] : ''), + ), $sql); return $sql; } /** - * 获取最近一次查询的sql语句 + * 获取最近一次查询的sql语句 * @param string $model 模型名 * @access public * @return string */ - public function getLastSql($model='') { - return $model?$this->modelSql[$model]:$this->queryStr; + public function getLastSql($model = '') + { + return $model ? $this->modelSql[$model] : $this->queryStr; } /** @@ -1008,7 +1105,8 @@ public function getLastSql($model='') { * @access public * @return string */ - public function getLastInsID() { + public function getLastInsID() + { return $this->lastInsID; } @@ -1017,7 +1115,8 @@ public function getLastInsID() { * @access public * @return string */ - public function getError() { + public function getError() + { return $this->error; } @@ -1027,7 +1126,8 @@ public function getError() { * @param string $str SQL字符串 * @return string */ - public function escapeString($str) { + public function escapeString($str) + { return addslashes($str); } @@ -1037,8 +1137,9 @@ public function escapeString($str) { * @param string $model 模型名 * @return void */ - public function setModel($model){ - $this->model = $model; + public function setModel($model) + { + $this->model = $model; } /** @@ -1046,16 +1147,18 @@ public function setModel($model){ * @access protected * @param boolean $start 调试开始标记 true 开始 false 结束 */ - protected function debug($start) { - if($this->config['debug']) {// 开启数据库调试模式 - if($start) { + protected function debug($start) + { + if ($this->config['debug']) { +// 开启数据库调试模式 + if ($start) { G('queryStartTime'); - }else{ - $this->modelSql[$this->model] = $this->queryStr; + } else { + $this->modelSql[$this->model] = $this->queryStr; //$this->model = '_think_'; // 记录操作结束时间 G('queryEndTime'); - trace($this->queryStr.' [ RunTime:'.G('queryStartTime','queryEndTime').'s ]','','SQL'); + trace($this->queryStr . ' [ RunTime:' . G('queryStartTime', 'queryEndTime') . 's ]', '', 'SQL'); } } } @@ -1066,13 +1169,18 @@ protected function debug($start) { * @param boolean $master 主服务器 * @return void */ - protected function initConnect($master=true) { - if(!empty($this->config['deploy'])) - // 采用分布式数据库 + protected function initConnect($master = true) + { + if (!empty($this->config['deploy'])) + // 采用分布式数据库 + { $this->_linkID = $this->multiConnect($master); - else - // 默认单数据库 - if ( !$this->_linkID ) $this->_linkID = $this->connect(); + } else + // 默认单数据库 + if (!$this->_linkID) { + $this->_linkID = $this->connect(); + } + } /** @@ -1081,66 +1189,70 @@ protected function initConnect($master=true) { * @param boolean $master 主服务器 * @return void */ - protected function multiConnect($master=false) { + protected function multiConnect($master = false) + { // 分布式数据库配置解析 - $_config['username'] = explode(',',$this->config['username']); - $_config['password'] = explode(',',$this->config['password']); - $_config['hostname'] = explode(',',$this->config['hostname']); - $_config['hostport'] = explode(',',$this->config['hostport']); - $_config['database'] = explode(',',$this->config['database']); - $_config['dsn'] = explode(',',$this->config['dsn']); - $_config['charset'] = explode(',',$this->config['charset']); - - $m = floor(mt_rand(0,$this->config['master_num']-1)); + $_config['username'] = explode(',', $this->config['username']); + $_config['password'] = explode(',', $this->config['password']); + $_config['hostname'] = explode(',', $this->config['hostname']); + $_config['hostport'] = explode(',', $this->config['hostport']); + $_config['database'] = explode(',', $this->config['database']); + $_config['dsn'] = explode(',', $this->config['dsn']); + $_config['charset'] = explode(',', $this->config['charset']); + + $m = floor(mt_rand(0, $this->config['master_num'] - 1)); // 数据库读写是否分离 - if($this->config['rw_separate']){ + if ($this->config['rw_separate']) { // 主从式采用读写分离 - if($master) - // 主服务器写入 - $r = $m; - else{ - if(is_numeric($this->config['slave_no'])) {// 指定服务器读 + if ($master) + // 主服务器写入 + { + $r = $m; + } else { + if (is_numeric($this->config['slave_no'])) { +// 指定服务器读 $r = $this->config['slave_no']; - }else{ + } else { // 读操作连接从服务器 - $r = floor(mt_rand($this->config['master_num'],count($_config['hostname'])-1)); // 每次随机连接的数据库 + $r = floor(mt_rand($this->config['master_num'], count($_config['hostname']) - 1)); // 每次随机连接的数据库 } } - }else{ + } else { // 读写操作不区分服务器 - $r = floor(mt_rand(0,count($_config['hostname'])-1)); // 每次随机连接的数据库 + $r = floor(mt_rand(0, count($_config['hostname']) - 1)); // 每次随机连接的数据库 } - - if($m != $r ){ - $db_master = array( - 'username' => isset($_config['username'][$m])?$_config['username'][$m]:$_config['username'][0], - 'password' => isset($_config['password'][$m])?$_config['password'][$m]:$_config['password'][0], - 'hostname' => isset($_config['hostname'][$m])?$_config['hostname'][$m]:$_config['hostname'][0], - 'hostport' => isset($_config['hostport'][$m])?$_config['hostport'][$m]:$_config['hostport'][0], - 'database' => isset($_config['database'][$m])?$_config['database'][$m]:$_config['database'][0], - 'dsn' => isset($_config['dsn'][$m])?$_config['dsn'][$m]:$_config['dsn'][0], - 'charset' => isset($_config['charset'][$m])?$_config['charset'][$m]:$_config['charset'][0], + + if ($m != $r) { + $db_master = array( + 'username' => isset($_config['username'][$m]) ? $_config['username'][$m] : $_config['username'][0], + 'password' => isset($_config['password'][$m]) ? $_config['password'][$m] : $_config['password'][0], + 'hostname' => isset($_config['hostname'][$m]) ? $_config['hostname'][$m] : $_config['hostname'][0], + 'hostport' => isset($_config['hostport'][$m]) ? $_config['hostport'][$m] : $_config['hostport'][0], + 'database' => isset($_config['database'][$m]) ? $_config['database'][$m] : $_config['database'][0], + 'dsn' => isset($_config['dsn'][$m]) ? $_config['dsn'][$m] : $_config['dsn'][0], + 'charset' => isset($_config['charset'][$m]) ? $_config['charset'][$m] : $_config['charset'][0], ); } $db_config = array( - 'username' => isset($_config['username'][$r])?$_config['username'][$r]:$_config['username'][0], - 'password' => isset($_config['password'][$r])?$_config['password'][$r]:$_config['password'][0], - 'hostname' => isset($_config['hostname'][$r])?$_config['hostname'][$r]:$_config['hostname'][0], - 'hostport' => isset($_config['hostport'][$r])?$_config['hostport'][$r]:$_config['hostport'][0], - 'database' => isset($_config['database'][$r])?$_config['database'][$r]:$_config['database'][0], - 'dsn' => isset($_config['dsn'][$r])?$_config['dsn'][$r]:$_config['dsn'][0], - 'charset' => isset($_config['charset'][$r])?$_config['charset'][$r]:$_config['charset'][0], + 'username' => isset($_config['username'][$r]) ? $_config['username'][$r] : $_config['username'][0], + 'password' => isset($_config['password'][$r]) ? $_config['password'][$r] : $_config['password'][0], + 'hostname' => isset($_config['hostname'][$r]) ? $_config['hostname'][$r] : $_config['hostname'][0], + 'hostport' => isset($_config['hostport'][$r]) ? $_config['hostport'][$r] : $_config['hostport'][0], + 'database' => isset($_config['database'][$r]) ? $_config['database'][$r] : $_config['database'][0], + 'dsn' => isset($_config['dsn'][$r]) ? $_config['dsn'][$r] : $_config['dsn'][0], + 'charset' => isset($_config['charset'][$r]) ? $_config['charset'][$r] : $_config['charset'][0], ); - return $this->connect($db_config,$r,$r == $m ? false : $db_master); + return $this->connect($db_config, $r, $r == $m ? false : $db_master); } - /** + /** * 析构方法 * @access public */ - public function __destruct() { + public function __destruct() + { // 释放查询 - if ($this->PDOStatement){ + if ($this->PDOStatement) { $this->free(); } // 关闭连接 diff --git a/ThinkPHP/Library/Think/Db/Driver/Firebird.class.php b/ThinkPHP/Library/Think/Db/Driver/Firebird.class.php index 6cc281dd3..56a01f043 100644 --- a/ThinkPHP/Library/Think/Db/Driver/Firebird.class.php +++ b/ThinkPHP/Library/Think/Db/Driver/Firebird.class.php @@ -9,13 +9,15 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think\Db\Driver; + use Think\Db\Driver; /** - * Firebird数据库驱动 + * Firebird数据库驱动 */ -class Firebird extends Driver{ - protected $selectSql = 'SELECT %LIMIT% %DISTINCT% %FIELD% FROM %TABLE%%JOIN%%WHERE%%GROUP%%HAVING%%ORDER%'; +class Firebird extends Driver +{ + protected $selectSql = 'SELECT %LIMIT% %DISTINCT% %FIELD% FROM %TABLE%%JOIN%%WHERE%%GROUP%%HAVING%%ORDER%'; /** * 解析pdo连接的dsn信息 @@ -23,11 +25,12 @@ class Firebird extends Driver{ * @param array $config 连接信息 * @return string */ - protected function parseDsn($config){ - $dsn = 'firebird:dbname='.$config['hostname'].'/'.($config['hostport']?:3050).':'.$config['database']; - return $dsn; + protected function parseDsn($config) + { + $dsn = 'firebird:dbname=' . $config['hostname'] . '/' . ($config['hostport'] ?: 3050) . ':' . $config['database']; + return $dsn; } - + /** * 执行语句 * @access public @@ -35,38 +38,45 @@ protected function parseDsn($config){ * @param boolean $fetchSql 不执行只是获取SQL * @return mixed */ - public function execute($str,$fetchSql=false) { + public function execute($str, $fetchSql = false) + { $this->initConnect(true); - if ( !$this->_linkID ) return false; + 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 (!empty($this->bind)) { + $that = $this; + $this->queryStr = strtr($this->queryStr, array_map(function ($val) use ($that) {return '\'' . $that->escapeString($val) . '\'';}, $this->bind)); } - if($fetchSql){ + if ($fetchSql) { return $this->queryStr; } //释放前次的查询结果 - if ( !empty($this->PDOStatement) ) $this->free(); + if (!empty($this->PDOStatement)) { + $this->free(); + } + $this->executeTimes++; - N('db_write',1); // 兼容代码 + N('db_write', 1); // 兼容代码 // 记录开始执行时间 $this->debug(true); - $this->PDOStatement = $this->_linkID->prepare($str); - if(false === $this->PDOStatement) { + $this->PDOStatement = $this->_linkID->prepare($str); + if (false === $this->PDOStatement) { E($this->error()); } foreach ($this->bind as $key => $val) { - if(is_array($val)){ + if (is_array($val)) { $this->PDOStatement->bindValue($key, $val[0], $val[1]); - }else{ + } else { $this->PDOStatement->bindValue($key, $val); } } - $this->bind = array(); - $result = $this->PDOStatement->execute(); + $this->bind = array(); + $result = $this->PDOStatement->execute(); $this->debug(false); - if ( false === $result) { + if (false === $result) { $this->error(); return false; } else { @@ -74,23 +84,24 @@ public function execute($str,$fetchSql=false) { return $this->numRows; } } - + /** * 取得数据表的字段信息 * @access public */ - public function getFields($tableName) { + 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){ + $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 + 'notnull' => (bool) (1 == $val['null1']), // 1表示不为Null 'default' => $val['default1'], 'primary' => false, 'autoinc' => false, @@ -98,35 +109,37 @@ public function getFields($tableName) { } } //获取主键 - $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.'\')'; + $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; + 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(); + 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) { + public function escapeString($str) + { return str_replace("'", "''", $str); } @@ -136,14 +149,15 @@ public function escapeString($str) { * @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].' '; + 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; diff --git a/ThinkPHP/Library/Think/Db/Driver/Mongo.class.php b/ThinkPHP/Library/Think/Db/Driver/Mongo.class.php index a070b8ce7..36e0c64b3 100644 --- a/ThinkPHP/Library/Think/Db/Driver/Mongo.class.php +++ b/ThinkPHP/Library/Think/Db/Driver/Mongo.class.php @@ -10,34 +10,37 @@ // +---------------------------------------------------------------------- namespace Think\Db\Driver; + use Think\Db\Driver; /** * Mongo数据库驱动 */ -class Mongo extends Driver { +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'); + 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(); - } + 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(); + } } } @@ -45,13 +48,17 @@ public function __construct($config=''){ * 连接数据库方法 * @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){ + 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()); } } @@ -66,28 +73,33 @@ public function connect($config='',$linkNum=0) { * @param boolean $master 是否主服务器 * @return void */ - public function switchCollection($collection,$db='',$master=true){ + public function switchCollection($collection, $db = '', $master = true) + { // 当前没有连接 则首先进行数据库连接 - if ( !$this->_linkID ) $this->initConnect($master); - try{ - if(!empty($db)) { // 传人Db则切换数据库 + if (!$this->_linkID) { + $this->initConnect($master); + } + + try { + if (!empty($db)) { + // 传人Db则切换数据库 // 当前MongoDb对象 - $this->_dbName = $db; - $this->_mongo = $this->_linkID->selectDb($db); + $this->_dbName = $db; + $this->_mongo = $this->_linkID->selectDb($db); } // 当前MongoCollection对象 - if($this->config['debug']) { - $this->queryStr = $this->_dbName.'.getCollection('.$collection.')'; + if ($this->config['debug']) { + $this->queryStr = $this->_dbName . '.getCollection(' . $collection . ')'; } - if($this->_collectionName != $collection) { + if ($this->_collectionName != $collection) { $this->queryTimes++; - N('db_query',1); // 兼容代码 + N('db_query', 1); // 兼容代码 $this->debug(true); - $this->_collection = $this->_mongo->selectCollection($collection); + $this->_collection = $this->_mongo->selectCollection($collection); $this->debug(false); - $this->_collectionName = $collection; // 记录当前Collection名称 + $this->_collectionName = $collection; // 记录当前Collection名称 } - }catch (MongoException $e){ + } catch (MongoException $e) { E($e->getMessage()); } } @@ -96,7 +108,8 @@ public function switchCollection($collection,$db='',$master=true){ * 释放查询结果 * @access public */ - public function free() { + public function free() + { $this->_cursor = null; } @@ -106,29 +119,32 @@ public function free() { * @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) { + 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); // 兼容代码 + 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 .= ')'; + 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); + $result = $this->_mongo->command($command); $this->debug(false); - - if($cache && $result['ok']) { // 查询缓存写入 - S($key,$result,$cache['expire'],$cache['type']); + + if ($cache && $result['ok']) { + // 查询缓存写入 + S($key, $result, $cache['expire'], $cache['type']); } return $result; } catch (\MongoCursorException $e) { @@ -143,16 +159,17 @@ public function command($command=array(), $options=array()) { * @param array $args 参数 * @return mixed */ - public function execute($code,$args=array()) { + public function execute($code, $args = array()) + { $this->executeTimes++; - N('db_write',1); // 兼容代码 + N('db_write', 1); // 兼容代码 $this->debug(true); - $this->queryStr = 'execute:'.$code; - $result = $this->_mongo->execute($code,$args); + $this->queryStr = 'execute:' . $code; + $result = $this->_mongo->execute($code, $args); $this->debug(false); - if($result['ok']) { + if ($result['ok']) { return $result['retval']; - }else{ + } else { E($result['errmsg']); } } @@ -161,13 +178,14 @@ public function execute($code,$args=array()) { * 关闭数据库 * @access public */ - public function close() { - if($this->_linkID) { + public function close() + { + if ($this->_linkID) { $this->_linkID->close(); - $this->_linkID = null; - $this->_mongo = null; - $this->_collection = null; - $this->_cursor = null; + $this->_linkID = null; + $this->_mongo = null; + $this->_collection = null; + $this->_cursor = null; } } @@ -176,9 +194,10 @@ public function close() { * @access public * @return string */ - public function error() { + public function error() + { $this->error = $this->_mongo->lastError(); - trace($this->error,'','ERR'); + trace($this->error, '', 'ERR'); return $this->error; } @@ -190,28 +209,29 @@ public function error() { * @param boolean $replace 是否replace * @return false | integer */ - public function insert($data,$options=array(),$replace=false) { - if(isset($options['table'])) { + public function insert($data, $options = array(), $replace = false) + { + if (isset($options['table'])) { $this->switchCollection($options['table']); } - $this->model = $options['model']; + $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 .= ')'; + N('db_write', 1); // 兼容代码 + if ($this->config['debug']) { + $this->queryStr = $this->_dbName . '.' . $this->_collectionName . '.insert('; + $this->queryStr .= $data ? json_encode($data) : '{}'; + $this->queryStr .= ')'; } - try{ + try { $this->debug(true); - $result = $replace? $this->_collection->save($data): $this->_collection->insert($data); + $result = $replace ? $this->_collection->save($data) : $this->_collection->insert($data); $this->debug(false); - if($result) { - $_id = $data['_id']; - if(is_object($_id)) { + if ($result) { + $_id = $data['_id']; + if (is_object($_id)) { $_id = $_id->__toString(); } - $this->lastInsID = $_id; + $this->lastInsID = $_id; } return $result; } catch (\MongoCursorException $e) { @@ -226,16 +246,17 @@ public function insert($data,$options=array(),$replace=false) { * @param array $options 参数表达式 * @return bool */ - public function insertAll($dataList,$options=array()) { - if(isset($options['table'])) { + public function insertAll($dataList, $options = array()) + { + if (isset($options['table'])) { $this->switchCollection($options['table']); } - $this->model = $options['model']; + $this->model = $options['model']; $this->executeTimes++; - N('db_write',1); // 兼容代码 - try{ + N('db_write', 1); // 兼容代码 + try { $this->debug(true); - $result = $this->_collection->batchInsert($dataList); + $result = $this->_collection->batchInsert($dataList); $this->debug(false); return $result; } catch (\MongoCursorException $e) { @@ -249,19 +270,20 @@ public function insertAll($dataList,$options=array()) { * @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)'; + public function getMongoNextId($pk) + { + if ($this->config['debug']) { + $this->queryStr = $this->_dbName . '.' . $this->_collectionName . '.find({},{' . $pk . ':1}).sort({' . $pk . ':-1}).limit(1)'; } - try{ + try { $this->debug(true); - $result = $this->_collection->find(array(),array($pk=>1))->sort(array($pk=>-1))->limit(1); + $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; + return isset($data[$pk]) ? $data[$pk] + 1 : 1; } /** @@ -271,28 +293,29 @@ public function getMongoNextId($pk) { * @param array $options 表达式 * @return bool */ - public function update($data,$options) { - if(isset($options['table'])) { + 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{ + 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); + if (isset($options['limit']) && 1 == $options['limit']) { + $multiple = array("multiple" => false); + } else { + $multiple = array("multiple" => true); } - $result = $this->_collection->update($query,$set,$multiple); + $result = $this->_collection->update($query, $set, $multiple); $this->debug(false); return $result; } catch (\MongoCursorException $e) { @@ -306,20 +329,21 @@ public function update($data,$options) { * @param array $options 表达式 * @return false | integer */ - public function delete($options=array()) { - if(isset($options['table'])) { + 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']; + $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).')'; + N('db_write', 1); // 兼容代码 + if ($this->config['debug']) { + $this->queryStr = $this->_dbName . '.' . $this->_collectionName . '.remove(' . json_encode($query) . ')'; } - try{ + try { $this->debug(true); - $result = $this->_collection->remove($query); + $result = $this->_collection->remove($query); $this->debug(false); return $result; } catch (\MongoCursorException $e) { @@ -333,19 +357,20 @@ public function delete($options=array()) { * @param array $options 表达式 * @return false | integer */ - public function clear($options=array()){ - if(isset($options['table'])) { + public function clear($options = array()) + { + if (isset($options['table'])) { $this->switchCollection($options['table']); } - $this->model = $options['model']; + $this->model = $options['model']; $this->executeTimes++; - N('db_write',1); // 兼容代码 - if($this->config['debug']) { - $this->queryStr = $this->_dbName.'.'.$this->_collectionName.'.remove({})'; + N('db_write', 1); // 兼容代码 + if ($this->config['debug']) { + $this->queryStr = $this->_dbName . '.' . $this->_collectionName . '.remove({})'; } - try{ + try { $this->debug(true); - $result = $this->_collection->drop(); + $result = $this->_collection->drop(); $this->debug(false); return $result; } catch (\MongoCursorException $e) { @@ -359,59 +384,62 @@ public function clear($options=array()){ * @param array $options 表达式 * @return iterator */ - public function select($options=array()) { - if(isset($options['table'])) { - $this->switchCollection($options['table'],'',false); + public function select($options = array()) + { + if (isset($options['table'])) { + $this->switchCollection($options['table'], '', false); } - $this->model = $options['model']; + $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) + 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 .= $field ? ', ' . json_encode($_field_array) : ', {}'; } - $this->queryStr .= ')'; + $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 = $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); + $_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['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).')'; + 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)); + $_cursor = $_cursor->skip(intval($offset)); } - if($this->config['debug']) { - $this->queryStr .= '.limit('.intval($length).')'; + if ($this->config['debug']) { + $this->queryStr .= '.limit(' . intval($length) . ')'; } - $_cursor = $_cursor->limit(intval($length)); + $_cursor = $_cursor->limit(intval($length)); } $this->debug(false); - $this->_cursor = $_cursor; - $resultSet = iterator_to_array($_cursor); + $this->_cursor = $_cursor; + $resultSet = iterator_to_array($_cursor); return $resultSet; } catch (\MongoCursorException $e) { E($e->getMessage()); @@ -424,9 +452,10 @@ public function select($options=array()) { * @param array $options 表达式 * @return array */ - public function find($options=array()){ + public function find($options = array()) + { $options['limit'] = 1; - $find = $this->select($options); + $find = $this->select($options); return array_shift($find); } @@ -436,22 +465,23 @@ public function find($options=array()){ * @param array $options 表达式 * @return iterator */ - public function count($options=array()){ - if(isset($options['table'])) { - $this->switchCollection($options['table'],'',false); + public function count($options = array()) + { + if (isset($options['table'])) { + $this->switchCollection($options['table'], '', false); } - $this->model = $options['model']; + $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{ + 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); + $count = $this->_collection->count($query); $this->debug(false); return $count; } catch (\MongoCursorException $e) { @@ -459,40 +489,42 @@ public function count($options=array()){ } } - public function group($keys,$initial,$reduce,$options=array()){ - if(isset($options['table']) && $this->_collectionName != $options['table']) { - $this->switchCollection($options['table'],'',false); + 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) { + + $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->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:'. + 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).'})'; + json_encode($reduce) . ',initial:' . + json_encode($initial) . '})'; } - try{ + try { $this->debug(true); - $option = array('condition'=>$options['condition'], 'finalize'=>$options['finalize'], 'maxTimeMS'=>$options['maxTimeMS']); - $group = $this->_collection->group($keys,$initial,$reduce,$options); + $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']); - + + if ($cache && $group['ok']) { + S($key, $group, $cache['expire'], $cache['type']); + } + return $group; } catch (\MongoCursorException $e) { E($e->getMessage()); @@ -504,28 +536,30 @@ public function group($keys,$initial,$reduce,$options=array()){ * @access public * @return array */ - public function getFields($collection=''){ - if(!empty($collection) && $collection != $this->_collectionName) { - $this->switchCollection($collection,'',false); + 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()'; + N('db_query', 1); // 兼容代码 + if ($this->config['debug']) { + $this->queryStr = $this->_dbName . '.' . $this->_collectionName . '.findOne()'; } - try{ + try { $this->debug(true); - $result = $this->_collection->findOne(); + $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), + if ($result) { + // 存在数据则分析字段 + $info = array(); + foreach ($result as $key => $val) { + $info[$key] = array( + 'name' => $key, + 'type' => getType($val), ); } return $info; @@ -538,18 +572,19 @@ public function getFields($collection=''){ * 取得当前数据库的collection信息 * @access public */ - public function getTables(){ - if($this->config['debug']) { - $this->queryStr = $this->_dbName.'.getCollenctionNames()'; + public function getTables() + { + if ($this->config['debug']) { + $this->queryStr = $this->_dbName . '.getCollenctionNames()'; } $this->queryTimes++; - N('db_query',1); // 兼容代码 + N('db_query', 1); // 兼容代码 $this->debug(true); - $list = $this->_mongo->listCollections(); + $list = $this->_mongo->listCollections(); $this->debug(false); - $info = array(); - foreach ($list as $collection){ - $info[] = $collection->getName(); + $info = array(); + foreach ($list as $collection) { + $info[] = $collection->getName(); } return $info; } @@ -559,16 +594,18 @@ public function getTables(){ * @access public * @return object mongoClient */ - public function getDB(){ + public function getDB() + { return $this->_mongo; } - + /** * 取得当前集合的对象 * @access public * @return object MongoCollection */ - public function getCollection(){ + public function getCollection() + { return $this->_collection; } @@ -578,13 +615,14 @@ public function getCollection(){ * @param array $data * @return string */ - protected function parseSet($data) { - $result = array(); - foreach ($data as $key=>$val){ - if(is_array($val)) { - switch($val[0]) { + 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]; + $result['$inc'][$key] = (int) $val[1]; break; case 'set': case 'unset': @@ -594,13 +632,13 @@ protected function parseSet($data) { case 'pop': case 'pull': case 'pullall': - $result['$'.$val[0]][$key] = $val[1]; + $result['$' . $val[0]][$key] = $val[1]; break; default: - $result['$set'][$key] = $val; + $result['$set'][$key] = $val; } - }else{ - $result['$set'][$key] = $val; + } else { + $result['$set'][$key] = $val; } } return $result; @@ -612,18 +650,19 @@ protected function parseSet($data) { * @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; + 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] = 'asc' == $arr[1] ? 1 : -1; + } else { + $arr[1] = 1; } - $order[$arr[0]] = $arr[1]; + $order[$arr[0]] = $arr[1]; } } return $order; @@ -635,11 +674,12 @@ protected function parseOrder($order) { * @param mixed $limit * @return array */ - protected function parseLimit($limit) { - if(strpos($limit,',')) { - $array = explode(',',$limit); - }else{ - $array = array(0,$limit); + protected function parseLimit($limit) + { + if (strpos($limit, ',')) { + $array = explode(',', $limit); + } else { + $array = array(0, $limit); } return $array; } @@ -650,23 +690,28 @@ protected function parseLimit($limit) { * @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) + 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)) + } + + } elseif (is_array($fields)) { + $_fields = $fields; + $fields = array(); + foreach ($_fields as $f => $v) { + if (is_numeric($f)) { $fields[$v] = true; - else + } else { $fields[$f] = $v ? true : false; + } + } } return $fields; @@ -678,51 +723,54 @@ public function parseField($fields){ * @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; + 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,'_')) { + foreach ($where as $key => $val) { + if ('_id' != $key && 0 === strpos($key, '_')) { // 解析特殊条件表达式 - $parse = $this->parseThinkWhere($key,$val); - $query = array_merge($query,$parse); - }else{ + $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); + if (!preg_match('/^[A-Z_\|\&\-.a-z0-9]+$/', trim($key))) { + E(L('_ERROR_QUERY_') . ':' . $key); } $key = trim($key); - if(strpos($key,'|')) { - $array = explode('|',$key); + if (strpos($key, '|')) { + $array = explode('|', $key); $str = array(); - foreach ($array as $k){ - $str[] = $this->parseWhereItem($k,$val); + foreach ($array as $k) { + $str[] = $this->parseWhereItem($k, $val); } - $query['$or'] = $str; - }elseif(strpos($key,'&')){ - $array = explode('&',$key); + $query['$or'] = $str; + } elseif (strpos($key, '&')) { + $array = explode('&', $key); $str = array(); - foreach ($array as $k){ - $str[] = $this->parseWhereItem($k,$val); + 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); + $query = array_merge($query, $str); + } else { + $str = $this->parseWhereItem($key, $val); + $query = array_merge($query, $str); } } } - if($_logic == '$and') + if ('$and' == $_logic) { return $query; - - foreach($query as $key=>$val) - $return[$_logic][] = array($key=>$val); + } + + foreach ($query as $key => $val) { + $return[$_logic][] = array($key => $val); + } return $return; } @@ -734,34 +782,37 @@ public function parseWhere($where){ * @param mixed $val * @return string */ - protected function parseThinkWhere($key,$val) { - $query = array(); - $_logic = array('or','xor','nor', 'and'); - - switch($key) { + 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' ) { + parse_str($val, $query); + if (isset($query['_logic']) && strtolower($query['_logic']) == 'or') { unset($query['_logic']); - $query['$or'] = $query; + $query['$or'] = $query; } break; case '_complex': // 子查询模式查询条件 $__logic = strtolower($val['_logic']); - if(isset($val['_logic']) && in_array($__logic, $_logic) ) { + if (isset($val['_logic']) && in_array($__logic, $_logic)) { unset($val['_logic']); - $query['$'.$__logic] = $val; + $query['$' . $__logic] = $val; } break; - case '_string':// MongoCode查询 - $query['$where'] = new \MongoCode($val); + case '_string': // MongoCode查询 + $query['$where'] = new \MongoCode($val); break; } //兼容 MongoClient OR条件查询方法 - if(isset($query['$or']) && !is_array(current($query['$or']))) { + if (isset($query['$or']) && !is_array(current($query['$or']))) { $val = array(); - foreach ($query['$or'] as $k=>$v) - $val[] = array($k=>$v); + foreach ($query['$or'] as $k => $v) { + $val[] = array($k => $v); + } + $query['$or'] = $val; } return $query; @@ -774,48 +825,60 @@ protected function parseThinkWhere($key,$val) { * @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; + 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; + $query[$key] = $val; return $query; } } diff --git a/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php b/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php index ee0a33858..b999ff782 100644 --- a/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php +++ b/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php @@ -10,12 +10,14 @@ // +---------------------------------------------------------------------- namespace Think\Db\Driver; + use Think\Db\Driver; /** - * mysql数据库驱动 + * mysql数据库驱动 */ -class Mysql extends Driver{ +class Mysql extends Driver +{ /** * 解析pdo连接的dsn信息 @@ -23,18 +25,19 @@ class Mysql extends Driver{ * @param array $config 连接信息 * @return string */ - protected function parseDsn($config){ - $dsn = 'mysql:dbname='.$config['database'].';host='.$config['hostname']; - if(!empty($config['hostport'])) { - $dsn .= ';port='.$config['hostport']; - }elseif(!empty($config['socket'])){ - $dsn .= ';unix_socket='.$config['socket']; + protected function parseDsn($config) + { + $dsn = 'mysql:dbname=' . $config['database'] . ';host=' . $config['hostname']; + if (!empty($config['hostport'])) { + $dsn .= ';port=' . $config['hostport']; + } elseif (!empty($config['socket'])) { + $dsn .= ';unix_socket=' . $config['socket']; } - if(!empty($config['charset'])){ + if (!empty($config['charset'])) { //为兼容各版本PHP,用两种方式设置编码 - $this->options[\PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES '.$config['charset']; - $dsn .= ';charset='.$config['charset']; + $this->options[\PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES ' . $config['charset']; + $dsn .= ';charset=' . $config['charset']; } return $dsn; } @@ -43,27 +46,28 @@ protected function parseDsn($config){ * 取得数据表的字段信息 * @access public */ - public function getFields($tableName) { + public function getFields($tableName) + { $this->initConnect(true); list($tableName) = explode(' ', $tableName); - if(strpos($tableName,'.')){ - list($dbName,$tableName) = explode('.',$tableName); - $sql = 'SHOW COLUMNS FROM `'.$dbName.'`.`'.$tableName.'`'; - }else{ - $sql = 'SHOW COLUMNS FROM `'.$tableName.'`'; + if (strpos($tableName, '.')) { + list($dbName, $tableName) = explode('.', $tableName); + $sql = 'SHOW COLUMNS FROM `' . $dbName . '`.`' . $tableName . '`'; + } else { + $sql = 'SHOW COLUMNS FROM `' . $tableName . '`'; } - + $result = $this->query($sql); - $info = array(); - if($result) { + $info = array(); + if ($result) { foreach ($result as $key => $val) { - if(\PDO::CASE_LOWER != $this->_linkID->getAttribute(\PDO::ATTR_CASE)){ - $val = array_change_key_case ( $val , CASE_LOWER ); - } + if (\PDO::CASE_LOWER != $this->_linkID->getAttribute(\PDO::ATTR_CASE)) { + $val = array_change_key_case($val, CASE_LOWER); + } $info[$val['field']] = array( 'name' => $val['field'], 'type' => $val['type'], - 'notnull' => (bool) ($val['null'] === ''), // not null is empty, null is yes + 'notnull' => (bool) ('' === $val['null']), // not null is empty, null is yes 'default' => $val['default'], 'primary' => (strtolower($val['key']) == 'pri'), 'autoinc' => (strtolower($val['extra']) == 'auto_increment'), @@ -77,10 +81,11 @@ public function getFields($tableName) { * 取得数据库的表信息 * @access public */ - public function getTables($dbName='') { - $sql = !empty($dbName)?'SHOW TABLES FROM '.$dbName:'SHOW TABLES '; + public function getTables($dbName = '') + { + $sql = !empty($dbName) ? 'SHOW TABLES FROM ' . $dbName : 'SHOW TABLES '; $result = $this->query($sql); - $info = array(); + $info = array(); foreach ($result as $key => $val) { $info[$key] = current($val); } @@ -93,10 +98,11 @@ public function getTables($dbName='') { * @param string $key * @return string */ - protected function parseKey(&$key) { - $key = trim($key); - if(!is_numeric($key) && !preg_match('/[,\'\"\*\(\)`.\s]/',$key)) { - $key = '`'.$key.'`'; + protected function parseKey(&$key) + { + $key = trim($key); + if (!is_numeric($key) && !preg_match('/[,\'\"\*\(\)`.\s]/', $key)) { + $key = '`' . $key . '`'; } return $key; } @@ -109,81 +115,96 @@ protected function parseKey(&$key) { * @param boolean $replace 是否replace * @return false | integer */ - public function insertAll($dataSet,$options=array(),$replace=false) { - $values = array(); - $this->model = $options['model']; - if(!is_array($dataSet[0])) return false; - $this->parseBind(!empty($options['bind'])?$options['bind']:array()); - $fields = array_map(array($this,'parseKey'),array_keys($dataSet[0])); - foreach ($dataSet as $data){ - $value = array(); - foreach ($data as $key=>$val){ - if(is_array($val) && 'exp' == $val[0]){ - $value[] = $val[1]; - }elseif(is_null($val)){ - $value[] = 'NULL'; - }elseif(is_scalar($val)){ - if(0===strpos($val,':') && in_array($val,array_keys($this->bind))){ - $value[] = $this->parseValue($val); - }else{ - $name = count($this->bind); - $value[] = ':'.$name; - $this->bindParam($name,$val); + public function insertAll($dataSet, $options = array(), $replace = false) + { + $values = array(); + $this->model = $options['model']; + if (!is_array($dataSet[0])) { + return false; + } + + $this->parseBind(!empty($options['bind']) ? $options['bind'] : array()); + $fields = array_map(array($this, 'parseKey'), array_keys($dataSet[0])); + foreach ($dataSet as $data) { + $value = array(); + foreach ($data as $key => $val) { + if (is_array($val) && 'exp' == $val[0]) { + $value[] = $val[1]; + } elseif (is_null($val)) { + $value[] = 'NULL'; + } elseif (is_scalar($val)) { + if (0 === strpos($val, ':') && in_array($val, array_keys($this->bind))) { + $value[] = $this->parseValue($val); + } else { + $name = count($this->bind); + $value[] = ':' . $name; + $this->bindParam($name, $val); } } } - $values[] = '('.implode(',', $value).')'; + $values[] = '(' . implode(',', $value) . ')'; } // 兼容数字传入方式 - $replace= (is_numeric($replace) && $replace>0)?true:$replace; - $sql = (true===$replace?'REPLACE':'INSERT').' INTO '.$this->parseTable($options['table']).' ('.implode(',', $fields).') VALUES '.implode(',',$values).$this->parseDuplicate($replace); - $sql .= $this->parseComment(!empty($options['comment'])?$options['comment']:''); - return $this->execute($sql,!empty($options['fetch_sql']) ? true : false); + $replace = (is_numeric($replace) && $replace > 0) ? true : $replace; + $sql = (true === $replace ? 'REPLACE' : 'INSERT') . ' INTO ' . $this->parseTable($options['table']) . ' (' . implode(',', $fields) . ') VALUES ' . implode(',', $values) . $this->parseDuplicate($replace); + $sql .= $this->parseComment(!empty($options['comment']) ? $options['comment'] : ''); + return $this->execute($sql, !empty($options['fetch_sql']) ? true : false); } /** * ON DUPLICATE KEY UPDATE 分析 * @access protected - * @param mixed $duplicate + * @param mixed $duplicate * @return string */ - protected function parseDuplicate($duplicate){ + protected function parseDuplicate($duplicate) + { // 布尔值或空则返回空字符串 - if(is_bool($duplicate) || empty($duplicate)) return ''; - - if(is_string($duplicate)){ - // field1,field2 转数组 - $duplicate = explode(',', $duplicate); - }elseif(is_object($duplicate)){ - // 对象转数组 - $duplicate = get_class_vars($duplicate); - } - $updates = array(); - foreach((array) $duplicate as $key=>$val){ - if(is_numeric($key)){ // array('field1', 'field2', 'field3') 解析为 ON DUPLICATE KEY UPDATE field1=VALUES(field1), field2=VALUES(field2), field3=VALUES(field3) - $updates[] = $this->parseKey($val)."=VALUES(".$this->parseKey($val).")"; - }else{ - if(is_scalar($val)) // 兼容标量传值方式 - $val = array('value', $val); - if(!isset($val[1])) continue; - switch($val[0]){ + if (is_bool($duplicate) || empty($duplicate)) { + return ''; + } + + if (is_string($duplicate)) { + // field1,field2 转数组 + $duplicate = explode(',', $duplicate); + } elseif (is_object($duplicate)) { + // 对象转数组 + $duplicate = get_class_vars($duplicate); + } + $updates = array(); + foreach ((array) $duplicate as $key => $val) { + if (is_numeric($key)) { + // array('field1', 'field2', 'field3') 解析为 ON DUPLICATE KEY UPDATE field1=VALUES(field1), field2=VALUES(field2), field3=VALUES(field3) + $updates[] = $this->parseKey($val) . "=VALUES(" . $this->parseKey($val) . ")"; + } else { + if (is_scalar($val)) // 兼容标量传值方式 + { + $val = array('value', $val); + } + + if (!isset($val[1])) { + continue; + } + + switch ($val[0]) { case 'exp': // 表达式 - $updates[] = $this->parseKey($key)."=($val[1])"; + $updates[] = $this->parseKey($key) . "=($val[1])"; break; case 'value': // 值 default: - $name = count($this->bind); - $updates[] = $this->parseKey($key)."=:".$name; + $name = count($this->bind); + $updates[] = $this->parseKey($key) . "=:" . $name; $this->bindParam($name, $val[1]); break; } } } - if(empty($updates)) return ''; - return " ON DUPLICATE KEY UPDATE ".join(', ', $updates); + if (empty($updates)) { + return ''; + } + + return " ON DUPLICATE KEY UPDATE " . join(', ', $updates); } - - /** * 执行存储过程查询 返回多个数据集 @@ -192,41 +213,45 @@ protected function parseDuplicate($duplicate){ * @param boolean $fetchSql 不执行只是获取SQL * @return mixed */ - public function procedure($str,$fetchSql=false) { + public function procedure($str, $fetchSql = false) + { $this->initConnect(false); $this->_linkID->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_WARNING); - if ( !$this->_linkID ) return false; - $this->queryStr = $str; - if($fetchSql){ + if (!$this->_linkID) { + return false; + } + + $this->queryStr = $str; + if ($fetchSql) { return $this->queryStr; } //释放前次的查询结果 - if ( !empty($this->PDOStatement) ) $this->free(); + if (!empty($this->PDOStatement)) { + $this->free(); + } + $this->queryTimes++; - N('db_query',1); // 兼容代码 + N('db_query', 1); // 兼容代码 // 调试开始 $this->debug(true); $this->PDOStatement = $this->_linkID->prepare($str); - if(false === $this->PDOStatement){ + if (false === $this->PDOStatement) { $this->error(); return false; } - try{ + try { $result = $this->PDOStatement->execute(); // 调试结束 $this->debug(false); - do - { + do { $result = $this->PDOStatement->fetchAll(\PDO::FETCH_ASSOC); - if ($result) - { + if ($result) { $resultArr[] = $result; } - } - while ($this->PDOStatement->nextRowset()); + } while ($this->PDOStatement->nextRowset()); $this->_linkID->setAttribute(\PDO::ATTR_ERRMODE, $this->options[\PDO::ATTR_ERRMODE]); return $resultArr; - }catch (\PDOException $e) { + } catch (\PDOException $e) { $this->error(); $this->_linkID->setAttribute(\PDO::ATTR_ERRMODE, $this->options[\PDO::ATTR_ERRMODE]); return false; diff --git a/ThinkPHP/Library/Think/Db/Driver/Oracle.class.php b/ThinkPHP/Library/Think/Db/Driver/Oracle.class.php index 6bf5477f4..6059ad66a 100644 --- a/ThinkPHP/Library/Think/Db/Driver/Oracle.class.php +++ b/ThinkPHP/Library/Think/Db/Driver/Oracle.class.php @@ -10,15 +10,17 @@ // +---------------------------------------------------------------------- namespace Think\Db\Driver; + use Think\Db\Driver; /** * Oracle数据库驱动 */ -class Oracle extends Driver{ +class Oracle extends Driver +{ - private $table = ''; - protected $selectSql = 'SELECT * FROM (SELECT thinkphp.*, rownum AS numrow FROM (SELECT %DISTINCT% %FIELD% FROM %TABLE%%JOIN%%WHERE%%GROUP%%HAVING%%ORDER%) thinkphp ) %LIMIT%%COMMENT%'; + private $table = ''; + protected $selectSql = 'SELECT * FROM (SELECT thinkphp.*, rownum AS numrow FROM (SELECT %DISTINCT% %FIELD% FROM %TABLE%%JOIN%%WHERE%%GROUP%%HAVING%%ORDER%) thinkphp ) %LIMIT%%COMMENT%'; /** * 解析pdo连接的dsn信息 @@ -26,10 +28,11 @@ class Oracle extends Driver{ * @param array $config 连接信息 * @return string */ - protected function parseDsn($config){ - $dsn = 'oci:dbname=//'.$config['hostname'].($config['hostport']?':'.$config['hostport']:'').'/'.$config['database']; - if(!empty($config['charset'])) { - $dsn .= ';charset='.$config['charset']; + protected function parseDsn($config) + { + $dsn = 'oci:dbname=//' . $config['hostname'] . ($config['hostport'] ? ':' . $config['hostport'] : '') . '/' . $config['database']; + if (!empty($config['charset'])) { + $dsn .= ';charset=' . $config['charset']; } return $dsn; } @@ -38,52 +41,59 @@ protected function parseDsn($config){ * 执行语句 * @access public * @param string $str sql指令 - * @param boolean $fetchSql 不执行只是获取SQL + * @param boolean $fetchSql 不执行只是获取SQL * @return integer */ - public function execute($str,$fetchSql=false) { + public function execute($str, $fetchSql = false) + { $this->initConnect(true); - if ( !$this->_linkID ) return false; + 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 (!empty($this->bind)) { + $that = $this; + $this->queryStr = strtr($this->queryStr, array_map(function ($val) use ($that) {return '\'' . $that->escapeString($val) . '\'';}, $this->bind)); } - if($fetchSql){ + if ($fetchSql) { return $this->queryStr; } $flag = false; - if(preg_match("/^\s*(INSERT\s+INTO)\s+(\w+)\s+/i", $str, $match)) { - $this->table = C("DB_SEQUENCE_PREFIX").str_ireplace(C("DB_PREFIX"), "", $match[2]); - $flag = (boolean)$this->query("SELECT * FROM user_sequences WHERE sequence_name='" . strtoupper($this->table) . "'"); + if (preg_match("/^\s*(INSERT\s+INTO)\s+(\w+)\s+/i", $str, $match)) { + $this->table = C("DB_SEQUENCE_PREFIX") . str_ireplace(C("DB_PREFIX"), "", $match[2]); + $flag = (boolean) $this->query("SELECT * FROM user_sequences WHERE sequence_name='" . strtoupper($this->table) . "'"); } //释放前次的查询结果 - if ( !empty($this->PDOStatement) ) $this->free(); + if (!empty($this->PDOStatement)) { + $this->free(); + } + $this->executeTimes++; - N('db_write',1); // 兼容代码 + N('db_write', 1); // 兼容代码 // 记录开始执行时间 $this->debug(true); - $this->PDOStatement = $this->_linkID->prepare($str); - if(false === $this->PDOStatement) { + $this->PDOStatement = $this->_linkID->prepare($str); + if (false === $this->PDOStatement) { $this->error(); return false; } foreach ($this->bind as $key => $val) { - if(is_array($val)){ + if (is_array($val)) { $this->PDOStatement->bindValue($key, $val[0], $val[1]); - }else{ + } else { $this->PDOStatement->bindValue($key, $val); } } - $this->bind = array(); - $result = $this->PDOStatement->execute(); + $this->bind = array(); + $result = $this->PDOStatement->execute(); $this->debug(false); - if ( false === $result) { + if (false === $result) { $this->error(); return false; } else { $this->numRows = $this->PDOStatement->rowCount(); - if($flag || preg_match("/^\s*(INSERT\s+INTO|REPLACE\s+INTO)\s+/i", $str)) { + if ($flag || preg_match("/^\s*(INSERT\s+INTO|REPLACE\s+INTO)\s+/i", $str)) { $this->lastInsID = $this->_linkID->lastInsertId(); } return $this->numRows; @@ -94,14 +104,15 @@ public function execute($str,$fetchSql=false) { * 取得数据表的字段信息 * @access public */ - public function getFields($tableName) { + public function getFields($tableName) + { list($tableName) = explode(' ', $tableName); - $result = $this->query("select a.column_name,data_type,decode(nullable,'Y',0,1) notnull,data_default,decode(a.column_name,b.column_name,1,0) pk " - ."from user_tab_columns a,(select column_name from user_constraints c,user_cons_columns col " - ."where c.constraint_name=col.constraint_name and c.constraint_type='P'and c.table_name='".strtoupper($tableName) - ."') b where table_name='".strtoupper($tableName)."' and a.column_name=b.column_name(+)"); - $info = array(); - if($result) { + $result = $this->query("select a.column_name,data_type,decode(nullable,'Y',0,1) notnull,data_default,decode(a.column_name,b.column_name,1,0) pk " + . "from user_tab_columns a,(select column_name from user_constraints c,user_cons_columns col " + . "where c.constraint_name=col.constraint_name and c.constraint_type='P'and c.table_name='" . strtoupper($tableName) + . "') b where table_name='" . strtoupper($tableName) . "' and a.column_name=b.column_name(+)"); + $info = array(); + if ($result) { foreach ($result as $key => $val) { $info[strtolower($val['column_name'])] = array( 'name' => strtolower($val['column_name']), @@ -120,9 +131,10 @@ public function getFields($tableName) { * 取得数据库的表信息(暂时实现取得用户表信息) * @access public */ - public function getTables($dbName='') { + public function getTables($dbName = '') + { $result = $this->query("select table_name from user_tables"); - $info = array(); + $info = array(); foreach ($result as $key => $val) { $info[$key] = current($val); } @@ -135,7 +147,8 @@ public function getTables($dbName='') { * @param string $str SQL指令 * @return string */ - public function escapeString($str) { + public function escapeString($str) + { return str_ireplace("'", "''", $str); } @@ -144,16 +157,19 @@ public function escapeString($str) { * @access public * @return string */ - public function parseLimit($limit) { - $limitStr = ''; - if(!empty($limit)) { - $limit = explode(',',$limit); - if(count($limit)>1) - $limitStr = "(numrow>" . $limit[0] . ") AND (numrow<=" . ($limit[0]+$limit[1]) . ")"; - else - $limitStr = "(numrow>0 AND numrow<=".$limit[0].")"; + public function parseLimit($limit) + { + $limitStr = ''; + if (!empty($limit)) { + $limit = explode(',', $limit); + if (count($limit) > 1) { + $limitStr = "(numrow>" . $limit[0] . ") AND (numrow<=" . ($limit[0] + $limit[1]) . ")"; + } else { + $limitStr = "(numrow>0 AND numrow<=" . $limit[0] . ")"; + } + } - return $limitStr?' WHERE '.$limitStr:''; + return $limitStr ? ' WHERE ' . $limitStr : ''; } /** @@ -161,8 +177,12 @@ public function parseLimit($limit) { * @access protected * @return string */ - protected function parseLock($lock=false) { - if(!$lock) return ''; + protected function parseLock($lock = false) + { + if (!$lock) { + return ''; + } + return ' FOR UPDATE NOWAIT '; } } diff --git a/ThinkPHP/Library/Think/Db/Driver/Pgsql.class.php b/ThinkPHP/Library/Think/Db/Driver/Pgsql.class.php index e1223a4ab..0b27cbf18 100644 --- a/ThinkPHP/Library/Think/Db/Driver/Pgsql.class.php +++ b/ThinkPHP/Library/Think/Db/Driver/Pgsql.class.php @@ -10,12 +10,14 @@ // +---------------------------------------------------------------------- namespace Think\Db\Driver; + use Think\Db\Driver; /** * Pgsql数据库驱动 */ -class Pgsql extends Driver{ +class Pgsql extends Driver +{ /** * 解析pdo连接的dsn信息 @@ -23,10 +25,11 @@ class Pgsql extends Driver{ * @param array $config 连接信息 * @return string */ - protected function parseDsn($config){ - $dsn = 'pgsql:dbname='.$config['database'].';host='.$config['hostname']; - if(!empty($config['hostport'])) { - $dsn .= ';port='.$config['hostport']; + protected function parseDsn($config) + { + $dsn = 'pgsql:dbname=' . $config['database'] . ';host=' . $config['hostname']; + if (!empty($config['hostport'])) { + $dsn .= ';port=' . $config['hostport']; } return $dsn; } @@ -36,16 +39,17 @@ protected function parseDsn($config){ * @access public * @return array */ - public function getFields($tableName) { + public function getFields($tableName) + { list($tableName) = explode(' ', $tableName); - $result = $this->query('select fields_name as "field",fields_type as "type",fields_not_null as "null",fields_key_name as "key",fields_default as "default",fields_default as "extra" from table_msg('.$tableName.');'); - $info = array(); - if($result){ + $result = $this->query('select fields_name as "field",fields_type as "type",fields_not_null as "null",fields_key_name as "key",fields_default as "default",fields_default as "extra" from table_msg(' . $tableName . ');'); + $info = array(); + if ($result) { foreach ($result as $key => $val) { $info[$val['field']] = array( 'name' => $val['field'], 'type' => $val['type'], - 'notnull' => (bool) ($val['null'] === ''), // not null is empty, null is yes + 'notnull' => (bool) ('' === $val['null']), // not null is empty, null is yes 'default' => $val['default'], 'primary' => (strtolower($val['key']) == 'pri'), 'autoinc' => (strtolower($val['extra']) == 'auto_increment'), @@ -60,9 +64,10 @@ public function getFields($tableName) { * @access public * @return array */ - public function getTables($dbName='') { - $result = $this->query("select tablename as Tables_in_test from pg_tables where schemaname ='public'"); - $info = array(); + public function getTables($dbName = '') + { + $result = $this->query("select tablename as Tables_in_test from pg_tables where schemaname ='public'"); + $info = array(); foreach ($result as $key => $val) { $info[$key] = current($val); } @@ -75,14 +80,15 @@ public function getTables($dbName='') { * @param mixed $lmit * @return string */ - public function parseLimit($limit) { - $limitStr = ''; - if(!empty($limit)) { - $limit = explode(',',$limit); - if(count($limit)>1) { - $limitStr .= ' LIMIT '.$limit[1].' OFFSET '.$limit[0].' '; - }else{ - $limitStr .= ' LIMIT '.$limit[0].' '; + public function parseLimit($limit) + { + $limitStr = ''; + if (!empty($limit)) { + $limit = explode(',', $limit); + if (count($limit) > 1) { + $limitStr .= ' LIMIT ' . $limit[1] . ' OFFSET ' . $limit[0] . ' '; + } else { + $limitStr .= ' LIMIT ' . $limit[0] . ' '; } } return $limitStr; diff --git a/ThinkPHP/Library/Think/Db/Driver/Sqlite.class.php b/ThinkPHP/Library/Think/Db/Driver/Sqlite.class.php index d7fd64196..1bfb6190a 100644 --- a/ThinkPHP/Library/Think/Db/Driver/Sqlite.class.php +++ b/ThinkPHP/Library/Think/Db/Driver/Sqlite.class.php @@ -10,12 +10,14 @@ // +---------------------------------------------------------------------- namespace Think\Db\Driver; + use Think\Db\Driver; /** * Sqlite数据库驱动 */ -class Sqlite extends Driver { +class Sqlite extends Driver +{ /** * 解析pdo连接的dsn信息 @@ -23,8 +25,9 @@ class Sqlite extends Driver { * @param array $config 连接信息 * @return string */ - protected function parseDsn($config){ - $dsn = 'sqlite:'.$config['database']; + protected function parseDsn($config) + { + $dsn = 'sqlite:' . $config['database']; return $dsn; } @@ -33,16 +36,17 @@ protected function parseDsn($config){ * @access public * @return array */ - public function getFields($tableName) { + public function getFields($tableName) + { list($tableName) = explode(' ', $tableName); - $result = $this->query('PRAGMA table_info( '.$tableName.' )'); - $info = array(); - if($result){ + $result = $this->query('PRAGMA table_info( ' . $tableName . ' )'); + $info = array(); + if ($result) { foreach ($result as $key => $val) { $info[$val['field']] = array( 'name' => $val['field'], 'type' => $val['type'], - 'notnull' => (bool) ($val['null'] === ''), // not null is empty, null is yes + 'notnull' => (bool) ('' === $val['null']), // not null is empty, null is yes 'default' => $val['default'], 'primary' => (strtolower($val['dey']) == 'pri'), 'autoinc' => (strtolower($val['extra']) == 'auto_increment'), @@ -57,11 +61,12 @@ public function getFields($tableName) { * @access public * @return array */ - public function getTables($dbName='') { - $result = $this->query("SELECT name FROM sqlite_master WHERE type='table' " - . "UNION ALL SELECT name FROM sqlite_temp_master " - . "WHERE type='table' ORDER BY name"); - $info = array(); + public function getTables($dbName = '') + { + $result = $this->query("SELECT name FROM sqlite_master WHERE type='table' " + . "UNION ALL SELECT name FROM sqlite_temp_master " + . "WHERE type='table' ORDER BY name"); + $info = array(); foreach ($result as $key => $val) { $info[$key] = current($val); } @@ -74,7 +79,8 @@ public function getTables($dbName='') { * @param string $str SQL指令 * @return string */ - public function escapeString($str) { + public function escapeString($str) + { return str_ireplace("'", "''", $str); } @@ -83,14 +89,15 @@ public function escapeString($str) { * @access public * @return string */ - public function parseLimit($limit) { - $limitStr = ''; - if(!empty($limit)) { - $limit = explode(',',$limit); - if(count($limit)>1) { - $limitStr .= ' LIMIT '.$limit[1].' OFFSET '.$limit[0].' '; - }else{ - $limitStr .= ' LIMIT '.$limit[0].' '; + public function parseLimit($limit) + { + $limitStr = ''; + if (!empty($limit)) { + $limit = explode(',', $limit); + if (count($limit) > 1) { + $limitStr .= ' LIMIT ' . $limit[1] . ' OFFSET ' . $limit[0] . ' '; + } else { + $limitStr .= ' LIMIT ' . $limit[0] . ' '; } } return $limitStr; diff --git a/ThinkPHP/Library/Think/Db/Driver/Sqlsrv.class.php b/ThinkPHP/Library/Think/Db/Driver/Sqlsrv.class.php index 9df1c9256..fadf0a2c9 100644 --- a/ThinkPHP/Library/Think/Db/Driver/Sqlsrv.class.php +++ b/ThinkPHP/Library/Think/Db/Driver/Sqlsrv.class.php @@ -10,20 +10,22 @@ // +---------------------------------------------------------------------- namespace Think\Db\Driver; -use Think\Db\Driver; + use PDO; +use Think\Db\Driver; /** * Sqlsrv数据库驱动 */ -class Sqlsrv extends Driver{ - protected $selectSql = 'SELECT T1.* FROM (SELECT thinkphp.*, ROW_NUMBER() OVER (%ORDER%) AS ROW_NUMBER FROM (SELECT %DISTINCT% %FIELD% FROM %TABLE%%JOIN%%WHERE%%GROUP%%HAVING% %UNION%) AS thinkphp) AS T1 %LIMIT%%COMMENT%'; +class Sqlsrv extends Driver +{ + protected $selectSql = 'SELECT T1.* FROM (SELECT thinkphp.*, ROW_NUMBER() OVER (%ORDER%) AS ROW_NUMBER FROM (SELECT %DISTINCT% %FIELD% FROM %TABLE%%JOIN%%WHERE%%GROUP%%HAVING% %UNION%) AS thinkphp) AS T1 %LIMIT%%COMMENT%'; // PDO连接参数 protected $options = array( - PDO::ATTR_CASE => PDO::CASE_LOWER, - PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, - PDO::ATTR_STRINGIFY_FETCHES => false, - PDO::SQLSRV_ATTR_ENCODING => PDO::SQLSRV_ENCODING_UTF8, + PDO::ATTR_CASE => PDO::CASE_LOWER, + PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, + PDO::ATTR_STRINGIFY_FETCHES => false, + PDO::SQLSRV_ATTR_ENCODING => PDO::SQLSRV_ENCODING_UTF8, ); /** @@ -32,10 +34,11 @@ class Sqlsrv extends Driver{ * @param array $config 连接信息 * @return string */ - protected function parseDsn($config){ - $dsn = 'sqlsrv:Database='.$config['database'].';Server='.$config['hostname']; - if(!empty($config['hostport'])) { - $dsn .= ','.$config['hostport']; + protected function parseDsn($config) + { + $dsn = 'sqlsrv:Database=' . $config['database'] . ';Server=' . $config['hostname']; + if (!empty($config['hostport'])) { + $dsn .= ',' . $config['hostport']; } return $dsn; } @@ -45,22 +48,23 @@ protected function parseDsn($config){ * @access public * @return array */ - public function getFields($tableName) { + public function getFields($tableName) + { list($tableName) = explode(' ', $tableName); - $result = $this->query("SELECT column_name, data_type, column_default, is_nullable + $result = $this->query("SELECT column_name, data_type, column_default, is_nullable FROM information_schema.tables AS t JOIN information_schema.columns AS c ON t.table_catalog = c.table_catalog AND t.table_schema = c.table_schema AND t.table_name = c.table_name WHERE t.table_name = '$tableName'"); - $info = array(); - if($result) { + $info = array(); + if ($result) { foreach ($result as $key => $val) { $info[$val['column_name']] = array( 'name' => $val['column_name'], 'type' => $val['data_type'], - 'notnull' => (bool) ($val['is_nullable'] === ''), // not null is empty, null is yes + 'notnull' => (bool) ('' === $val['is_nullable']), // not null is empty, null is yes 'default' => $val['column_default'], 'primary' => false, 'autoinc' => false, @@ -75,26 +79,28 @@ public function getFields($tableName) { * @access public * @return array */ - public function getTables($dbName='') { - $result = $this->query("SELECT TABLE_NAME + public function getTables($dbName = '') + { + $result = $this->query("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' "); - $info = array(); + $info = array(); foreach ($result as $key => $val) { $info[$key] = current($val); } return $info; } - /** + /** * order分析 * @access protected * @param mixed $order * @return string */ - protected function parseOrder($order) { - return !empty($order)? ' ORDER BY '.$order:' ORDER BY rand()'; + protected function parseOrder($order) + { + return !empty($order) ? ' ORDER BY ' . $order : ' ORDER BY rand()'; } /** @@ -103,12 +109,13 @@ protected function parseOrder($order) { * @param string $key * @return string */ - protected function parseKey(&$key) { - $key = trim($key); - if(!is_numeric($key) && !preg_match('/[,\'\"\*\(\)\[.\s]/',$key)) { - $key = '['.$key.']'; + protected function parseKey(&$key) + { + $key = trim($key); + if (!is_numeric($key) && !preg_match('/[,\'\"\*\(\)\[.\s]/', $key)) { + $key = '[' . $key . ']'; } - return $key; + return $key; } /** @@ -117,14 +124,20 @@ protected function parseKey(&$key) { * @param mixed $limit * @return string */ - public function parseLimit($limit) { - if(empty($limit)) return ''; - $limit = explode(',',$limit); - if(count($limit)>1) - $limitStr = '(T1.ROW_NUMBER BETWEEN '.$limit[0].' + 1 AND '.$limit[0].' + '.$limit[1].')'; - else - $limitStr = '(T1.ROW_NUMBER BETWEEN 1 AND '.$limit[0].")"; - return 'WHERE '.$limitStr; + public function parseLimit($limit) + { + if (empty($limit)) { + return ''; + } + + $limit = explode(',', $limit); + if (count($limit) > 1) { + $limitStr = '(T1.ROW_NUMBER BETWEEN ' . $limit[0] . ' + 1 AND ' . $limit[0] . ' + ' . $limit[1] . ')'; + } else { + $limitStr = '(T1.ROW_NUMBER BETWEEN 1 AND ' . $limit[0] . ")"; + } + + return 'WHERE ' . $limitStr; } /** @@ -134,16 +147,17 @@ public function parseLimit($limit) { * @param array $options 表达式 * @return false | integer */ - public function update($data,$options) { - $this->model = $options['model']; - $this->parseBind(!empty($options['bind'])?$options['bind']:array()); - $sql = 'UPDATE ' - .$this->parseTable($options['table']) - .$this->parseSet($data) - .$this->parseWhere(!empty($options['where'])?$options['where']:'') - .$this->parseLock(isset($options['lock'])?$options['lock']:false) - .$this->parseComment(!empty($options['comment'])?$options['comment']:''); - return $this->execute($sql,!empty($options['fetch_sql']) ? true : false); + public function update($data, $options) + { + $this->model = $options['model']; + $this->parseBind(!empty($options['bind']) ? $options['bind'] : array()); + $sql = 'UPDATE ' + . $this->parseTable($options['table']) + . $this->parseSet($data) + . $this->parseWhere(!empty($options['where']) ? $options['where'] : '') + . $this->parseLock(isset($options['lock']) ? $options['lock'] : false) + . $this->parseComment(!empty($options['comment']) ? $options['comment'] : ''); + return $this->execute($sql, !empty($options['fetch_sql']) ? true : false); } /** @@ -152,15 +166,16 @@ public function update($data,$options) { * @param array $options 表达式 * @return false | integer */ - public function delete($options=array()) { - $this->model = $options['model']; - $this->parseBind(!empty($options['bind'])?$options['bind']:array()); - $sql = 'DELETE FROM ' - .$this->parseTable($options['table']) - .$this->parseWhere(!empty($options['where'])?$options['where']:'') - .$this->parseLock(isset($options['lock'])?$options['lock']:false) - .$this->parseComment(!empty($options['comment'])?$options['comment']:''); - return $this->execute($sql,!empty($options['fetch_sql']) ? true : false); + public function delete($options = array()) + { + $this->model = $options['model']; + $this->parseBind(!empty($options['bind']) ? $options['bind'] : array()); + $sql = 'DELETE FROM ' + . $this->parseTable($options['table']) + . $this->parseWhere(!empty($options['where']) ? $options['where'] : '') + . $this->parseLock(isset($options['lock']) ? $options['lock'] : false) + . $this->parseComment(!empty($options['comment']) ? $options['comment'] : ''); + return $this->execute($sql, !empty($options['fetch_sql']) ? true : false); } -} \ No newline at end of file +} diff --git a/ThinkPHP/Library/Think/Db/Lite.class.php b/ThinkPHP/Library/Think/Db/Lite.class.php index 577c44b62..ad6ef16ed 100644 --- a/ThinkPHP/Library/Think/Db/Lite.class.php +++ b/ThinkPHP/Library/Think/Db/Lite.class.php @@ -10,63 +10,64 @@ // +---------------------------------------------------------------------- namespace Think\Db; + +use PDO; use Think\Config; use Think\Debug; -use Think\Log; -use PDO; -class Lite { +class Lite +{ // PDO操作实例 protected $PDOStatement = null; // 当前操作所属的模型名 - protected $model = '_think_'; + protected $model = '_think_'; // 当前SQL指令 - protected $queryStr = ''; - protected $modelSql = array(); + protected $queryStr = ''; + protected $modelSql = array(); // 最后插入ID - protected $lastInsID = null; + protected $lastInsID = null; // 返回或者影响记录数 - protected $numRows = 0; + protected $numRows = 0; // 事务指令数 protected $transTimes = 0; // 错误信息 - protected $error = ''; + protected $error = ''; // 数据库连接ID 支持多个连接 - protected $linkID = array(); + protected $linkID = array(); // 当前连接ID - protected $_linkID = null; + protected $_linkID = null; // 数据库连接参数配置 - protected $config = array( - 'type' => '', // 数据库类型 - 'hostname' => '127.0.0.1', // 服务器地址 - 'database' => '', // 数据库名 - 'username' => '', // 用户名 - 'password' => '', // 密码 - 'hostport' => '', // 端口 - 'dsn' => '', // - 'params' => array(), // 数据库连接参数 - 'charset' => 'utf8', // 数据库编码默认采用utf8 - 'prefix' => '', // 数据库表前缀 - 'debug' => false, // 数据库调试模式 - 'deploy' => 0, // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器) - 'rw_separate' => false, // 数据库读写是否分离 主从式有效 - 'master_num' => 1, // 读写分离后 主服务器数量 - 'slave_no' => '', // 指定从服务器序号 + protected $config = array( + 'type' => '', // 数据库类型 + 'hostname' => '127.0.0.1', // 服务器地址 + 'database' => '', // 数据库名 + 'username' => '', // 用户名 + 'password' => '', // 密码 + 'hostport' => '', // 端口 + 'dsn' => '', // + 'params' => array(), // 数据库连接参数 + 'charset' => 'utf8', // 数据库编码默认采用utf8 + 'prefix' => '', // 数据库表前缀 + 'debug' => false, // 数据库调试模式 + 'deploy' => 0, // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器) + 'rw_separate' => false, // 数据库读写是否分离 主从式有效 + 'master_num' => 1, // 读写分离后 主服务器数量 + 'slave_no' => '', // 指定从服务器序号 ); // 数据库表达式 - protected $comparison = array('eq'=>'=','neq'=>'<>','gt'=>'>','egt'=>'>=','lt'=>'<','elt'=>'<=','notlike'=>'NOT LIKE','like'=>'LIKE','in'=>'IN','notin'=>'NOT IN'); + protected $comparison = array('eq' => '=', 'neq' => '<>', 'gt' => '>', 'egt' => '>=', 'lt' => '<', 'elt' => '<=', 'notlike' => 'NOT LIKE', 'like' => 'LIKE', 'in' => 'IN', 'notin' => 'NOT IN'); // 查询表达式 - protected $selectSql = 'SELECT%DISTINCT% %FIELD% FROM %TABLE%%JOIN%%WHERE%%GROUP%%HAVING%%ORDER%%LIMIT% %UNION%%COMMENT%'; + protected $selectSql = 'SELECT%DISTINCT% %FIELD% FROM %TABLE%%JOIN%%WHERE%%GROUP%%HAVING%%ORDER%%LIMIT% %UNION%%COMMENT%'; // 查询次数 - protected $queryTimes = 0; + protected $queryTimes = 0; // 执行次数 - protected $executeTimes = 0; + protected $executeTimes = 0; // PDO连接参数 protected $options = array( - PDO::ATTR_CASE => PDO::CASE_LOWER, - PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, - PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL, - PDO::ATTR_STRINGIFY_FETCHES => false, + PDO::ATTR_CASE => PDO::CASE_LOWER, + PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, + PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL, + PDO::ATTR_STRINGIFY_FETCHES => false, ); /** @@ -74,11 +75,12 @@ class Lite { * @access public * @param array $config 数据库配置数组 */ - public function __construct($config=''){ - if(!empty($config)) { - $this->config = array_merge($this->config,$config); - if(is_array($this->config['params'])){ - $this->options += $this->config['params']; + public function __construct($config = '') + { + if (!empty($config)) { + $this->config = array_merge($this->config, $config); + if (is_array($this->config['params'])) { + $this->options += $this->config['params']; } } } @@ -87,18 +89,23 @@ public function __construct($config=''){ * 连接数据库方法 * @access public */ - public function connect($config='',$linkNum=0) { - if ( !isset($this->linkID[$linkNum]) ) { - if(empty($config)) $config = $this->config; - try{ - if(empty($config['dsn'])) { - $config['dsn'] = $this->parseDsn($config); + public function connect($config = '', $linkNum = 0) + { + if (!isset($this->linkID[$linkNum])) { + if (empty($config)) { + $config = $this->config; + } + + try { + if (empty($config['dsn'])) { + $config['dsn'] = $this->parseDsn($config); } - if(version_compare(PHP_VERSION,'5.3.6','<=')){ //禁用模拟预处理语句 - $this->options[PDO::ATTR_EMULATE_PREPARES] = false; + if (version_compare(PHP_VERSION, '5.3.6', '<=')) { + //禁用模拟预处理语句 + $this->options[PDO::ATTR_EMULATE_PREPARES] = false; } - $this->linkID[$linkNum] = new PDO( $config['dsn'], $config['username'], $config['password'],$this->options); - }catch (\PDOException $e) { + $this->linkID[$linkNum] = new PDO($config['dsn'], $config['username'], $config['password'], $this->options); + } catch (\PDOException $e) { E($e->getMessage()); } } @@ -111,13 +118,15 @@ public function connect($config='',$linkNum=0) { * @param array $config 连接信息 * @return string */ - protected function parseDsn($config){} + protected function parseDsn($config) + {} /** * 释放查询结果 * @access public */ - public function free() { + public function free() + { $this->PDOStatement = null; } @@ -128,34 +137,43 @@ public function free() { * @param array $bind 参数绑定 * @return mixed */ - public function query($str,$bind=array()) { + public function query($str, $bind = array()) + { $this->initConnect(false); - if ( !$this->_linkID ) return false; - $this->queryStr = $str; - if(!empty($bind)){ - $that = $this; - $this->queryStr = strtr($this->queryStr,array_map(function($val) use($that){ return '\''.$that->escapeString($val).'\''; },$bind)); + if (!$this->_linkID) { + return false; + } + + $this->queryStr = $str; + if (!empty($bind)) { + $that = $this; + $this->queryStr = strtr($this->queryStr, array_map(function ($val) use ($that) {return '\'' . $that->escapeString($val) . '\'';}, $bind)); } //释放前次的查询结果 - if ( !empty($this->PDOStatement) ) $this->free(); + if (!empty($this->PDOStatement)) { + $this->free(); + } + $this->queryTimes++; - N('db_query',1); // 兼容代码 + N('db_query', 1); // 兼容代码 // 调试开始 $this->debug(true); $this->PDOStatement = $this->_linkID->prepare($str); - if(false === $this->PDOStatement) + if (false === $this->PDOStatement) { E($this->error()); + } + foreach ($bind as $key => $val) { - if(is_array($val)){ + if (is_array($val)) { $this->PDOStatement->bindValue($key, $val[0], $val[1]); - }else{ + } else { $this->PDOStatement->bindValue($key, $val); } } - $result = $this->PDOStatement->execute(); + $result = $this->PDOStatement->execute(); // 调试结束 $this->debug(false); - if ( false === $result ) { + if (false === $result) { $this->error(); return false; } else { @@ -170,39 +188,46 @@ public function query($str,$bind=array()) { * @param array $bind 参数绑定 * @return integer */ - public function execute($str,$bind=array()) { + public function execute($str, $bind = array()) + { $this->initConnect(true); - if ( !$this->_linkID ) return false; + if (!$this->_linkID) { + return false; + } + $this->queryStr = $str; - if(!empty($bind)){ - $that = $this; - $this->queryStr = strtr($this->queryStr,array_map(function($val) use($that){ return '\''.$that->escapeString($val).'\''; },$bind)); - } + if (!empty($bind)) { + $that = $this; + $this->queryStr = strtr($this->queryStr, array_map(function ($val) use ($that) {return '\'' . $that->escapeString($val) . '\'';}, $bind)); + } //释放前次的查询结果 - if ( !empty($this->PDOStatement) ) $this->free(); + if (!empty($this->PDOStatement)) { + $this->free(); + } + $this->executeTimes++; - N('db_write',1); // 兼容代码 + N('db_write', 1); // 兼容代码 // 记录开始执行时间 $this->debug(true); - $this->PDOStatement = $this->_linkID->prepare($str); - if(false === $this->PDOStatement) { + $this->PDOStatement = $this->_linkID->prepare($str); + if (false === $this->PDOStatement) { E($this->error()); } foreach ($bind as $key => $val) { - if(is_array($val)){ + if (is_array($val)) { $this->PDOStatement->bindValue($key, $val[0], $val[1]); - }else{ + } else { $this->PDOStatement->bindValue($key, $val); } } - $result = $this->PDOStatement->execute(); + $result = $this->PDOStatement->execute(); $this->debug(false); - if ( false === $result) { + if (false === $result) { $this->error(); return false; } else { $this->numRows = $this->PDOStatement->rowCount(); - if(preg_match("/^\s*(INSERT\s+INTO|REPLACE\s+INTO)\s+/i", $str)) { + if (preg_match("/^\s*(INSERT\s+INTO|REPLACE\s+INTO)\s+/i", $str)) { $this->lastInsID = $this->_linkID->lastInsertId(); } return $this->numRows; @@ -214,15 +239,19 @@ public function execute($str,$bind=array()) { * @access public * @return void */ - public function startTrans() { + public function startTrans() + { $this->initConnect(true); - if ( !$this->_linkID ) return false; + if (!$this->_linkID) { + return false; + } + //数据rollback 支持 - if ($this->transTimes == 0) { + if (0 == $this->transTimes) { $this->_linkID->beginTransaction(); } $this->transTimes++; - return ; + return; } /** @@ -230,11 +259,12 @@ public function startTrans() { * @access public * @return boolean */ - public function commit() { + public function commit() + { if ($this->transTimes > 0) { - $result = $this->_linkID->commit(); + $result = $this->_linkID->commit(); $this->transTimes = 0; - if(!$result){ + if (!$result) { $this->error(); return false; } @@ -247,11 +277,12 @@ public function commit() { * @access public * @return boolean */ - public function rollback() { + public function rollback() + { if ($this->transTimes > 0) { - $result = $this->_linkID->rollback(); + $result = $this->_linkID->rollback(); $this->transTimes = 0; - if(!$result){ + if (!$result) { $this->error(); return false; } @@ -264,10 +295,11 @@ public function rollback() { * @access private * @return array */ - private function getResult() { + private function getResult() + { //返回数据集 - $result = $this->PDOStatement->fetchAll(PDO::FETCH_ASSOC); - $this->numRows = count( $result ); + $result = $this->PDOStatement->fetchAll(PDO::FETCH_ASSOC); + $this->numRows = count($result); return $result; } @@ -277,8 +309,9 @@ private function getResult() { * @param boolean $execute 是否包含所有查询 * @return integer */ - public function getQueryTimes($execute=false){ - return $execute?$this->queryTimes+$this->executeTimes:$this->queryTimes; + public function getQueryTimes($execute = false) + { + return $execute ? $this->queryTimes + $this->executeTimes : $this->queryTimes; } /** @@ -286,7 +319,8 @@ public function getQueryTimes($execute=false){ * @access public * @return integer */ - public function getExecuteTimes(){ + public function getExecuteTimes() + { return $this->executeTimes; } @@ -294,7 +328,8 @@ public function getExecuteTimes(){ * 关闭数据库 * @access public */ - public function close() { + public function close() + { $this->_linkID = null; } @@ -304,33 +339,36 @@ public function close() { * @access public * @return string */ - public function error() { - if($this->PDOStatement) { - $error = $this->PDOStatement->errorInfo(); - $this->error = $error[1].':'.$error[2]; - }else{ + public function error() + { + if ($this->PDOStatement) { + $error = $this->PDOStatement->errorInfo(); + $this->error = $error[1] . ':' . $error[2]; + } else { $this->error = ''; } - if('' != $this->queryStr){ - $this->error .= "\n [ SQL语句 ] : ".$this->queryStr; + if ('' != $this->queryStr) { + $this->error .= "\n [ SQL语句 ] : " . $this->queryStr; } // 记录错误日志 - trace($this->error,'','ERR'); - if($this->config['debug']) {// 开启数据库调试模式 + trace($this->error, '', 'ERR'); + if ($this->config['debug']) { +// 开启数据库调试模式 E($this->error); - }else{ + } else { return $this->error; } } /** - * 获取最近一次查询的sql语句 + * 获取最近一次查询的sql语句 * @param string $model 模型名 * @access public * @return string */ - public function getLastSql($model='') { - return $model?$this->modelSql[$model]:$this->queryStr; + public function getLastSql($model = '') + { + return $model ? $this->modelSql[$model] : $this->queryStr; } /** @@ -338,7 +376,8 @@ public function getLastSql($model='') { * @access public * @return string */ - public function getLastInsID() { + public function getLastInsID() + { return $this->lastInsID; } @@ -347,7 +386,8 @@ public function getLastInsID() { * @access public * @return string */ - public function getError() { + public function getError() + { return $this->error; } @@ -357,7 +397,8 @@ public function getError() { * @param string $str SQL字符串 * @return string */ - public function escapeString($str) { + public function escapeString($str) + { return addslashes($str); } @@ -367,8 +408,9 @@ public function escapeString($str) { * @param string $model 模型名 * @return void */ - public function setModel($model){ - $this->model = $model; + public function setModel($model) + { + $this->model = $model; } /** @@ -376,16 +418,18 @@ public function setModel($model){ * @access protected * @param boolean $start 调试开始标记 true 开始 false 结束 */ - protected function debug($start) { - if($this->config['debug']) {// 开启数据库调试模式 - if($start) { + protected function debug($start) + { + if ($this->config['debug']) { +// 开启数据库调试模式 + if ($start) { G('queryStartTime'); - }else{ - $this->modelSql[$this->model] = $this->queryStr; + } else { + $this->modelSql[$this->model] = $this->queryStr; //$this->model = '_think_'; // 记录操作结束时间 G('queryEndTime'); - trace($this->queryStr.' [ RunTime:'.G('queryStartTime','queryEndTime').'s ]','','SQL'); + trace($this->queryStr . ' [ RunTime:' . G('queryStartTime', 'queryEndTime') . 's ]', '', 'SQL'); } } } @@ -396,13 +440,18 @@ protected function debug($start) { * @param boolean $master 主服务器 * @return void */ - protected function initConnect($master=true) { - if(!empty($this->config['deploy'])) - // 采用分布式数据库 + protected function initConnect($master = true) + { + if (!empty($this->config['deploy'])) + // 采用分布式数据库 + { $this->_linkID = $this->multiConnect($master); - else - // 默认单数据库 - if ( !$this->_linkID ) $this->_linkID = $this->connect(); + } else + // 默认单数据库 + if (!$this->_linkID) { + $this->_linkID = $this->connect(); + } + } /** @@ -411,56 +460,60 @@ protected function initConnect($master=true) { * @param boolean $master 主服务器 * @return void */ - protected function multiConnect($master=false) { + protected function multiConnect($master = false) + { // 分布式数据库配置解析 - $_config['username'] = explode(',',$this->config['username']); - $_config['password'] = explode(',',$this->config['password']); - $_config['hostname'] = explode(',',$this->config['hostname']); - $_config['hostport'] = explode(',',$this->config['hostport']); - $_config['database'] = explode(',',$this->config['database']); - $_config['dsn'] = explode(',',$this->config['dsn']); - $_config['charset'] = explode(',',$this->config['charset']); + $_config['username'] = explode(',', $this->config['username']); + $_config['password'] = explode(',', $this->config['password']); + $_config['hostname'] = explode(',', $this->config['hostname']); + $_config['hostport'] = explode(',', $this->config['hostport']); + $_config['database'] = explode(',', $this->config['database']); + $_config['dsn'] = explode(',', $this->config['dsn']); + $_config['charset'] = explode(',', $this->config['charset']); // 数据库读写是否分离 - if($this->config['rw_separate']){ + if ($this->config['rw_separate']) { // 主从式采用读写分离 - if($master) - // 主服务器写入 - $r = floor(mt_rand(0,$this->config['master_num']-1)); - else{ - if(is_numeric($this->config['slave_no'])) {// 指定服务器读 + if ($master) + // 主服务器写入 + { + $r = floor(mt_rand(0, $this->config['master_num'] - 1)); + } else { + if (is_numeric($this->config['slave_no'])) { +// 指定服务器读 $r = $this->config['slave_no']; - }else{ + } else { // 读操作连接从服务器 - $r = floor(mt_rand($this->config['master_num'],count($_config['hostname'])-1)); // 每次随机连接的数据库 + $r = floor(mt_rand($this->config['master_num'], count($_config['hostname']) - 1)); // 每次随机连接的数据库 } } - }else{ + } else { // 读写操作不区分服务器 - $r = floor(mt_rand(0,count($_config['hostname'])-1)); // 每次随机连接的数据库 + $r = floor(mt_rand(0, count($_config['hostname']) - 1)); // 每次随机连接的数据库 } $db_config = array( - 'username' => isset($_config['username'][$r])?$_config['username'][$r]:$_config['username'][0], - 'password' => isset($_config['password'][$r])?$_config['password'][$r]:$_config['password'][0], - 'hostname' => isset($_config['hostname'][$r])?$_config['hostname'][$r]:$_config['hostname'][0], - 'hostport' => isset($_config['hostport'][$r])?$_config['hostport'][$r]:$_config['hostport'][0], - 'database' => isset($_config['database'][$r])?$_config['database'][$r]:$_config['database'][0], - 'dsn' => isset($_config['dsn'][$r])?$_config['dsn'][$r]:$_config['dsn'][0], - 'charset' => isset($_config['charset'][$r])?$_config['charset'][$r]:$_config['charset'][0], + 'username' => isset($_config['username'][$r]) ? $_config['username'][$r] : $_config['username'][0], + 'password' => isset($_config['password'][$r]) ? $_config['password'][$r] : $_config['password'][0], + 'hostname' => isset($_config['hostname'][$r]) ? $_config['hostname'][$r] : $_config['hostname'][0], + 'hostport' => isset($_config['hostport'][$r]) ? $_config['hostport'][$r] : $_config['hostport'][0], + 'database' => isset($_config['database'][$r]) ? $_config['database'][$r] : $_config['database'][0], + 'dsn' => isset($_config['dsn'][$r]) ? $_config['dsn'][$r] : $_config['dsn'][0], + 'charset' => isset($_config['charset'][$r]) ? $_config['charset'][$r] : $_config['charset'][0], ); - return $this->connect($db_config,$r); + return $this->connect($db_config, $r); } - /** + /** * 析构方法 * @access public */ - public function __destruct() { + public function __destruct() + { // 释放查询 - if ($this->PDOStatement){ + if ($this->PDOStatement) { $this->free(); } // 关闭连接 $this->close(); } -} \ No newline at end of file +} diff --git a/ThinkPHP/Library/Think/Dispatcher.class.php b/ThinkPHP/Library/Think/Dispatcher.class.php index e793dcffb..a276e4ea4 100644 --- a/ThinkPHP/Library/Think/Dispatcher.class.php +++ b/ThinkPHP/Library/Think/Dispatcher.class.php @@ -9,248 +9,280 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think; + /** * ThinkPHP内置的Dispatcher类 * 完成URL解析、路由和调度 */ -class Dispatcher { + +class Dispatcher +{ /** * URL映射到控制器 * @access public * @return void */ - static public function dispatch() { - $varPath = C('VAR_PATHINFO'); - $varAddon = C('VAR_ADDON'); - $varModule = C('VAR_MODULE'); - $varController = C('VAR_CONTROLLER'); - $varAction = C('VAR_ACTION'); - $urlCase = C('URL_CASE_INSENSITIVE'); - if(isset($_GET[$varPath])) { // 判断URL里面是否有兼容模式参数 + public static function dispatch() + { + $varPath = C('VAR_PATHINFO'); + $varAddon = C('VAR_ADDON'); + $varModule = C('VAR_MODULE'); + $varController = C('VAR_CONTROLLER'); + $varAction = C('VAR_ACTION'); + $urlCase = C('URL_CASE_INSENSITIVE'); + if (isset($_GET[$varPath])) { + // 判断URL里面是否有兼容模式参数 $_SERVER['PATH_INFO'] = $_GET[$varPath]; unset($_GET[$varPath]); - }elseif(IS_CLI){ // CLI模式下 index.php module/controller/action/params/... + } elseif (IS_CLI) { + // CLI模式下 index.php module/controller/action/params/... $_SERVER['PATH_INFO'] = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : ''; } // 开启子域名部署 - if(C('APP_SUB_DOMAIN_DEPLOY')) { - $rules = C('APP_SUB_DOMAIN_RULES'); - if(isset($rules[$_SERVER['HTTP_HOST']])) { // 完整域名或者IP配置 - define('APP_DOMAIN',$_SERVER['HTTP_HOST']); // 当前完整域名 + if (C('APP_SUB_DOMAIN_DEPLOY')) { + $rules = C('APP_SUB_DOMAIN_RULES'); + if (isset($rules[$_SERVER['HTTP_HOST']])) { + // 完整域名或者IP配置 + define('APP_DOMAIN', $_SERVER['HTTP_HOST']); // 当前完整域名 $rule = $rules[APP_DOMAIN]; - }else{ - if(strpos(C('APP_DOMAIN_SUFFIX'),'.')){ // com.cn net.cn + } else { + if (strpos(C('APP_DOMAIN_SUFFIX'), '.')) { + // com.cn net.cn $domain = array_slice(explode('.', $_SERVER['HTTP_HOST']), 0, -3); - }else{ - $domain = array_slice(explode('.', $_SERVER['HTTP_HOST']), 0, -2); + } else { + $domain = array_slice(explode('.', $_SERVER['HTTP_HOST']), 0, -2); } - if(!empty($domain)) { + if (!empty($domain)) { $subDomain = implode('.', $domain); - define('SUB_DOMAIN',$subDomain); // 当前完整子域名 - $domain2 = array_pop($domain); // 二级域名 - if($domain) { // 存在三级域名 + define('SUB_DOMAIN', $subDomain); // 当前完整子域名 + $domain2 = array_pop($domain); // 二级域名 + if ($domain) { + // 存在三级域名 $domain3 = array_pop($domain); } - if(isset($rules[$subDomain])) { // 子域名 + if (isset($rules[$subDomain])) { + // 子域名 $rule = $rules[$subDomain]; - }elseif(isset($rules['*.' . $domain2]) && !empty($domain3)){ // 泛三级域名 - $rule = $rules['*.' . $domain2]; + } elseif (isset($rules['*.' . $domain2]) && !empty($domain3)) { + // 泛三级域名 + $rule = $rules['*.' . $domain2]; $panDomain = $domain3; - }elseif(isset($rules['*']) && !empty($domain2) && 'www' != $domain2 ){ // 泛二级域名 + } elseif (isset($rules['*']) && !empty($domain2) && 'www' != $domain2) { + // 泛二级域名 $rule = $rules['*']; $panDomain = $domain2; } - } + } } - if(!empty($rule)) { + if (!empty($rule)) { // 子域名部署规则 '子域名'=>array('模块名[/控制器名]','var1=a&var2=b'); - if(is_array($rule)){ - list($rule,$vars) = $rule; + if (is_array($rule)) { + list($rule, $vars) = $rule; } - $array = explode('/',$rule); + $array = explode('/', $rule); // 模块绑定 - define('BIND_MODULE',array_shift($array)); - // 控制器绑定 - if(!empty($array)) { - $controller = array_shift($array); - if($controller){ - define('BIND_CONTROLLER',$controller); + define('BIND_MODULE', array_shift($array)); + // 控制器绑定 + if (!empty($array)) { + $controller = array_shift($array); + if ($controller) { + define('BIND_CONTROLLER', $controller); } } - if(isset($vars)) { // 传入参数 - parse_str($vars,$parms); - if(isset($panDomain)){ + if (isset($vars)) { + // 传入参数 + parse_str($vars, $parms); + if (isset($panDomain)) { $pos = array_search('*', $parms); - if(false !== $pos) { + if (false !== $pos) { // 泛域名作为参数 $parms[$pos] = $panDomain; - } - } - $_GET = array_merge($_GET,$parms); + } + } + $_GET = array_merge($_GET, $parms); } } } // 分析PATHINFO信息 - if(!isset($_SERVER['PATH_INFO'])) { - $types = explode(',',C('URL_PATHINFO_FETCH')); - foreach ($types as $type){ - if(0===strpos($type,':')) {// 支持函数判断 - $_SERVER['PATH_INFO'] = call_user_func(substr($type,1)); + if (!isset($_SERVER['PATH_INFO'])) { + $types = explode(',', C('URL_PATHINFO_FETCH')); + foreach ($types as $type) { + if (0 === strpos($type, ':')) { + // 支持函数判断 + $_SERVER['PATH_INFO'] = call_user_func(substr($type, 1)); break; - }elseif(!empty($_SERVER[$type])) { - $_SERVER['PATH_INFO'] = (0 === strpos($_SERVER[$type],$_SERVER['SCRIPT_NAME']))? - substr($_SERVER[$type], strlen($_SERVER['SCRIPT_NAME'])) : $_SERVER[$type]; + } elseif (!empty($_SERVER[$type])) { + $_SERVER['PATH_INFO'] = (0 === strpos($_SERVER[$type], $_SERVER['SCRIPT_NAME'])) ? + substr($_SERVER[$type], strlen($_SERVER['SCRIPT_NAME'])) : $_SERVER[$type]; break; } } } $depr = C('URL_PATHINFO_DEPR'); - define('MODULE_PATHINFO_DEPR', $depr); + define('MODULE_PATHINFO_DEPR', $depr); - if(empty($_SERVER['PATH_INFO'])) { + if (empty($_SERVER['PATH_INFO'])) { $_SERVER['PATH_INFO'] = ''; - define('__INFO__',''); - define('__EXT__',''); - }else{ - define('__INFO__',trim($_SERVER['PATH_INFO'],'/')); + define('__INFO__', ''); + define('__EXT__', ''); + } else { + define('__INFO__', trim($_SERVER['PATH_INFO'], '/')); // URL后缀 - define('__EXT__', strtolower(pathinfo($_SERVER['PATH_INFO'],PATHINFO_EXTENSION))); - $_SERVER['PATH_INFO'] = __INFO__; - if(!defined('BIND_MODULE') && (!C('URL_ROUTER_ON') || !Route::check())){ - if (__INFO__ && C('MULTI_MODULE')){ // 获取模块名 - $paths = explode($depr,__INFO__,2); - $_GET[$varModule] = preg_replace('/\.' . __EXT__ . '$/i', '',$paths[0]); - $_SERVER['PATH_INFO'] = isset($paths[1])?$paths[1]:''; + define('__EXT__', strtolower(pathinfo($_SERVER['PATH_INFO'], PATHINFO_EXTENSION))); + $_SERVER['PATH_INFO'] = __INFO__; + if (!defined('BIND_MODULE') && (!C('URL_ROUTER_ON') || !Route::check())) { + if (__INFO__ && C('MULTI_MODULE')) { + // 获取模块名 + $paths = explode($depr, __INFO__, 2); + $_GET[$varModule] = preg_replace('/\.' . __EXT__ . '$/i', '', $paths[0]); + $_SERVER['PATH_INFO'] = isset($paths[1]) ? $paths[1] : ''; } - } + } } // URL常量 - define('__SELF__',strip_tags($_SERVER[C('URL_REQUEST_URI')])); + define('__SELF__', strip_tags($_SERVER[C('URL_REQUEST_URI')])); // 获取模块名称 - define('MODULE_NAME', defined('BIND_MODULE')? BIND_MODULE : self::getModule($varModule)); - + define('MODULE_NAME', defined('BIND_MODULE') ? BIND_MODULE : self::getModule($varModule)); + // 检测模块是否存在 - if( MODULE_NAME && !in_array_case(MODULE_NAME,C('MODULE_DENY_LIST')) && is_dir(APP_PATH.MODULE_NAME)){ + if (MODULE_NAME && !in_array_case(MODULE_NAME, C('MODULE_DENY_LIST')) && is_dir(APP_PATH . MODULE_NAME)) { // 定义当前模块路径 - define('MODULE_PATH', APP_PATH.MODULE_NAME.'/'); + define('MODULE_PATH', APP_PATH . MODULE_NAME . '/'); // 定义当前模块的模版缓存路径 - C('CACHE_PATH',CACHE_PATH.MODULE_NAME.'/'); + C('CACHE_PATH', CACHE_PATH . MODULE_NAME . '/'); // 定义当前模块的日志目录 - C('LOG_PATH', realpath(LOG_PATH).'/'.MODULE_NAME.'/'); + C('LOG_PATH', realpath(LOG_PATH) . '/' . MODULE_NAME . '/'); // 模块检测 Hook::listen('module_check'); // 加载模块配置文件 - if(is_file(MODULE_PATH.'Conf/config'.CONF_EXT)) - C(load_config(MODULE_PATH.'Conf/config'.CONF_EXT)); + if (is_file(MODULE_PATH . 'Conf/config' . CONF_EXT)) { + C(load_config(MODULE_PATH . 'Conf/config' . CONF_EXT)); + } + // 加载应用模式对应的配置文件 - if('common' != APP_MODE && is_file(MODULE_PATH.'Conf/config_'.APP_MODE.CONF_EXT)) - C(load_config(MODULE_PATH.'Conf/config_'.APP_MODE.CONF_EXT)); + if ('common' != APP_MODE && is_file(MODULE_PATH . 'Conf/config_' . APP_MODE . CONF_EXT)) { + C(load_config(MODULE_PATH . 'Conf/config_' . APP_MODE . CONF_EXT)); + } + // 当前应用状态对应的配置文件 - if(APP_STATUS && is_file(MODULE_PATH.'Conf/'.APP_STATUS.CONF_EXT)) - C(load_config(MODULE_PATH.'Conf/'.APP_STATUS.CONF_EXT)); + if (APP_STATUS && is_file(MODULE_PATH . 'Conf/' . APP_STATUS . CONF_EXT)) { + C(load_config(MODULE_PATH . 'Conf/' . APP_STATUS . CONF_EXT)); + } // 加载模块别名定义 - if(is_file(MODULE_PATH.'Conf/alias.php')) - Think::addMap(include MODULE_PATH.'Conf/alias.php'); + if (is_file(MODULE_PATH . 'Conf/alias.php')) { + Think::addMap(include MODULE_PATH . 'Conf/alias.php'); + } + // 加载模块tags文件定义 - if(is_file(MODULE_PATH.'Conf/tags.php')) - Hook::import(include MODULE_PATH.'Conf/tags.php'); + if (is_file(MODULE_PATH . 'Conf/tags.php')) { + Hook::import(include MODULE_PATH . 'Conf/tags.php'); + } + // 加载模块函数文件 - if(is_file(MODULE_PATH.'Common/function.php')) - include MODULE_PATH.'Common/function.php'; - - $urlCase = C('URL_CASE_INSENSITIVE'); + if (is_file(MODULE_PATH . 'Common/function.php')) { + include MODULE_PATH . 'Common/function.php'; + } + + $urlCase = C('URL_CASE_INSENSITIVE'); // 加载模块的扩展配置文件 load_ext_file(MODULE_PATH); - }else{ - E(L('_MODULE_NOT_EXIST_').':'.MODULE_NAME); + } else { + E(L('_MODULE_NOT_EXIST_') . ':' . MODULE_NAME); } - if(!defined('__APP__')){ - $urlMode = C('URL_MODEL'); - if($urlMode == URL_COMPAT ){// 兼容模式判断 - define('PHP_FILE',_PHP_FILE_.'?'.$varPath.'='); - }elseif($urlMode == URL_REWRITE ) { - $url = dirname(_PHP_FILE_); - if($url == '/' || $url == '\\') - $url = ''; - define('PHP_FILE',$url); - }else { - define('PHP_FILE',_PHP_FILE_); - } - // 当前应用地址 - define('__APP__',strip_tags(PHP_FILE)); - } + if (!defined('__APP__')) { + $urlMode = C('URL_MODEL'); + if (URL_COMPAT == $urlMode) { + // 兼容模式判断 + define('PHP_FILE', _PHP_FILE_ . '?' . $varPath . '='); + } elseif (URL_REWRITE == $urlMode) { + $url = dirname(_PHP_FILE_); + if ('/' == $url || '\\' == $url) { + $url = ''; + } + + define('PHP_FILE', $url); + } else { + define('PHP_FILE', _PHP_FILE_); + } + // 当前应用地址 + define('__APP__', strip_tags(PHP_FILE)); + } // 模块URL地址 - $moduleName = defined('MODULE_ALIAS')? MODULE_ALIAS : MODULE_NAME; - define('__MODULE__',(defined('BIND_MODULE') || !C('MULTI_MODULE'))? __APP__ : __APP__.'/'.($urlCase ? strtolower($moduleName) : $moduleName)); + $moduleName = defined('MODULE_ALIAS') ? MODULE_ALIAS : MODULE_NAME; + define('__MODULE__', (defined('BIND_MODULE') || !C('MULTI_MODULE')) ? __APP__ : __APP__ . '/' . ($urlCase ? strtolower($moduleName) : $moduleName)); - if('' != $_SERVER['PATH_INFO'] && (!C('URL_ROUTER_ON') || !Route::check()) ){ // 检测路由规则 如果没有则按默认规则调度URL + if ('' != $_SERVER['PATH_INFO'] && (!C('URL_ROUTER_ON') || !Route::check())) { + // 检测路由规则 如果没有则按默认规则调度URL Hook::listen('path_info'); // 检查禁止访问的URL后缀 - if(C('URL_DENY_SUFFIX') && preg_match('/\.('.trim(C('URL_DENY_SUFFIX'),'.').')$/i', $_SERVER['PATH_INFO'])){ + if (C('URL_DENY_SUFFIX') && preg_match('/\.(' . trim(C('URL_DENY_SUFFIX'), '.') . ')$/i', $_SERVER['PATH_INFO'])) { send_http_status(404); exit; } - + // 去除URL后缀 - $_SERVER['PATH_INFO'] = preg_replace(C('URL_HTML_SUFFIX')? '/\.('.trim(C('URL_HTML_SUFFIX'),'.').')$/i' : '/\.'.__EXT__.'$/i', '', $_SERVER['PATH_INFO']); + $_SERVER['PATH_INFO'] = preg_replace(C('URL_HTML_SUFFIX') ? '/\.(' . trim(C('URL_HTML_SUFFIX'), '.') . ')$/i' : '/\.' . __EXT__ . '$/i', '', $_SERVER['PATH_INFO']); - $depr = C('URL_PATHINFO_DEPR'); - $paths = explode($depr,trim($_SERVER['PATH_INFO'],$depr)); + $depr = C('URL_PATHINFO_DEPR'); + $paths = explode($depr, trim($_SERVER['PATH_INFO'], $depr)); - if(!defined('BIND_CONTROLLER')) {// 获取控制器 - if(C('CONTROLLER_LEVEL')>1){// 控制器层次 - $_GET[$varController] = implode('/',array_slice($paths,0,C('CONTROLLER_LEVEL'))); - $paths = array_slice($paths, C('CONTROLLER_LEVEL')); - }else{ - $_GET[$varController] = array_shift($paths); + if (!defined('BIND_CONTROLLER')) { + // 获取控制器 + if (C('CONTROLLER_LEVEL') > 1) { + // 控制器层次 + $_GET[$varController] = implode('/', array_slice($paths, 0, C('CONTROLLER_LEVEL'))); + $paths = array_slice($paths, C('CONTROLLER_LEVEL')); + } else { + $_GET[$varController] = array_shift($paths); } } // 获取操作 - if(!defined('BIND_ACTION')){ - $_GET[$varAction] = array_shift($paths); + if (!defined('BIND_ACTION')) { + $_GET[$varAction] = array_shift($paths); } // 解析剩余的URL参数 - $var = array(); - if(C('URL_PARAMS_BIND') && 1 == C('URL_PARAMS_BIND_TYPE')){ + $var = array(); + if (C('URL_PARAMS_BIND') && 1 == C('URL_PARAMS_BIND_TYPE')) { // URL参数按顺序绑定变量 - $var = $paths; - }else{ - preg_replace_callback('/(\w+)\/([^\/]+)/', function($match) use(&$var){$var[$match[1]]=strip_tags($match[2]);}, implode('/',$paths)); + $var = $paths; + } else { + preg_replace_callback('/(\w+)\/([^\/]+)/', function ($match) use (&$var) {$var[$match[1]] = strip_tags($match[2]);}, implode('/', $paths)); } - $_GET = array_merge($var,$_GET); + $_GET = array_merge($var, $_GET); } // 获取控制器的命名空间(路径) - define('CONTROLLER_PATH', self::getSpace($varAddon,$urlCase)); + define('CONTROLLER_PATH', self::getSpace($varAddon, $urlCase)); // 获取控制器和操作名 - define('CONTROLLER_NAME', defined('BIND_CONTROLLER')? BIND_CONTROLLER : self::getController($varController,$urlCase)); - define('ACTION_NAME', defined('BIND_ACTION')? BIND_ACTION : self::getAction($varAction,$urlCase)); + define('CONTROLLER_NAME', defined('BIND_CONTROLLER') ? BIND_CONTROLLER : self::getController($varController, $urlCase)); + define('ACTION_NAME', defined('BIND_ACTION') ? BIND_ACTION : self::getAction($varAction, $urlCase)); // 当前控制器的UR地址 - $controllerName = defined('CONTROLLER_ALIAS')? CONTROLLER_ALIAS : CONTROLLER_NAME; - define('__CONTROLLER__',__MODULE__.$depr.(defined('BIND_CONTROLLER')? '': ( $urlCase ? parse_name($controllerName) : $controllerName )) ); + $controllerName = defined('CONTROLLER_ALIAS') ? CONTROLLER_ALIAS : CONTROLLER_NAME; + define('__CONTROLLER__', __MODULE__ . $depr . (defined('BIND_CONTROLLER') ? '' : ($urlCase ? parse_name($controllerName) : $controllerName))); // 当前操作的URL地址 - define('__ACTION__',__CONTROLLER__.$depr.(defined('ACTION_ALIAS')?ACTION_ALIAS:ACTION_NAME)); + define('__ACTION__', __CONTROLLER__ . $depr . (defined('ACTION_ALIAS') ? ACTION_ALIAS : ACTION_NAME)); //保证$_REQUEST正常取值 - $_REQUEST = array_merge($_POST,$_GET,$_COOKIE); // -- 加了$_COOKIE. 保证哦.. + $_REQUEST = array_merge($_POST, $_GET, $_COOKIE); // -- 加了$_COOKIE. 保证哦.. } /** * 获得控制器的命名空间路径 便于插件机制访问 */ - static private function getSpace($var,$urlCase) { - $space = !empty($_GET[$var])?strip_tags($_GET[$var]):''; + private static function getSpace($var, $urlCase) + { + $space = !empty($_GET[$var]) ? strip_tags($_GET[$var]) : ''; unset($_GET[$var]); return $space; } @@ -258,24 +290,25 @@ static private function getSpace($var,$urlCase) { /** * 获得实际的控制器名称 */ - static private function getController($var,$urlCase) { - $controller = (!empty($_GET[$var])? $_GET[$var]:C('DEFAULT_CONTROLLER')); + private static function getController($var, $urlCase) + { + $controller = (!empty($_GET[$var]) ? $_GET[$var] : C('DEFAULT_CONTROLLER')); unset($_GET[$var]); - if($maps = C('URL_CONTROLLER_MAP')) { - if(isset($maps[strtolower($controller)])) { + if ($maps = C('URL_CONTROLLER_MAP')) { + if (isset($maps[strtolower($controller)])) { // 记录当前别名 - define('CONTROLLER_ALIAS',strtolower($controller)); + define('CONTROLLER_ALIAS', strtolower($controller)); // 获取实际的控制器名 - return ucfirst($maps[CONTROLLER_ALIAS]); - }elseif(array_search(strtolower($controller),$maps)){ + return ucfirst($maps[CONTROLLER_ALIAS]); + } elseif (array_search(strtolower($controller), $maps)) { // 禁止访问原始控制器 - return ''; + return ''; } } - if($urlCase) { + if ($urlCase) { // URL地址不区分大小写 // 智能识别方式 user_type 识别到 UserTypeController 控制器 - $controller = parse_name($controller,1); + $controller = parse_name($controller, 1); } return strip_tags(ucfirst($controller)); } @@ -283,54 +316,56 @@ static private function getController($var,$urlCase) { /** * 获得实际的操作名称 */ - static private function getAction($var,$urlCase) { - $action = !empty($_POST[$var]) ? - $_POST[$var] : - (!empty($_GET[$var])?$_GET[$var]:C('DEFAULT_ACTION')); - unset($_POST[$var],$_GET[$var]); - if($maps = C('URL_ACTION_MAP')) { - if(isset($maps[strtolower(CONTROLLER_NAME)])) { - $maps = $maps[strtolower(CONTROLLER_NAME)]; - if(isset($maps[strtolower($action)])) { + private static function getAction($var, $urlCase) + { + $action = !empty($_POST[$var]) ? + $_POST[$var] : + (!empty($_GET[$var]) ? $_GET[$var] : C('DEFAULT_ACTION')); + unset($_POST[$var], $_GET[$var]); + if ($maps = C('URL_ACTION_MAP')) { + if (isset($maps[strtolower(CONTROLLER_NAME)])) { + $maps = $maps[strtolower(CONTROLLER_NAME)]; + if (isset($maps[strtolower($action)])) { // 记录当前别名 - define('ACTION_ALIAS',strtolower($action)); + define('ACTION_ALIAS', strtolower($action)); // 获取实际的操作名 - if(is_array($maps[ACTION_ALIAS])){ - parse_str($maps[ACTION_ALIAS][1],$vars); - $_GET = array_merge($_GET,$vars); + if (is_array($maps[ACTION_ALIAS])) { + parse_str($maps[ACTION_ALIAS][1], $vars); + $_GET = array_merge($_GET, $vars); return $maps[ACTION_ALIAS][0]; - }else{ + } else { return $maps[ACTION_ALIAS]; } - - }elseif(array_search(strtolower($action),$maps)){ + + } elseif (array_search(strtolower($action), $maps)) { // 禁止访问原始操作 - return ''; + return ''; } } } - return strip_tags( $urlCase? strtolower($action) : $action ); + return strip_tags($urlCase ? strtolower($action) : $action); } /** * 获得实际的模块名称 */ - static private function getModule($var) { - $module = (!empty($_GET[$var])?$_GET[$var]:C('DEFAULT_MODULE')); + private static function getModule($var) + { + $module = (!empty($_GET[$var]) ? $_GET[$var] : C('DEFAULT_MODULE')); unset($_GET[$var]); - $allowList = C('MODULE_ALLOW_LIST'); // 允许的模块列表 - if( !empty($allowList) && is_array($allowList) && !in_array_case($module, $allowList)){ - E(L('_MODULE_NOT_EXIST_').':'.strip_tags(ucfirst($module))); - } - if($maps = C('URL_MODULE_MAP')) { - if(isset($maps[strtolower($module)])) { + $allowList = C('MODULE_ALLOW_LIST'); // 允许的模块列表 + if (!empty($allowList) && is_array($allowList) && !in_array_case($module, $allowList)) { + E(L('_MODULE_NOT_EXIST_') . ':' . strip_tags(ucfirst($module))); + } + if ($maps = C('URL_MODULE_MAP')) { + if (isset($maps[strtolower($module)])) { // 记录当前别名 - define('MODULE_ALIAS',strtolower($module)); + define('MODULE_ALIAS', strtolower($module)); // 获取实际的模块名 - return ucfirst($maps[MODULE_ALIAS]); - }elseif(array_search(strtolower($module),$maps)){ + return ucfirst($maps[MODULE_ALIAS]); + } elseif (array_search(strtolower($module), $maps)) { // 禁止访问原始模块 - return ''; + return ''; } } return strip_tags(ucfirst($module)); diff --git a/ThinkPHP/Library/Think/Exception.class.php b/ThinkPHP/Library/Think/Exception.class.php index 7b4a918c0..16fa27972 100644 --- a/ThinkPHP/Library/Think/Exception.class.php +++ b/ThinkPHP/Library/Think/Exception.class.php @@ -9,8 +9,10 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think; + /** * ThinkPHP系统异常基类 */ -class Exception extends \Exception { -} \ No newline at end of file +class Exception extends \Exception +{ +} diff --git a/ThinkPHP/Library/Think/Hook.class.php b/ThinkPHP/Library/Think/Hook.class.php index 51176c7b8..cfee1a740 100644 --- a/ThinkPHP/Library/Think/Hook.class.php +++ b/ThinkPHP/Library/Think/Hook.class.php @@ -9,12 +9,14 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think; + /** * ThinkPHP系统钩子实现 */ -class Hook { +class Hook +{ - static private $tags = array(); + private static $tags = array(); /** * 动态添加插件到某个标签 @@ -22,14 +24,15 @@ class Hook { * @param mixed $name 插件名称 * @return void */ - static public function add($tag,$name) { - if(!isset(self::$tags[$tag])){ - self::$tags[$tag] = array(); + public static function add($tag, $name) + { + if (!isset(self::$tags[$tag])) { + self::$tags[$tag] = array(); } - if(is_array($name)){ - self::$tags[$tag] = array_merge(self::$tags[$tag],$name); - }else{ - self::$tags[$tag][] = $name; + if (is_array($name)) { + self::$tags[$tag] = array_merge(self::$tags[$tag], $name); + } else { + self::$tags[$tag][] = $name; } } @@ -39,22 +42,27 @@ static public function add($tag,$name) { * @param boolean $recursive 是否递归合并 * @return void */ - static public function import($data,$recursive=true) { - if(!$recursive){ // 覆盖导入 - self::$tags = array_merge(self::$tags,$data); - }else{ // 合并导入 - foreach ($data as $tag=>$val){ - if(!isset(self::$tags[$tag])) - self::$tags[$tag] = array(); - if(!empty($val['_overlay'])){ + public static function import($data, $recursive = true) + { + if (!$recursive) { + // 覆盖导入 + self::$tags = array_merge(self::$tags, $data); + } else { + // 合并导入 + foreach ($data as $tag => $val) { + if (!isset(self::$tags[$tag])) { + self::$tags[$tag] = array(); + } + + if (!empty($val['_overlay'])) { // 可以针对某个标签指定覆盖模式 unset($val['_overlay']); - self::$tags[$tag] = $val; - }else{ + self::$tags[$tag] = $val; + } else { // 合并模式 - self::$tags[$tag] = array_merge(self::$tags[$tag],$val); + self::$tags[$tag] = array_merge(self::$tags[$tag], $val); } - } + } } } @@ -63,11 +71,12 @@ static public function import($data,$recursive=true) { * @param string $tag 插件位置 留空获取全部 * @return array */ - static public function get($tag='') { - if(empty($tag)){ + public static function get($tag = '') + { + if (empty($tag)) { // 获取全部的插件信息 return self::$tags; - }else{ + } else { return self::$tags[$tag]; } } @@ -78,26 +87,28 @@ static public function get($tag='') { * @param mixed $params 传入参数 * @return void */ - static public function listen($tag, &$params=NULL) { - if(isset(self::$tags[$tag])) { - if(APP_DEBUG) { - G($tag.'Start'); - trace('[ '.$tag.' ] --START--','','INFO'); + public static function listen($tag, &$params = null) + { + if (isset(self::$tags[$tag])) { + if (APP_DEBUG) { + G($tag . 'Start'); + trace('[ ' . $tag . ' ] --START--', '', 'INFO'); } foreach (self::$tags[$tag] as $name) { - APP_DEBUG && G($name.'_start'); - $result = self::exec($name, $tag,$params); - if(APP_DEBUG){ - G($name.'_end'); - trace('Run '.$name.' [ RunTime:'.G($name.'_start',$name.'_end',6).'s ]','','INFO'); + APP_DEBUG && G($name . '_start'); + $result = self::exec($name, $tag, $params); + if (APP_DEBUG) { + G($name . '_end'); + trace('Run ' . $name . ' [ RunTime:' . G($name . '_start', $name . '_end', 6) . 's ]', '', 'INFO'); } - if(false === $result) { + if (false === $result) { // 如果返回false 则中断插件执行 - return ; + return; } } - if(APP_DEBUG) { // 记录行为的执行日志 - trace('[ '.$tag.' ] --END-- [ RunTime:'.G($tag.'Start',$tag.'End',6).'s ]','','INFO'); + if (APP_DEBUG) { + // 记录行为的执行日志 + trace('[ ' . $tag . ' ] --END-- [ RunTime:' . G($tag . 'Start', $tag . 'End', 6) . 's ]', '', 'INFO'); } } return; @@ -106,16 +117,17 @@ static public function listen($tag, &$params=NULL) { /** * 执行某个插件 * @param string $name 插件名称 - * @param string $tag 方法名(标签名) + * @param string $tag 方法名(标签名) * @param Mixed $params 传入的参数 * @return void */ - static public function exec($name, $tag,&$params=NULL) { - if('Behavior' == substr($name,-8) ){ + public static function exec($name, $tag, &$params = null) + { + if ('Behavior' == substr($name, -8)) { // 行为扩展必须用run入口方法 - $tag = 'run'; + $tag = 'run'; } - $addon = new $name(); + $addon = new $name(); return $addon->$tag($params); } } diff --git a/ThinkPHP/Library/Think/Image.class.php b/ThinkPHP/Library/Think/Image.class.php index 178365e32..1c5fabb96 100644 --- a/ThinkPHP/Library/Think/Image.class.php +++ b/ThinkPHP/Library/Think/Image.class.php @@ -18,29 +18,30 @@ * 目前支持GD库和imagick * @author 麦当苗儿 */ -class Image{ +class Image +{ /* 驱动相关常量定义 */ - const IMAGE_GD = 1; //常量,标识GD库类型 - const IMAGE_IMAGICK = 2; //常量,标识imagick库类型 + const IMAGE_GD = 1; //常量,标识GD库类型 + const IMAGE_IMAGICK = 2; //常量,标识imagick库类型 /* 缩略图相关常量定义 */ - const IMAGE_THUMB_SCALE = 1 ; //常量,标识缩略图等比例缩放类型 - const IMAGE_THUMB_FILLED = 2 ; //常量,标识缩略图缩放后填充类型 - const IMAGE_THUMB_CENTER = 3 ; //常量,标识缩略图居中裁剪类型 - const IMAGE_THUMB_NORTHWEST = 4 ; //常量,标识缩略图左上角裁剪类型 - const IMAGE_THUMB_SOUTHEAST = 5 ; //常量,标识缩略图右下角裁剪类型 - const IMAGE_THUMB_FIXED = 6 ; //常量,标识缩略图固定尺寸缩放类型 + const IMAGE_THUMB_SCALE = 1; //常量,标识缩略图等比例缩放类型 + const IMAGE_THUMB_FILLED = 2; //常量,标识缩略图缩放后填充类型 + const IMAGE_THUMB_CENTER = 3; //常量,标识缩略图居中裁剪类型 + const IMAGE_THUMB_NORTHWEST = 4; //常量,标识缩略图左上角裁剪类型 + const IMAGE_THUMB_SOUTHEAST = 5; //常量,标识缩略图右下角裁剪类型 + const IMAGE_THUMB_FIXED = 6; //常量,标识缩略图固定尺寸缩放类型 /* 水印相关常量定义 */ - const IMAGE_WATER_NORTHWEST = 1 ; //常量,标识左上角水印 - const IMAGE_WATER_NORTH = 2 ; //常量,标识上居中水印 - const IMAGE_WATER_NORTHEAST = 3 ; //常量,标识右上角水印 - const IMAGE_WATER_WEST = 4 ; //常量,标识左居中水印 - const IMAGE_WATER_CENTER = 5 ; //常量,标识居中水印 - const IMAGE_WATER_EAST = 6 ; //常量,标识右居中水印 - const IMAGE_WATER_SOUTHWEST = 7 ; //常量,标识左下角水印 - const IMAGE_WATER_SOUTH = 8 ; //常量,标识下居中水印 - const IMAGE_WATER_SOUTHEAST = 9 ; //常量,标识右下角水印 + const IMAGE_WATER_NORTHWEST = 1; //常量,标识左上角水印 + const IMAGE_WATER_NORTH = 2; //常量,标识上居中水印 + const IMAGE_WATER_NORTHEAST = 3; //常量,标识右上角水印 + const IMAGE_WATER_WEST = 4; //常量,标识左居中水印 + const IMAGE_WATER_CENTER = 5; //常量,标识居中水印 + const IMAGE_WATER_EAST = 6; //常量,标识右居中水印 + const IMAGE_WATER_SOUTHWEST = 7; //常量,标识左下角水印 + const IMAGE_WATER_SOUTH = 8; //常量,标识下居中水印 + const IMAGE_WATER_SOUTHEAST = 9; //常量,标识右下角水印 /** * 图片资源 @@ -52,7 +53,8 @@ class Image{ * 构造方法,用于实例化一个图片处理对象 * @param string $type 要使用的类库,默认使用GD库 */ - public function __construct($type = self::IMAGE_GD, $imgname = null){ + public function __construct($type = self::IMAGE_GD, $imgname = null) + { /* 判断调用库的类型 */ switch ($type) { case self::IMAGE_GD: @@ -66,7 +68,7 @@ public function __construct($type = self::IMAGE_GD, $imgname = null){ } /* 引入处理库,实例化图片处理对象 */ - $class = "Think\\Image\\Driver\\{$class}"; + $class = "Think\\Image\\Driver\\{$class}"; $this->img = new $class($imgname); } @@ -75,7 +77,8 @@ public function __construct($type = self::IMAGE_GD, $imgname = null){ * @param string $imgname 图片路径 * @return Object 当前图片处理库对象 */ - public function open($imgname){ + public function open($imgname) + { $this->img->open($imgname); return $this; } @@ -84,12 +87,13 @@ public function open($imgname){ * 保存图片 * @param string $imgname 图片保存名称 * @param string $type 图片类型 - * @param integer $quality 图像质量 + * @param integer $quality 图像质量 * @param boolean $interlace 是否对JPEG类型图片设置隔行扫描 * @return Object 当前图片处理库对象 */ - public function save($imgname, $type = null, $quality=80,$interlace = true){ - $this->img->save($imgname, $type, $quality,$interlace); + public function save($imgname, $type = null, $quality = 80, $interlace = true) + { + $this->img->save($imgname, $type, $quality, $interlace); return $this; } @@ -97,7 +101,8 @@ public function save($imgname, $type = null, $quality=80,$interlace = true){ * 返回图片宽度 * @return integer 图片宽度 */ - public function width(){ + public function width() + { return $this->img->width(); } @@ -105,7 +110,8 @@ public function width(){ * 返回图片高度 * @return integer 图片高度 */ - public function height(){ + public function height() + { return $this->img->height(); } @@ -113,7 +119,8 @@ public function height(){ * 返回图像类型 * @return string 图片类型 */ - public function type(){ + public function type() + { return $this->img->type(); } @@ -121,7 +128,8 @@ public function type(){ * 返回图像MIME类型 * @return string 图像MIME类型 */ - public function mime(){ + public function mime() + { return $this->img->mime(); } @@ -129,7 +137,8 @@ public function mime(){ * 返回图像尺寸数组 0 - 图片宽度,1 - 图片高度 * @return array 图片尺寸 */ - public function size(){ + public function size() + { return $this->img->size(); } @@ -143,7 +152,8 @@ public function size(){ * @param integer $height 图片保存高度 * @return Object 当前图片处理库对象 */ - public function crop($w, $h, $x = 0, $y = 0, $width = null, $height = null){ + public function crop($w, $h, $x = 0, $y = 0, $width = null, $height = null) + { $this->img->crop($w, $h, $x, $y, $width, $height); return $this; } @@ -155,7 +165,8 @@ public function crop($w, $h, $x = 0, $y = 0, $width = null, $height = null){ * @param integer $type 缩略图裁剪类型 * @return Object 当前图片处理库对象 */ - public function thumb($width, $height, $type = self::IMAGE_THUMB_SCALE){ + public function thumb($width, $height, $type = self::IMAGE_THUMB_SCALE) + { $this->img->thumb($width, $height, $type); return $this; } @@ -167,8 +178,9 @@ public function thumb($width, $height, $type = self::IMAGE_THUMB_SCALE){ * @param integer $alpha 水印透明度 * @return Object 当前图片处理库对象 */ - public function water($source, $locate = self::IMAGE_WATER_SOUTHEAST,$alpha=80){ - $this->img->water($source, $locate,$alpha); + public function water($source, $locate = self::IMAGE_WATER_SOUTHEAST, $alpha = 80) + { + $this->img->water($source, $locate, $alpha); return $this; } @@ -183,9 +195,9 @@ public function water($source, $locate = self::IMAGE_WATER_SOUTHEAST,$alpha=80){ * @param integer $angle 文字倾斜角度 * @return Object 当前图片处理库对象 */ - public function text($text, $font, $size, $color = '#00000000', - $locate = self::IMAGE_WATER_SOUTHEAST, $offset = 0, $angle = 0){ + public function text($text, $font, $size, $color = '#00000000', + $locate = self::IMAGE_WATER_SOUTHEAST, $offset = 0, $angle = 0) { $this->img->text($text, $font, $size, $color, $locate, $offset, $angle); return $this; } -} \ No newline at end of file +} diff --git a/ThinkPHP/Library/Think/Image/Driver/GIF.class.php b/ThinkPHP/Library/Think/Image/Driver/GIF.class.php index 359d2ae9c..d39ccbdbb 100644 --- a/ThinkPHP/Library/Think/Image/Driver/GIF.class.php +++ b/ThinkPHP/Library/Think/Image/Driver/GIF.class.php @@ -11,81 +11,86 @@ // | GIF.class.php 2013-03-09 // +---------------------------------------------------------------------- namespace Think\Image\Driver; -class GIF{ - /** - * GIF帧列表 - * @var array - */ - private $frames = array(); - - /** - * 每帧等待时间列表 - * @var array - */ - private $delays = array(); - - /** - * 构造方法,用于解码GIF图片 - * @param string $src GIF图片数据 - * @param string $mod 图片数据类型 - */ - public function __construct($src = null, $mod = 'url') { - if(!is_null($src)){ - if('url' == $mod && is_file($src)){ - $src = file_get_contents($src); - } - - /* 解码GIF图片 */ - try{ - $de = new GIFDecoder($src); - $this->frames = $de->GIFGetFrames(); - $this->delays = $de->GIFGetDelays(); - } catch(\Exception $e){ - E("解码GIF图片出错"); - } - } - } - - /** - * 设置或获取当前帧的数据 - * @param string $stream 二进制数据流 - * @return boolean 获取到的数据 - */ - public function image($stream = null){ - if(is_null($stream)){ - $current = current($this->frames); - return false === $current ? reset($this->frames) : $current; - } else { - $this->frames[key($this->frames)] = $stream; - } - } - - /** - * 将当前帧移动到下一帧 - * @return string 当前帧数据 - */ - public function nextImage(){ - return next($this->frames); - } - - /** - * 编码并保存当前GIF图片 - * @param string $gifname 图片名称 - */ - public function save($gifname){ - $gif = new GIFEncoder($this->frames, $this->delays, 0, 2, 0, 0, 0, 'bin'); - file_put_contents($gifname, $gif->GetAnimation()); - } -} +class GIF +{ + /** + * GIF帧列表 + * @var array + */ + private $frames = array(); + + /** + * 每帧等待时间列表 + * @var array + */ + private $delays = array(); + + /** + * 构造方法,用于解码GIF图片 + * @param string $src GIF图片数据 + * @param string $mod 图片数据类型 + */ + public function __construct($src = null, $mod = 'url') + { + if (!is_null($src)) { + if ('url' == $mod && is_file($src)) { + $src = file_get_contents($src); + } + + /* 解码GIF图片 */ + try { + $de = new GIFDecoder($src); + $this->frames = $de->GIFGetFrames(); + $this->delays = $de->GIFGetDelays(); + } catch (\Exception $e) { + E("解码GIF图片出错"); + } + } + } + + /** + * 设置或获取当前帧的数据 + * @param string $stream 二进制数据流 + * @return boolean 获取到的数据 + */ + public function image($stream = null) + { + if (is_null($stream)) { + $current = current($this->frames); + return false === $current ? reset($this->frames) : $current; + } else { + $this->frames[key($this->frames)] = $stream; + } + } + + /** + * 将当前帧移动到下一帧 + * @return string 当前帧数据 + */ + public function nextImage() + { + return next($this->frames); + } + + /** + * 编码并保存当前GIF图片 + * @param string $gifname 图片名称 + */ + public function save($gifname) + { + $gif = new GIFEncoder($this->frames, $this->delays, 0, 2, 0, 0, 0, 'bin'); + file_put_contents($gifname, $gif->GetAnimation()); + } +} /* ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :: -:: GIFEncoder Version 2.0 by László Zsidi, http://gifs.hu +:: GIFEncoder Version 2.0 by László Zsidi, http://gifs.hu :: -:: This class is a rewritten 'GifMerge.class.php' version. +:: This class is a rewritten 'GifMerge.class.php' version. :: :: Modification: :: - Simplified and easy code, @@ -94,7 +99,7 @@ public function save($gifname){ :: - Stable working :: :: -:: Updated at 2007. 02. 13. '00.05.AM' +:: Updated at 2007. 02. 13. '00.05.AM' :: :: :: @@ -103,225 +108,227 @@ public function save($gifname){ :: http://gifs.hu/phpclasses/demos/GifBuilder/ :: ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -*/ - -Class GIFEncoder { - private $GIF = "GIF89a"; /* GIF header 6 bytes */ - private $VER = "GIFEncoder V2.05"; /* Encoder version */ - - private $BUF = Array ( ); - private $LOP = 0; - private $DIS = 2; - private $COL = -1; - private $IMG = -1; - - private $ERR = Array ( - 'ERR00' => "Does not supported function for only one image!", - 'ERR01' => "Source is not a GIF image!", - 'ERR02' => "Unintelligible flag ", - 'ERR03' => "Does not make animation from animated GIF source", - ); - - /* - ::::::::::::::::::::::::::::::::::::::::::::::::::: - :: - :: GIFEncoder... - :: - */ - public function __construct($GIF_src, $GIF_dly, $GIF_lop, $GIF_dis,$GIF_red, $GIF_grn, $GIF_blu, $GIF_mod) { - if ( ! is_array ( $GIF_src ) && ! is_array ( $GIF_dly ) ) { - printf ( "%s: %s", $this->VER, $this->ERR [ 'ERR00' ] ); - exit ( 0 ); - } - $this->LOP = ( $GIF_lop > -1 ) ? $GIF_lop : 0; - $this->DIS = ( $GIF_dis > -1 ) ? ( ( $GIF_dis < 3 ) ? $GIF_dis : 3 ) : 2; - $this->COL = ( $GIF_red > -1 && $GIF_grn > -1 && $GIF_blu > -1 ) ? - ( $GIF_red | ( $GIF_grn << 8 ) | ( $GIF_blu << 16 ) ) : -1; - - for ( $i = 0; $i < count ( $GIF_src ); $i++ ) { - if ( strToLower ( $GIF_mod ) == "url" ) { - $this->BUF [ ] = fread ( fopen ( $GIF_src [ $i ], "rb" ), filesize ( $GIF_src [ $i ] ) ); - } - else if ( strToLower ( $GIF_mod ) == "bin" ) { - $this->BUF [ ] = $GIF_src [ $i ]; - } - else { - printf ( "%s: %s ( %s )!", $this->VER, $this->ERR [ 'ERR02' ], $GIF_mod ); - exit ( 0 ); - } - if ( substr ( $this->BUF [ $i ], 0, 6 ) != "GIF87a" && substr ( $this->BUF [ $i ], 0, 6 ) != "GIF89a" ) { - printf ( "%s: %d %s", $this->VER, $i, $this->ERR [ 'ERR01' ] ); - exit ( 0 ); - } - for ( $j = ( 13 + 3 * ( 2 << ( ord ( $this->BUF [ $i ] { 10 } ) & 0x07 ) ) ), $k = TRUE; $k; $j++ ) { - switch ( $this->BUF [ $i ] { $j } ) { - case "!": - if ( ( substr ( $this->BUF [ $i ], ( $j + 3 ), 8 ) ) == "NETSCAPE" ) { - printf ( "%s: %s ( %s source )!", $this->VER, $this->ERR [ 'ERR03' ], ( $i + 1 ) ); - exit ( 0 ); - } - break; - case ";": - $k = FALSE; - break; - } - } - } - $this->GIFAddHeader ( ); - for ( $i = 0; $i < count ( $this->BUF ); $i++ ) { - $this->GIFAddFrames ( $i, $GIF_dly [ $i ] ); - } - $this->GIFAddFooter ( ); - } - /* - ::::::::::::::::::::::::::::::::::::::::::::::::::: - :: - :: GIFAddHeader... - :: - */ - private function GIFAddHeader ( ) { - $cmap = 0; - - if ( ord ( $this->BUF [ 0 ] { 10 } ) & 0x80 ) { - $cmap = 3 * ( 2 << ( ord ( $this->BUF [ 0 ] { 10 } ) & 0x07 ) ); - - $this->GIF .= substr ( $this->BUF [ 0 ], 6, 7 ); - $this->GIF .= substr ( $this->BUF [ 0 ], 13, $cmap ); - $this->GIF .= "!\377\13NETSCAPE2.0\3\1" . $this->GIFWord ( $this->LOP ) . "\0"; - } - } - /* - ::::::::::::::::::::::::::::::::::::::::::::::::::: - :: - :: GIFAddFrames... - :: - */ - private function GIFAddFrames ( $i, $d ) { - - $Locals_str = 13 + 3 * ( 2 << ( ord ( $this->BUF [ $i ] { 10 } ) & 0x07 ) ); - - $Locals_end = strlen ( $this->BUF [ $i ] ) - $Locals_str - 1; - $Locals_tmp = substr ( $this->BUF [ $i ], $Locals_str, $Locals_end ); - - $Global_len = 2 << ( ord ( $this->BUF [ 0 ] { 10 } ) & 0x07 ); - $Locals_len = 2 << ( ord ( $this->BUF [ $i ] { 10 } ) & 0x07 ); - - $Global_rgb = substr ( $this->BUF [ 0 ], 13, - 3 * ( 2 << ( ord ( $this->BUF [ 0 ] { 10 } ) & 0x07 ) ) ); - $Locals_rgb = substr ( $this->BUF [ $i ], 13, - 3 * ( 2 << ( ord ( $this->BUF [ $i ] { 10 } ) & 0x07 ) ) ); - - $Locals_ext = "!\xF9\x04" . chr ( ( $this->DIS << 2 ) + 0 ) . - chr ( ( $d >> 0 ) & 0xFF ) . chr ( ( $d >> 8 ) & 0xFF ) . "\x0\x0"; - - if ( $this->COL > -1 && ord ( $this->BUF [ $i ] { 10 } ) & 0x80 ) { - for ( $j = 0; $j < ( 2 << ( ord ( $this->BUF [ $i ] { 10 } ) & 0x07 ) ); $j++ ) { - if ( - ord ( $Locals_rgb { 3 * $j + 0 } ) == ( ( $this->COL >> 16 ) & 0xFF ) && - ord ( $Locals_rgb { 3 * $j + 1 } ) == ( ( $this->COL >> 8 ) & 0xFF ) && - ord ( $Locals_rgb { 3 * $j + 2 } ) == ( ( $this->COL >> 0 ) & 0xFF ) - ) { - $Locals_ext = "!\xF9\x04" . chr ( ( $this->DIS << 2 ) + 1 ) . - chr ( ( $d >> 0 ) & 0xFF ) . chr ( ( $d >> 8 ) & 0xFF ) . chr ( $j ) . "\x0"; - break; - } - } - } - switch ( $Locals_tmp { 0 } ) { - case "!": - $Locals_img = substr ( $Locals_tmp, 8, 10 ); - $Locals_tmp = substr ( $Locals_tmp, 18, strlen ( $Locals_tmp ) - 18 ); - break; - case ",": - $Locals_img = substr ( $Locals_tmp, 0, 10 ); - $Locals_tmp = substr ( $Locals_tmp, 10, strlen ( $Locals_tmp ) - 10 ); - break; - } - if ( ord ( $this->BUF [ $i ] { 10 } ) & 0x80 && $this->IMG > -1 ) { - if ( $Global_len == $Locals_len ) { - if ( $this->GIFBlockCompare ( $Global_rgb, $Locals_rgb, $Global_len ) ) { - $this->GIF .= ( $Locals_ext . $Locals_img . $Locals_tmp ); - } - else { - $byte = ord ( $Locals_img { 9 } ); - $byte |= 0x80; - $byte &= 0xF8; - $byte |= ( ord ( $this->BUF [ 0 ] { 10 } ) & 0x07 ); - $Locals_img { 9 } = chr ( $byte ); - $this->GIF .= ( $Locals_ext . $Locals_img . $Locals_rgb . $Locals_tmp ); - } - } - else { - $byte = ord ( $Locals_img { 9 } ); - $byte |= 0x80; - $byte &= 0xF8; - $byte |= ( ord ( $this->BUF [ $i ] { 10 } ) & 0x07 ); - $Locals_img { 9 } = chr ( $byte ); - $this->GIF .= ( $Locals_ext . $Locals_img . $Locals_rgb . $Locals_tmp ); - } - } - else { - $this->GIF .= ( $Locals_ext . $Locals_img . $Locals_tmp ); - } - $this->IMG = 1; - } - /* - ::::::::::::::::::::::::::::::::::::::::::::::::::: - :: - :: GIFAddFooter... - :: - */ - private function GIFAddFooter ( ) { - $this->GIF .= ";"; - } - /* - ::::::::::::::::::::::::::::::::::::::::::::::::::: - :: - :: GIFBlockCompare... - :: - */ - private function GIFBlockCompare ( $GlobalBlock, $LocalBlock, $Len ) { - - for ( $i = 0; $i < $Len; $i++ ) { - if ( - $GlobalBlock { 3 * $i + 0 } != $LocalBlock { 3 * $i + 0 } || - $GlobalBlock { 3 * $i + 1 } != $LocalBlock { 3 * $i + 1 } || - $GlobalBlock { 3 * $i + 2 } != $LocalBlock { 3 * $i + 2 } - ) { - return ( 0 ); - } - } - - return ( 1 ); - } - /* - ::::::::::::::::::::::::::::::::::::::::::::::::::: - :: - :: GIFWord... - :: - */ - private function GIFWord ( $int ) { - - return ( chr ( $int & 0xFF ) . chr ( ( $int >> 8 ) & 0xFF ) ); - } - /* - ::::::::::::::::::::::::::::::::::::::::::::::::::: - :: - :: GetAnimation... - :: - */ - public function GetAnimation ( ) { - return ( $this->GIF ); - } + */ + +class GIFEncoder +{ + private $GIF = "GIF89a"; /* GIF header 6 bytes */ + private $VER = "GIFEncoder V2.05"; /* Encoder version */ + + private $BUF = array(); + private $LOP = 0; + private $DIS = 2; + private $COL = -1; + private $IMG = -1; + + private $ERR = array( + 'ERR00' => "Does not supported function for only one image!", + 'ERR01' => "Source is not a GIF image!", + 'ERR02' => "Unintelligible flag ", + 'ERR03' => "Does not make animation from animated GIF source", + ); + + /* + ::::::::::::::::::::::::::::::::::::::::::::::::::: + :: + :: GIFEncoder... + :: + */ + public function __construct($GIF_src, $GIF_dly, $GIF_lop, $GIF_dis, $GIF_red, $GIF_grn, $GIF_blu, $GIF_mod) + { + if (!is_array($GIF_src) && !is_array($GIF_dly)) { + printf("%s: %s", $this->VER, $this->ERR['ERR00']); + exit(0); + } + $this->LOP = ($GIF_lop > -1) ? $GIF_lop : 0; + $this->DIS = ($GIF_dis > -1) ? (($GIF_dis < 3) ? $GIF_dis : 3) : 2; + $this->COL = ($GIF_red > -1 && $GIF_grn > -1 && $GIF_blu > -1) ? + ($GIF_red | ($GIF_grn << 8) | ($GIF_blu << 16)) : -1; + + for ($i = 0; $i < count($GIF_src); $i++) { + if (strToLower($GIF_mod) == "url") { + $this->BUF[] = fread(fopen($GIF_src[$i], "rb"), filesize($GIF_src[$i])); + } else if (strToLower($GIF_mod) == "bin") { + $this->BUF[] = $GIF_src[$i]; + } else { + printf("%s: %s ( %s )!", $this->VER, $this->ERR['ERR02'], $GIF_mod); + exit(0); + } + if (substr($this->BUF[$i], 0, 6) != "GIF87a" && substr($this->BUF[$i], 0, 6) != "GIF89a") { + printf("%s: %d %s", $this->VER, $i, $this->ERR['ERR01']); + exit(0); + } + for ($j = (13 + 3 * (2 << (ord($this->BUF[$i]{10}) & 0x07))), $k = true; $k; $j++) { + switch ($this->BUF[$i]{ $j}) { + case "!": + if ((substr($this->BUF[$i], ($j + 3), 8)) == "NETSCAPE") { + printf("%s: %s ( %s source )!", $this->VER, $this->ERR['ERR03'], ($i + 1)); + exit(0); + } + break; + case ";": + $k = false; + break; + } + } + } + $this->GIFAddHeader(); + for ($i = 0; $i < count($this->BUF); $i++) { + $this->GIFAddFrames($i, $GIF_dly[$i]); + } + $this->GIFAddFooter(); + } + /* + ::::::::::::::::::::::::::::::::::::::::::::::::::: + :: + :: GIFAddHeader... + :: + */ + private function GIFAddHeader() + { + $cmap = 0; + + if (ord($this->BUF[0]{10}) & 0x80) { + $cmap = 3 * (2 << (ord($this->BUF[0]{10}) & 0x07)); + + $this->GIF .= substr($this->BUF[0], 6, 7); + $this->GIF .= substr($this->BUF[0], 13, $cmap); + $this->GIF .= "!\377\13NETSCAPE2.0\3\1" . $this->GIFWord($this->LOP) . "\0"; + } + } + /* + ::::::::::::::::::::::::::::::::::::::::::::::::::: + :: + :: GIFAddFrames... + :: + */ + private function GIFAddFrames($i, $d) + { + + $Locals_str = 13 + 3 * (2 << (ord($this->BUF[$i]{10}) & 0x07)); + + $Locals_end = strlen($this->BUF[$i]) - $Locals_str - 1; + $Locals_tmp = substr($this->BUF[$i], $Locals_str, $Locals_end); + + $Global_len = 2 << (ord($this->BUF[0]{10}) & 0x07); + $Locals_len = 2 << (ord($this->BUF[$i]{10}) & 0x07); + + $Global_rgb = substr($this->BUF[0], 13, + 3 * (2 << (ord($this->BUF[0]{10}) & 0x07))); + $Locals_rgb = substr($this->BUF[$i], 13, + 3 * (2 << (ord($this->BUF[$i]{10}) & 0x07))); + + $Locals_ext = "!\xF9\x04" . chr(($this->DIS << 2) + 0) . + chr(($d >> 0) & 0xFF) . chr(($d >> 8) & 0xFF) . "\x0\x0"; + + if ($this->COL > -1 && ord($this->BUF[$i]{10}) & 0x80) { + for ($j = 0; $j < (2 << (ord($this->BUF[$i]{10}) & 0x07)); $j++) { + if ( + ord($Locals_rgb{3 * $j + 0}) == (($this->COL >> 16) & 0xFF) && + ord($Locals_rgb{3 * $j + 1}) == (($this->COL >> 8) & 0xFF) && + ord($Locals_rgb{3 * $j + 2}) == (($this->COL >> 0) & 0xFF) + ) { + $Locals_ext = "!\xF9\x04" . chr(($this->DIS << 2) + 1) . + chr(($d >> 0) & 0xFF) . chr(($d >> 8) & 0xFF) . chr($j) . "\x0"; + break; + } + } + } + switch ($Locals_tmp{0}) { + case "!": + $Locals_img = substr($Locals_tmp, 8, 10); + $Locals_tmp = substr($Locals_tmp, 18, strlen($Locals_tmp) - 18); + break; + case ",": + $Locals_img = substr($Locals_tmp, 0, 10); + $Locals_tmp = substr($Locals_tmp, 10, strlen($Locals_tmp) - 10); + break; + } + if (ord($this->BUF[$i]{10}) & 0x80 && $this->IMG > -1) { + if ($Global_len == $Locals_len) { + if ($this->GIFBlockCompare($Global_rgb, $Locals_rgb, $Global_len)) { + $this->GIF .= ($Locals_ext . $Locals_img . $Locals_tmp); + } else { + $byte = ord($Locals_img{9}); + $byte |= 0x80; + $byte &= 0xF8; + $byte |= (ord($this->BUF[0]{10}) & 0x07); + $Locals_img{9} = chr($byte); + $this->GIF .= ($Locals_ext . $Locals_img . $Locals_rgb . $Locals_tmp); + } + } else { + $byte = ord($Locals_img{9}); + $byte |= 0x80; + $byte &= 0xF8; + $byte |= (ord($this->BUF[$i]{10}) & 0x07); + $Locals_img{9} = chr($byte); + $this->GIF .= ($Locals_ext . $Locals_img . $Locals_rgb . $Locals_tmp); + } + } else { + $this->GIF .= ($Locals_ext . $Locals_img . $Locals_tmp); + } + $this->IMG = 1; + } + /* + ::::::::::::::::::::::::::::::::::::::::::::::::::: + :: + :: GIFAddFooter... + :: + */ + private function GIFAddFooter() + { + $this->GIF .= ";"; + } + /* + ::::::::::::::::::::::::::::::::::::::::::::::::::: + :: + :: GIFBlockCompare... + :: + */ + private function GIFBlockCompare($GlobalBlock, $LocalBlock, $Len) + { + + for ($i = 0; $i < $Len; $i++) { + if ( + $GlobalBlock{3 * $i + 0} != $LocalBlock{3 * $i + 0} || + $GlobalBlock{3 * $i + 1} != $LocalBlock{3 * $i + 1} || + $GlobalBlock{3 * $i + 2} != $LocalBlock{3 * $i + 2} + ) { + return (0); + } + } + + return (1); + } + /* + ::::::::::::::::::::::::::::::::::::::::::::::::::: + :: + :: GIFWord... + :: + */ + private function GIFWord($int) + { + + return (chr($int & 0xFF) . chr(($int >> 8) & 0xFF)); + } + /* + ::::::::::::::::::::::::::::::::::::::::::::::::::: + :: + :: GetAnimation... + :: + */ + public function GetAnimation() + { + return ($this->GIF); + } } - /* ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :: -:: GIFDecoder Version 2.0 by László Zsidi, http://gifs.hu +:: GIFDecoder Version 2.0 by László Zsidi, http://gifs.hu :: -:: Created at 2007. 02. 01. '07.47.AM' +:: Created at 2007. 02. 01. '07.47.AM' :: :: :: @@ -331,237 +338,242 @@ public function GetAnimation ( ) { :: http://gifs.hu/phpclasses/demos/GifBuilder/ :: ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -*/ - -Class GIFDecoder { - private $GIF_buffer = Array ( ); - private $GIF_arrays = Array ( ); - private $GIF_delays = Array ( ); - private $GIF_stream = ""; - private $GIF_string = ""; - private $GIF_bfseek = 0; - - private $GIF_screen = Array ( ); - private $GIF_global = Array ( ); - private $GIF_sorted; - private $GIF_colorS; - private $GIF_colorC; - private $GIF_colorF; - - /* - ::::::::::::::::::::::::::::::::::::::::::::::::::: - :: - :: GIFDecoder ( $GIF_pointer ) - :: - */ - public function __construct ( $GIF_pointer ) { - $this->GIF_stream = $GIF_pointer; - - $this->GIFGetByte ( 6 ); // GIF89a - $this->GIFGetByte ( 7 ); // Logical Screen Descriptor - - $this->GIF_screen = $this->GIF_buffer; - $this->GIF_colorF = $this->GIF_buffer [ 4 ] & 0x80 ? 1 : 0; - $this->GIF_sorted = $this->GIF_buffer [ 4 ] & 0x08 ? 1 : 0; - $this->GIF_colorC = $this->GIF_buffer [ 4 ] & 0x07; - $this->GIF_colorS = 2 << $this->GIF_colorC; - - if ( $this->GIF_colorF == 1 ) { - $this->GIFGetByte ( 3 * $this->GIF_colorS ); - $this->GIF_global = $this->GIF_buffer; - } - /* - * - * 05.06.2007. - * Made a little modification - * - * - - for ( $cycle = 1; $cycle; ) { - + if ( GIFDecoder::GIFGetByte ( 1 ) ) { - - switch ( $this->GIF_buffer [ 0 ] ) { - - case 0x21: - - GIFDecoder::GIFReadExtensions ( ); - - break; - - case 0x2C: - - GIFDecoder::GIFReadDescriptor ( ); - - break; - - case 0x3B: - - $cycle = 0; - - break; - - } - - } - + else { - + $cycle = 0; - + } - - } - */ - for ( $cycle = 1; $cycle; ) { - if ( $this->GIFGetByte ( 1 ) ) { - switch ( $this->GIF_buffer [ 0 ] ) { - case 0x21: - $this->GIFReadExtensions ( ); - break; - case 0x2C: - $this->GIFReadDescriptor ( ); - break; - case 0x3B: - $cycle = 0; - break; - } - } - else { - $cycle = 0; - } - } - } - /* - ::::::::::::::::::::::::::::::::::::::::::::::::::: - :: - :: GIFReadExtension ( ) - :: - */ - private function GIFReadExtensions ( ) { - $this->GIFGetByte ( 1 ); - for ( ; ; ) { - $this->GIFGetByte ( 1 ); - if ( ( $u = $this->GIF_buffer [ 0 ] ) == 0x00 ) { - break; - } - $this->GIFGetByte ( $u ); - /* - * 07.05.2007. - * Implemented a new line for a new function - * to determine the originaly delays between - * frames. - * - */ - if ( $u == 4 ) { - $this->GIF_delays [ ] = ( $this->GIF_buffer [ 1 ] | $this->GIF_buffer [ 2 ] << 8 ); - } - } - } - /* - ::::::::::::::::::::::::::::::::::::::::::::::::::: - :: - :: GIFReadExtension ( ) - :: - */ - private function GIFReadDescriptor ( ) { - $GIF_screen = Array ( ); - - $this->GIFGetByte ( 9 ); - $GIF_screen = $this->GIF_buffer; - $GIF_colorF = $this->GIF_buffer [ 8 ] & 0x80 ? 1 : 0; - if ( $GIF_colorF ) { - $GIF_code = $this->GIF_buffer [ 8 ] & 0x07; - $GIF_sort = $this->GIF_buffer [ 8 ] & 0x20 ? 1 : 0; - } - else { - $GIF_code = $this->GIF_colorC; - $GIF_sort = $this->GIF_sorted; - } - $GIF_size = 2 << $GIF_code; - $this->GIF_screen [ 4 ] &= 0x70; - $this->GIF_screen [ 4 ] |= 0x80; - $this->GIF_screen [ 4 ] |= $GIF_code; - if ( $GIF_sort ) { - $this->GIF_screen [ 4 ] |= 0x08; - } - $this->GIF_string = "GIF87a"; - $this->GIFPutByte ( $this->GIF_screen ); - if ( $GIF_colorF == 1 ) { - $this->GIFGetByte ( 3 * $GIF_size ); - $this->GIFPutByte ( $this->GIF_buffer ); - } - else { - $this->GIFPutByte ( $this->GIF_global ); - } - $this->GIF_string .= chr ( 0x2C ); - $GIF_screen [ 8 ] &= 0x40; - $this->GIFPutByte ( $GIF_screen ); - $this->GIFGetByte ( 1 ); - $this->GIFPutByte ( $this->GIF_buffer ); - for ( ; ; ) { - $this->GIFGetByte ( 1 ); - $this->GIFPutByte ( $this->GIF_buffer ); - if ( ( $u = $this->GIF_buffer [ 0 ] ) == 0x00 ) { - break; - } - $this->GIFGetByte ( $u ); - $this->GIFPutByte ( $this->GIF_buffer ); - } - $this->GIF_string .= chr ( 0x3B ); - /* - Add frames into $GIF_stream array... - */ - $this->GIF_arrays [ ] = $this->GIF_string; - } - /* - ::::::::::::::::::::::::::::::::::::::::::::::::::: - :: - :: GIFGetByte ( $len ) - :: - */ - - /* - * - * 05.06.2007. - * Made a little modification - * - * - - function GIFGetByte ( $len ) { - - $this->GIF_buffer = Array ( ); - - - - for ( $i = 0; $i < $len; $i++ ) { - + if ( $this->GIF_bfseek > strlen ( $this->GIF_stream ) ) { - + return 0; - + } - - $this->GIF_buffer [ ] = ord ( $this->GIF_stream { $this->GIF_bfseek++ } ); - - } - + return 1; - - } - */ - private function GIFGetByte ( $len ) { - $this->GIF_buffer = Array ( ); - - for ( $i = 0; $i < $len; $i++ ) { - if ( $this->GIF_bfseek > strlen ( $this->GIF_stream ) ) { - return 0; - } - $this->GIF_buffer [ ] = ord ( $this->GIF_stream { $this->GIF_bfseek++ } ); - } - return 1; - } - /* - ::::::::::::::::::::::::::::::::::::::::::::::::::: - :: - :: GIFPutByte ( $bytes ) - :: - */ - private function GIFPutByte ( $bytes ) { - for ( $i = 0; $i < count ( $bytes ); $i++ ) { - $this->GIF_string .= chr ( $bytes [ $i ] ); - } - } - /* - ::::::::::::::::::::::::::::::::::::::::::::::::::: - :: - :: PUBLIC FUNCTIONS - :: - :: - :: GIFGetFrames ( ) - :: - */ - public function GIFGetFrames ( ) { - return ( $this->GIF_arrays ); - } - /* - ::::::::::::::::::::::::::::::::::::::::::::::::::: - :: - :: GIFGetDelays ( ) - :: - */ - public function GIFGetDelays ( ) { - return ( $this->GIF_delays ); - } + */ + +class GIFDecoder +{ + private $GIF_buffer = array(); + private $GIF_arrays = array(); + private $GIF_delays = array(); + private $GIF_stream = ""; + private $GIF_string = ""; + private $GIF_bfseek = 0; + + private $GIF_screen = array(); + private $GIF_global = array(); + private $GIF_sorted; + private $GIF_colorS; + private $GIF_colorC; + private $GIF_colorF; + + /* + ::::::::::::::::::::::::::::::::::::::::::::::::::: + :: + :: GIFDecoder ( $GIF_pointer ) + :: + */ + public function __construct($GIF_pointer) + { + $this->GIF_stream = $GIF_pointer; + + $this->GIFGetByte(6); // GIF89a + $this->GIFGetByte(7); // Logical Screen Descriptor + + $this->GIF_screen = $this->GIF_buffer; + $this->GIF_colorF = $this->GIF_buffer[4] & 0x80 ? 1 : 0; + $this->GIF_sorted = $this->GIF_buffer[4] & 0x08 ? 1 : 0; + $this->GIF_colorC = $this->GIF_buffer[4] & 0x07; + $this->GIF_colorS = 2 << $this->GIF_colorC; + + if (1 == $this->GIF_colorF) { + $this->GIFGetByte(3 * $this->GIF_colorS); + $this->GIF_global = $this->GIF_buffer; + } + /* + * + * 05.06.2007. + * Made a little modification + * + * + - for ( $cycle = 1; $cycle; ) { + + if ( GIFDecoder::GIFGetByte ( 1 ) ) { + - switch ( $this->GIF_buffer [ 0 ] ) { + - case 0x21: + - GIFDecoder::GIFReadExtensions ( ); + - break; + - case 0x2C: + - GIFDecoder::GIFReadDescriptor ( ); + - break; + - case 0x3B: + - $cycle = 0; + - break; + - } + - } + + else { + + $cycle = 0; + + } + - } + */ + for ($cycle = 1; $cycle;) { + if ($this->GIFGetByte(1)) { + switch ($this->GIF_buffer[0]) { + case 0x21: + $this->GIFReadExtensions(); + break; + case 0x2C: + $this->GIFReadDescriptor(); + break; + case 0x3B: + $cycle = 0; + break; + } + } else { + $cycle = 0; + } + } + } + /* + ::::::::::::::::::::::::::::::::::::::::::::::::::: + :: + :: GIFReadExtension ( ) + :: + */ + private function GIFReadExtensions() + { + $this->GIFGetByte(1); + for (;;) { + $this->GIFGetByte(1); + if (($u = $this->GIF_buffer[0]) == 0x00) { + break; + } + $this->GIFGetByte($u); + /* + * 07.05.2007. + * Implemented a new line for a new function + * to determine the originaly delays between + * frames. + * + */ + if (4 == $u) { + $this->GIF_delays[] = ($this->GIF_buffer[1] | $this->GIF_buffer[2] << 8); + } + } + } + /* + ::::::::::::::::::::::::::::::::::::::::::::::::::: + :: + :: GIFReadExtension ( ) + :: + */ + private function GIFReadDescriptor() + { + $GIF_screen = array(); + + $this->GIFGetByte(9); + $GIF_screen = $this->GIF_buffer; + $GIF_colorF = $this->GIF_buffer[8] & 0x80 ? 1 : 0; + if ($GIF_colorF) { + $GIF_code = $this->GIF_buffer[8] & 0x07; + $GIF_sort = $this->GIF_buffer[8] & 0x20 ? 1 : 0; + } else { + $GIF_code = $this->GIF_colorC; + $GIF_sort = $this->GIF_sorted; + } + $GIF_size = 2 << $GIF_code; + $this->GIF_screen[4] &= 0x70; + $this->GIF_screen[4] |= 0x80; + $this->GIF_screen[4] |= $GIF_code; + if ($GIF_sort) { + $this->GIF_screen[4] |= 0x08; + } + $this->GIF_string = "GIF87a"; + $this->GIFPutByte($this->GIF_screen); + if (1 == $GIF_colorF) { + $this->GIFGetByte(3 * $GIF_size); + $this->GIFPutByte($this->GIF_buffer); + } else { + $this->GIFPutByte($this->GIF_global); + } + $this->GIF_string .= chr(0x2C); + $GIF_screen[8] &= 0x40; + $this->GIFPutByte($GIF_screen); + $this->GIFGetByte(1); + $this->GIFPutByte($this->GIF_buffer); + for (;;) { + $this->GIFGetByte(1); + $this->GIFPutByte($this->GIF_buffer); + if (($u = $this->GIF_buffer[0]) == 0x00) { + break; + } + $this->GIFGetByte($u); + $this->GIFPutByte($this->GIF_buffer); + } + $this->GIF_string .= chr(0x3B); + /* + Add frames into $GIF_stream array... + */ + $this->GIF_arrays[] = $this->GIF_string; + } + /* + ::::::::::::::::::::::::::::::::::::::::::::::::::: + :: + :: GIFGetByte ( $len ) + :: + */ + + /* + * + * 05.06.2007. + * Made a little modification + * + * + - function GIFGetByte ( $len ) { + - $this->GIF_buffer = Array ( ); + - + - for ( $i = 0; $i < $len; $i++ ) { + + if ( $this->GIF_bfseek > strlen ( $this->GIF_stream ) ) { + + return 0; + + } + - $this->GIF_buffer [ ] = ord ( $this->GIF_stream { $this->GIF_bfseek++ } ); + - } + + return 1; + - } + */ + private function GIFGetByte($len) + { + $this->GIF_buffer = array(); + + for ($i = 0; $i < $len; $i++) { + if ($this->GIF_bfseek > strlen($this->GIF_stream)) { + return 0; + } + $this->GIF_buffer[] = ord($this->GIF_stream{$this->GIF_bfseek++}); + } + return 1; + } + /* + ::::::::::::::::::::::::::::::::::::::::::::::::::: + :: + :: GIFPutByte ( $bytes ) + :: + */ + private function GIFPutByte($bytes) + { + for ($i = 0; $i < count($bytes); $i++) { + $this->GIF_string .= chr($bytes[$i]); + } + } + /* + ::::::::::::::::::::::::::::::::::::::::::::::::::: + :: + :: PUBLIC FUNCTIONS + :: + :: + :: GIFGetFrames ( ) + :: + */ + public function GIFGetFrames() + { + return ($this->GIF_arrays); + } + /* + ::::::::::::::::::::::::::::::::::::::::::::::::::: + :: + :: GIFGetDelays ( ) + :: + */ + public function GIFGetDelays() + { + return ($this->GIF_delays); + } } diff --git a/ThinkPHP/Library/Think/Image/Driver/Gd.class.php b/ThinkPHP/Library/Think/Image/Driver/Gd.class.php index 0df755472..9ddc35548 100644 --- a/ThinkPHP/Library/Think/Image/Driver/Gd.class.php +++ b/ThinkPHP/Library/Think/Image/Driver/Gd.class.php @@ -11,8 +11,11 @@ // | ImageGd.class.php 2013-03-05 // +---------------------------------------------------------------------- namespace Think\Image\Driver; + use Think\Image; -class Gd{ + +class Gd +{ /** * 图像资源对象 * @var resource @@ -29,7 +32,8 @@ class Gd{ * 构造方法,可用于打开一张图像 * @param string $imgname 图像路径 */ - public function __construct($imgname = null) { + public function __construct($imgname = null) + { $imgname && $this->open($imgname); } @@ -37,15 +41,18 @@ public function __construct($imgname = null) { * 打开一张图像 * @param string $imgname 图像路径 */ - public function open($imgname){ + public function open($imgname) + { //检测图像文件 - if(!is_file($imgname)) E('不存在的图像文件'); + if (!is_file($imgname)) { + E('不存在的图像文件'); + } //获取图像信息 $info = getimagesize($imgname); //检测图像合法性 - if(false === $info || (IMAGETYPE_GIF === $info[2] && empty($info['bits']))){ + if (false === $info || (IMAGETYPE_GIF === $info[2] && empty($info['bits']))) { E('非法图像文件'); } @@ -61,12 +68,12 @@ public function open($imgname){ empty($this->img) || imagedestroy($this->img); //打开图像 - if('gif' == $this->info['type']){ - $class = 'Think\\Image\\Driver\\GIF'; + if ('gif' == $this->info['type']) { + $class = 'Think\\Image\\Driver\\GIF'; $this->gif = new $class($imgname); $this->img = imagecreatefromstring($this->gif->image()); } else { - $fun = "imagecreatefrom{$this->info['type']}"; + $fun = "imagecreatefrom{$this->info['type']}"; $this->img = $fun($imgname); } } @@ -75,27 +82,30 @@ public function open($imgname){ * 保存图像 * @param string $imgname 图像保存名称 * @param string $type 图像类型 - * @param integer $quality 图像质量 + * @param integer $quality 图像质量 * @param boolean $interlace 是否对JPEG类型图像设置隔行扫描 */ - public function save($imgname, $type = null, $quality=80,$interlace = true){ - if(empty($this->img)) E('没有可以被保存的图像资源'); + public function save($imgname, $type = null, $quality = 80, $interlace = true) + { + if (empty($this->img)) { + E('没有可以被保存的图像资源'); + } //自动获取图像类型 - if(is_null($type)){ + if (is_null($type)) { $type = $this->info['type']; } else { $type = strtolower($type); } //保存图像 - if('jpeg' == $type || 'jpg' == $type){ + if ('jpeg' == $type || 'jpg' == $type) { //JPEG图像设置隔行扫描 imageinterlace($this->img, $interlace); - imagejpeg($this->img, $imgname,$quality); - }elseif('gif' == $type && !empty($this->gif)){ + imagejpeg($this->img, $imgname, $quality); + } elseif ('gif' == $type && !empty($this->gif)) { $this->gif->save($imgname); - }else{ - $fun = 'image'.$type; + } else { + $fun = 'image' . $type; $fun($this->img, $imgname); } } @@ -104,8 +114,12 @@ public function save($imgname, $type = null, $quality=80,$interlace = true){ * 返回图像宽度 * @return integer 图像宽度 */ - public function width(){ - if(empty($this->img)) E('没有指定图像资源'); + public function width() + { + if (empty($this->img)) { + E('没有指定图像资源'); + } + return $this->info['width']; } @@ -113,8 +127,12 @@ public function width(){ * 返回图像高度 * @return integer 图像高度 */ - public function height(){ - if(empty($this->img)) E('没有指定图像资源'); + public function height() + { + if (empty($this->img)) { + E('没有指定图像资源'); + } + return $this->info['height']; } @@ -122,8 +140,12 @@ public function height(){ * 返回图像类型 * @return string 图像类型 */ - public function type(){ - if(empty($this->img)) E('没有指定图像资源'); + public function type() + { + if (empty($this->img)) { + E('没有指定图像资源'); + } + return $this->info['type']; } @@ -131,8 +153,12 @@ public function type(){ * 返回图像MIME类型 * @return string 图像MIME类型 */ - public function mime(){ - if(empty($this->img)) E('没有指定图像资源'); + public function mime() + { + if (empty($this->img)) { + E('没有指定图像资源'); + } + return $this->info['mime']; } @@ -140,8 +166,12 @@ public function mime(){ * 返回图像尺寸数组 0 - 图像宽度,1 - 图像高度 * @return array 图像尺寸 */ - public function size(){ - if(empty($this->img)) E('没有指定图像资源'); + public function size() + { + if (empty($this->img)) { + E('没有指定图像资源'); + } + return array($this->info['width'], $this->info['height']); } @@ -154,11 +184,14 @@ public function size(){ * @param integer $width 图像保存宽度 * @param integer $height 图像保存高度 */ - public function crop($w, $h, $x = 0, $y = 0, $width = null, $height = null){ - if(empty($this->img)) E('没有可以被裁剪的图像资源'); + public function crop($w, $h, $x = 0, $y = 0, $width = null, $height = null) + { + if (empty($this->img)) { + E('没有可以被裁剪的图像资源'); + } //设置保存尺寸 - empty($width) && $width = $w; + empty($width) && $width = $w; empty($height) && $height = $h; do { @@ -174,7 +207,7 @@ public function crop($w, $h, $x = 0, $y = 0, $width = null, $height = null){ //设置新图像 $this->img = $img; - } while(!empty($this->gif) && $this->gifNext()); + } while (!empty($this->gif) && $this->gifNext()); $this->info['width'] = $width; $this->info['height'] = $height; @@ -186,8 +219,11 @@ public function crop($w, $h, $x = 0, $y = 0, $width = null, $height = null){ * @param integer $height 缩略图最大高度 * @param integer $type 缩略图裁剪类型 */ - public function thumb($width, $height, $type = Image::IMAGE_THUMB_SCALE){ - if(empty($this->img)) E('没有可以被缩略的图像资源'); + public function thumb($width, $height, $type = Image::IMAGE_THUMB_SCALE) + { + if (empty($this->img)) { + E('没有可以被缩略的图像资源'); + } //原图宽度和高度 $w = $this->info['width']; @@ -198,13 +234,15 @@ public function thumb($width, $height, $type = Image::IMAGE_THUMB_SCALE){ /* 等比例缩放 */ case Image::IMAGE_THUMB_SCALE: //原图尺寸小于缩略图尺寸则不进行缩略 - if($w < $width && $h < $height) return; + if ($w < $width && $h < $height) { + return; + } //计算缩放比例 - $scale = min($width/$w, $height/$h); - + $scale = min($width / $w, $height / $h); + //设置缩略图的坐标及宽度和高度 - $x = $y = 0; + $x = $y = 0; $width = $w * $scale; $height = $h * $scale; break; @@ -212,34 +250,34 @@ public function thumb($width, $height, $type = Image::IMAGE_THUMB_SCALE){ /* 居中裁剪 */ case Image::IMAGE_THUMB_CENTER: //计算缩放比例 - $scale = max($width/$w, $height/$h); + $scale = max($width / $w, $height / $h); //设置缩略图的坐标及宽度和高度 - $w = $width/$scale; - $h = $height/$scale; - $x = ($this->info['width'] - $w)/2; - $y = ($this->info['height'] - $h)/2; + $w = $width / $scale; + $h = $height / $scale; + $x = ($this->info['width'] - $w) / 2; + $y = ($this->info['height'] - $h) / 2; break; /* 左上角裁剪 */ case Image::IMAGE_THUMB_NORTHWEST: //计算缩放比例 - $scale = max($width/$w, $height/$h); + $scale = max($width / $w, $height / $h); //设置缩略图的坐标及宽度和高度 $x = $y = 0; - $w = $width/$scale; - $h = $height/$scale; + $w = $width / $scale; + $h = $height / $scale; break; /* 右下角裁剪 */ case Image::IMAGE_THUMB_SOUTHEAST: //计算缩放比例 - $scale = max($width/$w, $height/$h); + $scale = max($width / $w, $height / $h); //设置缩略图的坐标及宽度和高度 - $w = $width/$scale; - $h = $height/$scale; + $w = $width / $scale; + $h = $height / $scale; $x = $this->info['width'] - $w; $y = $this->info['height'] - $h; break; @@ -247,19 +285,19 @@ public function thumb($width, $height, $type = Image::IMAGE_THUMB_SCALE){ /* 填充 */ case Image::IMAGE_THUMB_FILLED: //计算缩放比例 - if($w < $width && $h < $height){ + if ($w < $width && $h < $height) { $scale = 1; } else { - $scale = min($width/$w, $height/$h); + $scale = min($width / $w, $height / $h); } //设置缩略图的坐标及宽度和高度 $neww = $w * $scale; $newh = $h * $scale; - $posx = ($width - $w * $scale)/2; - $posy = ($height - $h * $scale)/2; + $posx = ($width - $w * $scale) / 2; + $posy = ($height - $h * $scale) / 2; - do{ + do { //创建新图像 $img = imagecreatetruecolor($width, $height); // 调整默认颜色 @@ -270,8 +308,8 @@ public function thumb($width, $height, $type = Image::IMAGE_THUMB_SCALE){ imagecopyresampled($img, $this->img, $posx, $posy, $x, $y, $neww, $newh, $w, $h); imagedestroy($this->img); //销毁原图 $this->img = $img; - } while(!empty($this->gif) && $this->gifNext()); - + } while (!empty($this->gif) && $this->gifNext()); + $this->info['width'] = $width; $this->info['height'] = $height; return; @@ -295,14 +333,20 @@ public function thumb($width, $height, $type = Image::IMAGE_THUMB_SCALE){ * @param integer $locate 水印位置 * @param integer $alpha 水印透明度 */ - public function water($source, $locate = Image::IMAGE_WATER_SOUTHEAST,$alpha=80){ + public function water($source, $locate = Image::IMAGE_WATER_SOUTHEAST, $alpha = 80) + { //资源检测 - if(empty($this->img)) E('没有可以被添加水印的图像资源'); - if(!is_file($source)) E('水印图像不存在'); + if (empty($this->img)) { + E('没有可以被添加水印的图像资源'); + } + + if (!is_file($source)) { + E('水印图像不存在'); + } //获取水印图像信息 $info = getimagesize($source); - if(false === $info || (IMAGETYPE_GIF === $info[2] && empty($info['bits']))){ + if (false === $info || (IMAGETYPE_GIF === $info[2] && empty($info['bits']))) { E('非法水印文件'); } @@ -340,44 +384,44 @@ public function water($source, $locate = Image::IMAGE_WATER_SOUTHEAST,$alpha=80) /* 居中水印 */ case Image::IMAGE_WATER_CENTER: - $x = ($this->info['width'] - $info[0])/2; - $y = ($this->info['height'] - $info[1])/2; + $x = ($this->info['width'] - $info[0]) / 2; + $y = ($this->info['height'] - $info[1]) / 2; break; /* 下居中水印 */ case Image::IMAGE_WATER_SOUTH: - $x = ($this->info['width'] - $info[0])/2; + $x = ($this->info['width'] - $info[0]) / 2; $y = $this->info['height'] - $info[1]; break; /* 右居中水印 */ case Image::IMAGE_WATER_EAST: $x = $this->info['width'] - $info[0]; - $y = ($this->info['height'] - $info[1])/2; + $y = ($this->info['height'] - $info[1]) / 2; break; /* 上居中水印 */ case Image::IMAGE_WATER_NORTH: - $x = ($this->info['width'] - $info[0])/2; + $x = ($this->info['width'] - $info[0]) / 2; $y = 0; break; /* 左居中水印 */ case Image::IMAGE_WATER_WEST: $x = 0; - $y = ($this->info['height'] - $info[1])/2; + $y = ($this->info['height'] - $info[1]) / 2; break; default: /* 自定义水印坐标 */ - if(is_array($locate)){ + if (is_array($locate)) { list($x, $y) = $locate; } else { E('不支持的水印位置类型'); } } - do{ + do { //添加水印 $src = imagecreatetruecolor($info[0], $info[1]); // 调整默认颜色 @@ -390,7 +434,7 @@ public function water($source, $locate = Image::IMAGE_WATER_SOUTHEAST,$alpha=80) //销毁零时图片资源 imagedestroy($src); - } while(!empty($this->gif) && $this->gifNext()); + } while (!empty($this->gif) && $this->gifNext()); //销毁水印资源 imagedestroy($water); @@ -406,18 +450,23 @@ public function water($source, $locate = Image::IMAGE_WATER_SOUTHEAST,$alpha=80) * @param integer $offset 文字相对当前位置的偏移量 * @param integer $angle 文字倾斜角度 */ - public function text($text, $font, $size, $color = '#00000000', - $locate = Image::IMAGE_WATER_SOUTHEAST, $offset = 0, $angle = 0){ + public function text($text, $font, $size, $color = '#00000000', + $locate = Image::IMAGE_WATER_SOUTHEAST, $offset = 0, $angle = 0) { //资源检测 - if(empty($this->img)) E('没有可以被写入文字的图像资源'); - if(!is_file($font)) E("不存在的字体文件:{$font}"); + if (empty($this->img)) { + E('没有可以被写入文字的图像资源'); + } + + if (!is_file($font)) { + E("不存在的字体文件:{$font}"); + } //获取文字信息 $info = imagettfbbox($size, $angle, $font, $text); - $minx = min($info[0], $info[2], $info[4], $info[6]); - $maxx = max($info[0], $info[2], $info[4], $info[6]); - $miny = min($info[1], $info[3], $info[5], $info[7]); - $maxy = max($info[1], $info[3], $info[5], $info[7]); + $minx = min($info[0], $info[2], $info[4], $info[6]); + $maxx = max($info[0], $info[2], $info[4], $info[6]); + $miny = min($info[1], $info[3], $info[5], $info[7]); + $maxy = max($info[1], $info[3], $info[5], $info[7]); /* 计算文字初始坐标和尺寸 */ $x = $minx; @@ -429,7 +478,7 @@ public function text($text, $font, $size, $color = '#00000000', switch ($locate) { /* 右下角文字 */ case Image::IMAGE_WATER_SOUTHEAST: - $x += $this->info['width'] - $w; + $x += $this->info['width'] - $w; $y += $this->info['height'] - $h; break; @@ -450,35 +499,35 @@ public function text($text, $font, $size, $color = '#00000000', /* 居中文字 */ case Image::IMAGE_WATER_CENTER: - $x += ($this->info['width'] - $w)/2; - $y += ($this->info['height'] - $h)/2; + $x += ($this->info['width'] - $w) / 2; + $y += ($this->info['height'] - $h) / 2; break; /* 下居中文字 */ case Image::IMAGE_WATER_SOUTH: - $x += ($this->info['width'] - $w)/2; + $x += ($this->info['width'] - $w) / 2; $y += $this->info['height'] - $h; break; /* 右居中文字 */ case Image::IMAGE_WATER_EAST: $x += $this->info['width'] - $w; - $y += ($this->info['height'] - $h)/2; + $y += ($this->info['height'] - $h) / 2; break; /* 上居中文字 */ case Image::IMAGE_WATER_NORTH: - $x += ($this->info['width'] - $w)/2; + $x += ($this->info['width'] - $w) / 2; break; /* 左居中文字 */ case Image::IMAGE_WATER_WEST: - $y += ($this->info['height'] - $h)/2; + $y += ($this->info['height'] - $h) / 2; break; default: /* 自定义文字坐标 */ - if(is_array($locate)){ + if (is_array($locate)) { list($posx, $posy) = $locate; $x += $posx; $y += $posy; @@ -488,34 +537,35 @@ public function text($text, $font, $size, $color = '#00000000', } /* 设置偏移量 */ - if(is_array($offset)){ - $offset = array_map('intval', $offset); + if (is_array($offset)) { + $offset = array_map('intval', $offset); list($ox, $oy) = $offset; - } else{ + } else { $offset = intval($offset); - $ox = $oy = $offset; + $ox = $oy = $offset; } /* 设置颜色 */ - if(is_string($color) && 0 === strpos($color, '#')){ + if (is_string($color) && 0 === strpos($color, '#')) { $color = str_split(substr($color, 1), 2); $color = array_map('hexdec', $color); - if(empty($color[3]) || $color[3] > 127){ + if (empty($color[3]) || $color[3] > 127) { $color[3] = 0; } } elseif (!is_array($color)) { E('错误的颜色值'); } - do{ + do { /* 写入文字 */ $col = imagecolorallocatealpha($this->img, $color[0], $color[1], $color[2], $color[3]); imagettftext($this->img, $size, $angle, $x + $ox, $y + $oy, $col, $font, $text); - } while(!empty($this->gif) && $this->gifNext()); + } while (!empty($this->gif) && $this->gifNext()); } /* 切换到GIF的下一帧并保存当前帧,内部使用 */ - private function gifNext(){ + private function gifNext() + { ob_start(); ob_implicit_flush(0); imagegif($this->img); @@ -524,7 +574,7 @@ private function gifNext(){ $this->gif->image($img); $next = $this->gif->nextImage(); - if($next){ + if ($next) { $this->img = imagecreatefromstring($next); return $next; } else { @@ -536,7 +586,8 @@ private function gifNext(){ /** * 析构方法,用于销毁图像资源 */ - public function __destruct() { + public function __destruct() + { empty($this->img) || imagedestroy($this->img); } -} \ No newline at end of file +} diff --git a/ThinkPHP/Library/Think/Image/Driver/Imagick.class.php b/ThinkPHP/Library/Think/Image/Driver/Imagick.class.php index df952a67c..20c6a1274 100644 --- a/ThinkPHP/Library/Think/Image/Driver/Imagick.class.php +++ b/ThinkPHP/Library/Think/Image/Driver/Imagick.class.php @@ -11,8 +11,11 @@ // | ImageImagick.class.php 2013-03-06 // +---------------------------------------------------------------------- namespace Think\Image\Driver; + use Think\Image; -class Imagick{ + +class Imagick +{ /** * 图像资源对象 * @var resource @@ -29,7 +32,8 @@ class Imagick{ * 构造方法,可用于打开一张图像 * @param string $imgname 图像路径 */ - public function __construct($imgname = null) { + public function __construct($imgname = null) + { $imgname && $this->open($imgname); } @@ -37,9 +41,12 @@ public function __construct($imgname = null) { * 打开一张图像 * @param string $imgname 图像路径 */ - public function open($imgname){ + public function open($imgname) + { //检测图像文件 - if(!is_file($imgname)) E('不存在的图像文件'); + if (!is_file($imgname)) { + E('不存在的图像文件'); + } //销毁已存在的图像 empty($this->img) || $this->img->destroy(); @@ -60,14 +67,17 @@ public function open($imgname){ * 保存图像 * @param string $imgname 图像保存名称 * @param string $type 图像类型 - * @param integer $quality JPEG图像质量 + * @param integer $quality JPEG图像质量 * @param boolean $interlace 是否对JPEG类型图像设置隔行扫描 */ - public function save($imgname, $type = null, $quality=80,$interlace = true){ - if(empty($this->img)) E('没有可以被保存的图像资源'); + public function save($imgname, $type = null, $quality = 80, $interlace = true) + { + if (empty($this->img)) { + E('没有可以被保存的图像资源'); + } //设置图片类型 - if(is_null($type)){ + if (is_null($type)) { $type = $this->info['type']; } else { $type = strtolower($type); @@ -75,12 +85,12 @@ public function save($imgname, $type = null, $quality=80,$interlace = true){ } //JPEG图像设置隔行扫描 - if('jpeg' == $type || 'jpg' == $type){ + if ('jpeg' == $type || 'jpg' == $type) { $this->img->setImageInterlaceScheme(1); } // 设置图像质量 - $this->img->setImageCompressionQuality($quality); + $this->img->setImageCompressionQuality($quality); //去除图像配置信息 $this->img->stripImage(); @@ -98,8 +108,12 @@ public function save($imgname, $type = null, $quality=80,$interlace = true){ * 返回图像宽度 * @return integer 图像宽度 */ - public function width(){ - if(empty($this->img)) E('没有指定图像资源'); + public function width() + { + if (empty($this->img)) { + E('没有指定图像资源'); + } + return $this->info['width']; } @@ -107,8 +121,12 @@ public function width(){ * 返回图像高度 * @return integer 图像高度 */ - public function height(){ - if(empty($this->img)) E('没有指定图像资源'); + public function height() + { + if (empty($this->img)) { + E('没有指定图像资源'); + } + return $this->info['height']; } @@ -116,8 +134,12 @@ public function height(){ * 返回图像类型 * @return string 图像类型 */ - public function type(){ - if(empty($this->img)) E('没有指定图像资源'); + public function type() + { + if (empty($this->img)) { + E('没有指定图像资源'); + } + return $this->info['type']; } @@ -125,8 +147,12 @@ public function type(){ * 返回图像MIME类型 * @return string 图像MIME类型 */ - public function mime(){ - if(empty($this->img)) E('没有指定图像资源'); + public function mime() + { + if (empty($this->img)) { + E('没有指定图像资源'); + } + return $this->info['mime']; } @@ -134,8 +160,12 @@ public function mime(){ * 返回图像尺寸数组 0 - 图像宽度,1 - 图像高度 * @return array 图像尺寸 */ - public function size(){ - if(empty($this->img)) E('没有指定图像资源'); + public function size() + { + if (empty($this->img)) { + E('没有指定图像资源'); + } + return array($this->info['width'], $this->info['height']); } @@ -148,15 +178,18 @@ public function size(){ * @param integer $width 图像保存宽度 * @param integer $height 图像保存高度 */ - public function crop($w, $h, $x = 0, $y = 0, $width = null, $height = null){ - if(empty($this->img)) E('没有可以被裁剪的图像资源'); + public function crop($w, $h, $x = 0, $y = 0, $width = null, $height = null) + { + if (empty($this->img)) { + E('没有可以被裁剪的图像资源'); + } //设置保存尺寸 - empty($width) && $width = $w; + empty($width) && $width = $w; empty($height) && $height = $h; //裁剪图片 - if('gif' == $this->info['type']){ + if ('gif' == $this->info['type']) { $img = $this->img->coalesceImages(); $this->img->destroy(); //销毁原图 @@ -164,7 +197,7 @@ public function crop($w, $h, $x = 0, $y = 0, $width = null, $height = null){ do { $this->_crop($w, $h, $x, $y, $width, $height, $img); } while ($img->nextImage()); - + //压缩图片 $this->img = $img->deconstructImages(); $img->destroy(); //销毁零时图片 @@ -174,18 +207,19 @@ public function crop($w, $h, $x = 0, $y = 0, $width = null, $height = null){ } /* 裁剪图片,内部调用 */ - private function _crop($w, $h, $x, $y, $width, $height, $img = null){ + private function _crop($w, $h, $x, $y, $width, $height, $img = null) + { is_null($img) && $img = $this->img; //裁剪 $info = $this->info; - if($x != 0 || $y != 0 || $w != $info['width'] || $h != $info['height']){ + if (0 != $x || 0 != $y || $w != $info['width'] || $h != $info['height']) { $img->cropImage($w, $h, $x, $y); $img->setImagePage($w, $h, 0, 0); //调整画布和图片一致 } - + //调整大小 - if($w != $width || $h != $height){ + if ($w != $width || $h != $height) { $img->sampleImage($width, $height); } @@ -200,8 +234,11 @@ private function _crop($w, $h, $x, $y, $width, $height, $img = null){ * @param integer $height 缩略图最大高度 * @param integer $type 缩略图裁剪类型 */ - public function thumb($width, $height, $type = Image::IMAGE_THUMB_SCALE){ - if(empty($this->img)) E('没有可以被缩略的图像资源'); + public function thumb($width, $height, $type = Image::IMAGE_THUMB_SCALE) + { + if (empty($this->img)) { + E('没有可以被缩略的图像资源'); + } //原图宽度和高度 $w = $this->info['width']; @@ -212,13 +249,15 @@ public function thumb($width, $height, $type = Image::IMAGE_THUMB_SCALE){ /* 等比例缩放 */ case Image::IMAGE_THUMB_SCALE: //原图尺寸小于缩略图尺寸则不进行缩略 - if($w < $width && $h < $height) return; + if ($w < $width && $h < $height) { + return; + } //计算缩放比例 - $scale = min($width/$w, $height/$h); - + $scale = min($width / $w, $height / $h); + //设置缩略图的坐标及宽度和高度 - $x = $y = 0; + $x = $y = 0; $width = $w * $scale; $height = $h * $scale; break; @@ -226,34 +265,34 @@ public function thumb($width, $height, $type = Image::IMAGE_THUMB_SCALE){ /* 居中裁剪 */ case Image::IMAGE_THUMB_CENTER: //计算缩放比例 - $scale = max($width/$w, $height/$h); + $scale = max($width / $w, $height / $h); //设置缩略图的坐标及宽度和高度 - $w = $width/$scale; - $h = $height/$scale; - $x = ($this->info['width'] - $w)/2; - $y = ($this->info['height'] - $h)/2; + $w = $width / $scale; + $h = $height / $scale; + $x = ($this->info['width'] - $w) / 2; + $y = ($this->info['height'] - $h) / 2; break; /* 左上角裁剪 */ case Image::IMAGE_THUMB_NORTHWEST: //计算缩放比例 - $scale = max($width/$w, $height/$h); + $scale = max($width / $w, $height / $h); //设置缩略图的坐标及宽度和高度 $x = $y = 0; - $w = $width/$scale; - $h = $height/$scale; + $w = $width / $scale; + $h = $height / $scale; break; /* 右下角裁剪 */ case Image::IMAGE_THUMB_SOUTHEAST: //计算缩放比例 - $scale = max($width/$w, $height/$h); + $scale = max($width / $w, $height / $h); //设置缩略图的坐标及宽度和高度 - $w = $width/$scale; - $h = $height/$scale; + $w = $width / $scale; + $h = $height / $scale; $x = $this->info['width'] - $w; $y = $this->info['height'] - $h; break; @@ -261,24 +300,23 @@ public function thumb($width, $height, $type = Image::IMAGE_THUMB_SCALE){ /* 填充 */ case Image::IMAGE_THUMB_FILLED: //计算缩放比例 - if($w < $width && $h < $height){ + if ($w < $width && $h < $height) { $scale = 1; } else { - $scale = min($width/$w, $height/$h); + $scale = min($width / $w, $height / $h); } //设置缩略图的坐标及宽度和高度 $neww = $w * $scale; $newh = $h * $scale; - $posx = ($width - $w * $scale)/2; - $posy = ($height - $h * $scale)/2; + $posx = ($width - $w * $scale) / 2; + $posy = ($height - $h * $scale) / 2; //创建一张新图像 $newimg = new \Imagick(); $newimg->newImage($width, $height, 'white', $this->info['type']); - - if('gif' == $this->info['type']){ + if ('gif' == $this->info['type']) { $imgs = $this->img->coalesceImages(); $img = new \Imagick(); $this->img->destroy(); //销毁原图 @@ -287,7 +325,7 @@ public function thumb($width, $height, $type = Image::IMAGE_THUMB_SCALE){ do { //填充图像 $image = $this->_fill($newimg, $posx, $posy, $neww, $newh, $imgs); - + $img->addImage($image); $img->setImageDelay($imgs->getImageDelay()); $img->setImagePage($width, $height, 0, 0); @@ -329,11 +367,12 @@ public function thumb($width, $height, $type = Image::IMAGE_THUMB_SCALE){ } /* 填充指定图像,内部使用 */ - private function _fill($newimg, $posx, $posy, $neww, $newh, $img = null){ + private function _fill($newimg, $posx, $posy, $neww, $newh, $img = null) + { is_null($img) && $img = $this->img; /* 将指定图片绘入空白图片 */ - $draw = new \ImagickDraw(); + $draw = new \ImagickDraw(); $draw->composite($img->getImageCompose(), $posx, $posy, $neww, $newh, $img); $image = $newimg->clone(); $image->drawImage($draw); @@ -348,10 +387,16 @@ private function _fill($newimg, $posx, $posy, $neww, $newh, $img = null){ * @param integer $locate 水印位置 * @param integer $alpha 水印透明度 */ - public function water($source, $locate = Image::IMAGE_WATER_SOUTHEAST,$alpha=80){ + public function water($source, $locate = Image::IMAGE_WATER_SOUTHEAST, $alpha = 80) + { //资源检测 - if(empty($this->img)) E('没有可以被添加水印的图像资源'); - if(!is_file($source)) E('水印图像不存在'); + if (empty($this->img)) { + E('没有可以被添加水印的图像资源'); + } + + if (!is_file($source)) { + E('水印图像不存在'); + } //创建水印图像资源 $water = new \Imagick(realpath($source)); @@ -384,37 +429,37 @@ public function water($source, $locate = Image::IMAGE_WATER_SOUTHEAST,$alpha=80) /* 居中水印 */ case Image::IMAGE_WATER_CENTER: - $x = ($this->info['width'] - $info[0])/2; - $y = ($this->info['height'] - $info[1])/2; + $x = ($this->info['width'] - $info[0]) / 2; + $y = ($this->info['height'] - $info[1]) / 2; break; /* 下居中水印 */ case Image::IMAGE_WATER_SOUTH: - $x = ($this->info['width'] - $info[0])/2; + $x = ($this->info['width'] - $info[0]) / 2; $y = $this->info['height'] - $info[1]; break; /* 右居中水印 */ case Image::IMAGE_WATER_EAST: $x = $this->info['width'] - $info[0]; - $y = ($this->info['height'] - $info[1])/2; + $y = ($this->info['height'] - $info[1]) / 2; break; /* 上居中水印 */ case Image::IMAGE_WATER_NORTH: - $x = ($this->info['width'] - $info[0])/2; + $x = ($this->info['width'] - $info[0]) / 2; $y = 0; break; /* 左居中水印 */ case Image::IMAGE_WATER_WEST: $x = 0; - $y = ($this->info['height'] - $info[1])/2; + $y = ($this->info['height'] - $info[1]) / 2; break; default: /* 自定义水印坐标 */ - if(is_array($locate)){ + if (is_array($locate)) { list($x, $y) = $locate; } else { E('不支持的水印位置类型'); @@ -424,12 +469,12 @@ public function water($source, $locate = Image::IMAGE_WATER_SOUTHEAST,$alpha=80) //创建绘图资源 $draw = new \ImagickDraw(); $draw->composite($water->getImageCompose(), $x, $y, $info[0], $info[1], $water); - - if('gif' == $this->info['type']){ + + if ('gif' == $this->info['type']) { $img = $this->img->coalesceImages(); $this->img->destroy(); //销毁原图 - do{ + do { //添加水印 $img->drawImage($draw); } while ($img->nextImage()); @@ -458,35 +503,39 @@ public function water($source, $locate = Image::IMAGE_WATER_SOUTHEAST,$alpha=80) * @param integer $offset 文字相对当前位置的偏移量 * @param integer $angle 文字倾斜角度 */ - public function text($text, $font, $size, $color = '#00000000', - $locate = Image::IMAGE_WATER_SOUTHEAST, $offset = 0, $angle = 0){ + public function text($text, $font, $size, $color = '#00000000', + $locate = Image::IMAGE_WATER_SOUTHEAST, $offset = 0, $angle = 0) { //资源检测 - if(empty($this->img)) E('没有可以被写入文字的图像资源'); - if(!is_file($font)) E("不存在的字体文件:{$font}"); + if (empty($this->img)) { + E('没有可以被写入文字的图像资源'); + } + + if (!is_file($font)) { + E("不存在的字体文件:{$font}"); + } //获取颜色和透明度 - if(is_array($color)){ + if (is_array($color)) { $color = array_map('dechex', $color); foreach ($color as &$value) { $value = str_pad($value, 2, '0', STR_PAD_LEFT); } $color = '#' . implode('', $color); - } elseif(!is_string($color) || 0 !== strpos($color, '#')) { + } elseif (!is_string($color) || 0 !== strpos($color, '#')) { E('错误的颜色值'); } $col = substr($color, 0, 7); $alp = strlen($color) == 9 ? substr($color, -2) : 0; - //获取文字信息 $draw = new \ImagickDraw(); $draw->setFont(realpath($font)); $draw->setFontSize($size); $draw->setFillColor($col); - $draw->setFillAlpha(1-hexdec($alp)/127); + $draw->setFillAlpha(1 - hexdec($alp) / 127); $draw->setTextAntialias(true); $draw->setStrokeAntialias(true); - + $metrics = $this->img->queryFontMetrics($draw, $text); /* 计算文字初始坐标和尺寸 */ @@ -499,7 +548,7 @@ public function text($text, $font, $size, $color = '#00000000', switch ($locate) { /* 右下角文字 */ case Image::IMAGE_WATER_SOUTHEAST: - $x += $this->info['width'] - $w; + $x += $this->info['width'] - $w; $y += $this->info['height'] - $h; break; @@ -520,35 +569,35 @@ public function text($text, $font, $size, $color = '#00000000', /* 居中文字 */ case Image::IMAGE_WATER_CENTER: - $x += ($this->info['width'] - $w)/2; - $y += ($this->info['height'] - $h)/2; + $x += ($this->info['width'] - $w) / 2; + $y += ($this->info['height'] - $h) / 2; break; /* 下居中文字 */ case Image::IMAGE_WATER_SOUTH: - $x += ($this->info['width'] - $w)/2; + $x += ($this->info['width'] - $w) / 2; $y += $this->info['height'] - $h; break; /* 右居中文字 */ case Image::IMAGE_WATER_EAST: $x += $this->info['width'] - $w; - $y += ($this->info['height'] - $h)/2; + $y += ($this->info['height'] - $h) / 2; break; /* 上居中文字 */ case Image::IMAGE_WATER_NORTH: - $x += ($this->info['width'] - $w)/2; + $x += ($this->info['width'] - $w) / 2; break; /* 左居中文字 */ case Image::IMAGE_WATER_WEST: - $y += ($this->info['height'] - $h)/2; + $y += ($this->info['height'] - $h) / 2; break; default: /* 自定义文字坐标 */ - if(is_array($locate)){ + if (is_array($locate)) { list($posx, $posy) = $locate; $x += $posx; $y += $posy; @@ -558,19 +607,19 @@ public function text($text, $font, $size, $color = '#00000000', } /* 设置偏移量 */ - if(is_array($offset)){ - $offset = array_map('intval', $offset); + if (is_array($offset)) { + $offset = array_map('intval', $offset); list($ox, $oy) = $offset; - } else{ + } else { $offset = intval($offset); - $ox = $oy = $offset; + $ox = $oy = $offset; } /* 写入文字 */ - if('gif' == $this->info['type']){ + if ('gif' == $this->info['type']) { $img = $this->img->coalesceImages(); $this->img->destroy(); //销毁原图 - do{ + do { $img->annotateImage($draw, $x + $ox, $y + $oy, $angle, $text); } while ($img->nextImage()); @@ -587,7 +636,8 @@ public function text($text, $font, $size, $color = '#00000000', /** * 析构方法,用于销毁图像资源 */ - public function __destruct() { + public function __destruct() + { empty($this->img) || $this->img->destroy(); } -} \ No newline at end of file +} diff --git a/ThinkPHP/Library/Think/Log.class.php b/ThinkPHP/Library/Think/Log.class.php index 09b1155ab..2bafe8679 100644 --- a/ThinkPHP/Library/Think/Log.class.php +++ b/ThinkPHP/Library/Think/Log.class.php @@ -9,32 +9,35 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think; + /** * 日志处理类 */ -class Log { +class Log +{ // 日志级别 从上到下,由低到高 - const EMERG = 'EMERG'; // 严重错误: 导致系统崩溃无法使用 - const ALERT = 'ALERT'; // 警戒性错误: 必须被立即修改的错误 - const CRIT = 'CRIT'; // 临界值错误: 超过临界值的错误,例如一天24小时,而输入的是25小时这样 - const ERR = 'ERR'; // 一般错误: 一般性错误 - const WARN = 'WARN'; // 警告性错误: 需要发出警告的错误 - const NOTICE = 'NOTIC'; // 通知: 程序可以运行但是还不够完美的错误 - const INFO = 'INFO'; // 信息: 程序输出信息 - const DEBUG = 'DEBUG'; // 调试: 调试信息 - const SQL = 'SQL'; // SQL:SQL语句 注意只在调试模式开启时有效 + const EMERG = 'EMERG'; // 严重错误: 导致系统崩溃无法使用 + const ALERT = 'ALERT'; // 警戒性错误: 必须被立即修改的错误 + const CRIT = 'CRIT'; // 临界值错误: 超过临界值的错误,例如一天24小时,而输入的是25小时这样 + const ERR = 'ERR'; // 一般错误: 一般性错误 + const WARN = 'WARN'; // 警告性错误: 需要发出警告的错误 + const NOTICE = 'NOTIC'; // 通知: 程序可以运行但是还不够完美的错误 + const INFO = 'INFO'; // 信息: 程序输出信息 + const DEBUG = 'DEBUG'; // 调试: 调试信息 + const SQL = 'SQL'; // SQL:SQL语句 注意只在调试模式开启时有效 // 日志信息 - static protected $log = array(); + protected static $log = array(); // 日志存储 - static protected $storage = null; + protected static $storage = null; // 日志初始化 - static public function init($config=array()){ - $type = isset($config['type']) ? $config['type'] : 'File'; - $class = strpos($type,'\\')? $type: 'Think\\Log\\Driver\\'. ucwords(strtolower($type)); + public static function init($config = array()) + { + $type = isset($config['type']) ? $config['type'] : 'File'; + $class = strpos($type, '\\') ? $type : 'Think\\Log\\Driver\\' . ucwords(strtolower($type)); unset($config['type']); self::$storage = new $class($config); } @@ -48,9 +51,10 @@ static public function init($config=array()){ * @param boolean $record 是否强制记录 * @return void */ - static function record($message,$level=self::ERR,$record=false) { - if($record || false !== strpos(C('LOG_LEVEL'),$level)) { - self::$log[] = "{$level}: {$message}\r\n"; + public static function record($message, $level = self::ERR, $record = false) + { + if ($record || false !== strpos(C('LOG_LEVEL'), $level)) { + self::$log[] = "{$level}: {$message}\r\n"; } } @@ -62,19 +66,22 @@ static function record($message,$level=self::ERR,$record=false) { * @param string $destination 写入目标 * @return void */ - static function save($type='',$destination='') { - if(empty(self::$log)) return ; + public static function save($type = '', $destination = '') + { + if (empty(self::$log)) { + return; + } - if(empty($destination)){ - $destination = C('LOG_PATH').date('y_m_d').'.log'; + if (empty($destination)) { + $destination = C('LOG_PATH') . date('y_m_d') . '.log'; } - if(!self::$storage){ - $type = $type ? : C('LOG_TYPE'); - $class = 'Think\\Log\\Driver\\'. ucwords($type); - self::$storage = new $class(); + if (!self::$storage) { + $type = $type ?: C('LOG_TYPE'); + $class = 'Think\\Log\\Driver\\' . ucwords($type); + self::$storage = new $class(); } - $message = implode('',self::$log); - self::$storage->write($message,$destination); + $message = implode('', self::$log); + self::$storage->write($message, $destination); // 保存后清空日志缓存 self::$log = array(); } @@ -89,16 +96,17 @@ static function save($type='',$destination='') { * @param string $destination 写入目标 * @return void */ - static function write($message,$level=self::ERR,$type='',$destination='') { - if(!self::$storage){ - $type = $type ? : C('LOG_TYPE'); - $class = 'Think\\Log\\Driver\\'. ucwords($type); + public static function write($message, $level = self::ERR, $type = '', $destination = '') + { + if (!self::$storage) { + $type = $type ?: C('LOG_TYPE'); + $class = 'Think\\Log\\Driver\\' . ucwords($type); $config['log_path'] = C('LOG_PATH'); - self::$storage = new $class($config); + self::$storage = new $class($config); } - if(empty($destination)){ - $destination = C('LOG_PATH').date('y_m_d').'.log'; + if (empty($destination)) { + $destination = C('LOG_PATH') . date('y_m_d') . '.log'; } self::$storage->write("{$level}: {$message}", $destination); } -} \ No newline at end of file +} diff --git a/ThinkPHP/Library/Think/Log/Driver/File.class.php b/ThinkPHP/Library/Think/Log/Driver/File.class.php index 290746e65..447ed10b4 100644 --- a/ThinkPHP/Library/Think/Log/Driver/File.class.php +++ b/ThinkPHP/Library/Think/Log/Driver/File.class.php @@ -11,17 +11,19 @@ namespace Think\Log\Driver; -class File { +class File +{ - protected $config = array( - 'log_time_format' => ' c ', - 'log_file_size' => 2097152, - 'log_path' => '', + protected $config = array( + 'log_time_format' => ' c ', + 'log_file_size' => 2097152, + 'log_path' => '', ); // 实例化并传入参数 - public function __construct($config=array()){ - $this->config = array_merge($this->config,$config); + public function __construct($config = array()) + { + $this->config = array_merge($this->config, $config); } /** @@ -31,20 +33,21 @@ public function __construct($config=array()){ * @param string $destination 写入目标 * @return void */ - public function write($log,$destination='') { + public function write($log, $destination = '') + { $now = date($this->config['log_time_format']); - if(empty($destination)){ - $destination = $this->config['log_path'].date('y_m_d').'.log'; + if (empty($destination)) { + $destination = $this->config['log_path'] . date('y_m_d') . '.log'; } // 自动创建日志目录 $log_dir = dirname($destination); if (!is_dir($log_dir)) { mkdir($log_dir, 0755, true); - } + } //检测日志文件大小,超过配置大小则备份日志文件重新生成 - if(is_file($destination) && floor($this->config['log_file_size']) <= filesize($destination) ){ - rename($destination,dirname($destination).'/'.time().'-'.basename($destination)); + if (is_file($destination) && floor($this->config['log_file_size']) <= filesize($destination)) { + rename($destination, dirname($destination) . '/' . time() . '-' . basename($destination)); } - error_log("[{$now}] ".$_SERVER['REMOTE_ADDR'].' '.$_SERVER['REQUEST_URI']."\r\n{$log}\r\n", 3,$destination); + error_log("[{$now}] " . $_SERVER['REMOTE_ADDR'] . ' ' . $_SERVER['REQUEST_URI'] . "\r\n{$log}\r\n", 3, $destination); } } diff --git a/ThinkPHP/Library/Think/Log/Driver/Sae.class.php b/ThinkPHP/Library/Think/Log/Driver/Sae.class.php index accbcae5c..98b862cd7 100644 --- a/ThinkPHP/Library/Think/Log/Driver/Sae.class.php +++ b/ThinkPHP/Library/Think/Log/Driver/Sae.class.php @@ -11,15 +11,17 @@ namespace Think\Log\Driver; -class Sae { +class Sae +{ - protected $config = array( - 'log_time_format' => ' c ', + protected $config = array( + 'log_time_format' => ' c ', ); // 实例化并传入参数 - public function __construct($config=array()){ - $this->config = array_merge($this->config,$config); + public function __construct($config = array()) + { + $this->config = array_merge($this->config, $config); } /** @@ -29,19 +31,20 @@ public function __construct($config=array()){ * @param string $destination 写入目标 * @return void */ - public function write($log,$destination='') { - static $is_debug=null; - $now = date($this->config['log_time_format']); - $logstr="[{$now}] ".$_SERVER['REMOTE_ADDR'].' '.$_SERVER['REQUEST_URI']."\r\n{$log}\r\n"; - if(is_null($is_debug)){ + public function write($log, $destination = '') + { + static $is_debug = null; + $now = date($this->config['log_time_format']); + $logstr = "[{$now}] " . $_SERVER['REMOTE_ADDR'] . ' ' . $_SERVER['REQUEST_URI'] . "\r\n{$log}\r\n"; + if (is_null($is_debug)) { preg_replace('@(\w+)\=([^;]*)@e', '$appSettings[\'\\1\']="\\2";', $_SERVER['HTTP_APPCOOKIE']); $is_debug = in_array($_SERVER['HTTP_APPVERSION'], explode(',', $appSettings['debug'])) ? true : false; } - if($is_debug){ - sae_set_display_errors(false);//记录日志不将日志打印出来 + if ($is_debug) { + sae_set_display_errors(false); //记录日志不将日志打印出来 } sae_debug($logstr); - if($is_debug){ + if ($is_debug) { sae_set_display_errors(true); } diff --git a/ThinkPHP/Library/Think/Model.class.php b/ThinkPHP/Library/Think/Model.class.php index 0e920e559..77f69abeb 100644 --- a/ThinkPHP/Library/Think/Model.class.php +++ b/ThinkPHP/Library/Think/Model.class.php @@ -9,57 +9,59 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think; + /** * ThinkPHP Model模型类 * 实现了ORM和ActiveRecords模式 */ -class Model { +class Model +{ // 操作状态 - const MODEL_INSERT = 1; // 插入模型数据 - const MODEL_UPDATE = 2; // 更新模型数据 - const MODEL_BOTH = 3; // 包含上面两种方式 - const MUST_VALIDATE = 1; // 必须验证 - const EXISTS_VALIDATE = 0; // 表单存在字段则验证 - const VALUE_VALIDATE = 2; // 表单值不为空则验证 + const MODEL_INSERT = 1; // 插入模型数据 + const MODEL_UPDATE = 2; // 更新模型数据 + const MODEL_BOTH = 3; // 包含上面两种方式 + const MUST_VALIDATE = 1; // 必须验证 + const EXISTS_VALIDATE = 0; // 表单存在字段则验证 + const VALUE_VALIDATE = 2; // 表单值不为空则验证 // 当前数据库操作对象 - protected $db = null; - // 数据库对象池 - private $_db = array(); + protected $db = null; + // 数据库对象池 + private $_db = array(); // 主键名称 - protected $pk = 'id'; + protected $pk = 'id'; // 主键是否自动增长 - protected $autoinc = false; + protected $autoinc = false; // 数据表前缀 - protected $tablePrefix = null; + protected $tablePrefix = null; // 模型名称 - protected $name = ''; + protected $name = ''; // 数据库名称 - protected $dbName = ''; + protected $dbName = ''; //数据库配置 - protected $connection = ''; + protected $connection = ''; // 数据表名(不包含表前缀) - protected $tableName = ''; + protected $tableName = ''; // 实际数据表名(包含表前缀) - protected $trueTableName = ''; + protected $trueTableName = ''; // 最近错误信息 - protected $error = ''; + protected $error = ''; // 字段信息 - protected $fields = array(); + protected $fields = array(); // 数据信息 - protected $data = array(); + protected $data = array(); // 查询表达式参数 - protected $options = array(); - protected $_validate = array(); // 自动验证定义 - protected $_auto = array(); // 自动完成定义 - protected $_map = array(); // 字段映射定义 - protected $_scope = array(); // 命名范围定义 + protected $options = array(); + protected $_validate = array(); // 自动验证定义 + protected $_auto = array(); // 自动完成定义 + protected $_map = array(); // 字段映射定义 + protected $_scope = array(); // 命名范围定义 // 是否自动检测数据表字段信息 - protected $autoCheckFields = true; + protected $autoCheckFields = true; // 是否批处理验证 - protected $patchValidate = false; + protected $patchValidate = false; // 链操作方法列表 - protected $methods = array('strict','order','alias','having','group','lock','distinct','auto','filter','validate','result','token','index','force'); + protected $methods = array('strict', 'order', 'alias', 'having', 'group', 'lock', 'distinct', 'auto', 'filter', 'validate', 'result', 'token', 'index', 'force'); /** * 架构函数 @@ -69,32 +71,35 @@ class Model { * @param string $tablePrefix 表前缀 * @param mixed $connection 数据库连接信息 */ - public function __construct($name='',$tablePrefix='',$connection='') { + public function __construct($name = '', $tablePrefix = '', $connection = '') + { // 模型初始化 $this->_initialize(); // 获取模型名称 - if(!empty($name)) { - if(strpos($name,'.')) { // 支持 数据库名.模型名的 定义 - list($this->dbName,$this->name) = explode('.',$name); - }else{ - $this->name = $name; + if (!empty($name)) { + if (strpos($name, '.')) { + // 支持 数据库名.模型名的 定义 + list($this->dbName, $this->name) = explode('.', $name); + } else { + $this->name = $name; } - }elseif(empty($this->name)){ - $this->name = $this->getModelName(); + } elseif (empty($this->name)) { + $this->name = $this->getModelName(); } // 设置表前缀 - if(is_null($tablePrefix)) {// 前缀为Null表示没有前缀 + if (is_null($tablePrefix)) { + // 前缀为Null表示没有前缀 $this->tablePrefix = ''; - }elseif('' != $tablePrefix) { + } elseif ('' != $tablePrefix) { $this->tablePrefix = $tablePrefix; - }elseif(!isset($this->tablePrefix)){ + } elseif (!isset($this->tablePrefix)) { $this->tablePrefix = C('DB_PREFIX'); } // 数据库初始化操作 // 获取数据库操作对象 // 当前模型有独立的数据库连接信息 - $this->db(0,empty($this->connection)?$connection:$this->connection,true); + $this->db(0, empty($this->connection) ? $connection : $this->connection, true); } /** @@ -102,20 +107,21 @@ public function __construct($name='',$tablePrefix='',$connection='') { * @access protected * @return void */ - protected function _checkTableInfo() { + protected function _checkTableInfo() + { // 如果不是Model类 自动记录数据表信息 // 只在第一次执行记录 - if(empty($this->fields)) { + if (empty($this->fields)) { // 如果数据表字段没有定义则自动获取 - if(C('DB_FIELDS_CACHE')) { - $db = $this->dbName?:C('DB_NAME'); - $fields = F('_fields/'.strtolower($db.'.'.$this->tablePrefix.$this->name)); - if($fields) { - $this->fields = $fields; - if(!empty($fields['_pk'])){ - $this->pk = $fields['_pk']; + if (C('DB_FIELDS_CACHE')) { + $db = $this->dbName ?: C('DB_NAME'); + $fields = F('_fields/' . strtolower($db . '.' . $this->tablePrefix . $this->name)); + if ($fields) { + $this->fields = $fields; + if (!empty($fields['_pk'])) { + $this->pk = $fields['_pk']; } - return ; + return; } } // 每次都会读取数据表信息 @@ -128,42 +134,47 @@ protected function _checkTableInfo() { * @access public * @return void */ - public function flush() { + public function flush() + { // 缓存不存在则查询数据表信息 $this->db->setModel($this->name); - $fields = $this->db->getFields($this->getTableName()); - if(!$fields) { // 无法获取字段信息 + $fields = $this->db->getFields($this->getTableName()); + if (!$fields) { + // 无法获取字段信息 return false; } - $this->fields = array_keys($fields); + $this->fields = array_keys($fields); unset($this->fields['_pk']); - foreach ($fields as $key=>$val){ + foreach ($fields as $key => $val) { // 记录字段类型 - $type[$key] = $val['type']; - if($val['primary']) { - // 增加复合主键支持 - if (isset($this->fields['_pk']) && $this->fields['_pk'] != null) { + $type[$key] = $val['type']; + if ($val['primary']) { + // 增加复合主键支持 + if (isset($this->fields['_pk']) && null != $this->fields['_pk']) { if (is_string($this->fields['_pk'])) { - $this->pk = array($this->fields['_pk']); - $this->fields['_pk'] = $this->pk; + $this->pk = array($this->fields['_pk']); + $this->fields['_pk'] = $this->pk; } - $this->pk[] = $key; - $this->fields['_pk'][] = $key; + $this->pk[] = $key; + $this->fields['_pk'][] = $key; } else { - $this->pk = $key; - $this->fields['_pk'] = $key; + $this->pk = $key; + $this->fields['_pk'] = $key; + } + if ($val['autoinc']) { + $this->autoinc = true; } - if($val['autoinc']) $this->autoinc = true; + } } // 记录字段类型信息 - $this->fields['_type'] = $type; + $this->fields['_type'] = $type; // 2008-3-7 增加缓存开关控制 - if(C('DB_FIELDS_CACHE')){ + if (C('DB_FIELDS_CACHE')) { // 永久缓存数据表信息 - $db = $this->dbName?:C('DB_NAME'); - F('_fields/'.strtolower($db.'.'.$this->tablePrefix.$this->name),$this->fields); + $db = $this->dbName ?: C('DB_NAME'); + F('_fields/' . strtolower($db . '.' . $this->tablePrefix . $this->name), $this->fields); } } @@ -174,9 +185,10 @@ public function flush() { * @param mixed $value 值 * @return void */ - public function __set($name,$value) { + public function __set($name, $value) + { // 设置数据对象属性 - $this->data[$name] = $value; + $this->data[$name] = $value; } /** @@ -185,8 +197,9 @@ public function __set($name,$value) { * @param string $name 名称 * @return mixed */ - public function __get($name) { - return isset($this->data[$name])?$this->data[$name]:null; + public function __get($name) + { + return isset($this->data[$name]) ? $this->data[$name] : null; } /** @@ -195,7 +208,8 @@ public function __get($name) { * @param string $name 名称 * @return boolean */ - public function __isset($name) { + public function __isset($name) + { return isset($this->data[$name]); } @@ -205,7 +219,8 @@ public function __isset($name) { * @param string $name 名称 * @return void */ - public function __unset($name) { + public function __unset($name) + { unset($this->data[$name]); } @@ -216,34 +231,37 @@ public function __unset($name) { * @param array $args 调用参数 * @return mixed */ - public function __call($method,$args) { - if(in_array(strtolower($method),$this->methods,true)) { + public function __call($method, $args) + { + if (in_array(strtolower($method), $this->methods, true)) { // 连贯操作的实现 - $this->options[strtolower($method)] = $args[0]; + $this->options[strtolower($method)] = $args[0]; return $this; - }elseif(in_array(strtolower($method),array('count','sum','min','max','avg'),true)){ + } elseif (in_array(strtolower($method), array('count', 'sum', 'min', 'max', 'avg'), true)) { // 统计查询的实现 - $field = isset($args[0])?$args[0]:'*'; - return $this->getField(strtoupper($method).'('.$field.') AS tp_'.$method); - }elseif(strtolower(substr($method,0,5))=='getby') { + $field = isset($args[0]) ? $args[0] : '*'; + return $this->getField(strtoupper($method) . '(' . $field . ') AS tp_' . $method); + } elseif (strtolower(substr($method, 0, 5)) == 'getby') { // 根据某个字段获取记录 - $field = parse_name(substr($method,5)); - $where[$field] = $args[0]; + $field = parse_name(substr($method, 5)); + $where[$field] = $args[0]; return $this->where($where)->find(); - }elseif(strtolower(substr($method,0,10))=='getfieldby') { + } elseif (strtolower(substr($method, 0, 10)) == 'getfieldby') { // 根据某个字段获取记录的某个值 - $name = parse_name(substr($method,10)); - $where[$name] =$args[0]; + $name = parse_name(substr($method, 10)); + $where[$name] = $args[0]; return $this->where($where)->getField($args[1]); - }elseif(isset($this->_scope[$method])){// 命名范围的单独调用支持 - return $this->scope($method,$args[0]); - }else{ - E(__CLASS__.':'.$method.L('_METHOD_NOT_EXIST_')); + } elseif (isset($this->_scope[$method])) { +// 命名范围的单独调用支持 + return $this->scope($method, $args[0]); + } else { + E(__CLASS__ . ':' . $method . L('_METHOD_NOT_EXIST_')); return; } } // 回调方法 初始化模型 - protected function _initialize() {} + protected function _initialize() + {} /** * 对保存到数据库的数据进行处理 @@ -251,43 +269,45 @@ protected function _initialize() {} * @param mixed $data 要操作的数据 * @return boolean */ - protected function _facade($data) { + protected function _facade($data) + { // 检查数据字段合法性 - if(!empty($this->fields)) { - if(!empty($this->options['field'])) { - $fields = $this->options['field']; + if (!empty($this->fields)) { + if (!empty($this->options['field'])) { + $fields = $this->options['field']; unset($this->options['field']); - if(is_string($fields)) { - $fields = explode(',',$fields); - } - }else{ - $fields = $this->fields; - } - foreach ($data as $key=>$val){ - if(!in_array($key,$fields,true)){ - if(!empty($this->options['strict'])){ - E(L('_DATA_TYPE_INVALID_').':['.$key.'=>'.$val.']'); + if (is_string($fields)) { + $fields = explode(',', $fields); + } + } else { + $fields = $this->fields; + } + foreach ($data as $key => $val) { + if (!in_array($key, $fields, true)) { + if (!empty($this->options['strict'])) { + E(L('_DATA_TYPE_INVALID_') . ':[' . $key . '=>' . $val . ']'); } unset($data[$key]); - }elseif(is_scalar($val)) { + } elseif (is_scalar($val)) { // 字段类型检查 和 强制转换 - $this->_parseType($data,$key); + $this->_parseType($data, $key); } } } - + // 安全过滤 - if(!empty($this->options['filter'])) { - $data = array_map($this->options['filter'],$data); + if (!empty($this->options['filter'])) { + $data = array_map($this->options['filter'], $data); unset($this->options['filter']); } $this->_before_write($data); return $data; - } + } // 写入数据前的回调方法 包括新增和更新 - protected function _before_write(&$data) {} + protected function _before_write(&$data) + {} /** * 新增数据 @@ -297,67 +317,74 @@ protected function _before_write(&$data) {} * @param boolean $replace 是否replace * @return mixed */ - public function add($data='',$options=array(),$replace=false) { - if(empty($data)) { + public function add($data = '', $options = array(), $replace = false) + { + if (empty($data)) { // 没有传递数据,获取当前数据对象的值 - if(!empty($this->data)) { - $data = $this->data; + if (!empty($this->data)) { + $data = $this->data; // 重置数据 - $this->data = array(); - }else{ - $this->error = L('_DATA_TYPE_INVALID_'); + $this->data = array(); + } else { + $this->error = L('_DATA_TYPE_INVALID_'); return false; } } // 数据处理 - $data = $this->_facade($data); + $data = $this->_facade($data); // 分析表达式 - $options = $this->_parseOptions($options); - if(false === $this->_before_insert($data,$options)) { + $options = $this->_parseOptions($options); + if (false === $this->_before_insert($data, $options)) { return false; } // 写入数据到数据库 - $result = $this->db->insert($data,$options,$replace); - if(false !== $result && is_numeric($result)) { - $pk = $this->getPk(); - // 增加复合主键支持 - if (is_array($pk)) return $result; - $insertId = $this->getLastInsID(); - if($insertId) { + $result = $this->db->insert($data, $options, $replace); + if (false !== $result && is_numeric($result)) { + $pk = $this->getPk(); + // 增加复合主键支持 + if (is_array($pk)) { + return $result; + } + + $insertId = $this->getLastInsID(); + if ($insertId) { // 自增主键返回插入ID - $data[$pk] = $insertId; - if(false === $this->_after_insert($data,$options)) { + $data[$pk] = $insertId; + if (false === $this->_after_insert($data, $options)) { return false; } return $insertId; } - if(false === $this->_after_insert($data,$options)) { + if (false === $this->_after_insert($data, $options)) { return false; } } return $result; } // 插入数据前的回调方法 - protected function _before_insert(&$data,$options) {} + protected function _before_insert(&$data, $options) + {} // 插入成功后的回调方法 - protected function _after_insert($data,$options) {} + protected function _after_insert($data, $options) + {} - public function addAll($dataList,$options=array(),$replace=false){ - if(empty($dataList)) { + public function addAll($dataList, $options = array(), $replace = false) + { + if (empty($dataList)) { $this->error = L('_DATA_TYPE_INVALID_'); return false; } // 数据处理 - foreach ($dataList as $key=>$data){ + foreach ($dataList as $key => $data) { $dataList[$key] = $this->_facade($data); } // 分析表达式 - $options = $this->_parseOptions($options); + $options = $this->_parseOptions($options); // 写入数据到数据库 - $result = $this->db->insertAll($dataList,$options,$replace); - if(false !== $result ) { - $insertId = $this->getLastInsID(); - if($insertId) { + $result = $this->db->insertAll($dataList, $options, $replace); + if (false !== $result) { + $insertId = $this->getLastInsID(); + if ($insertId) { return $insertId; } } @@ -372,15 +399,16 @@ public function addAll($dataList,$options=array(),$replace=false){ * @param array $options 表达式 * @return boolean */ - public function selectAdd($fields='',$table='',$options=array()) { + public function selectAdd($fields = '', $table = '', $options = array()) + { // 分析表达式 - $options = $this->_parseOptions($options); + $options = $this->_parseOptions($options); // 写入数据到数据库 - if(false === $result = $this->db->selectInsert($fields?:$options['field'],$table?:$this->getTableName(),$options)){ + if (false === $result = $this->db->selectInsert($fields ?: $options['field'], $table ?: $this->getTableName(), $options)) { // 数据库插入操作失败 $this->error = L('_OPERATION_WRONG_'); return false; - }else { + } else { // 插入成功 return $result; } @@ -393,72 +421,78 @@ public function selectAdd($fields='',$table='',$options=array()) { * @param array $options 表达式 * @return boolean */ - public function save($data='',$options=array()) { - if(empty($data)) { + public function save($data = '', $options = array()) + { + if (empty($data)) { // 没有传递数据,获取当前数据对象的值 - if(!empty($this->data)) { - $data = $this->data; + if (!empty($this->data)) { + $data = $this->data; // 重置数据 - $this->data = array(); - }else{ - $this->error = L('_DATA_TYPE_INVALID_'); + $this->data = array(); + } else { + $this->error = L('_DATA_TYPE_INVALID_'); return false; } } // 数据处理 - $data = $this->_facade($data); - if(empty($data)){ + $data = $this->_facade($data); + if (empty($data)) { // 没有数据则不执行 - $this->error = L('_DATA_TYPE_INVALID_'); + $this->error = L('_DATA_TYPE_INVALID_'); return false; } // 分析表达式 - $options = $this->_parseOptions($options); - $pk = $this->getPk(); - if(!isset($options['where']) ) { + $options = $this->_parseOptions($options); + $pk = $this->getPk(); + if (!isset($options['where'])) { // 如果存在主键数据 则自动作为更新条件 if (is_string($pk) && isset($data[$pk])) { - $where[$pk] = $data[$pk]; + $where[$pk] = $data[$pk]; unset($data[$pk]); } elseif (is_array($pk)) { // 增加复合主键支持 foreach ($pk as $field) { - if(isset($data[$field])) { - $where[$field] = $data[$field]; + if (isset($data[$field])) { + $where[$field] = $data[$field]; } else { - // 如果缺少复合主键数据则不执行 - $this->error = L('_OPERATION_WRONG_'); + // 如果缺少复合主键数据则不执行 + $this->error = L('_OPERATION_WRONG_'); return false; } unset($data[$field]); } } - if(!isset($where)){ + if (!isset($where)) { // 如果没有任何更新条件则不执行 - $this->error = L('_OPERATION_WRONG_'); + $this->error = L('_OPERATION_WRONG_'); return false; - }else{ - $options['where'] = $where; + } else { + $options['where'] = $where; } } - if(is_array($options['where']) && isset($options['where'][$pk])){ - $pkValue = $options['where'][$pk]; + if (is_array($options['where']) && isset($options['where'][$pk])) { + $pkValue = $options['where'][$pk]; } - if(false === $this->_before_update($data,$options)) { + if (false === $this->_before_update($data, $options)) { return false; } - $result = $this->db->update($data,$options); - if(false !== $result && is_numeric($result)) { - if(isset($pkValue)) $data[$pk] = $pkValue; - $this->_after_update($data,$options); + $result = $this->db->update($data, $options); + if (false !== $result && is_numeric($result)) { + if (isset($pkValue)) { + $data[$pk] = $pkValue; + } + + $this->_after_update($data, $options); } return $result; } // 更新数据前的回调方法 - protected function _before_update(&$data,$options) {} + protected function _before_update(&$data, $options) + {} // 更新成功后的回调方法 - protected function _after_update($data,$options) {} + protected function _after_update($data, $options) + {} /** * 删除数据 @@ -466,68 +500,79 @@ protected function _after_update($data,$options) {} * @param mixed $options 表达式 * @return mixed */ - public function delete($options=array()) { - $pk = $this->getPk(); - if(empty($options) && empty($this->options['where'])) { + public function delete($options = array()) + { + $pk = $this->getPk(); + if (empty($options) && empty($this->options['where'])) { // 如果删除条件为空 则删除当前数据对象所对应的记录 - if(!empty($this->data) && isset($this->data[$pk])) + if (!empty($this->data) && isset($this->data[$pk])) { return $this->delete($this->data[$pk]); - else + } else { return false; + } + } - if(is_numeric($options) || is_string($options)) { + if (is_numeric($options) || is_string($options)) { // 根据主键删除记录 - if(strpos($options,',')) { - $where[$pk] = array('IN', $options); - }else{ - $where[$pk] = $options; + if (strpos($options, ',')) { + $where[$pk] = array('IN', $options); + } else { + $where[$pk] = $options; } - $options = array(); - $options['where'] = $where; + $options = array(); + $options['where'] = $where; } // 根据复合主键删除记录 if (is_array($options) && (count($options) > 0) && is_array($pk)) { $count = 0; foreach (array_keys($options) as $key) { - if (is_int($key)) $count++; - } - if ($count == count($pk)) { + if (is_int($key)) { + $count++; + } + + } + if (count($pk) == $count) { $i = 0; foreach ($pk as $field) { $where[$field] = $options[$i]; unset($options[$i++]); } - $options['where'] = $where; + $options['where'] = $where; } else { return false; } } // 分析表达式 - $options = $this->_parseOptions($options); - if(empty($options['where'])){ + $options = $this->_parseOptions($options); + if (empty($options['where'])) { // 如果条件为空 不进行删除操作 除非设置 1=1 return false; - } - if(is_array($options['where']) && isset($options['where'][$pk])){ - $pkValue = $options['where'][$pk]; + } + if (is_array($options['where']) && isset($options['where'][$pk])) { + $pkValue = $options['where'][$pk]; } - if(false === $this->_before_delete($options)) { + if (false === $this->_before_delete($options)) { return false; - } - $result = $this->db->delete($options); - if(false !== $result && is_numeric($result)) { + } + $result = $this->db->delete($options); + if (false !== $result && is_numeric($result)) { $data = array(); - if(isset($pkValue)) $data[$pk] = $pkValue; - $this->_after_delete($data,$options); + if (isset($pkValue)) { + $data[$pk] = $pkValue; + } + + $this->_after_delete($data, $options); } // 返回删除记录个数 return $result; } // 删除数据前的回调方法 - protected function _before_delete($options) {} + protected function _before_delete($options) + {} // 删除成功后的回调方法 - protected function _after_delete($data,$options) {} + protected function _after_delete($data, $options) + {} /** * 查询数据集 @@ -535,87 +580,96 @@ protected function _after_delete($data,$options) {} * @param array $options 表达式参数 * @return mixed */ - public function select($options=array()) { - $pk = $this->getPk(); - if(is_string($options) || is_numeric($options)) { + public function select($options = array()) + { + $pk = $this->getPk(); + if (is_string($options) || is_numeric($options)) { // 根据主键查询 - if(strpos($options,',')) { - $where[$pk] = array('IN',$options); - }else{ - $where[$pk] = $options; - } - $options = array(); - $options['where'] = $where; - }elseif (is_array($options) && (count($options) > 0) && is_array($pk)) { + if (strpos($options, ',')) { + $where[$pk] = array('IN', $options); + } else { + $where[$pk] = $options; + } + $options = array(); + $options['where'] = $where; + } elseif (is_array($options) && (count($options) > 0) && is_array($pk)) { // 根据复合主键查询 $count = 0; foreach (array_keys($options) as $key) { - if (is_int($key)) $count++; - } - if ($count == count($pk)) { + if (is_int($key)) { + $count++; + } + + } + if (count($pk) == $count) { $i = 0; foreach ($pk as $field) { $where[$field] = $options[$i]; unset($options[$i++]); } - $options['where'] = $where; + $options['where'] = $where; } else { return false; } - } elseif(false === $options){ // 用于子查询 不查询只返回SQL - $options['fetch_sql'] = true; + } elseif (false === $options) { + // 用于子查询 不查询只返回SQL + $options['fetch_sql'] = true; } // 分析表达式 - $options = $this->_parseOptions($options); + $options = $this->_parseOptions($options); // 判断查询缓存 - if(isset($options['cache'])){ - $cache = $options['cache']; - $key = is_string($cache['key'])?$cache['key']:md5(serialize($options)); - $data = S($key,'',$cache); - if(false !== $data){ + if (isset($options['cache'])) { + $cache = $options['cache']; + $key = is_string($cache['key']) ? $cache['key'] : md5(serialize($options)); + $data = S($key, '', $cache); + if (false !== $data) { return $data; } - } - $resultSet = $this->db->select($options); - if(false === $resultSet) { + } + $resultSet = $this->db->select($options); + if (false === $resultSet) { return false; } - if(!empty($resultSet)) { // 有查询结果 - if(is_string($resultSet)){ + if (!empty($resultSet)) { + // 有查询结果 + if (is_string($resultSet)) { return $resultSet; } - $resultSet = array_map(array($this,'_read_data'),$resultSet); - $this->_after_select($resultSet,$options); - if(isset($options['index'])){ // 对数据集进行索引 - $index = explode(',',$options['index']); - foreach ($resultSet as $result){ - $_key = $result[$index[0]]; - if(isset($index[1]) && isset($result[$index[1]])){ - $cols[$_key] = $result[$index[1]]; - }else{ - $cols[$_key] = $result; + $resultSet = array_map(array($this, '_read_data'), $resultSet); + $this->_after_select($resultSet, $options); + if (isset($options['index'])) { + // 对数据集进行索引 + $index = explode(',', $options['index']); + foreach ($resultSet as $result) { + $_key = $result[$index[0]]; + if (isset($index[1]) && isset($result[$index[1]])) { + $cols[$_key] = $result[$index[1]]; + } else { + $cols[$_key] = $result; } } - $resultSet = $cols; + $resultSet = $cols; } } - if(isset($cache)){ - S($key,$resultSet,$cache); + if (isset($cache)) { + S($key, $resultSet, $cache); } return $resultSet; } // 查询成功后的回调方法 - protected function _after_select(&$resultSet,$options) {} + protected function _after_select(&$resultSet, $options) + {} /** * 生成查询SQL 可用于子查询 * @access public * @return string */ - public function buildSql() { - return '( '.$this->fetchSql(true)->select().' )'; + public function buildSql() + { + return '( ' . $this->fetchSql(true)->select() . ' )'; } /** @@ -624,51 +678,54 @@ public function buildSql() { * @param array $options 表达式参数 * @return array */ - protected function _parseOptions($options=array()) { - if(is_array($options)) - $options = array_merge($this->options,$options); + protected function _parseOptions($options = array()) + { + if (is_array($options)) { + $options = array_merge($this->options, $options); + } - if(!isset($options['table'])){ + if (!isset($options['table'])) { // 自动获取表名 - $options['table'] = $this->getTableName(); - $fields = $this->fields; - }else{ + $options['table'] = $this->getTableName(); + $fields = $this->fields; + } else { // 指定数据表 则重新获取字段列表 但不支持类型检测 - $fields = $this->getDbFields(); + $fields = $this->getDbFields(); } // 数据表别名 - if(!empty($options['alias'])) { - $options['table'] .= ' '.$options['alias']; + if (!empty($options['alias'])) { + $options['table'] .= ' ' . $options['alias']; } // 记录操作的模型名称 - $options['model'] = $this->name; + $options['model'] = $this->name; // 字段类型验证 - if(isset($options['where']) && is_array($options['where']) && !empty($fields) && !isset($options['join'])) { + if (isset($options['where']) && is_array($options['where']) && !empty($fields) && !isset($options['join'])) { // 对数组查询条件进行字段类型检查 - foreach ($options['where'] as $key=>$val){ - $key = trim($key); - if(in_array($key,$fields,true)){ - if(is_scalar($val)) { - $this->_parseType($options['where'],$key); + foreach ($options['where'] as $key => $val) { + $key = trim($key); + if (in_array($key, $fields, true)) { + if (is_scalar($val)) { + $this->_parseType($options['where'], $key); + } + } elseif (!is_numeric($key) && '_' != substr($key, 0, 1) && false === strpos($key, '.') && false === strpos($key, '(') && false === strpos($key, '|') && false === strpos($key, '&')) { + if (!empty($this->options['strict'])) { + E(L('_ERROR_QUERY_EXPRESS_') . ':[' . $key . '=>' . $val . ']'); } - }elseif(!is_numeric($key) && '_' != substr($key,0,1) && false === strpos($key,'.') && false === strpos($key,'(') && false === strpos($key,'|') && false === strpos($key,'&')){ - if(!empty($this->options['strict'])){ - E(L('_ERROR_QUERY_EXPRESS_').':['.$key.'=>'.$val.']'); - } unset($options['where'][$key]); } } } // 查询过后清空sql表达式组装 避免影响下次查询 - $this->options = array(); + $this->options = array(); // 表达式过滤 $this->_options_filter($options); return $options; } // 表达式过滤回调方法 - protected function _options_filter(&$options) {} + protected function _options_filter(&$options) + {} /** * 数据类型检测 @@ -677,17 +734,18 @@ protected function _options_filter(&$options) {} * @param string $key 字段名 * @return void */ - protected function _parseType(&$data,$key) { - if(!isset($this->options['bind'][':'.$key]) && isset($this->fields['_type'][$key])){ + protected function _parseType(&$data, $key) + { + if (!isset($this->options['bind'][':' . $key]) && isset($this->fields['_type'][$key])) { $fieldType = strtolower($this->fields['_type'][$key]); - if(false !== strpos($fieldType,'enum')){ + if (false !== strpos($fieldType, 'enum')) { // 支持ENUM类型优先检测 - }elseif(false === strpos($fieldType,'bigint') && false !== strpos($fieldType,'int')) { - $data[$key] = intval($data[$key]); - }elseif(false !== strpos($fieldType,'float') || false !== strpos($fieldType,'double')){ - $data[$key] = floatval($data[$key]); - }elseif(false !== strpos($fieldType,'bool')){ - $data[$key] = (bool)$data[$key]; + } elseif (false === strpos($fieldType, 'bigint') && false !== strpos($fieldType, 'int')) { + $data[$key] = intval($data[$key]); + } elseif (false !== strpos($fieldType, 'float') || false !== strpos($fieldType, 'double')) { + $data[$key] = floatval($data[$key]); + } elseif (false !== strpos($fieldType, 'bool')) { + $data[$key] = (bool) $data[$key]; } } } @@ -698,12 +756,13 @@ protected function _parseType(&$data,$key) { * @param array $data 当前数据 * @return array */ - protected function _read_data($data) { + protected function _read_data($data) + { // 检查字段映射 - if(!empty($this->_map) && C('READ_DATA_MAP')) { - foreach ($this->_map as $key=>$val){ - if(isset($data[$val])) { - $data[$key] = $data[$val]; + if (!empty($this->_map) && C('READ_DATA_MAP')) { + foreach ($this->_map as $key => $val) { + if (isset($data[$val])) { + $data[$key] = $data[$val]; unset($data[$val]); } } @@ -717,77 +776,84 @@ protected function _read_data($data) { * @param mixed $options 表达式参数 * @return mixed */ - public function find($options=array()) { - if(is_numeric($options) || is_string($options)) { - $where[$this->getPk()] = $options; - $options = array(); - $options['where'] = $where; + public function find($options = array()) + { + if (is_numeric($options) || is_string($options)) { + $where[$this->getPk()] = $options; + $options = array(); + $options['where'] = $where; } // 根据复合主键查找记录 - $pk = $this->getPk(); + $pk = $this->getPk(); if (is_array($options) && (count($options) > 0) && is_array($pk)) { // 根据复合主键查询 $count = 0; foreach (array_keys($options) as $key) { - if (is_int($key)) $count++; - } - if ($count == count($pk)) { + if (is_int($key)) { + $count++; + } + + } + if (count($pk) == $count) { $i = 0; foreach ($pk as $field) { $where[$field] = $options[$i]; unset($options[$i++]); } - $options['where'] = $where; + $options['where'] = $where; } else { return false; } } // 总是查找一条记录 - $options['limit'] = 1; + $options['limit'] = 1; // 分析表达式 - $options = $this->_parseOptions($options); + $options = $this->_parseOptions($options); // 判断查询缓存 - if(isset($options['cache'])){ - $cache = $options['cache']; - $key = is_string($cache['key'])?$cache['key']:md5(serialize($options)); - $data = S($key,'',$cache); - if(false !== $data){ - $this->data = $data; + if (isset($options['cache'])) { + $cache = $options['cache']; + $key = is_string($cache['key']) ? $cache['key'] : md5(serialize($options)); + $data = S($key, '', $cache); + if (false !== $data) { + $this->data = $data; return $data; } } - $resultSet = $this->db->select($options); - if(false === $resultSet) { + $resultSet = $this->db->select($options); + if (false === $resultSet) { return false; } - if(empty($resultSet)) {// 查询结果为空 + if (empty($resultSet)) { +// 查询结果为空 return null; } - if(is_string($resultSet)){ + if (is_string($resultSet)) { return $resultSet; } // 读取数据后的处理 - $data = $this->_read_data($resultSet[0]); - $this->_after_find($data,$options); - if(!empty($this->options['result'])) { - return $this->returnResult($data,$this->options['result']); + $data = $this->_read_data($resultSet[0]); + $this->_after_find($data, $options); + if (!empty($this->options['result'])) { + return $this->returnResult($data, $this->options['result']); } - $this->data = $data; - if(isset($cache)){ - S($key,$data,$cache); + $this->data = $data; + if (isset($cache)) { + S($key, $data, $cache); } return $this->data; } // 查询成功的回调方法 - protected function _after_find(&$result,$options) {} - - protected function returnResult($data,$type=''){ - if ($type){ - if(is_callable($type)){ - return call_user_func($type,$data); + protected function _after_find(&$result, $options) + {} + + protected function returnResult($data, $type = '') + { + if ($type) { + if (is_callable($type)) { + return call_user_func($type, $data); } - switch (strtolower($type)){ + switch (strtolower($type)) { case 'json': return json_encode($data); case 'xml': @@ -804,18 +870,20 @@ protected function returnResult($data,$type=''){ * @param integer $type 类型 0 写入 1 读取 * @return array */ - public function parseFieldsMap($data,$type=1) { + public function parseFieldsMap($data, $type = 1) + { // 检查字段映射 - if(!empty($this->_map)) { - foreach ($this->_map as $key=>$val){ - if($type==1) { // 读取 - if(isset($data[$val])) { - $data[$key] = $data[$val]; + if (!empty($this->_map)) { + foreach ($this->_map as $key => $val) { + if (1 == $type) { + // 读取 + if (isset($data[$val])) { + $data[$key] = $data[$val]; unset($data[$val]); } - }else{ - if(isset($data[$key])) { - $data[$val] = $data[$key]; + } else { + if (isset($data[$key])) { + $data[$val] = $data[$key]; unset($data[$key]); } } @@ -832,11 +900,12 @@ public function parseFieldsMap($data,$type=1) { * @param string $value 字段值 * @return boolean */ - public function setField($field,$value='') { - if(is_array($field)) { - $data = $field; - }else{ - $data[$field] = $value; + public function setField($field, $value = '') + { + if (is_array($field)) { + $data = $field; + } else { + $data[$field] = $value; } return $this->save($data); } @@ -849,18 +918,20 @@ public function setField($field,$value='') { * @param integer $lazyTime 延时时间(s) * @return boolean */ - public function setInc($field,$step=1,$lazyTime=0) { - if($lazyTime>0) {// 延迟写入 - $condition = $this->options['where']; - $guid = md5($this->name.'_'.$field.'_'.serialize($condition)); - $step = $this->lazyWrite($guid,$step,$lazyTime); - if(empty($step)) { - return true; // 等待下次写入 - }elseif($step < 0) { - $step = '-'.$step; + public function setInc($field, $step = 1, $lazyTime = 0) + { + if ($lazyTime > 0) { +// 延迟写入 + $condition = $this->options['where']; + $guid = md5($this->name . '_' . $field . '_' . serialize($condition)); + $step = $this->lazyWrite($guid, $step, $lazyTime); + if (empty($step)) { + return true; // 等待下次写入 + } elseif ($step < 0) { + $step = '-' . $step; } } - return $this->setField($field,array('exp',$field.'+'.$step)); + return $this->setField($field, array('exp', $field . '+' . $step)); } /** @@ -871,18 +942,20 @@ public function setInc($field,$step=1,$lazyTime=0) { * @param integer $lazyTime 延时时间(s) * @return boolean */ - public function setDec($field,$step=1,$lazyTime=0) { - if($lazyTime>0) {// 延迟写入 - $condition = $this->options['where']; - $guid = md5($this->name.'_'.$field.'_'.serialize($condition)); - $step = $this->lazyWrite($guid,-$step,$lazyTime); - if(empty($step)) { - return true; // 等待下次写入 - }elseif($step > 0) { - $step = '-'.$step; + public function setDec($field, $step = 1, $lazyTime = 0) + { + if ($lazyTime > 0) { +// 延迟写入 + $condition = $this->options['where']; + $guid = md5($this->name . '_' . $field . '_' . serialize($condition)); + $step = $this->lazyWrite($guid, -$step, $lazyTime); + if (empty($step)) { + return true; // 等待下次写入 + } elseif ($step > 0) { + $step = '-' . $step; } } - return $this->setField($field,array('exp',$field.'-'.$step)); + return $this->setField($field, array('exp', $field . '-' . $step)); } /** @@ -894,22 +967,25 @@ public function setDec($field,$step=1,$lazyTime=0) { * @param integer $lazyTime 延时时间(s) * @return false|integer */ - protected function lazyWrite($guid,$step,$lazyTime) { - if(false !== ($value = S($guid))) { // 存在缓存写入数据 - if(NOW_TIME > S($guid.'_time')+$lazyTime) { + protected function lazyWrite($guid, $step, $lazyTime) + { + if (false !== ($value = S($guid))) { + // 存在缓存写入数据 + if (NOW_TIME > S($guid . '_time') + $lazyTime) { // 延时更新时间到了,删除缓存数据 并实际写入数据库 - S($guid,NULL); - S($guid.'_time',NULL); - return $value+$step; - }else{ + S($guid, null); + S($guid . '_time', null); + return $value + $step; + } else { // 追加数据到缓存 - S($guid,$value+$step); + S($guid, $value + $step); return false; } - }else{ // 没有缓存数据 - S($guid,$step); + } else { + // 没有缓存数据 + S($guid, $step); // 计时开始 - S($guid.'_time',NOW_TIME); + S($guid . '_time', NOW_TIME); return false; } } @@ -921,70 +997,74 @@ protected function lazyWrite($guid,$step,$lazyTime) { * @param string $spea 字段数据间隔符号 NULL返回数组 * @return mixed */ - public function getField($field,$sepa=null) { - $options['field'] = $field; - $options = $this->_parseOptions($options); + public function getField($field, $sepa = null) + { + $options['field'] = $field; + $options = $this->_parseOptions($options); // 判断查询缓存 - if(isset($options['cache'])){ - $cache = $options['cache']; - $key = is_string($cache['key'])?$cache['key']:md5($sepa.serialize($options)); - $data = S($key,'',$cache); - if(false !== $data){ + if (isset($options['cache'])) { + $cache = $options['cache']; + $key = is_string($cache['key']) ? $cache['key'] : md5($sepa . serialize($options)); + $data = S($key, '', $cache); + if (false !== $data) { return $data; } - } - $field = trim($field); - if(strpos($field,',') && false !== $sepa) { // 多字段 - if(!isset($options['limit'])){ - $options['limit'] = is_numeric($sepa)?$sepa:''; - } - $resultSet = $this->db->select($options); - if(!empty($resultSet)) { - if(is_string($resultSet)){ - return $resultSet; - } - $_field = explode(',', $field); - $field = array_keys($resultSet[0]); - $key1 = array_shift($field); - $key2 = array_shift($field); - $cols = array(); - $count = count($_field); - foreach ($resultSet as $result){ - $name = $result[$key1]; - if(2==$count) { - $cols[$name] = $result[$key2]; - }else{ - $cols[$name] = is_string($sepa)?implode($sepa,array_slice($result,1)):$result; + } + $field = trim($field); + if (strpos($field, ',') && false !== $sepa) { + // 多字段 + if (!isset($options['limit'])) { + $options['limit'] = is_numeric($sepa) ? $sepa : ''; + } + $resultSet = $this->db->select($options); + if (!empty($resultSet)) { + if (is_string($resultSet)) { + return $resultSet; + } + $_field = explode(',', $field); + $field = array_keys($resultSet[0]); + $key1 = array_shift($field); + $key2 = array_shift($field); + $cols = array(); + $count = count($_field); + foreach ($resultSet as $result) { + $name = $result[$key1]; + if (2 == $count) { + $cols[$name] = $result[$key2]; + } else { + $cols[$name] = is_string($sepa) ? implode($sepa, array_slice($result, 1)) : $result; } } - if(isset($cache)){ - S($key,$cols,$cache); + if (isset($cache)) { + S($key, $cols, $cache); } return $cols; } - }else{ // 查找一条记录 + } else { + // 查找一条记录 // 返回数据个数 - if(true !== $sepa) {// 当sepa指定为true的时候 返回所有数据 - $options['limit'] = is_numeric($sepa)?$sepa:1; + if (true !== $sepa) { + // 当sepa指定为true的时候 返回所有数据 + $options['limit'] = is_numeric($sepa) ? $sepa : 1; } $result = $this->db->select($options); - if(!empty($result)) { - if(is_string($result)){ - return $result; - } - if(true !== $sepa && 1==$options['limit']) { - $data = reset($result[0]); - if(isset($cache)){ - S($key,$data,$cache); - } + if (!empty($result)) { + if (is_string($result)) { + return $result; + } + if (true !== $sepa && 1 == $options['limit']) { + $data = reset($result[0]); + if (isset($cache)) { + S($key, $data, $cache); + } return $data; } - foreach ($result as $val){ - $array[] = reset($val); + foreach ($result as $val) { + $array[] = reset($val); + } + if (isset($cache)) { + S($key, $array, $cache); } - if(isset($cache)){ - S($key,$array,$cache); - } return $array; } } @@ -998,95 +1078,112 @@ public function getField($field,$sepa=null) { * @param string $type 状态 * @return mixed */ - public function create($data='',$type='') { + public function create($data = '', $type = '') + { // 如果没有传值默认取POST数据 - if(empty($data)) { - $data = I('post.'); - }elseif(is_object($data)){ - $data = get_object_vars($data); + if (empty($data)) { + $data = I('post.'); + } elseif (is_object($data)) { + $data = get_object_vars($data); } // 验证数据 - if(empty($data) || !is_array($data)) { + if (empty($data) || !is_array($data)) { $this->error = L('_DATA_TYPE_INVALID_'); return false; } // 状态 - $type = $type?:(!empty($data[$this->getPk()])?self::MODEL_UPDATE:self::MODEL_INSERT); + $type = $type ?: (!empty($data[$this->getPk()]) ? self::MODEL_UPDATE : self::MODEL_INSERT); // 检查字段映射 - $data = $this->parseFieldsMap($data,0); + $data = $this->parseFieldsMap($data, 0); // 检测提交字段的合法性 - if(isset($this->options['field'])) { // $this->field('field1,field2...')->create() - $fields = $this->options['field']; + if (isset($this->options['field'])) { + // $this->field('field1,field2...')->create() + $fields = $this->options['field']; unset($this->options['field']); - }elseif($type == self::MODEL_INSERT && isset($this->insertFields)) { - $fields = $this->insertFields; - }elseif($type == self::MODEL_UPDATE && isset($this->updateFields)) { - $fields = $this->updateFields; - } - if(isset($fields)) { - if(is_string($fields)) { - $fields = explode(',',$fields); + } elseif (self::MODEL_INSERT == $type && isset($this->insertFields)) { + $fields = $this->insertFields; + } elseif (self::MODEL_UPDATE == $type && isset($this->updateFields)) { + $fields = $this->updateFields; + } + if (isset($fields)) { + if (is_string($fields)) { + $fields = explode(',', $fields); } // 判断令牌验证字段 - if(C('TOKEN_ON')) $fields[] = C('TOKEN_NAME', null, '__hash__'); - foreach ($data as $key=>$val){ - if(!in_array($key,$fields)) { + if (C('TOKEN_ON')) { + $fields[] = C('TOKEN_NAME', null, '__hash__'); + } + + foreach ($data as $key => $val) { + if (!in_array($key, $fields)) { unset($data[$key]); } } } // 数据自动验证 - if(!$this->autoValidation($data,$type)) return false; + if (!$this->autoValidation($data, $type)) { + return false; + } // 表单令牌验证 - if(!$this->autoCheckToken($data)) { + if (!$this->autoCheckToken($data)) { $this->error = L('_TOKEN_ERROR_'); return false; } // 验证完成生成数据对象 - if($this->autoCheckFields) { // 开启字段检测 则过滤非法字段数据 - $fields = $this->getDbFields(); - foreach ($data as $key=>$val){ - if(!in_array($key,$fields)) { + if ($this->autoCheckFields) { + // 开启字段检测 则过滤非法字段数据 + $fields = $this->getDbFields(); + foreach ($data as $key => $val) { + if (!in_array($key, $fields)) { unset($data[$key]); - }elseif(MAGIC_QUOTES_GPC && is_string($val)){ - $data[$key] = stripslashes($val); + } elseif (MAGIC_QUOTES_GPC && is_string($val)) { + $data[$key] = stripslashes($val); } } } // 创建完成对数据进行自动处理 - $this->autoOperation($data,$type); + $this->autoOperation($data, $type); // 赋值当前数据对象 - $this->data = $data; + $this->data = $data; // 返回创建的数据以供其他调用 return $data; - } + } // 自动表单令牌验证 // TODO ajax无刷新多次提交暂不能满足 - public function autoCheckToken($data) { + public function autoCheckToken($data) + { // 支持使用token(false) 关闭令牌验证 - if(isset($this->options['token']) && !$this->options['token']) return true; - if(C('TOKEN_ON')){ - $name = C('TOKEN_NAME', null, '__hash__'); - if(!isset($data[$name]) || !isset($_SESSION[$name])) { // 令牌数据无效 + if (isset($this->options['token']) && !$this->options['token']) { + return true; + } + + if (C('TOKEN_ON')) { + $name = C('TOKEN_NAME', null, '__hash__'); + if (!isset($data[$name]) || !isset($_SESSION[$name])) { + // 令牌数据无效 return false; } // 令牌验证 - list($key,$value) = explode('_',$data[$name]); - if(isset($_SESSION[$name][$key]) && $value && $_SESSION[$name][$key] === $value) { // 防止重复提交 + list($key, $value) = explode('_', $data[$name]); + if (isset($_SESSION[$name][$key]) && $value && $_SESSION[$name][$key] === $value) { + // 防止重复提交 unset($_SESSION[$name][$key]); // 验证完成销毁session return true; } // 开启TOKEN重置 - if(C('TOKEN_RESET')) unset($_SESSION[$name][$key]); + if (C('TOKEN_RESET')) { + unset($_SESSION[$name][$key]); + } + return false; } return true; @@ -1099,22 +1196,25 @@ public function autoCheckToken($data) { * @param string $rule 验证规则 * @return boolean */ - public function regex($value,$rule) { + public function regex($value, $rule) + { $validate = array( - 'require' => '/\S+/', - 'email' => '/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/', - 'url' => '/^http(s?):\/\/(?:[A-za-z0-9-]+\.)+[A-za-z]{2,4}(:\d+)?(?:[\/\?#][\/=\?%\-&~`@[\]\':+!\.#\w]*)?$/', - 'currency' => '/^\d+(\.\d+)?$/', - 'number' => '/^\d+$/', - 'zip' => '/^\d{6}$/', - 'integer' => '/^[-\+]?\d+$/', - 'double' => '/^[-\+]?\d+(\.\d+)?$/', - 'english' => '/^[A-Za-z]+$/', + 'require' => '/\S+/', + 'email' => '/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/', + 'url' => '/^http(s?):\/\/(?:[A-za-z0-9-]+\.)+[A-za-z]{2,4}(:\d+)?(?:[\/\?#][\/=\?%\-&~`@[\]\':+!\.#\w]*)?$/', + 'currency' => '/^\d+(\.\d+)?$/', + 'number' => '/^\d+$/', + 'zip' => '/^\d{6}$/', + 'integer' => '/^[-\+]?\d+$/', + 'double' => '/^[-\+]?\d+(\.\d+)?$/', + 'english' => '/^[A-Za-z]+$/', ); // 检查是否有内置的正则表达式 - if(isset($validate[strtolower($rule)])) - $rule = $validate[strtolower($rule)]; - return preg_match($rule,$value)===1; + if (isset($validate[strtolower($rule)])) { + $rule = $validate[strtolower($rule)]; + } + + return preg_match($rule, $value) === 1; } /** @@ -1124,50 +1224,62 @@ public function regex($value,$rule) { * @param string $type 创建类型 * @return mixed */ - private function autoOperation(&$data,$type) { - if(isset($this->options['auto']) && false === $this->options['auto']){ - // 关闭自动完成 - return $data; - } - if(!empty($this->options['auto'])) { - $_auto = $this->options['auto']; + private function autoOperation(&$data, $type) + { + if (isset($this->options['auto']) && false === $this->options['auto']) { + // 关闭自动完成 + return $data; + } + if (!empty($this->options['auto'])) { + $_auto = $this->options['auto']; unset($this->options['auto']); - }elseif(!empty($this->_auto)){ - $_auto = $this->_auto; + } elseif (!empty($this->_auto)) { + $_auto = $this->_auto; } // 自动填充 - if(isset($_auto)) { - foreach ($_auto as $auto){ + if (isset($_auto)) { + foreach ($_auto as $auto) { // 填充因子定义格式 // array('field','填充内容','填充条件','附加规则',[额外参数]) - if(empty($auto[2])) $auto[2] = self::MODEL_INSERT; // 默认为新增的时候自动填充 - if( $type == $auto[2] || $auto[2] == self::MODEL_BOTH) { - if(empty($auto[3])) $auto[3] = 'string'; - switch(trim($auto[3])) { - case 'function': // 使用函数进行填充 字段的值作为参数 + if (empty($auto[2])) { + $auto[2] = self::MODEL_INSERT; + } + // 默认为新增的时候自动填充 + if ($type == $auto[2] || self::MODEL_BOTH == $auto[2]) { + if (empty($auto[3])) { + $auto[3] = 'string'; + } + + switch (trim($auto[3])) { + case 'function': // 使用函数进行填充 字段的值作为参数 case 'callback': // 使用回调方法 - $args = isset($auto[4])?(array)$auto[4]:array(); - if(isset($data[$auto[0]])) { - array_unshift($args,$data[$auto[0]]); + $args = isset($auto[4]) ? (array) $auto[4] : array(); + if (isset($data[$auto[0]])) { + array_unshift($args, $data[$auto[0]]); } - if('function'==$auto[3]) { - $data[$auto[0]] = call_user_func_array($auto[1], $args); - }else{ - $data[$auto[0]] = call_user_func_array(array(&$this,$auto[1]), $args); + if ('function' == $auto[3]) { + $data[$auto[0]] = call_user_func_array($auto[1], $args); + } else { + $data[$auto[0]] = call_user_func_array(array(&$this, $auto[1]), $args); } break; - case 'field': // 用其它字段的值进行填充 + case 'field': // 用其它字段的值进行填充 $data[$auto[0]] = $data[$auto[1]]; break; case 'ignore': // 为空忽略 - if($auto[1]===$data[$auto[0]]) + if ($auto[1] === $data[$auto[0]]) { unset($data[$auto[0]]); + } + break; case 'string': default: // 默认作为字符串填充 $data[$auto[0]] = $auto[1]; } - if(isset($data[$auto[0]]) && false === $data[$auto[0]] ) unset($data[$auto[0]]); + if (isset($data[$auto[0]]) && false === $data[$auto[0]]) { + unset($data[$auto[0]]); + } + } } } @@ -1181,52 +1293,69 @@ private function autoOperation(&$data,$type) { * @param string $type 创建类型 * @return boolean */ - protected function autoValidation($data,$type) { - if(isset($this->options['validate']) && false === $this->options['validate'] ){ - // 关闭自动验证 - return true; - } - if(!empty($this->options['validate'])) { - $_validate = $this->options['validate']; + protected function autoValidation($data, $type) + { + if (isset($this->options['validate']) && false === $this->options['validate']) { + // 关闭自动验证 + return true; + } + if (!empty($this->options['validate'])) { + $_validate = $this->options['validate']; unset($this->options['validate']); - }elseif(!empty($this->_validate)){ - $_validate = $this->_validate; + } elseif (!empty($this->_validate)) { + $_validate = $this->_validate; } // 属性验证 - if(isset($_validate)) { // 如果设置了数据自动验证则进行数据验证 - if($this->patchValidate) { // 重置验证错误信息 + if (isset($_validate)) { + // 如果设置了数据自动验证则进行数据验证 + if ($this->patchValidate) { + // 重置验证错误信息 $this->error = array(); } - foreach($_validate as $key=>$val) { + foreach ($_validate as $key => $val) { // 验证因子定义格式 // array(field,rule,message,condition,type,when,params) // 判断是否需要执行验证 - if(empty($val[5]) || ( $val[5]== self::MODEL_BOTH && $type < 3 ) || $val[5]== $type ) { - if(0==strpos($val[2],'{%') && strpos($val[2],'}')) - // 支持提示信息的多语言 使用 {%语言定义} 方式 - $val[2] = L(substr($val[2],2,-1)); - $val[3] = isset($val[3])?$val[3]:self::EXISTS_VALIDATE; - $val[4] = isset($val[4])?$val[4]:'regex'; + if (empty($val[5]) || (self::MODEL_BOTH == $val[5] && $type < 3) || $val[5] == $type) { + if (0 == strpos($val[2], '{%') && strpos($val[2], '}')) + // 支持提示信息的多语言 使用 {%语言定义} 方式 + { + $val[2] = L(substr($val[2], 2, -1)); + } + + $val[3] = isset($val[3]) ? $val[3] : self::EXISTS_VALIDATE; + $val[4] = isset($val[4]) ? $val[4] : 'regex'; // 判断验证条件 - switch($val[3]) { - case self::MUST_VALIDATE: // 必须验证 不管表单是否有设置该字段 - if(false === $this->_validationField($data,$val)) + switch ($val[3]) { + case self::MUST_VALIDATE: // 必须验证 不管表单是否有设置该字段 + if (false === $this->_validationField($data, $val)) { return false; + } + break; - case self::VALUE_VALIDATE: // 值不为空的时候才验证 - if('' != trim($data[$val[0]])) - if(false === $this->_validationField($data,$val)) + case self::VALUE_VALIDATE: // 值不为空的时候才验证 + if ('' != trim($data[$val[0]])) { + if (false === $this->_validationField($data, $val)) { return false; + } + } + break; - default: // 默认表单存在该字段就验证 - if(isset($data[$val[0]])) - if(false === $this->_validationField($data,$val)) + default: // 默认表单存在该字段就验证 + if (isset($data[$val[0]])) { + if (false === $this->_validationField($data, $val)) { return false; + } + } + } } } // 批量验证的时候最后返回错误 - if(!empty($this->error)) return false; + if (!empty($this->error)) { + return false; + } + } return true; } @@ -1239,18 +1368,21 @@ protected function autoValidation($data,$type) { * @param array $val 验证因子 * @return boolean */ - protected function _validationField($data,$val) { - if($this->patchValidate && isset($this->error[$val[0]])) - return ; //当前字段已经有规则验证没有通过 - if(false === $this->_validationFieldItem($data,$val)){ - if($this->patchValidate) { - $this->error[$val[0]] = $val[2]; - }else{ - $this->error = $val[2]; + protected function _validationField($data, $val) + { + if ($this->patchValidate && isset($this->error[$val[0]])) { + return; + } + //当前字段已经有规则验证没有通过 + if (false === $this->_validationFieldItem($data, $val)) { + if ($this->patchValidate) { + $this->error[$val[0]] = $val[2]; + } else { + $this->error = $val[2]; return false; } } - return ; + return; } /** @@ -1260,50 +1392,62 @@ protected function _validationField($data,$val) { * @param array $val 验证因子 * @return boolean */ - protected function _validationFieldItem($data,$val) { - switch(strtolower(trim($val[4]))) { - case 'function':// 使用函数进行验证 - case 'callback':// 调用方法进行验证 - $args = isset($val[6])?(array)$val[6]:array(); - if(is_string($val[0]) && strpos($val[0], ',')) + protected function _validationFieldItem($data, $val) + { + switch (strtolower(trim($val[4]))) { + case 'function': // 使用函数进行验证 + case 'callback': // 调用方法进行验证 + $args = isset($val[6]) ? (array) $val[6] : array(); + if (is_string($val[0]) && strpos($val[0], ',')) { $val[0] = explode(',', $val[0]); - if(is_array($val[0])){ + } + + if (is_array($val[0])) { // 支持多个字段验证 - foreach($val[0] as $field) + foreach ($val[0] as $field) { $_data[$field] = $data[$field]; + } + array_unshift($args, $_data); - }else{ + } else { array_unshift($args, $data[$val[0]]); } - if('function'==$val[4]) { + if ('function' == $val[4]) { return call_user_func_array($val[1], $args); - }else{ + } else { return call_user_func_array(array(&$this, $val[1]), $args); } case 'confirm': // 验证两个字段是否相同 return $data[$val[0]] == $data[$val[1]]; case 'unique': // 验证某个值是否唯一 - if(is_string($val[0]) && strpos($val[0],',')) - $val[0] = explode(',',$val[0]); + if (is_string($val[0]) && strpos($val[0], ',')) { + $val[0] = explode(',', $val[0]); + } + $map = array(); - if(is_array($val[0])) { + if (is_array($val[0])) { // 支持多个字段验证 - foreach ($val[0] as $field) - $map[$field] = $data[$field]; - }else{ + foreach ($val[0] as $field) { + $map[$field] = $data[$field]; + } + + } else { $map[$val[0]] = $data[$val[0]]; } - $pk = $this->getPk(); - if(!empty($data[$pk]) && is_string($pk)) { // 完善编辑的时候验证唯一 - $map[$pk] = array('neq',$data[$pk]); + $pk = $this->getPk(); + if (!empty($data[$pk]) && is_string($pk)) { + // 完善编辑的时候验证唯一 + $map[$pk] = array('neq', $data[$pk]); } $options = $this->options; - if($this->where($map)->find()) - return false; + if ($this->where($map)->find()) { + return false; + } + $this->options = $options; return true; - default: // 检查附加规则 - return $this->check($data[$val[0]],$val[1],$val[4]); + default: // 检查附加规则 + return $this->check($data[$val[0]], $val[1], $val[4]); } } @@ -1315,46 +1459,55 @@ protected function _validationFieldItem($data,$val) { * @param string $type 验证方式 默认为正则验证 * @return boolean */ - public function check($value,$rule,$type='regex'){ - $type = strtolower(trim($type)); - switch($type) { + public function check($value, $rule, $type = 'regex') + { + $type = strtolower(trim($type)); + switch ($type) { case 'in': // 验证是否在某个指定范围之内 逗号分隔字符串或者数组 case 'notin': - $range = is_array($rule)? $rule : explode(',',$rule); - return $type == 'in' ? in_array($value ,$range) : !in_array($value ,$range); + $range = is_array($rule) ? $rule : explode(',', $rule); + return 'in' == $type ? in_array($value, $range) : !in_array($value, $range); case 'between': // 验证是否在某个范围 - case 'notbetween': // 验证是否不在某个范围 - if (is_array($rule)){ - $min = $rule[0]; - $max = $rule[1]; - }else{ - list($min,$max) = explode(',',$rule); + case 'notbetween': // 验证是否不在某个范围 + if (is_array($rule)) { + $min = $rule[0]; + $max = $rule[1]; + } else { + list($min, $max) = explode(',', $rule); } - return $type == 'between' ? $value>=$min && $value<=$max : $value<$min || $value>$max; + return 'between' == $type ? $value >= $min && $value <= $max : $value < $min || $value > $max; case 'equal': // 验证是否等于某个值 - case 'notequal': // 验证是否等于某个值 - return $type == 'equal' ? $value == $rule : $value != $rule; + case 'notequal': // 验证是否等于某个值 + return 'equal' == $type ? $value == $rule : $value != $rule; case 'length': // 验证长度 - $length = mb_strlen($value,'utf-8'); // 当前数据长度 - if(strpos($rule,',')) { // 长度区间 - list($min,$max) = explode(',',$rule); + $length = mb_strlen($value, 'utf-8'); // 当前数据长度 + if (strpos($rule, ',')) { + // 长度区间 + list($min, $max) = explode(',', $rule); return $length >= $min && $length <= $max; - }else{// 指定长度 + } else { +// 指定长度 return $length == $rule; } case 'expire': - list($start,$end) = explode(',',$rule); - if(!is_numeric($start)) $start = strtotime($start); - if(!is_numeric($end)) $end = strtotime($end); + list($start, $end) = explode(',', $rule); + if (!is_numeric($start)) { + $start = strtotime($start); + } + + if (!is_numeric($end)) { + $end = strtotime($end); + } + return NOW_TIME >= $start && NOW_TIME <= $end; case 'ip_allow': // IP 操作许可验证 - return in_array(get_client_ip(),explode(',',$rule)); + return in_array(get_client_ip(), explode(',', $rule)); case 'ip_deny': // IP 操作禁止验证 - return !in_array(get_client_ip(),explode(',',$rule)); + return !in_array(get_client_ip(), explode(',', $rule)); case 'regex': - default: // 默认使用正则验证 可以使用验证类中定义的验证名称 + default: // 默认使用正则验证 可以使用验证类中定义的验证名称 // 检查附加规则 - return $this->regex($value,$rule); + return $this->regex($value, $rule); } } @@ -1365,7 +1518,8 @@ public function check($value,$rule,$type='regex'){ * @param mixed $parse 是否需要解析SQL * @return array */ - public function procedure($sql, $parse = false) { + public function procedure($sql, $parse = false) + { return $this->db->procedure($sql, $parse); } @@ -1376,12 +1530,13 @@ public function procedure($sql, $parse = false) { * @param mixed $parse 是否需要解析SQL * @return mixed */ - public function query($sql,$parse=false) { - if(!is_bool($parse) && !is_array($parse)) { + public function query($sql, $parse = false) + { + if (!is_bool($parse) && !is_array($parse)) { $parse = func_get_args(); array_shift($parse); } - $sql = $this->parseSql($sql,$parse); + $sql = $this->parseSql($sql, $parse); return $this->db->query($sql); } @@ -1392,12 +1547,13 @@ public function query($sql,$parse=false) { * @param mixed $parse 是否需要解析SQL * @return false | integer */ - public function execute($sql,$parse=false) { - if(!is_bool($parse) && !is_array($parse)) { + public function execute($sql, $parse = false) + { + if (!is_bool($parse) && !is_array($parse)) { $parse = func_get_args(); array_shift($parse); } - $sql = $this->parseSql($sql,$parse); + $sql = $this->parseSql($sql, $parse); return $this->db->execute($sql); } @@ -1408,18 +1564,20 @@ public function execute($sql,$parse=false) { * @param boolean $parse 是否需要解析SQL * @return string */ - protected function parseSql($sql,$parse) { + protected function parseSql($sql, $parse) + { // 分析表达式 - if(true === $parse) { - $options = $this->_parseOptions(); - $sql = $this->db->parseSql($sql,$options); - }elseif(is_array($parse)){ // SQL预处理 - $parse = array_map(array($this->db,'escapeString'),$parse); - $sql = vsprintf($sql,$parse); - }else{ - $sql = strtr($sql,array('__TABLE__'=>$this->getTableName(),'__PREFIX__'=>$this->tablePrefix)); - $prefix = $this->tablePrefix; - $sql = preg_replace_callback("/__([A-Z0-9_-]+)__/sU", function($match) use($prefix){ return $prefix.strtolower($match[1]);}, $sql); + if (true === $parse) { + $options = $this->_parseOptions(); + $sql = $this->db->parseSql($sql, $options); + } elseif (is_array($parse)) { + // SQL预处理 + $parse = array_map(array($this->db, 'escapeString'), $parse); + $sql = vsprintf($sql, $parse); + } else { + $sql = strtr($sql, array('__TABLE__' => $this->getTableName(), '__PREFIX__' => $this->tablePrefix)); + $prefix = $this->tablePrefix; + $sql = preg_replace_callback("/__([A-Z0-9_-]+)__/sU", function ($match) use ($prefix) {return $prefix . strtolower($match[1]);}, $sql); } $this->db->setModel($this->name); return $sql; @@ -1433,44 +1591,52 @@ protected function parseSql($sql,$parse) { * @param boolean $force 强制重新连接 * @return Model */ - public function db($linkNum='',$config='',$force=false) { - if('' === $linkNum && $this->db) { + public function db($linkNum = '', $config = '', $force = false) + { + if ('' === $linkNum && $this->db) { return $this->db; } - if(!isset($this->_db[$linkNum]) || $force ) { + if (!isset($this->_db[$linkNum]) || $force) { // 创建一个新的实例 - if(!empty($config) && is_string($config) && false === strpos($config,'/')) { // 支持读取配置参数 - $config = C($config); + if (!empty($config) && is_string($config) && false === strpos($config, '/')) { + // 支持读取配置参数 + $config = C($config); } - $this->_db[$linkNum] = Db::getInstance($config); - }elseif(NULL === $config){ + $this->_db[$linkNum] = Db::getInstance($config); + } elseif (null === $config) { $this->_db[$linkNum]->close(); // 关闭数据库连接 unset($this->_db[$linkNum]); - return ; + return; } // 切换数据库连接 - $this->db = $this->_db[$linkNum]; + $this->db = $this->_db[$linkNum]; $this->_after_db(); // 字段检测 - if(!empty($this->name) && $this->autoCheckFields) $this->_checkTableInfo(); + if (!empty($this->name) && $this->autoCheckFields) { + $this->_checkTableInfo(); + } + return $this; } // 数据库切换后回调方法 - protected function _after_db() {} + protected function _after_db() + {} /** * 得到当前的数据对象名称 * @access public * @return string */ - public function getModelName() { - if(empty($this->name)){ - $name = substr(get_class($this),0,-strlen(C('DEFAULT_M_LAYER'))); - if ( $pos = strrpos($name,'\\') ) {//有命名空间 - $this->name = substr($name,$pos+1); - }else{ + public function getModelName() + { + if (empty($this->name)) { + $name = substr(get_class($this), 0, -strlen(C('DEFAULT_M_LAYER'))); + if ($pos = strrpos($name, '\\')) { +//有命名空间 + $this->name = substr($name, $pos + 1); + } else { $this->name = $name; } } @@ -1482,17 +1648,18 @@ public function getModelName() { * @access public * @return string */ - public function getTableName() { - if(empty($this->trueTableName)) { - $tableName = !empty($this->tablePrefix) ? $this->tablePrefix : ''; - if(!empty($this->tableName)) { + public function getTableName() + { + if (empty($this->trueTableName)) { + $tableName = !empty($this->tablePrefix) ? $this->tablePrefix : ''; + if (!empty($this->tableName)) { $tableName .= $this->tableName; - }else{ + } else { $tableName .= parse_name($this->name); } - $this->trueTableName = strtolower($tableName); + $this->trueTableName = strtolower($tableName); } - return (!empty($this->dbName)?$this->dbName.'.':'').$this->trueTableName; + return (!empty($this->dbName) ? $this->dbName . '.' : '') . $this->trueTableName; } /** @@ -1500,10 +1667,11 @@ public function getTableName() { * @access public * @return void */ - public function startTrans() { + public function startTrans() + { $this->commit(); $this->db->startTrans(); - return ; + return; } /** @@ -1511,7 +1679,8 @@ public function startTrans() { * @access public * @return boolean */ - public function commit() { + public function commit() + { return $this->db->commit(); } @@ -1520,7 +1689,8 @@ public function commit() { * @access public * @return boolean */ - public function rollback() { + public function rollback() + { return $this->db->rollback(); } @@ -1529,7 +1699,8 @@ public function rollback() { * @access public * @return string */ - public function getError(){ + public function getError() + { return $this->error; } @@ -1538,7 +1709,8 @@ public function getError(){ * @access public * @return string */ - public function getDbError() { + public function getDbError() + { return $this->db->getError(); } @@ -1547,7 +1719,8 @@ public function getDbError() { * @access public * @return string */ - public function getLastInsID() { + public function getLastInsID() + { return $this->db->getLastInsID(); } @@ -1556,11 +1729,13 @@ public function getLastInsID() { * @access public * @return string */ - public function getLastSql() { + public function getLastSql() + { return $this->db->getLastSql($this->name); } // 鉴于getLastSql比较常用 增加_sql 别名 - public function _sql(){ + public function _sql() + { return $this->getLastSql(); } @@ -1569,7 +1744,8 @@ public function _sql(){ * @access public * @return string */ - public function getPk() { + public function getPk() + { return $this->pk; } @@ -1578,23 +1754,25 @@ public function getPk() { * @access public * @return array */ - public function getDbFields(){ - if(isset($this->options['table'])) {// 动态指定表名 - if(is_array($this->options['table'])){ - $table = key($this->options['table']); - }else{ - $table = $this->options['table']; - if(strpos($table,')')){ + public function getDbFields() + { + if (isset($this->options['table'])) { +// 动态指定表名 + if (is_array($this->options['table'])) { + $table = key($this->options['table']); + } else { + $table = $this->options['table']; + if (strpos($table, ')')) { // 子查询 return false; } } - $fields = $this->db->getFields($table); - return $fields ? array_keys($fields) : false; + $fields = $this->db->getFields($table); + return $fields ? array_keys($fields) : false; } - if($this->fields) { - $fields = $this->fields; - unset($fields['_type'],$fields['_pk']); + if ($this->fields) { + $fields = $this->fields; + unset($fields['_type'], $fields['_pk']); return $fields; } return false; @@ -1606,15 +1784,16 @@ public function getDbFields(){ * @param mixed $data 数据 * @return Model */ - public function data($data=''){ - if('' === $data && !empty($this->data)) { + public function data($data = '') + { + if ('' === $data && !empty($this->data)) { return $this->data; } - if(is_object($data)){ - $data = get_object_vars($data); - }elseif(is_string($data)){ - parse_str($data,$data); - }elseif(!is_array($data)){ + if (is_object($data)) { + $data = get_object_vars($data); + } elseif (is_string($data)) { + parse_str($data, $data); + } elseif (!is_array($data)) { E(L('_DATA_TYPE_INVALID_')); } $this->data = $data; @@ -1627,14 +1806,15 @@ public function data($data=''){ * @param mixed $table * @return Model */ - public function table($table) { - $prefix = $this->tablePrefix; - if(is_array($table)) { - $this->options['table'] = $table; - }elseif(!empty($table)) { + public function table($table) + { + $prefix = $this->tablePrefix; + if (is_array($table)) { + $this->options['table'] = $table; + } elseif (!empty($table)) { //将__TABLE_NAME__替换成带前缀的表名 - $table = preg_replace_callback("/__([A-Z0-9_-]+)__/sU", function($match) use($prefix){ return $prefix.strtolower($match[1]);}, $table); - $this->options['table'] = $table; + $table = preg_replace_callback("/__([A-Z0-9_-]+)__/sU", function ($match) use ($prefix) {return $prefix . strtolower($match[1]);}, $table); + $this->options['table'] = $table; } return $this; } @@ -1645,14 +1825,15 @@ public function table($table) { * @param mixed $using * @return Model */ - public function using($using){ - $prefix = $this->tablePrefix; - if(is_array($using)) { - $this->options['using'] = $using; - }elseif(!empty($using)) { + public function using($using) + { + $prefix = $this->tablePrefix; + if (is_array($using)) { + $this->options['using'] = $using; + } elseif (!empty($using)) { //将__TABLE_NAME__替换成带前缀的表名 - $using = preg_replace_callback("/__([A-Z0-9_-]+)__/sU", function($match) use($prefix){ return $prefix.strtolower($match[1]);}, $using); - $this->options['using'] = $using; + $using = preg_replace_callback("/__([A-Z0-9_-]+)__/sU", function ($match) use ($prefix) {return $prefix . strtolower($match[1]);}, $using); + $this->options['using'] = $using; } return $this; } @@ -1664,18 +1845,19 @@ public function using($using){ * @param string $type JOIN类型 * @return Model */ - public function join($join,$type='INNER') { - $prefix = $this->tablePrefix; - if(is_array($join)) { - foreach ($join as $key=>&$_join){ - $_join = preg_replace_callback("/__([A-Z0-9_-]+)__/sU", function($match) use($prefix){ return $prefix.strtolower($match[1]);}, $_join); - $_join = false !== stripos($_join,'JOIN')? $_join : $type.' JOIN ' .$_join; - } - $this->options['join'] = $join; - }elseif(!empty($join)) { + public function join($join, $type = 'INNER') + { + $prefix = $this->tablePrefix; + if (is_array($join)) { + foreach ($join as $key => &$_join) { + $_join = preg_replace_callback("/__([A-Z0-9_-]+)__/sU", function ($match) use ($prefix) {return $prefix . strtolower($match[1]);}, $_join); + $_join = false !== stripos($_join, 'JOIN') ? $_join : $type . ' JOIN ' . $_join; + } + $this->options['join'] = $join; + } elseif (!empty($join)) { //将__TABLE_NAME__字符串替换成带前缀的表名 - $join = preg_replace_callback("/__([A-Z0-9_-]+)__/sU", function($match) use($prefix){ return $prefix.strtolower($match[1]);}, $join); - $this->options['join'][] = false !== stripos($join,'JOIN')? $join : $type.' JOIN '.$join; + $join = preg_replace_callback("/__([A-Z0-9_-]+)__/sU", function ($match) use ($prefix) {return $prefix . strtolower($match[1]);}, $join); + $this->options['join'][] = false !== stripos($join, 'JOIN') ? $join : $type . ' JOIN ' . $join; } return $this; } @@ -1687,30 +1869,34 @@ public function join($join,$type='INNER') { * @param boolean $all * @return Model */ - public function union($union,$all=false) { - if(empty($union)) return $this; - if($all) { - $this->options['union']['_all'] = true; + public function union($union, $all = false) + { + if (empty($union)) { + return $this; + } + + if ($all) { + $this->options['union']['_all'] = true; } - if(is_object($union)) { - $union = get_object_vars($union); + if (is_object($union)) { + $union = get_object_vars($union); } // 转换union表达式 - if(is_string($union) ) { - $prefix = $this->tablePrefix; + if (is_string($union)) { + $prefix = $this->tablePrefix; //将__TABLE_NAME__字符串替换成带前缀的表名 - $options = preg_replace_callback("/__([A-Z0-9_-]+)__/sU", function($match) use($prefix){ return $prefix.strtolower($match[1]);}, $union); - }elseif(is_array($union)){ - if(isset($union[0])) { - $this->options['union'] = array_merge($this->options['union'],$union); + $options = preg_replace_callback("/__([A-Z0-9_-]+)__/sU", function ($match) use ($prefix) {return $prefix . strtolower($match[1]);}, $union); + } elseif (is_array($union)) { + if (isset($union[0])) { + $this->options['union'] = array_merge($this->options['union'], $union); return $this; - }else{ - $options = $union; + } else { + $options = $union; } - }else{ + } else { E(L('_DATA_TYPE_INVALID_')); } - $this->options['union'][] = $options; + $this->options['union'][] = $options; return $this; } @@ -1722,14 +1908,17 @@ public function union($union,$all=false) { * @param string $type * @return Model */ - public function cache($key=true,$expire=null,$type=''){ + public function cache($key = true, $expire = null, $type = '') + { // 增加快捷调用方式 cache(10) 等同于 cache(true, 10) - if(is_numeric($key) && is_null($expire)){ + if (is_numeric($key) && is_null($expire)) { $expire = $key; $key = true; } - if(false !== $key) - $this->options['cache'] = array('key'=>$key,'expire'=>$expire,'type'=>$type); + if (false !== $key) { + $this->options['cache'] = array('key' => $key, 'expire' => $expire, 'type' => $type); + } + return $this; } @@ -1740,18 +1929,21 @@ public function cache($key=true,$expire=null,$type=''){ * @param boolean $except 是否排除 * @return Model */ - public function field($field,$except=false){ - if(true === $field) {// 获取全部字段 - $fields = $this->getDbFields(); - $field = $fields?:'*'; - }elseif($except) {// 字段排除 - if(is_string($field)) { - $field = explode(',',$field); - } - $fields = $this->getDbFields(); - $field = $fields?array_diff($fields,$field):$field; - } - $this->options['field'] = $field; + public function field($field, $except = false) + { + if (true === $field) { +// 获取全部字段 + $fields = $this->getDbFields(); + $field = $fields ?: '*'; + } elseif ($except) { +// 字段排除 + if (is_string($field)) { + $field = explode(',', $field); + } + $fields = $this->getDbFields(); + $field = $fields ? array_diff($fields, $field) : $field; + } + $this->options['field'] = $field; return $this; } @@ -1762,30 +1954,36 @@ public function field($field,$except=false){ * @param array $args 参数 * @return Model */ - public function scope($scope='',$args=NULL){ - if('' === $scope) { - if(isset($this->_scope['default'])) { + public function scope($scope = '', $args = null) + { + if ('' === $scope) { + if (isset($this->_scope['default'])) { // 默认的命名范围 - $options = $this->_scope['default']; - }else{ + $options = $this->_scope['default']; + } else { return $this; } - }elseif(is_string($scope)){ // 支持多个命名范围调用 用逗号分割 - $scopes = explode(',',$scope); - $options = array(); - foreach ($scopes as $name){ - if(!isset($this->_scope[$name])) continue; - $options = array_merge($options,$this->_scope[$name]); + } elseif (is_string($scope)) { + // 支持多个命名范围调用 用逗号分割 + $scopes = explode(',', $scope); + $options = array(); + foreach ($scopes as $name) { + if (!isset($this->_scope[$name])) { + continue; + } + + $options = array_merge($options, $this->_scope[$name]); } - if(!empty($args) && is_array($args)) { - $options = array_merge($options,$args); + if (!empty($args) && is_array($args)) { + $options = array_merge($options, $args); } - }elseif(is_array($scope)){ // 直接传入命名范围定义 - $options = $scope; + } elseif (is_array($scope)) { + // 直接传入命名范围定义 + $options = $scope; } - - if(is_array($options) && !empty($options)){ - $this->options = array_merge($this->options,array_change_key_case($options)); + + if (is_array($options) && !empty($options)) { + $this->options = array_merge($this->options, array_change_key_case($options)); } return $this; } @@ -1797,28 +1995,29 @@ public function scope($scope='',$args=NULL){ * @param mixed $parse 预处理参数 * @return Model */ - public function where($where,$parse=null){ - if(!is_null($parse) && is_string($where)) { - if(!is_array($parse)) { + public function where($where, $parse = null) + { + if (!is_null($parse) && is_string($where)) { + if (!is_array($parse)) { $parse = func_get_args(); array_shift($parse); } - $parse = array_map(array($this->db,'escapeString'),$parse); - $where = vsprintf($where,$parse); - }elseif(is_object($where)){ - $where = get_object_vars($where); - } - if(is_string($where) && '' != $where){ - $map = array(); - $map['_string'] = $where; - $where = $map; - } - if(isset($this->options['where'])){ - $this->options['where'] = array_merge($this->options['where'],$where); - }else{ - $this->options['where'] = $where; - } - + $parse = array_map(array($this->db, 'escapeString'), $parse); + $where = vsprintf($where, $parse); + } elseif (is_object($where)) { + $where = get_object_vars($where); + } + if (is_string($where) && '' != $where) { + $map = array(); + $map['_string'] = $where; + $where = $map; + } + if (isset($this->options['where'])) { + $this->options['where'] = array_merge($this->options['where'], $where); + } else { + $this->options['where'] = $where; + } + return $this; } @@ -1829,11 +2028,12 @@ public function where($where,$parse=null){ * @param mixed $length 查询数量 * @return Model */ - public function limit($offset,$length=null){ - if(is_null($length) && strpos($offset,',')){ - list($offset,$length) = explode(',',$offset); + public function limit($offset, $length = null) + { + if (is_null($length) && strpos($offset, ',')) { + list($offset, $length) = explode(',', $offset); } - $this->options['limit'] = intval($offset).( $length? ','.intval($length) : '' ); + $this->options['limit'] = intval($offset) . ($length ? ',' . intval($length) : ''); return $this; } @@ -1844,11 +2044,12 @@ public function limit($offset,$length=null){ * @param mixed $listRows 每页数量 * @return Model */ - public function page($page,$listRows=null){ - if(is_null($listRows) && strpos($page,',')){ - list($page,$listRows) = explode(',',$page); + public function page($page, $listRows = null) + { + if (is_null($listRows) && strpos($page, ',')) { + list($page, $listRows) = explode(',', $page); } - $this->options['page'] = array(intval($page),intval($listRows)); + $this->options['page'] = array(intval($page), intval($listRows)); return $this; } @@ -1858,8 +2059,9 @@ public function page($page,$listRows=null){ * @param string $comment 注释 * @return Model */ - public function comment($comment){ - $this->options['comment'] = $comment; + public function comment($comment) + { + $this->options['comment'] = $comment; return $this; } @@ -1869,8 +2071,9 @@ public function comment($comment){ * @param boolean $fetch 是否返回sql * @return Model */ - public function fetchSql($fetch=true){ - $this->options['fetch_sql'] = $fetch; + public function fetchSql($fetch = true) + { + $this->options['fetch_sql'] = $fetch; return $this; } @@ -1881,18 +2084,19 @@ public function fetchSql($fetch=true){ * @param mixed $value 绑定的变量及绑定参数 * @return Model */ - public function bind($key,$value=false) { - if(is_array($key)){ - $this->options['bind'] = $key; - }else{ - $num = func_num_args(); - if($num>2){ - $params = func_get_args(); + public function bind($key, $value = false) + { + if (is_array($key)) { + $this->options['bind'] = $key; + } else { + $num = func_num_args(); + if ($num > 2) { + $params = func_get_args(); array_shift($params); - $this->options['bind'][$key] = $params; - }else{ - $this->options['bind'][$key] = $value; - } + $this->options['bind'][$key] = $params; + } else { + $this->options['bind'][$key] = $value; + } } return $this; } @@ -1904,9 +2108,12 @@ public function bind($key,$value=false) { * @param mixed $value 值 * @return Model */ - public function setProperty($name,$value) { - if(property_exists($this,$name)) + public function setProperty($name, $value) + { + if (property_exists($this, $name)) { $this->$name = $value; + } + return $this; } diff --git a/ThinkPHP/Library/Think/Model/AdvModel.class.php b/ThinkPHP/Library/Think/Model/AdvModel.class.php index 2e9199245..3664e0350 100644 --- a/ThinkPHP/Library/Think/Model/AdvModel.class.php +++ b/ThinkPHP/Library/Think/Model/AdvModel.class.php @@ -9,28 +9,32 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think\Model; + use Think\Model; + /** - * 高级模型扩展 + * 高级模型扩展 */ -class AdvModel extends Model { - protected $optimLock = 'lock_version'; - protected $returnType = 'array'; - protected $blobFields = array(); - protected $blobValues = null; - protected $serializeField = array(); - protected $readonlyField = array(); - protected $_filter = array(); - protected $partition = array(); - - public function __construct($name='',$tablePrefix='',$connection='') { - if('' !== $name || is_subclass_of($this,'AdvModel') ){ +class AdvModel extends Model +{ + protected $optimLock = 'lock_version'; + protected $returnType = 'array'; + protected $blobFields = array(); + protected $blobValues = null; + protected $serializeField = array(); + protected $readonlyField = array(); + protected $_filter = array(); + protected $partition = array(); + + public function __construct($name = '', $tablePrefix = '', $connection = '') + { + if ('' !== $name || is_subclass_of($this, 'AdvModel')) { // 如果是AdvModel子类或者有传入模型名称则获取字段缓存 - }else{ + } else { // 空的模型 关闭字段缓存 $this->autoCheckFields = false; } - parent::__construct($name,$tablePrefix,$connection); + parent::__construct($name, $tablePrefix, $connection); } /** @@ -40,14 +44,15 @@ public function __construct($name='',$tablePrefix='',$connection='') { * @param mixed $args 调用参数 * @return mixed */ - public function __call($method,$args) { - if(strtolower(substr($method,0,3))=='top'){ + public function __call($method, $args) + { + if (strtolower(substr($method, 0, 3)) == 'top') { // 获取前N条记录 - $count = substr($method,3); - array_unshift($args,$count); + $count = substr($method, 3); + array_unshift($args, $count); return call_user_func_array(array(&$this, 'topN'), $args); - }else{ - return parent::__call($method,$args); + } else { + return parent::__call($method, $args); } } @@ -57,36 +62,40 @@ public function __call($method,$args) { * @param mixed $data 要操作的数据 * @return boolean */ - protected function _facade($data) { + protected function _facade($data) + { // 检查序列化字段 $data = $this->serializeField($data); return parent::_facade($data); - } + } // 查询成功后的回调方法 - protected function _after_find(&$result,$options='') { + protected function _after_find(&$result, $options = '') + { // 检查序列化字段 $this->checkSerializeField($result); // 获取文本字段 $this->getBlobFields($result); // 检查字段过滤 - $result = $this->getFilterFields($result); + $result = $this->getFilterFields($result); // 缓存乐观锁 $this->cacheLockVersion($result); } // 查询数据集成功后的回调方法 - protected function _after_select(&$resultSet,$options='') { + protected function _after_select(&$resultSet, $options = '') + { // 检查序列化字段 - $resultSet = $this->checkListSerializeField($resultSet); + $resultSet = $this->checkListSerializeField($resultSet); // 获取文本字段 - $resultSet = $this->getListBlobFields($resultSet); + $resultSet = $this->getListBlobFields($resultSet); // 检查列表字段过滤 - $resultSet = $this->getFilterListFields($resultSet); + $resultSet = $this->getFilterListFields($resultSet); } // 写入前的回调方法 - protected function _before_insert(&$data,$options='') { + protected function _before_insert(&$data, $options = '') + { // 记录乐观锁 $data = $this->recordLockVersion($data); // 检查文本字段 @@ -95,18 +104,20 @@ protected function _before_insert(&$data,$options='') { $data = $this->setFilterFields($data); } - protected function _after_insert($data,$options) { + protected function _after_insert($data, $options) + { // 保存文本字段 $this->saveBlobFields($data); } // 更新前的回调方法 - protected function _before_update(&$data,$options='') { + protected function _before_update(&$data, $options = '') + { // 检查乐观锁 - $pk = $this->getPK(); - if(isset($options['where'][$pk])){ - $id = $options['where'][$pk]; - if(!$this->checkLockVersion($id,$data)) { + $pk = $this->getPK(); + if (isset($options['where'][$pk])) { + $id = $options['where'][$pk]; + if (!$this->checkLockVersion($id, $data)) { return false; } } @@ -118,12 +129,14 @@ protected function _before_update(&$data,$options='') { $data = $this->setFilterFields($data); } - protected function _after_update($data,$options) { + protected function _after_update($data, $options) + { // 保存文本字段 $this->saveBlobFields($data); } - protected function _after_delete($data,$options) { + protected function _after_delete($data, $options) + { // 删除Blob数据 $this->delBlobFields($data); } @@ -134,11 +147,12 @@ protected function _after_delete($data,$options) { * @param array $data 数据对象 * @return array */ - protected function recordLockVersion($data) { + protected function recordLockVersion($data) + { // 记录乐观锁 - if($this->optimLock && !isset($data[$this->optimLock]) ) { - if(in_array($this->optimLock,$this->fields,true)) { - $data[$this->optimLock] = 0; + if ($this->optimLock && !isset($data[$this->optimLock])) { + if (in_array($this->optimLock, $this->fields, true)) { + $data[$this->optimLock] = 0; } } return $data; @@ -150,11 +164,12 @@ protected function recordLockVersion($data) { * @param array $data 数据对象 * @return void */ - protected function cacheLockVersion($data) { - if($this->optimLock) { - if(isset($data[$this->optimLock]) && isset($data[$this->getPk()])) { + protected function cacheLockVersion($data) + { + if ($this->optimLock) { + if (isset($data[$this->optimLock]) && isset($data[$this->getPk()])) { // 只有当存在乐观锁字段和主键有值的时候才记录乐观锁 - $_SESSION[$this->name.'_'.$data[$this->getPk()].'_lock_version'] = $data[$this->optimLock]; + $_SESSION[$this->name . '_' . $data[$this->getPk()] . '_lock_version'] = $data[$this->optimLock]; } } } @@ -162,30 +177,31 @@ protected function cacheLockVersion($data) { /** * 检查乐观锁 * @access protected - * @param inteter $id 当前主键 + * @param inteter $id 当前主键 * @param array $data 当前数据 * @return mixed */ - protected function checkLockVersion($id,&$data) { + protected function checkLockVersion($id, &$data) + { // 检查乐观锁 - $identify = $this->name.'_'.$id.'_lock_version'; - if($this->optimLock && isset($_SESSION[$identify])) { - $lock_version = $_SESSION[$identify]; - $vo = $this->field($this->optimLock)->find($id); - $_SESSION[$identify] = $lock_version; - $curr_version = $vo[$this->optimLock]; - if(isset($curr_version)) { - if($curr_version>0 && $lock_version != $curr_version) { + $identify = $this->name . '_' . $id . '_lock_version'; + if ($this->optimLock && isset($_SESSION[$identify])) { + $lock_version = $_SESSION[$identify]; + $vo = $this->field($this->optimLock)->find($id); + $_SESSION[$identify] = $lock_version; + $curr_version = $vo[$this->optimLock]; + if (isset($curr_version)) { + if ($curr_version > 0 && $lock_version != $curr_version) { // 记录已经更新 $this->error = L('_RECORD_HAS_UPDATE_'); return false; - }else{ + } else { // 更新乐观锁 $save_version = $data[$this->optimLock]; - if($save_version != $lock_version+1) { - $data[$this->optimLock] = $lock_version+1; + if ($save_version != $lock_version + 1) { + $data[$this->optimLock] = $lock_version + 1; } - $_SESSION[$identify] = $lock_version+1; + $_SESSION[$identify] = $lock_version + 1; } } } @@ -199,8 +215,9 @@ protected function checkLockVersion($id,&$data) { * @param array $options 查询表达式 * @return array */ - public function topN($count,$options=array()) { - $options['limit'] = $count; + public function topN($count, $options = array()) + { + $options['limit'] = $count; return $this->select($options); } @@ -212,14 +229,17 @@ public function topN($count,$options=array()) { * @param array $options 查询表达式 * @return mixed */ - public function getN($position=0,$options=array()) { - if($position>=0) { // 正向查找 - $options['limit'] = $position.',1'; - $list = $this->select($options); - return $list?$list[0]:false; - }else{ // 逆序查找 - $list = $this->select($options); - return $list?$list[count($list)-abs($position)]:false; + public function getN($position = 0, $options = array()) + { + if ($position >= 0) { + // 正向查找 + $options['limit'] = $position . ',1'; + $list = $this->select($options); + return $list ? $list[0] : false; + } else { + // 逆序查找 + $list = $this->select($options); + return $list ? $list[count($list) - abs($position)] : false; } } @@ -229,8 +249,9 @@ public function getN($position=0,$options=array()) { * @param array $options 查询表达式 * @return mixed */ - public function first($options=array()) { - return $this->getN(0,$options); + public function first($options = array()) + { + return $this->getN(0, $options); } /** @@ -239,8 +260,9 @@ public function first($options=array()) { * @param array $options 查询表达式 * @return mixed */ - public function last($options=array()) { - return $this->getN(-1,$options); + public function last($options = array()) + { + return $this->getN(-1, $options); } /** @@ -250,17 +272,22 @@ public function last($options=array()) { * @param string $type 返回类型 默认为数组 * @return mixed */ - public function returnResult($data,$type='') { - if('' === $type) + public function returnResult($data, $type = '') + { + if ('' === $type) { $type = $this->returnType; - switch($type) { - case 'array' : return $data; - case 'object': return (object)$data; - default:// 允许用户自定义返回类型 - if(class_exists($type)) + } + + switch ($type) { + case 'array':return $data; + case 'object':return (object) $data; + default: // 允许用户自定义返回类型 + if (class_exists($type)) { return new $type($data); - else - E(L('_CLASS_NOT_EXIST_').':'.$type); + } else { + E(L('_CLASS_NOT_EXIST_') . ':' . $type); + } + } } @@ -270,18 +297,19 @@ public function returnResult($data,$type='') { * @param mixed $result 查询的数据 * @return array */ - protected function getFilterFields(&$result) { - if(!empty($this->_filter)) { - foreach ($this->_filter as $field=>$filter){ - if(isset($result[$field])) { - $fun = $filter[1]; - if(!empty($fun)) { - if(isset($filter[2]) && $filter[2]){ + protected function getFilterFields(&$result) + { + if (!empty($this->_filter)) { + foreach ($this->_filter as $field => $filter) { + if (isset($result[$field])) { + $fun = $filter[1]; + if (!empty($fun)) { + if (isset($filter[2]) && $filter[2]) { // 传递整个数据对象作为参数 - $result[$field] = call_user_func($fun,$result); - }else{ + $result[$field] = call_user_func($fun, $result); + } else { // 传递字段的值作为参数 - $result[$field] = call_user_func($fun,$result[$field]); + $result[$field] = call_user_func($fun, $result[$field]); } } } @@ -290,10 +318,13 @@ protected function getFilterFields(&$result) { return $result; } - protected function getFilterListFields(&$resultSet) { - if(!empty($this->_filter)) { - foreach ($resultSet as $key=>$result) - $resultSet[$key] = $this->getFilterFields($result); + protected function getFilterListFields(&$resultSet) + { + if (!empty($this->_filter)) { + foreach ($resultSet as $key => $result) { + $resultSet[$key] = $this->getFilterFields($result); + } + } return $resultSet; } @@ -304,18 +335,19 @@ protected function getFilterListFields(&$resultSet) { * @param mixed $result 查询的数据 * @return array */ - protected function setFilterFields($data) { - if(!empty($this->_filter)) { - foreach ($this->_filter as $field=>$filter){ - if(isset($data[$field])) { - $fun = $filter[0]; - if(!empty($fun)) { - if(isset($filter[2]) && $filter[2]) { + protected function setFilterFields($data) + { + if (!empty($this->_filter)) { + foreach ($this->_filter as $field => $filter) { + if (isset($data[$field])) { + $fun = $filter[0]; + if (!empty($fun)) { + if (isset($filter[2]) && $filter[2]) { // 传递整个数据对象作为参数 - $data[$field] = call_user_func($fun,$data); - }else{ + $data[$field] = call_user_func($fun, $data); + } else { // 传递字段的值作为参数 - $data[$field] = call_user_func($fun,$data[$field]); + $data[$field] = call_user_func($fun, $data[$field]); } } } @@ -331,21 +363,27 @@ protected function setFilterFields($data) { * @param string $type 返回类型 默认为数组 * @return void */ - protected function returnResultSet(&$resultSet,$type='') { - foreach ($resultSet as $key=>$data) - $resultSet[$key] = $this->returnResult($data,$type); + protected function returnResultSet(&$resultSet, $type = '') + { + foreach ($resultSet as $key => $data) { + $resultSet[$key] = $this->returnResult($data, $type); + } + return $resultSet; } - protected function checkBlobFields(&$data) { + protected function checkBlobFields(&$data) + { // 检查Blob文件保存字段 - if(!empty($this->blobFields)) { - foreach ($this->blobFields as $field){ - if(isset($data[$field])) { - if(isset($data[$this->getPk()])) - $this->blobValues[$this->name.'/'.$data[$this->getPk()].'_'.$field] = $data[$field]; - else - $this->blobValues[$this->name.'/@?id@_'.$field] = $data[$field]; + if (!empty($this->blobFields)) { + foreach ($this->blobFields as $field) { + if (isset($data[$field])) { + if (isset($data[$this->getPk()])) { + $this->blobValues[$this->name . '/' . $data[$this->getPk()] . '_' . $field] = $data[$field]; + } else { + $this->blobValues[$this->name . '/@?id@_' . $field] = $data[$field]; + } + unset($data[$field]); } } @@ -360,11 +398,12 @@ protected function checkBlobFields(&$data) { * @param string $field 查询的字段 * @return void */ - protected function getListBlobFields(&$resultSet,$field='') { - if(!empty($this->blobFields)) { - foreach ($resultSet as $key=>$result){ - $result = $this->getBlobFields($result,$field); - $resultSet[$key] = $result; + protected function getListBlobFields(&$resultSet, $field = '') + { + if (!empty($this->blobFields)) { + foreach ($resultSet as $key => $result) { + $result = $this->getBlobFields($result, $field); + $resultSet[$key] = $result; } } return $resultSet; @@ -377,18 +416,19 @@ protected function getListBlobFields(&$resultSet,$field='') { * @param string $field 查询的字段 * @return void */ - protected function getBlobFields(&$data,$field='') { - if(!empty($this->blobFields)) { - $pk = $this->getPk(); - $id = $data[$pk]; - if(empty($field)) { - foreach ($this->blobFields as $field){ - $identify = $this->name.'/'.$id.'_'.$field; - $data[$field] = F($identify); + protected function getBlobFields(&$data, $field = '') + { + if (!empty($this->blobFields)) { + $pk = $this->getPk(); + $id = $data[$pk]; + if (empty($field)) { + foreach ($this->blobFields as $field) { + $identify = $this->name . '/' . $id . '_' . $field; + $data[$field] = F($identify); } return $data; - }else{ - $identify = $this->name.'/'.$id.'_'.$field; + } else { + $identify = $this->name . '/' . $id . '_' . $field; return F($identify); } } @@ -400,12 +440,15 @@ protected function getBlobFields(&$data,$field='') { * @param mixed $data 保存的数据 * @return void */ - protected function saveBlobFields(&$data) { - if(!empty($this->blobFields)) { - foreach ($this->blobValues as $key=>$val){ - if(strpos($key,'@?id@')) - $key = str_replace('@?id@',$data[$this->getPk()],$key); - F($key,$val); + protected function saveBlobFields(&$data) + { + if (!empty($this->blobFields)) { + foreach ($this->blobValues as $key => $val) { + if (strpos($key, '@?id@')) { + $key = str_replace('@?id@', $data[$this->getPk()], $key); + } + + F($key, $val); } } } @@ -417,18 +460,19 @@ protected function saveBlobFields(&$data) { * @param string $field 查询的字段 * @return void */ - protected function delBlobFields(&$data,$field='') { - if(!empty($this->blobFields)) { - $pk = $this->getPk(); - $id = $data[$pk]; - if(empty($field)) { - foreach ($this->blobFields as $field){ - $identify = $this->name.'/'.$id.'_'.$field; - F($identify,null); + protected function delBlobFields(&$data, $field = '') + { + if (!empty($this->blobFields)) { + $pk = $this->getPk(); + $id = $data[$pk]; + if (empty($field)) { + foreach ($this->blobFields as $field) { + $identify = $this->name . '/' . $id . '_' . $field; + F($identify, null); } - }else{ - $identify = $this->name.'/'.$id.'_'.$field; - F($identify,null); + } else { + $identify = $this->name . '/' . $id . '_' . $field; + F($identify, null); } } } @@ -439,38 +483,42 @@ protected function delBlobFields(&$data,$field='') { * @param array $data 数据 * @return array */ - protected function serializeField(&$data) { + protected function serializeField(&$data) + { // 检查序列化字段 - if(!empty($this->serializeField)) { + if (!empty($this->serializeField)) { // 定义方式 $this->serializeField = array('ser'=>array('name','email')); - foreach ($this->serializeField as $key=>$val){ - if(empty($data[$key])) { - $serialize = array(); - foreach ($val as $name){ - if(isset($data[$name])) { - $serialize[$name] = $data[$name]; + foreach ($this->serializeField as $key => $val) { + if (empty($data[$key])) { + $serialize = array(); + foreach ($val as $name) { + if (isset($data[$name])) { + $serialize[$name] = $data[$name]; unset($data[$name]); } } - if(!empty($serialize)) { - $data[$key] = serialize($serialize); + if (!empty($serialize)) { + $data[$key] = serialize($serialize); } } } } return $data; - } + } // 检查返回数据的序列化字段 - protected function checkSerializeField(&$result) { + protected function checkSerializeField(&$result) + { // 检查序列化字段 - if(!empty($this->serializeField)) { - foreach ($this->serializeField as $key=>$val){ - if(isset($result[$key])) { - $serialize = unserialize($result[$key]); - foreach ($serialize as $name=>$value) - $result[$name] = $value; - unset($serialize,$result[$key]); + if (!empty($this->serializeField)) { + foreach ($this->serializeField as $key => $val) { + if (isset($result[$key])) { + $serialize = unserialize($result[$key]); + foreach ($serialize as $name => $value) { + $result[$name] = $value; + } + + unset($serialize, $result[$key]); } } } @@ -478,17 +526,20 @@ protected function checkSerializeField(&$result) { } // 检查数据集的序列化字段 - protected function checkListSerializeField(&$resultSet) { + protected function checkListSerializeField(&$resultSet) + { // 检查序列化字段 - if(!empty($this->serializeField)) { - foreach ($this->serializeField as $key=>$val){ - foreach ($resultSet as $k=>$result){ - if(isset($result[$key])) { - $serialize = unserialize($result[$key]); - foreach ($serialize as $name=>$value) - $result[$name] = $value; - unset($serialize,$result[$key]); - $resultSet[$k] = $result; + if (!empty($this->serializeField)) { + foreach ($this->serializeField as $key => $val) { + foreach ($resultSet as $k => $result) { + if (isset($result[$key])) { + $serialize = unserialize($result[$key]); + foreach ($serialize as $name => $value) { + $result[$name] = $value; + } + + unset($serialize, $result[$key]); + $resultSet[$k] = $result; } } } @@ -502,11 +553,14 @@ protected function checkListSerializeField(&$resultSet) { * @param array $data 数据 * @return array */ - protected function checkReadonlyField(&$data) { - if(!empty($this->readonlyField)) { - foreach ($this->readonlyField as $key=>$field){ - if(isset($data[$field])) + protected function checkReadonlyField(&$data) + { + if (!empty($this->readonlyField)) { + foreach ($this->readonlyField as $key => $field) { + if (isset($data[$field])) { unset($data[$field]); + } + } } return $data; @@ -519,14 +573,18 @@ protected function checkReadonlyField(&$data) { * @param array $sql SQL批处理指令 * @return boolean */ - public function patchQuery($sql=array()) { - if(!is_array($sql)) return false; + public function patchQuery($sql = array()) + { + if (!is_array($sql)) { + return false; + } + // 自动启动事务支持 $this->startTrans(); - try{ - foreach ($sql as $_sql){ - $result = $this->execute($_sql); - if(false === $result) { + try { + foreach ($sql as $_sql) { + $result = $this->execute($_sql); + if (false === $result) { // 发生错误自动回滚事务 $this->rollback(); return false; @@ -546,50 +604,53 @@ public function patchQuery($sql=array()) { * @param array $data 操作的数据 * @return string */ - public function getPartitionTableName($data=array()) { + public function getPartitionTableName($data = array()) + { // 对数据表进行分区 - if(isset($data[$this->partition['field']])) { - $field = $data[$this->partition['field']]; - switch($this->partition['type']) { + if (isset($data[$this->partition['field']])) { + $field = $data[$this->partition['field']]; + switch ($this->partition['type']) { case 'id': // 按照id范围分表 - $step = $this->partition['expr']; - $seq = floor($field / $step)+1; + $step = $this->partition['expr']; + $seq = floor($field / $step) + 1; break; case 'year': // 按照年份分表 - if(!is_numeric($field)) { - $field = strtotime($field); + if (!is_numeric($field)) { + $field = strtotime($field); } - $seq = date('Y',$field)-$this->partition['expr']+1; + $seq = date('Y', $field) - $this->partition['expr'] + 1; break; case 'mod': // 按照id的模数分表 - $seq = ($field % $this->partition['num'])+1; + $seq = ($field % $this->partition['num']) + 1; break; case 'md5': // 按照md5的序列分表 - $seq = (ord(substr(md5($field),0,1)) % $this->partition['num'])+1; + $seq = (ord(substr(md5($field), 0, 1)) % $this->partition['num']) + 1; break; - default : - if(function_exists($this->partition['type'])) { + default: + if (function_exists($this->partition['type'])) { // 支持指定函数哈希 - $fun = $this->partition['type']; - $seq = (ord(substr($fun($field),0,1)) % $this->partition['num'])+1; - }else{ + $fun = $this->partition['type']; + $seq = (ord(substr($fun($field), 0, 1)) % $this->partition['num']) + 1; + } else { // 按照字段的首字母的值分表 - $seq = (ord($field{0}) % $this->partition['num'])+1; + $seq = (ord($field{0}) % $this->partition['num']) + 1; } } - return $this->getTableName().'_'.$seq; - }else{ + return $this->getTableName() . '_' . $seq; + } else { // 当设置的分表字段不在查询条件或者数据中 // 进行联合查询,必须设定 partition['num'] - $tableName = array(); - for($i=0;$i<$this->partition['num'];$i++) - $tableName[] = 'SELECT * FROM '.$this->getTableName().'_'.($i+1); - $tableName = '( '.implode(" UNION ",$tableName).') AS '.$this->name; + $tableName = array(); + for ($i = 0; $i < $this->partition['num']; $i++) { + $tableName[] = 'SELECT * FROM ' . $this->getTableName() . '_' . ($i + 1); + } + + $tableName = '( ' . implode(" UNION ", $tableName) . ') AS ' . $this->name; return $tableName; } } -} \ No newline at end of file +} diff --git a/ThinkPHP/Library/Think/Model/MergeModel.class.php b/ThinkPHP/Library/Think/Model/MergeModel.class.php index 21b32a867..5b7ca2c7f 100644 --- a/ThinkPHP/Library/Think/Model/MergeModel.class.php +++ b/ThinkPHP/Library/Think/Model/MergeModel.class.php @@ -9,17 +9,20 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think\Model; + use Think\Model; + /** - * ThinkPHP 聚合模型扩展 + * ThinkPHP 聚合模型扩展 */ -class MergeModel extends Model { +class MergeModel extends Model +{ - protected $modelList = array(); // 包含的模型列表 第一个必须是主表模型 - protected $masterModel = ''; // 主模型 - protected $joinType = 'INNER'; // 聚合模型的查询JOIN类型 - protected $fk = ''; // 外键名 默认为主表名_id - protected $mapFields = array(); // 需要处理的模型映射字段,避免混淆 array( id => 'user.id' ) + protected $modelList = array(); // 包含的模型列表 第一个必须是主表模型 + protected $masterModel = ''; // 主模型 + protected $joinType = 'INNER'; // 聚合模型的查询JOIN类型 + protected $fk = ''; // 外键名 默认为主表名_id + protected $mapFields = array(); // 需要处理的模型映射字段,避免混淆 array( id => 'user.id' ) /** * 架构函数 @@ -29,31 +32,32 @@ class MergeModel extends Model { * @param string $tablePrefix 表前缀 * @param mixed $connection 数据库连接信息 */ - public function __construct($name='',$tablePrefix='',$connection=''){ - parent::__construct($name,$tablePrefix,$connection); + public function __construct($name = '', $tablePrefix = '', $connection = '') + { + parent::__construct($name, $tablePrefix, $connection); // 聚合模型的字段信息 - if(empty($this->fields) && !empty($this->modelList)){ - $fields = array(); - foreach($this->modelList as $model){ + if (empty($this->fields) && !empty($this->modelList)) { + $fields = array(); + foreach ($this->modelList as $model) { // 获取模型的字段信息 - $result = $this->db->getFields(M($model)->getTableName()); - $_fields = array_keys($result); - // $this->mapFields = array_intersect($fields,$_fields); - $fields = array_merge($fields,$_fields); + $result = $this->db->getFields(M($model)->getTableName()); + $_fields = array_keys($result); + // $this->mapFields = array_intersect($fields,$_fields); + $fields = array_merge($fields, $_fields); } - $this->fields = $fields; + $this->fields = $fields; } // 设置第一个模型为主表模型 - if(empty($this->masterModel) && !empty($this->modelList)){ - $this->masterModel = $this->modelList[0]; + if (empty($this->masterModel) && !empty($this->modelList)) { + $this->masterModel = $this->modelList[0]; } // 主表的主键名 - $this->pk = M($this->masterModel)->getPk(); + $this->pk = M($this->masterModel)->getPk(); // 设置默认外键名 仅支持单一外键 - if(empty($this->fk)){ - $this->fk = strtolower($this->masterModel).'_id'; + if (empty($this->fk)) { + $this->fk = strtolower($this->masterModel) . '_id'; } } @@ -63,14 +67,15 @@ public function __construct($name='',$tablePrefix='',$connection=''){ * @access public * @return string */ - public function getTableName() { - if(empty($this->trueTableName)) { - $tableName = array(); - $models = $this->modelList; - foreach($models as $model){ - $tableName[] = M($model)->getTableName().' '.$model; + public function getTableName() + { + if (empty($this->trueTableName)) { + $tableName = array(); + $models = $this->modelList; + foreach ($models as $model) { + $tableName[] = M($model)->getTableName() . ' ' . $model; } - $this->trueTableName = implode(',',$tableName); + $this->trueTableName = implode(',', $tableName); } return $this->trueTableName; } @@ -80,7 +85,8 @@ public function getTableName() { * @access protected * @return void */ - protected function _checkTableInfo() {} + protected function _checkTableInfo() + {} /** * 新增聚合数据 @@ -90,82 +96,84 @@ protected function _checkTableInfo() {} * @param boolean $replace 是否replace * @return mixed */ - public function add($data='',$options=array(),$replace=false){ - if(empty($data)) { + public function add($data = '', $options = array(), $replace = false) + { + if (empty($data)) { // 没有传递数据,获取当前数据对象的值 - if(!empty($this->data)) { - $data = $this->data; + if (!empty($this->data)) { + $data = $this->data; // 重置数据 - $this->data = array(); - }else{ - $this->error = L('_DATA_TYPE_INVALID_'); + $this->data = array(); + } else { + $this->error = L('_DATA_TYPE_INVALID_'); return false; } } // 启动事务 $this->startTrans(); // 写入主表数据 - $result = M($this->masterModel)->strict(false)->add($data); - if($result){ + $result = M($this->masterModel)->strict(false)->add($data); + if ($result) { // 写入外键数据 - $data[$this->fk] = $result; - $models = $this->modelList; + $data[$this->fk] = $result; + $models = $this->modelList; array_shift($models); // 写入附表数据 - foreach($models as $model){ - $res = M($model)->strict(false)->add($data); - if(!$res){ + foreach ($models as $model) { + $res = M($model)->strict(false)->add($data); + if (!$res) { $this->rollback(); return false; } } // 提交事务 $this->commit(); - }else{ + } else { $this->rollback(); return false; } return $result; } - /** + /** * 对保存到数据库的数据进行处理 * @access protected * @param mixed $data 要操作的数据 * @return boolean */ - protected function _facade($data) { + protected function _facade($data) + { // 检查数据字段合法性 - if(!empty($this->fields)) { - if(!empty($this->options['field'])) { - $fields = $this->options['field']; + if (!empty($this->fields)) { + if (!empty($this->options['field'])) { + $fields = $this->options['field']; unset($this->options['field']); - if(is_string($fields)) { - $fields = explode(',',$fields); - } - }else{ - $fields = $this->fields; - } - foreach ($data as $key=>$val){ - if(!in_array($key,$fields,true)){ + if (is_string($fields)) { + $fields = explode(',', $fields); + } + } else { + $fields = $this->fields; + } + foreach ($data as $key => $val) { + if (!in_array($key, $fields, true)) { unset($data[$key]); - }elseif(array_key_exists($key,$this->mapFields)){ + } elseif (array_key_exists($key, $this->mapFields)) { // 需要处理映射字段 $data[$this->mapFields[$key]] = $val; unset($data[$key]); } } } - + // 安全过滤 - if(!empty($this->options['filter'])) { - $data = array_map($this->options['filter'],$data); + if (!empty($this->options['filter'])) { + $data = array_map($this->options['filter'], $data); unset($this->options['filter']); } $this->_before_write($data); return $data; - } + } /** * 保存聚合模型数据 @@ -174,46 +182,50 @@ protected function _facade($data) { * @param array $options 表达式 * @return boolean */ - public function save($data='',$options=array()){ + public function save($data = '', $options = array()) + { // 根据主表的主键更新 - if(empty($data)) { + if (empty($data)) { // 没有传递数据,获取当前数据对象的值 - if(!empty($this->data)) { - $data = $this->data; + if (!empty($this->data)) { + $data = $this->data; // 重置数据 - $this->data = array(); - }else{ - $this->error = L('_DATA_TYPE_INVALID_'); + $this->data = array(); + } else { + $this->error = L('_DATA_TYPE_INVALID_'); return false; } } - if(empty($data)){ + if (empty($data)) { // 没有数据则不执行 - $this->error = L('_DATA_TYPE_INVALID_'); + $this->error = L('_DATA_TYPE_INVALID_'); return false; - } + } // 如果存在主键数据 则自动作为更新条件 - $pk = $this->pk; - if(isset($data[$pk])) { - $where[$pk] = $data[$pk]; - $options['where'] = $where; + $pk = $this->pk; + if (isset($data[$pk])) { + $where[$pk] = $data[$pk]; + $options['where'] = $where; unset($data[$pk]); } - $options['join'] = ''; - $options = $this->_parseOptions($options); - // 更新操作不使用JOIN - $options['table'] = $this->getTableName(); + $options['join'] = ''; + $options = $this->_parseOptions($options); + // 更新操作不使用JOIN + $options['table'] = $this->getTableName(); - if(is_array($options['where']) && isset($options['where'][$pk])){ - $pkValue = $options['where'][$pk]; + if (is_array($options['where']) && isset($options['where'][$pk])) { + $pkValue = $options['where'][$pk]; } - if(false === $this->_before_update($data,$options)) { + if (false === $this->_before_update($data, $options)) { return false; - } - $result = $this->db->update($data,$options); - if(false !== $result) { - if(isset($pkValue)) $data[$pk] = $pkValue; - $this->_after_update($data,$options); + } + $result = $this->db->update($data, $options); + if (false !== $result) { + if (isset($pkValue)) { + $data[$pk] = $pkValue; + } + + $this->_after_update($data, $options); } return $result; } @@ -224,47 +236,53 @@ public function save($data='',$options=array()){ * @param mixed $options 表达式 * @return mixed */ - public function delete($options=array()){ - $pk = $this->pk; - if(empty($options) && empty($this->options['where'])) { + public function delete($options = array()) + { + $pk = $this->pk; + if (empty($options) && empty($this->options['where'])) { // 如果删除条件为空 则删除当前数据对象所对应的记录 - if(!empty($this->data) && isset($this->data[$pk])) + if (!empty($this->data) && isset($this->data[$pk])) { return $this->delete($this->data[$pk]); - else + } else { return false; + } + } - - if(is_numeric($options) || is_string($options)) { + + if (is_numeric($options) || is_string($options)) { // 根据主键删除记录 - if(strpos($options,',')) { - $where[$pk] = array('IN', $options); - }else{ - $where[$pk] = $options; + if (strpos($options, ',')) { + $where[$pk] = array('IN', $options); + } else { + $where[$pk] = $options; } - $options = array(); - $options['where'] = $where; + $options = array(); + $options['where'] = $where; } // 分析表达式 - $options['join'] = ''; - $options = $this->_parseOptions($options); - if(empty($options['where'])){ + $options['join'] = ''; + $options = $this->_parseOptions($options); + if (empty($options['where'])) { // 如果条件为空 不进行删除操作 除非设置 1=1 return false; - } - if(is_array($options['where']) && isset($options['where'][$pk])){ - $pkValue = $options['where'][$pk]; } - - $options['table'] = implode(',',$this->modelList); - $options['using'] = $this->getTableName(); - if(false === $this->_before_delete($options)) { + if (is_array($options['where']) && isset($options['where'][$pk])) { + $pkValue = $options['where'][$pk]; + } + + $options['table'] = implode(',', $this->modelList); + $options['using'] = $this->getTableName(); + if (false === $this->_before_delete($options)) { return false; - } - $result = $this->db->delete($options); - if(false !== $result) { + } + $result = $this->db->delete($options); + if (false !== $result) { $data = array(); - if(isset($pkValue)) $data[$pk] = $pkValue; - $this->_after_delete($data,$options); + if (isset($pkValue)) { + $data[$pk] = $pkValue; + } + + $this->_after_delete($data, $options); } // 返回删除记录个数 return $result; @@ -276,22 +294,29 @@ public function delete($options=array()){ * @param string $options 表达式 * @return void */ - protected function _options_filter(&$options) { - if(!isset($options['join'])){ - $models = $this->modelList; + protected function _options_filter(&$options) + { + if (!isset($options['join'])) { + $models = $this->modelList; array_shift($models); - foreach($models as $model){ - $options['join'][] = $this->joinType.' JOIN '.M($model)->getTableName().' '.$model.' ON '.$this->masterModel.'.'.$this->pk.' = '.$model.'.'.$this->fk; + foreach ($models as $model) { + $options['join'][] = $this->joinType . ' JOIN ' . M($model)->getTableName() . ' ' . $model . ' ON ' . $this->masterModel . '.' . $this->pk . ' = ' . $model . '.' . $this->fk; } } - $options['table'] = M($this->masterModel)->getTableName().' '.$this->masterModel; - $options['field'] = $this->checkFields(isset($options['field'])?$options['field']:''); - if(isset($options['group'])) - $options['group'] = $this->checkGroup($options['group']); - if(isset($options['where'])) - $options['where'] = $this->checkCondition($options['where']); - if(isset($options['order'])) - $options['order'] = $this->checkOrder($options['order']); + $options['table'] = M($this->masterModel)->getTableName() . ' ' . $this->masterModel; + $options['field'] = $this->checkFields(isset($options['field']) ? $options['field'] : ''); + if (isset($options['group'])) { + $options['group'] = $this->checkGroup($options['group']); + } + + if (isset($options['where'])) { + $options['where'] = $this->checkCondition($options['where']); + } + + if (isset($options['order'])) { + $options['order'] = $this->checkOrder($options['order']); + } + } /** @@ -300,18 +325,19 @@ protected function _options_filter(&$options) { * @param mixed $data 条件表达式 * @return array */ - protected function checkCondition($where) { - if(is_array($where)) { - $view = array(); - foreach($where as $name=>$value){ - if(array_key_exists($name,$this->mapFields)){ + protected function checkCondition($where) + { + if (is_array($where)) { + $view = array(); + foreach ($where as $name => $value) { + if (array_key_exists($name, $this->mapFields)) { // 需要处理映射字段 $view[$this->mapFields[$name]] = $value; unset($where[$name]); } } - $where = array_merge($where,$view); - } + $where = array_merge($where, $view); + } return $where; } @@ -321,22 +347,23 @@ protected function checkCondition($where) { * @param string $order 字段 * @return string */ - protected function checkOrder($order='') { - if(is_string($order) && !empty($order)) { - $orders = explode(',',$order); + protected function checkOrder($order = '') + { + if (is_string($order) && !empty($order)) { + $orders = explode(',', $order); $_order = array(); - foreach ($orders as $order){ - $array = explode(' ',trim($order)); - $field = $array[0]; - $sort = isset($array[1])?$array[1]:'ASC'; - if(array_key_exists($field,$this->mapFields)){ + foreach ($orders as $order) { + $array = explode(' ', trim($order)); + $field = $array[0]; + $sort = isset($array[1]) ? $array[1] : 'ASC'; + if (array_key_exists($field, $this->mapFields)) { // 需要处理映射字段 - $field = $this->mapFields[$field]; - } - $_order[] = $field.' '.$sort; + $field = $this->mapFields[$field]; + } + $_order[] = $field . ' ' . $sort; } - $order = implode(',',$_order); - } + $order = implode(',', $_order); + } return $order; } @@ -346,20 +373,21 @@ protected function checkOrder($order='') { * @param string $group 字段 * @return string */ - protected function checkGroup($group='') { - if(!empty($group)) { - $groups = explode(',',$group); + protected function checkGroup($group = '') + { + if (!empty($group)) { + $groups = explode(',', $group); $_group = array(); - foreach ($groups as $field){ + foreach ($groups as $field) { // 解析成聚合字段 - if(array_key_exists($field,$this->mapFields)){ + if (array_key_exists($field, $this->mapFields)) { // 需要处理映射字段 - $field = $this->mapFields[$field]; - } + $field = $this->mapFields[$field]; + } $_group[] = $field; } - $group = implode(',',$_group); - } + $group = implode(',', $_group); + } return $group; } @@ -369,25 +397,27 @@ protected function checkGroup($group='') { * @param string $fields 字段 * @return string */ - protected function checkFields($fields='') { - if(empty($fields) || '*'==$fields ) { + protected function checkFields($fields = '') + { + if (empty($fields) || '*' == $fields) { // 获取全部聚合字段 - $fields = $this->fields; + $fields = $this->fields; + } + if (!is_array($fields)) { + $fields = explode(',', $fields); } - if(!is_array($fields)) - $fields = explode(',',$fields); // 解析成聚合字段 - $array = array(); - foreach ($fields as $field){ - if(array_key_exists($field,$this->mapFields)){ + $array = array(); + foreach ($fields as $field) { + if (array_key_exists($field, $this->mapFields)) { // 需要处理映射字段 - $array[] = $this->mapFields[$field].' AS '.$field; - }else{ - $array[] = $field; + $array[] = $this->mapFields[$field] . ' AS ' . $field; + } else { + $array[] = $field; } } - $fields = implode(',',$array); + $fields = implode(',', $array); return $fields; } @@ -396,8 +426,9 @@ protected function checkFields($fields='') { * @access public * @return array */ - public function getDbFields(){ + public function getDbFields() + { return $this->fields; } -} \ No newline at end of file +} diff --git a/ThinkPHP/Library/Think/Model/MongoModel.class.php b/ThinkPHP/Library/Think/Model/MongoModel.class.php index d1927d788..551b9461f 100644 --- a/ThinkPHP/Library/Think/Model/MongoModel.class.php +++ b/ThinkPHP/Library/Think/Model/MongoModel.class.php @@ -9,27 +9,30 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think\Model; + use Think\Model; + /** * MongoModel模型类 * 实现了ODM和ActiveRecords模式 */ -class MongoModel extends Model{ +class MongoModel extends Model +{ // 主键类型 - const TYPE_OBJECT = 1; - const TYPE_INT = 2; - const TYPE_STRING = 3; + const TYPE_OBJECT = 1; + const TYPE_INT = 2; + const TYPE_STRING = 3; // 主键名称 - protected $pk = '_id'; + protected $pk = '_id'; // _id 类型 1 Object 采用MongoId对象 2 Int 整形 支持自动增长 3 String 字符串Hash - protected $_idType = self::TYPE_OBJECT; + protected $_idType = self::TYPE_OBJECT; // 主键是否自增 - protected $_autoinc = true; + protected $_autoinc = true; // Mongo默认关闭字段检测 可以动态追加字段 - protected $autoCheckFields = false; + protected $autoCheckFields = false; // 链操作方法列表 - protected $methods = array('table','order','auto','filter','validate'); + protected $methods = array('table', 'order', 'auto', 'filter', 'validate'); /** * 利用__call方法实现一些特殊的Model方法 @@ -38,23 +41,24 @@ class MongoModel extends Model{ * @param array $args 调用参数 * @return mixed */ - public function __call($method,$args) { - if(in_array(strtolower($method),$this->methods,true)) { + public function __call($method, $args) + { + if (in_array(strtolower($method), $this->methods, true)) { // 连贯操作的实现 - $this->options[strtolower($method)] = $args[0]; + $this->options[strtolower($method)] = $args[0]; return $this; - }elseif(strtolower(substr($method,0,5))=='getby') { + } elseif (strtolower(substr($method, 0, 5)) == 'getby') { // 根据某个字段获取记录 - $field = parse_name(substr($method,5)); - $where[$field] =$args[0]; + $field = parse_name(substr($method, 5)); + $where[$field] = $args[0]; return $this->where($where)->find(); - }elseif(strtolower(substr($method,0,10))=='getfieldby') { + } elseif (strtolower(substr($method, 0, 10)) == 'getfieldby') { // 根据某个字段获取记录的某个值 - $name = parse_name(substr($method,10)); - $where[$name] =$args[0]; + $name = parse_name(substr($method, 10)); + $where[$name] = $args[0]; return $this->where($where)->getField($args[1]); - }else{ - E(__CLASS__.':'.$method.L('_METHOD_NOT_EXIST_')); + } else { + E(__CLASS__ . ':' . $method . L('_METHOD_NOT_EXIST_')); return; } } @@ -64,35 +68,40 @@ public function __call($method,$args) { * @access public * @return void */ - public function flush() { + public function flush() + { // 缓存不存在则查询数据表信息 - $fields = $this->db->getFields(); - if(!$fields) { // 暂时没有数据无法获取字段信息 下次查询 + $fields = $this->db->getFields(); + if (!$fields) { + // 暂时没有数据无法获取字段信息 下次查询 return false; } - $this->fields = array_keys($fields); - foreach ($fields as $key=>$val){ + $this->fields = array_keys($fields); + foreach ($fields as $key => $val) { // 记录字段类型 - $type[$key] = $val['type']; + $type[$key] = $val['type']; } // 记录字段类型信息 - if(C('DB_FIELDTYPE_CHECK')) $this->fields['_type'] = $type; + if (C('DB_FIELDTYPE_CHECK')) { + $this->fields['_type'] = $type; + } // 2008-3-7 增加缓存开关控制 - if(C('DB_FIELDS_CACHE')){ + if (C('DB_FIELDS_CACHE')) { // 永久缓存数据表信息 - $db = $this->dbName?$this->dbName:C('DB_NAME'); - F('_fields/'.$db.'.'.$this->name,$this->fields); + $db = $this->dbName ? $this->dbName : C('DB_NAME'); + F('_fields/' . $db . '.' . $this->name, $this->fields); } } // 写入数据前的回调方法 包括新增和更新 - protected function _before_write(&$data) { - $pk = $this->getPk(); + protected function _before_write(&$data) + { + $pk = $this->getPk(); // 根据主键类型处理主键数据 - if(isset($data[$pk]) && $this->_idType == self::TYPE_OBJECT) { - $data[$pk] = new \MongoId($data[$pk]); - } + if (isset($data[$pk]) && self::TYPE_OBJECT == $this->_idType) { + $data[$pk] = new \MongoId($data[$pk]); + } } /** @@ -100,9 +109,10 @@ protected function _before_write(&$data) { * @access public * @return integer */ - public function count(){ + public function count() + { // 分析表达式 - $options = $this->_parseOptions(); + $options = $this->_parseOptions(); return $this->db->count($options); } @@ -111,15 +121,16 @@ public function count(){ * @access public * @return array | false */ - public function distinct($field, $where=array() ){ + public function distinct($field, $where = array()) + { // 分析表达式 - $this->options = $this->_parseOptions(); - $this->options['where'] = array_merge((array)$this->options['where'], $where); + $this->options = $this->_parseOptions(); + $this->options['where'] = array_merge((array) $this->options['where'], $where); $command = array( "distinct" => $this->options['table'], - "key" => $field, - "query" => $this->options['where'] + "key" => $field, + "query" => $this->options['where'], ); $result = $this->command($command); @@ -132,9 +143,10 @@ public function distinct($field, $where=array() ){ * @param string $pk 字段名 默认为主键 * @return mixed */ - public function getMongoNextId($pk=''){ - if(empty($pk)) { - $pk = $this->getPk(); + public function getMongoNextId($pk = '') + { + if (empty($pk)) { + $pk = $this->getPk(); } return $this->db->getMongoNextId($pk); } @@ -147,30 +159,31 @@ public function getMongoNextId($pk=''){ * @param boolean $replace 是否replace * @return mixed */ - public function add($data='',$options=array(),$replace=false) { - if(empty($data)) { + public function add($data = '', $options = array(), $replace = false) + { + if (empty($data)) { // 没有传递数据,获取当前数据对象的值 - if(!empty($this->data)) { - $data = $this->data; + if (!empty($this->data)) { + $data = $this->data; // 重置数据 - $this->data = array(); - }else{ - $this->error = L('_DATA_TYPE_INVALID_'); + $this->data = array(); + } else { + $this->error = L('_DATA_TYPE_INVALID_'); return false; } } // 分析表达式 - $options = $this->_parseOptions($options); + $options = $this->_parseOptions($options); // 数据处理 - $data = $this->_facade($data); - if(false === $this->_before_insert($data,$options)) { + $data = $this->_facade($data); + if (false === $this->_before_insert($data, $options)) { return false; } // 写入数据到数据库 - $result = $this->db->insert($data,$options,$replace); - if(false !== $result ) { - $this->_after_insert($data,$options); - if(isset($data[$this->getPk()])){ + $result = $this->db->insert($data, $options, $replace); + if (false !== $result) { + $this->_after_insert($data, $options); + if (isset($data[$this->getPk()])) { return $data[$this->getPk()]; } } @@ -178,23 +191,27 @@ public function add($data='',$options=array(),$replace=false) { } // 插入数据前的回调方法 - protected function _before_insert(&$data,$options) { + protected function _before_insert(&$data, $options) + { // 写入数据到数据库 - if($this->_autoinc && $this->_idType== self::TYPE_INT) { // 主键自动增长 - $pk = $this->getPk(); - if(!isset($data[$pk])) { - $data[$pk] = $this->db->getMongoNextId($pk); + if ($this->_autoinc && self::TYPE_INT == $this->_idType) { + // 主键自动增长 + $pk = $this->getPk(); + if (!isset($data[$pk])) { + $data[$pk] = $this->db->getMongoNextId($pk); } } } - public function clear(){ + public function clear() + { return $this->db->clear(); } // 查询成功后的回调方法 - protected function _after_select(&$resultSet,$options) { - array_walk($resultSet,array($this,'checkMongoId')); + protected function _after_select(&$resultSet, $options) + { + array_walk($resultSet, array($this, 'checkMongoId')); } /** @@ -203,17 +220,19 @@ protected function _after_select(&$resultSet,$options) { * @param array $result 返回数据 * @return array */ - protected function checkMongoId(&$result){ - if(is_object($result['_id'])) { + protected function checkMongoId(&$result) + { + if (is_object($result['_id'])) { $result['_id'] = $result['_id']->__toString(); } return $result; } // 表达式过滤回调方法 - protected function _options_filter(&$options) { + protected function _options_filter(&$options) + { $id = $this->getPk(); - if(isset($options['where'][$id]) && is_scalar($options['where'][$id]) && $this->_idType== self::TYPE_OBJECT) { + if (isset($options['where'][$id]) && is_scalar($options['where'][$id]) && self::TYPE_OBJECT == $this->_idType) { $options['where'][$id] = new \MongoId($options['where'][$id]); } } @@ -224,28 +243,30 @@ protected function _options_filter(&$options) { * @param mixed $options 表达式参数 * @return mixed */ - public function find($options=array()) { - if( is_numeric($options) || is_string($options)) { - $id = $this->getPk(); - $where[$id] = $options; - $options = array(); + public function find($options = array()) + { + if (is_numeric($options) || is_string($options)) { + $id = $this->getPk(); + $where[$id] = $options; + $options = array(); $options['where'] = $where; - } + } // 分析表达式 - $options = $this->_parseOptions($options); - $result = $this->db->find($options); - if(false === $result) { + $options = $this->_parseOptions($options); + $result = $this->db->find($options); + if (false === $result) { return false; } - if(empty($result)) {// 查询结果为空 + if (empty($result)) { +// 查询结果为空 return null; - }else{ + } else { $this->checkMongoId($result); } $this->data = $result; - $this->_after_find($this->data,$options); + $this->_after_find($this->data, $options); return $this->data; - } + } /** * 字段值增长 @@ -254,8 +275,9 @@ public function find($options=array()) { * @param integer $step 增长值 * @return boolean */ - public function setInc($field,$step=1) { - return $this->setField($field,array('inc',$step)); + public function setInc($field, $step = 1) + { + return $this->setField($field, array('inc', $step)); } /** @@ -265,8 +287,9 @@ public function setInc($field,$step=1) { * @param integer $step 减少值 * @return boolean */ - public function setDec($field,$step=1) { - return $this->setField($field,array('inc','-'.$step)); + public function setDec($field, $step = 1) + { + return $this->setField($field, array('inc', '-' . $step)); } /** @@ -276,45 +299,48 @@ public function setDec($field,$step=1) { * @param string $spea 字段数据间隔符号 * @return mixed */ - public function getField($field,$sepa=null) { - $options['field'] = $field; - $options = $this->_parseOptions($options); - if(strpos($field,',')) { // 多字段 - if(is_numeric($sepa)) {// 限定数量 - $options['limit'] = $sepa; - $sepa = null;// 重置为null 返回数组 + public function getField($field, $sepa = null) + { + $options['field'] = $field; + $options = $this->_parseOptions($options); + if (strpos($field, ',')) { + // 多字段 + if (is_numeric($sepa)) { // 限定数量 + $options['limit'] = $sepa; + $sepa = null; // 重置为null 返回数组 } $resultSet = $this->db->select($options); - if(!empty($resultSet)) { + if (!empty($resultSet)) { $_field = explode(',', $field); $field = array_keys($resultSet[0]); - $key = array_shift($field); - $key2 = array_shift($field); - $cols = array(); - $count = count($_field); - foreach ($resultSet as $result){ - $name = $result[$key]; - if(2==$count) { - $cols[$name] = $result[$key2]; - }else{ - $cols[$name] = is_null($sepa)?$result:implode($sepa,$result); + $key = array_shift($field); + $key2 = array_shift($field); + $cols = array(); + $count = count($_field); + foreach ($resultSet as $result) { + $name = $result[$key]; + if (2 == $count) { + $cols[$name] = $result[$key2]; + } else { + $cols[$name] = is_null($sepa) ? $result : implode($sepa, $result); } } return $cols; } - }else{ + } else { // 返回数据个数 - if(true !== $sepa) {// 当sepa指定为true的时候 返回所有数据 - $options['limit'] = is_numeric($sepa)?$sepa:1; - } // 查找符合的记录 + if (true !== $sepa) { +// 当sepa指定为true的时候 返回所有数据 + $options['limit'] = is_numeric($sepa) ? $sepa : 1; + } // 查找符合的记录 $result = $this->db->select($options); - if(!empty($result)) { - if(1==$options['limit']) { - $result = reset($result); + if (!empty($result)) { + if (1 == $options['limit']) { + $result = reset($result); return $result[$field]; } - foreach ($result as $val){ - $array[] = $val[$field]; + foreach ($result as $val) { + $array[] = $val[$field]; } return $array; } @@ -328,8 +354,9 @@ public function getField($field,$sepa=null) { * @param array $command 指令 * @return mixed */ - public function command($command, $options=array()) { - $options = $this->_parseOptions($options); + public function command($command, $options = array()) + { + $options = $this->_parseOptions($options); return $this->db->command($command, $options); } @@ -340,14 +367,16 @@ public function command($command, $options=array()) { * @param array $args 参数 * @return mixed */ - public function mongoCode($code,$args=array()) { - return $this->db->execute($code,$args); + public function mongoCode($code, $args = array()) + { + return $this->db->execute($code, $args); } // 数据库切换后回调方法 - protected function _after_db() { + protected function _after_db() + { // 切换Collection - $this->db->switchCollection($this->getTableName(),$this->dbName?$this->dbName:C('db_name')); + $this->db->switchCollection($this->getTableName(), $this->dbName ? $this->dbName : C('db_name')); } /** @@ -355,15 +384,16 @@ protected function _after_db() { * @access public * @return string */ - public function getTableName() { - if(empty($this->trueTableName)) { - $tableName = !empty($this->tablePrefix) ? $this->tablePrefix : ''; - if(!empty($this->tableName)) { + public function getTableName() + { + if (empty($this->trueTableName)) { + $tableName = !empty($this->tablePrefix) ? $this->tablePrefix : ''; + if (!empty($this->tableName)) { $tableName .= $this->tableName; - }else{ + } else { $tableName .= parse_name($this->name); } - $this->trueTableName = strtolower($tableName); + $this->trueTableName = strtolower($tableName); } return $this->trueTableName; } @@ -373,12 +403,14 @@ public function getTableName() { * @access public * @return string */ - public function group($key, $init, $reduce, $option=array()) { + public function group($key, $init, $reduce, $option = array()) + { $option = $this->_parseOptions($option); //合并查询条件 - if(isset($option['where'])) - $option['condition'] = array_merge((array)$option['condition'], $option['where']); + if (isset($option['where'])) { + $option['condition'] = array_merge((array) $option['condition'], $option['where']); + } return $this->db->group($key, $init, $reduce, $option); } @@ -388,8 +420,9 @@ public function group($key, $init, $reduce, $option=array()) { * @access public * @return json */ - public function getLastError(){ - return $this->db->command(array('getLastError'=>1)); + public function getLastError() + { + return $this->db->command(array('getLastError' => 1)); } /** @@ -397,26 +430,29 @@ public function getLastError(){ * @access public * @return json */ - public function status(){ + public function status() + { $option = $this->_parseOptions(); - return $this->db->command(array('collStats'=>$option['table'])); + return $this->db->command(array('collStats' => $option['table'])); } - + /** * 取得当前数据库的对象 * @access public * @return object */ - public function getDB(){ + public function getDB() + { return $this->db->getDB(); } - + /** * 取得集合对象,可以进行创建索引等查询 * @access public * @return object */ - public function getCollection(){ + public function getCollection() + { return $this->db->getCollection(); } -} \ No newline at end of file +} diff --git a/ThinkPHP/Library/Think/Model/RelationModel.class.php b/ThinkPHP/Library/Think/Model/RelationModel.class.php index 6a3b39eb2..dd332a844 100644 --- a/ThinkPHP/Library/Think/Model/RelationModel.class.php +++ b/ThinkPHP/Library/Think/Model/RelationModel.class.php @@ -9,19 +9,22 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think\Model; + use Think\Model; + /** - * ThinkPHP关联模型扩展 + * ThinkPHP关联模型扩展 */ -class RelationModel extends Model { +class RelationModel extends Model +{ - const HAS_ONE = 1; - const BELONGS_TO = 2; - const HAS_MANY = 3; - const MANY_TO_MANY= 4; + const HAS_ONE = 1; + const BELONGS_TO = 2; + const HAS_MANY = 3; + const MANY_TO_MANY = 4; // 关联定义 - protected $_link = array(); + protected $_link = array(); /** * 动态方法实现 @@ -30,15 +33,16 @@ class RelationModel extends Model { * @param array $args 调用参数 * @return mixed */ - public function __call($method,$args) { - if(strtolower(substr($method,0,8))=='relation'){ - $type = strtoupper(substr($method,8)); - if(in_array($type,array('ADD','SAVE','DEL'),true)) { - array_unshift($args,$type); + public function __call($method, $args) + { + if (strtolower(substr($method, 0, 8)) == 'relation') { + $type = strtoupper(substr($method, 8)); + if (in_array($type, array('ADD', 'SAVE', 'DEL'), true)) { + array_unshift($args, $type); return call_user_func_array(array(&$this, 'opRelation'), $args); } - }else{ - return parent::__call($method,$args); + } else { + return parent::__call($method, $args); } } @@ -47,46 +51,62 @@ public function __call($method,$args) { * @access public * @return string */ - public function getRelationTableName($relation) { - $relationTable = !empty($this->tablePrefix) ? $this->tablePrefix : ''; - $relationTable .= $this->tableName?$this->tableName:$this->name; - $relationTable .= '_'.$relation->getModelName(); + public function getRelationTableName($relation) + { + $relationTable = !empty($this->tablePrefix) ? $this->tablePrefix : ''; + $relationTable .= $this->tableName ? $this->tableName : $this->name; + $relationTable .= '_' . $relation->getModelName(); return strtolower($relationTable); } // 查询成功后的回调方法 - protected function _after_find(&$result,$options) { + protected function _after_find(&$result, $options) + { // 获取关联数据 并附加到结果中 - if(!empty($options['link'])) - $this->getRelation($result,$options['link']); + if (!empty($options['link'])) { + $this->getRelation($result, $options['link']); + } + } // 查询数据集成功后的回调方法 - protected function _after_select(&$result,$options) { + protected function _after_select(&$result, $options) + { // 获取关联数据 并附加到结果中 - if(!empty($options['link'])) - $this->getRelations($result,$options['link']); + if (!empty($options['link'])) { + $this->getRelations($result, $options['link']); + } + } // 写入成功后的回调方法 - protected function _after_insert($data,$options) { + protected function _after_insert($data, $options) + { // 关联写入 - if(!empty($options['link'])) - $this->opRelation('ADD',$data,$options['link']); + if (!empty($options['link'])) { + $this->opRelation('ADD', $data, $options['link']); + } + } // 更新成功后的回调方法 - protected function _after_update($data,$options) { + protected function _after_update($data, $options) + { // 关联更新 - if(!empty($options['link'])) - $this->opRelation('SAVE',$data,$options['link']); + if (!empty($options['link'])) { + $this->opRelation('SAVE', $data, $options['link']); + } + } // 删除成功后的回调方法 - protected function _after_delete($data,$options) { + protected function _after_delete($data, $options) + { // 关联删除 - if(!empty($options['link'])) - $this->opRelation('DEL',$data,$options['link']); + if (!empty($options['link'])) { + $this->opRelation('DEL', $data, $options['link']); + } + } /** @@ -95,10 +115,11 @@ protected function _after_delete($data,$options) { * @param mixed $data 要操作的数据 * @return boolean */ - protected function _facade($data) { + protected function _facade($data) + { $this->_before_write($data); return $data; - } + } /** * 获取返回数据集的关联记录 @@ -107,11 +128,12 @@ protected function _facade($data) { * @param string|array $name 关联名称 * @return array */ - protected function getRelations(&$resultSet,$name='') { + protected function getRelations(&$resultSet, $name = '') + { // 获取记录集的主键列表 - foreach($resultSet as $key=>$val) { - $val = $this->getRelation($val,$name); - $resultSet[$key] = $val; + foreach ($resultSet as $key => $val) { + $val = $this->getRelation($val, $name); + $resultSet[$key] = $val; } return $resultSet; } @@ -124,113 +146,114 @@ protected function getRelations(&$resultSet,$name='') { * @param boolean $return 是否返回关联数据本身 * @return array */ - protected function getRelation(&$result,$name='',$return=false) { - if(!empty($this->_link)) { - foreach($this->_link as $key=>$val) { - $mappingName = !empty($val['mapping_name'])?$val['mapping_name']:$key; // 映射名称 - if(empty($name) || true === $name || $mappingName == $name || (is_array($name) && in_array($mappingName,$name))) { - $mappingType = !empty($val['mapping_type'])?$val['mapping_type']:$val; // 关联类型 - $mappingClass = !empty($val['class_name'])?$val['class_name']:$key; // 关联类名 - $mappingFields = !empty($val['mapping_fields'])?$val['mapping_fields']:'*'; // 映射字段 - $mappingCondition = !empty($val['condition'])?$val['condition']:'1=1'; // 关联条件 - $mappingKey =!empty($val['mapping_key'])? $val['mapping_key'] : $this->getPk(); // 关联键名 - if(strtoupper($mappingClass)==strtoupper($this->name)) { - // 自引用关联 获取父键名 - $mappingFk = !empty($val['parent_key'])? $val['parent_key'] : 'parent_id'; - }else{ - $mappingFk = !empty($val['foreign_key'])?$val['foreign_key']:strtolower($this->name).'_id'; // 关联外键 - } - // 获取关联模型对象 - $model = D($mappingClass); - switch($mappingType) { - case self::HAS_ONE: - $pk = $result[$mappingKey]; - $mappingCondition .= " AND {$mappingFk}='{$pk}'"; - $relationData = $model->where($mappingCondition)->field($mappingFields)->find(); - if (!empty($val['relation_deep'])){ - $model->getRelation($relationData,$val['relation_deep']); - } - break; - case self::BELONGS_TO: - if(strtoupper($mappingClass)==strtoupper($this->name)) { - // 自引用关联 获取父键名 - $mappingFk = !empty($val['parent_key'])? $val['parent_key'] : 'parent_id'; - }else{ - $mappingFk = !empty($val['foreign_key'])?$val['foreign_key']:strtolower($model->getModelName()).'_id'; // 关联外键 - } - $fk = $result[$mappingFk]; - $mappingCondition .= " AND {$model->getPk()}='{$fk}'"; - $relationData = $model->where($mappingCondition)->field($mappingFields)->find(); - if (!empty($val['relation_deep'])){ - $model->getRelation($relationData,$val['relation_deep']); - } - break; - case self::HAS_MANY: - $pk = $result[$mappingKey]; - $mappingCondition .= " AND {$mappingFk}='{$pk}'"; - $mappingOrder = !empty($val['mapping_order'])?$val['mapping_order']:''; - $mappingLimit = !empty($val['mapping_limit'])?$val['mapping_limit']:''; - // 延时获取关联记录 - $relationData = $model->where($mappingCondition)->field($mappingFields)->order($mappingOrder)->limit($mappingLimit)->select(); - if (!empty($val['relation_deep'])){ - foreach($relationData as $key=>$data){ - $model->getRelation($data,$val['relation_deep']); - $relationData[$key] = $data; - } - } - break; - case self::MANY_TO_MANY: - $pk = $result[$mappingKey]; - $prefix = $this->tablePrefix; - $mappingCondition = " {$mappingFk}='{$pk}'"; - $mappingOrder = $val['mapping_order']; - $mappingLimit = $val['mapping_limit']; - $mappingRelationFk = $val['relation_foreign_key']?$val['relation_foreign_key']:$model->getModelName().'_id'; - if(isset($val['relation_table'])){ - $mappingRelationTable = preg_replace_callback("/__([A-Z_-]+)__/sU", function($match) use($prefix){ return $prefix.strtolower($match[1]);}, $val['relation_table']); - }else{ - $mappingRelationTable = $this->getRelationTableName($model); - } - $sql = "SELECT b.{$mappingFields} FROM {$mappingRelationTable} AS a, ".$model->getTableName()." AS b WHERE a.{$mappingRelationFk} = b.{$model->getPk()} AND a.{$mappingCondition}"; - if(!empty($val['condition'])) { - $sql .= ' AND '.$val['condition']; - } - if(!empty($mappingOrder)) { - $sql .= ' ORDER BY '.$mappingOrder; + protected function getRelation(&$result, $name = '', $return = false) + { + if (!empty($this->_link)) { + foreach ($this->_link as $key => $val) { + $mappingName = !empty($val['mapping_name']) ? $val['mapping_name'] : $key; // 映射名称 + if (empty($name) || true === $name || $mappingName == $name || (is_array($name) && in_array($mappingName, $name))) { + $mappingType = !empty($val['mapping_type']) ? $val['mapping_type'] : $val; // 关联类型 + $mappingClass = !empty($val['class_name']) ? $val['class_name'] : $key; // 关联类名 + $mappingFields = !empty($val['mapping_fields']) ? $val['mapping_fields'] : '*'; // 映射字段 + $mappingCondition = !empty($val['condition']) ? $val['condition'] : '1=1'; // 关联条件 + $mappingKey = !empty($val['mapping_key']) ? $val['mapping_key'] : $this->getPk(); // 关联键名 + if (strtoupper($mappingClass) == strtoupper($this->name)) { + // 自引用关联 获取父键名 + $mappingFk = !empty($val['parent_key']) ? $val['parent_key'] : 'parent_id'; + } else { + $mappingFk = !empty($val['foreign_key']) ? $val['foreign_key'] : strtolower($this->name) . '_id'; // 关联外键 + } + // 获取关联模型对象 + $model = D($mappingClass); + switch ($mappingType) { + case self::HAS_ONE: + $pk = $result[$mappingKey]; + $mappingCondition .= " AND {$mappingFk}='{$pk}'"; + $relationData = $model->where($mappingCondition)->field($mappingFields)->find(); + if (!empty($val['relation_deep'])) { + $model->getRelation($relationData, $val['relation_deep']); + } + break; + case self::BELONGS_TO: + if (strtoupper($mappingClass) == strtoupper($this->name)) { + // 自引用关联 获取父键名 + $mappingFk = !empty($val['parent_key']) ? $val['parent_key'] : 'parent_id'; + } else { + $mappingFk = !empty($val['foreign_key']) ? $val['foreign_key'] : strtolower($model->getModelName()) . '_id'; // 关联外键 + } + $fk = $result[$mappingFk]; + $mappingCondition .= " AND {$model->getPk()}='{$fk}'"; + $relationData = $model->where($mappingCondition)->field($mappingFields)->find(); + if (!empty($val['relation_deep'])) { + $model->getRelation($relationData, $val['relation_deep']); + } + break; + case self::HAS_MANY: + $pk = $result[$mappingKey]; + $mappingCondition .= " AND {$mappingFk}='{$pk}'"; + $mappingOrder = !empty($val['mapping_order']) ? $val['mapping_order'] : ''; + $mappingLimit = !empty($val['mapping_limit']) ? $val['mapping_limit'] : ''; + // 延时获取关联记录 + $relationData = $model->where($mappingCondition)->field($mappingFields)->order($mappingOrder)->limit($mappingLimit)->select(); + if (!empty($val['relation_deep'])) { + foreach ($relationData as $key => $data) { + $model->getRelation($data, $val['relation_deep']); + $relationData[$key] = $data; } - if(!empty($mappingLimit)) { - $sql .= ' LIMIT '.$mappingLimit; + } + break; + case self::MANY_TO_MANY: + $pk = $result[$mappingKey]; + $prefix = $this->tablePrefix; + $mappingCondition = " {$mappingFk}='{$pk}'"; + $mappingOrder = $val['mapping_order']; + $mappingLimit = $val['mapping_limit']; + $mappingRelationFk = $val['relation_foreign_key'] ? $val['relation_foreign_key'] : $model->getModelName() . '_id'; + if (isset($val['relation_table'])) { + $mappingRelationTable = preg_replace_callback("/__([A-Z_-]+)__/sU", function ($match) use ($prefix) {return $prefix . strtolower($match[1]);}, $val['relation_table']); + } else { + $mappingRelationTable = $this->getRelationTableName($model); + } + $sql = "SELECT b.{$mappingFields} FROM {$mappingRelationTable} AS a, " . $model->getTableName() . " AS b WHERE a.{$mappingRelationFk} = b.{$model->getPk()} AND a.{$mappingCondition}"; + if (!empty($val['condition'])) { + $sql .= ' AND ' . $val['condition']; + } + if (!empty($mappingOrder)) { + $sql .= ' ORDER BY ' . $mappingOrder; + } + if (!empty($mappingLimit)) { + $sql .= ' LIMIT ' . $mappingLimit; + } + $relationData = $this->query($sql); + if (!empty($val['relation_deep'])) { + foreach ($relationData as $key => $data) { + $model->getRelation($data, $val['relation_deep']); + $relationData[$key] = $data; } - $relationData = $this->query($sql); - if (!empty($val['relation_deep'])){ - foreach($relationData as $key=>$data){ - $model->getRelation($data,$val['relation_deep']); - $relationData[$key] = $data; - } - } - break; - } - if(!$return){ - if(isset($val['as_fields']) && in_array($mappingType,array(self::HAS_ONE,self::BELONGS_TO)) ) { - // 支持直接把关联的字段值映射成数据对象中的某个字段 - // 仅仅支持HAS_ONE BELONGS_TO - $fields = explode(',',$val['as_fields']); - foreach ($fields as $field){ - if(strpos($field,':')) { - list($relationName,$nick) = explode(':',$field); - $result[$nick] = $relationData[$relationName]; - }else{ - $result[$field] = $relationData[$field]; - } + } + break; + } + if (!$return) { + if (isset($val['as_fields']) && in_array($mappingType, array(self::HAS_ONE, self::BELONGS_TO))) { + // 支持直接把关联的字段值映射成数据对象中的某个字段 + // 仅仅支持HAS_ONE BELONGS_TO + $fields = explode(',', $val['as_fields']); + foreach ($fields as $field) { + if (strpos($field, ':')) { + list($relationName, $nick) = explode(':', $field); + $result[$nick] = $relationData[$relationName]; + } else { + $result[$field] = $relationData[$field]; } - }else{ - $result[$mappingName] = $relationData; } - unset($relationData); - }else{ - return $relationData; + } else { + $result[$mappingName] = $relationData; } + unset($relationData); + } else { + return $relationData; } + } } } return $result; @@ -244,142 +267,155 @@ protected function getRelation(&$result,$name='',$return=false) { * @param string $name 关联名称 * @return mixed */ - protected function opRelation($opType,$data='',$name='') { - $result = false; - if(empty($data) && !empty($this->data)){ + protected function opRelation($opType, $data = '', $name = '') + { + $result = false; + if (empty($data) && !empty($this->data)) { $data = $this->data; - }elseif(!is_array($data)){ + } elseif (!is_array($data)) { // 数据无效返回 return false; } - if(!empty($this->_link)) { + if (!empty($this->_link)) { // 遍历关联定义 - foreach($this->_link as $key=>$val) { - // 操作制定关联类型 - $mappingName = $val['mapping_name']?$val['mapping_name']:$key; // 映射名称 - if(empty($name) || true === $name || $mappingName == $name || (is_array($name) && in_array($mappingName,$name)) ) { - // 操作制定的关联 - $mappingType = !empty($val['mapping_type'])?$val['mapping_type']:$val; // 关联类型 - $mappingClass = !empty($val['class_name'])?$val['class_name']:$key; // 关联类名 - $mappingKey =!empty($val['mapping_key'])? $val['mapping_key'] : $this->getPk(); // 关联键名 - // 当前数据对象主键值 - $pk = $data[$mappingKey]; - if(strtoupper($mappingClass)==strtoupper($this->name)) { - // 自引用关联 获取父键名 - $mappingFk = !empty($val['parent_key'])? $val['parent_key'] : 'parent_id'; - }else{ - $mappingFk = !empty($val['foreign_key'])?$val['foreign_key']:strtolower($this->name).'_id'; // 关联外键 - } - if(!empty($val['condition'])) { - $mappingCondition = $val['condition']; - }else{ - $mappingCondition = array(); - $mappingCondition[$mappingFk] = $pk; - } - // 获取关联model对象 - $model = D($mappingClass); - $mappingData = isset($data[$mappingName])?$data[$mappingName]:false; - if(!empty($mappingData) || $opType == 'DEL') { - switch($mappingType) { - case self::HAS_ONE: - switch (strtoupper($opType)){ - case 'ADD': // 增加关联数据 - $mappingData[$mappingFk] = $pk; - $result = $model->add($mappingData); + foreach ($this->_link as $key => $val) { + // 操作制定关联类型 + $mappingName = $val['mapping_name'] ? $val['mapping_name'] : $key; // 映射名称 + if (empty($name) || true === $name || $mappingName == $name || (is_array($name) && in_array($mappingName, $name))) { + // 操作制定的关联 + $mappingType = !empty($val['mapping_type']) ? $val['mapping_type'] : $val; // 关联类型 + $mappingClass = !empty($val['class_name']) ? $val['class_name'] : $key; // 关联类名 + $mappingKey = !empty($val['mapping_key']) ? $val['mapping_key'] : $this->getPk(); // 关联键名 + // 当前数据对象主键值 + $pk = $data[$mappingKey]; + if (strtoupper($mappingClass) == strtoupper($this->name)) { + // 自引用关联 获取父键名 + $mappingFk = !empty($val['parent_key']) ? $val['parent_key'] : 'parent_id'; + } else { + $mappingFk = !empty($val['foreign_key']) ? $val['foreign_key'] : strtolower($this->name) . '_id'; // 关联外键 + } + if (!empty($val['condition'])) { + $mappingCondition = $val['condition']; + } else { + $mappingCondition = array(); + $mappingCondition[$mappingFk] = $pk; + } + // 获取关联model对象 + $model = D($mappingClass); + $mappingData = isset($data[$mappingName]) ? $data[$mappingName] : false; + if (!empty($mappingData) || 'DEL' == $opType) { + switch ($mappingType) { + case self::HAS_ONE: + switch (strtoupper($opType)) { + case 'ADD': // 增加关联数据 + $mappingData[$mappingFk] = $pk; + $result = $model->add($mappingData); break; - case 'SAVE': // 更新关联数据 - $result = $model->where($mappingCondition)->save($mappingData); + case 'SAVE': // 更新关联数据 + $result = $model->where($mappingCondition)->save($mappingData); break; - case 'DEL': // 根据外键删除关联数据 - $result = $model->where($mappingCondition)->delete(); + case 'DEL': // 根据外键删除关联数据 + $result = $model->where($mappingCondition)->delete(); break; - } - break; - case self::BELONGS_TO: - break; - case self::HAS_MANY: - switch (strtoupper($opType)){ - case 'ADD' : // 增加关联数据 + } + break; + case self::BELONGS_TO: + break; + case self::HAS_MANY: + switch (strtoupper($opType)) { + case 'ADD': // 增加关联数据 $model->startTrans(); - foreach ($mappingData as $val){ - $val[$mappingFk] = $pk; - $result = $model->add($val); + foreach ($mappingData as $val) { + $val[$mappingFk] = $pk; + $result = $model->add($val); } $model->commit(); break; - case 'SAVE' : // 更新关联数据 + case 'SAVE': // 更新关联数据 $model->startTrans(); - $pk = $model->getPk(); - foreach ($mappingData as $vo){ - if(isset($vo[$pk])) {// 更新数据 - $mappingCondition = "$pk ={$vo[$pk]}"; - $result = $model->where($mappingCondition)->save($vo); - }else{ // 新增数据 - $vo[$mappingFk] = $data[$mappingKey]; - $result = $model->add($vo); + $pk = $model->getPk(); + foreach ($mappingData as $vo) { + if (isset($vo[$pk])) { +// 更新数据 + $mappingCondition = "$pk ={$vo[$pk]}"; + $result = $model->where($mappingCondition)->save($vo); + } else { + // 新增数据 + $vo[$mappingFk] = $data[$mappingKey]; + $result = $model->add($vo); } } $model->commit(); break; - case 'DEL' : // 删除关联数据 - $result = $model->where($mappingCondition)->delete(); + case 'DEL': // 删除关联数据 + $result = $model->where($mappingCondition)->delete(); break; + } + break; + case self::MANY_TO_MANY: + $mappingRelationFk = $val['relation_foreign_key'] ? $val['relation_foreign_key'] : $model->getModelName() . '_id'; // 关联 + $prefix = $this->tablePrefix; + if (isset($val['relation_table'])) { + $mappingRelationTable = preg_replace_callback("/__([A-Z_-]+)__/sU", function ($match) use ($prefix) {return $prefix . strtolower($match[1]);}, $val['relation_table']); + } else { + $mappingRelationTable = $this->getRelationTableName($model); + } + if (is_array($mappingData)) { + $ids = array(); + foreach ($mappingData as $vo) { + $ids[] = $vo[$mappingKey]; } - break; - case self::MANY_TO_MANY: - $mappingRelationFk = $val['relation_foreign_key']?$val['relation_foreign_key']:$model->getModelName().'_id';// 关联 - $prefix = $this->tablePrefix; - if(isset($val['relation_table'])){ - $mappingRelationTable = preg_replace_callback("/__([A-Z_-]+)__/sU", function($match) use($prefix){ return $prefix.strtolower($match[1]);}, $val['relation_table']); - }else{ - $mappingRelationTable = $this->getRelationTableName($model); - } - if(is_array($mappingData)) { - $ids = array(); - foreach ($mappingData as $vo) - $ids[] = $vo[$mappingKey]; - $relationId = implode(',',$ids); - } - switch (strtoupper($opType)){ - case 'ADD': // 增加关联数据 - if(isset($relationId)) { - $this->startTrans(); - // 插入关联表数据 - $sql = 'INSERT INTO '.$mappingRelationTable.' ('.$mappingFk.','.$mappingRelationFk.') SELECT a.'.$this->getPk().',b.'.$model->getPk().' FROM '.$this->getTableName().' AS a ,'.$model->getTableName()." AS b where a.".$this->getPk().' ='. $pk.' AND b.'.$model->getPk().' IN ('.$relationId.") "; - $result = $model->execute($sql); - if(false !== $result) - // 提交事务 - $this->commit(); - else - // 事务回滚 - $this->rollback(); + + $relationId = implode(',', $ids); + } + switch (strtoupper($opType)) { + case 'ADD': // 增加关联数据 + if (isset($relationId)) { + $this->startTrans(); + // 插入关联表数据 + $sql = 'INSERT INTO ' . $mappingRelationTable . ' (' . $mappingFk . ',' . $mappingRelationFk . ') SELECT a.' . $this->getPk() . ',b.' . $model->getPk() . ' FROM ' . $this->getTableName() . ' AS a ,' . $model->getTableName() . " AS b where a." . $this->getPk() . ' =' . $pk . ' AND b.' . $model->getPk() . ' IN (' . $relationId . ") "; + $result = $model->execute($sql); + if (false !== $result) + // 提交事务 + { + $this->commit(); + } else + // 事务回滚 + { + $this->rollback(); } - break; - case 'SAVE': // 更新关联数据 - if(isset($relationId)) { - $this->startTrans(); - // 删除关联表数据 - $this->table($mappingRelationTable)->where($mappingCondition)->delete(); - // 插入关联表数据 - $sql = 'INSERT INTO '.$mappingRelationTable.' ('.$mappingFk.','.$mappingRelationFk.') SELECT a.'.$this->getPk().',b.'.$model->getPk().' FROM '.$this->getTableName().' AS a ,'.$model->getTableName()." AS b where a.".$this->getPk().' ='. $pk.' AND b.'.$model->getPk().' IN ('.$relationId.") "; - $result = $model->execute($sql); - if(false !== $result) - // 提交事务 - $this->commit(); - else - // 事务回滚 - $this->rollback(); + + } + break; + case 'SAVE': // 更新关联数据 + if (isset($relationId)) { + $this->startTrans(); + // 删除关联表数据 + $this->table($mappingRelationTable)->where($mappingCondition)->delete(); + // 插入关联表数据 + $sql = 'INSERT INTO ' . $mappingRelationTable . ' (' . $mappingFk . ',' . $mappingRelationFk . ') SELECT a.' . $this->getPk() . ',b.' . $model->getPk() . ' FROM ' . $this->getTableName() . ' AS a ,' . $model->getTableName() . " AS b where a." . $this->getPk() . ' =' . $pk . ' AND b.' . $model->getPk() . ' IN (' . $relationId . ") "; + $result = $model->execute($sql); + if (false !== $result) + // 提交事务 + { + $this->commit(); + } else + // 事务回滚 + { + $this->rollback(); } - break; - case 'DEL': // 根据外键删除中间表关联数据 - $result = $this->table($mappingRelationTable)->where($mappingCondition)->delete(); - break; - } - break; - } - if (!empty($val['relation_deep'])){ - $model->opRelation($opType,$mappingData,$val['relation_deep']); - } + + } + break; + case 'DEL': // 根据外键删除中间表关联数据 + $result = $this->table($mappingRelationTable)->where($mappingCondition)->delete(); + break; + } + break; + } + if (!empty($val['relation_deep'])) { + $model->opRelation($opType, $mappingData, $val['relation_deep']); + } } } } @@ -393,8 +429,9 @@ protected function opRelation($opType,$data='',$name='') { * @param mixed $name 关联名称 * @return Model */ - public function relation($name) { - $this->options['link'] = $name; + public function relation($name) + { + $this->options['link'] = $name; return $this; } @@ -404,9 +441,12 @@ public function relation($name) { * @param string $name 关联名称 * @return array */ - public function relationGet($name) { - if(empty($this->data)) + public function relationGet($name) + { + if (empty($this->data)) { return false; - return $this->getRelation($this->data,$name,true); + } + + return $this->getRelation($this->data, $name, true); } -} \ No newline at end of file +} diff --git a/ThinkPHP/Library/Think/Model/ViewModel.class.php b/ThinkPHP/Library/Think/Model/ViewModel.class.php index 692874ee7..bfc494435 100644 --- a/ThinkPHP/Library/Think/Model/ViewModel.class.php +++ b/ThinkPHP/Library/Think/Model/ViewModel.class.php @@ -9,11 +9,14 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think\Model; + use Think\Model; + /** - * ThinkPHP视图模型扩展 + * ThinkPHP视图模型扩展 */ -class ViewModel extends Model { +class ViewModel extends Model +{ protected $viewFields = array(); @@ -22,38 +25,41 @@ class ViewModel extends Model { * @access protected * @return void */ - protected function _checkTableInfo() {} + protected function _checkTableInfo() + {} /** * 得到完整的数据表名 * @access public * @return string */ - public function getTableName() { - if(empty($this->trueTableName)) { + public function getTableName() + { + if (empty($this->trueTableName)) { $tableName = ''; - foreach ($this->viewFields as $key=>$view){ + foreach ($this->viewFields as $key => $view) { // 获取数据表名称 - if(isset($view['_table'])) { // 2011/10/17 添加实际表名定义支持 可以实现同一个表的视图 - $tableName .= $view['_table']; - $prefix = $this->tablePrefix; - $tableName = preg_replace_callback("/__([A-Z_-]+)__/sU", function($match) use($prefix){ return $prefix.strtolower($match[1]);}, $tableName); - }else{ - $class = $key.'Model'; - $Model = class_exists($class)?new $class():M($key); + if (isset($view['_table'])) { + // 2011/10/17 添加实际表名定义支持 可以实现同一个表的视图 + $tableName .= $view['_table']; + $prefix = $this->tablePrefix; + $tableName = preg_replace_callback("/__([A-Z_-]+)__/sU", function ($match) use ($prefix) {return $prefix . strtolower($match[1]);}, $tableName); + } else { + $class = $key . 'Model'; + $Model = class_exists($class) ? new $class() : M($key); $tableName .= $Model->getTableName(); } // 表别名定义 - $tableName .= !empty($view['_as'])?' '.$view['_as']:' '.$key; + $tableName .= !empty($view['_as']) ? ' ' . $view['_as'] : ' ' . $key; // 支持ON 条件定义 - $tableName .= !empty($view['_on'])?' ON '.$view['_on']:''; + $tableName .= !empty($view['_on']) ? ' ON ' . $view['_on'] : ''; // 指定JOIN类型 例如 RIGHT INNER LEFT 下一个表有效 - $type = !empty($view['_type'])?$view['_type']:''; - $tableName .= ' '.strtoupper($type).' JOIN '; - $len = strlen($type.'_JOIN '); + $type = !empty($view['_type']) ? $view['_type'] : ''; + $tableName .= ' ' . strtoupper($type) . ' JOIN '; + $len = strlen($type . '_JOIN '); } - $tableName = substr($tableName,0,-$len); - $this->trueTableName = $tableName; + $tableName = substr($tableName, 0, -$len); + $this->trueTableName = $tableName; } return $this->trueTableName; } @@ -64,17 +70,26 @@ public function getTableName() { * @param string $options 表达式 * @return void */ - protected function _options_filter(&$options) { - if(isset($options['field'])) + protected function _options_filter(&$options) + { + if (isset($options['field'])) { $options['field'] = $this->checkFields($options['field']); - else + } else { $options['field'] = $this->checkFields(); - if(isset($options['group'])) - $options['group'] = $this->checkGroup($options['group']); - if(isset($options['where'])) - $options['where'] = $this->checkCondition($options['where']); - if(isset($options['order'])) - $options['order'] = $this->checkOrder($options['order']); + } + + if (isset($options['group'])) { + $options['group'] = $this->checkGroup($options['group']); + } + + if (isset($options['where'])) { + $options['where'] = $this->checkCondition($options['where']); + } + + if (isset($options['order'])) { + $options['order'] = $this->checkOrder($options['order']); + } + } /** @@ -84,9 +99,11 @@ protected function _options_filter(&$options) { * @param array $fields 字段数组 * @return array */ - private function _checkFields($name,$fields) { - if(false !== $pos = array_search('*',$fields)) {// 定义所有字段 - $fields = array_merge($fields,M($name)->getDbFields()); + private function _checkFields($name, $fields) + { + if (false !== $pos = array_search('*', $fields)) { +// 定义所有字段 + $fields = array_merge($fields, M($name)->getDbFields()); unset($fields[$pos]); } return $fields; @@ -98,24 +115,25 @@ private function _checkFields($name,$fields) { * @param mixed $data 条件表达式 * @return array */ - protected function checkCondition($where) { - if(is_array($where)) { - $view = array(); + protected function checkCondition($where) + { + if (is_array($where)) { + $view = array(); // 检查视图字段 - foreach ($this->viewFields as $key=>$val){ - $k = isset($val['_as'])?$val['_as']:$key; - $val = $this->_checkFields($key,$val); - foreach ($where as $name=>$value){ - if(false !== $field = array_search($name,$val,true)) { + foreach ($this->viewFields as $key => $val) { + $k = isset($val['_as']) ? $val['_as'] : $key; + $val = $this->_checkFields($key, $val); + foreach ($where as $name => $value) { + if (false !== $field = array_search($name, $val, true)) { // 存在视图字段 - $_key = is_numeric($field)? $k.'.'.$name : $k.'.'.$field; - $view[$_key] = $value; + $_key = is_numeric($field) ? $k . '.' . $name : $k . '.' . $field; + $view[$_key] = $value; unset($where[$name]); } } } - $where = array_merge($where,$view); - } + $where = array_merge($where, $view); + } return $where; } @@ -125,28 +143,29 @@ protected function checkCondition($where) { * @param string $order 字段 * @return string */ - protected function checkOrder($order='') { - if(is_string($order) && !empty($order)) { - $orders = explode(',',$order); + protected function checkOrder($order = '') + { + if (is_string($order) && !empty($order)) { + $orders = explode(',', $order); $_order = array(); - foreach ($orders as $order){ - $array = explode(' ',trim($order)); - $field = $array[0]; - $sort = isset($array[1])?$array[1]:'ASC'; + foreach ($orders as $order) { + $array = explode(' ', trim($order)); + $field = $array[0]; + $sort = isset($array[1]) ? $array[1] : 'ASC'; // 解析成视图字段 - foreach ($this->viewFields as $name=>$val){ - $k = isset($val['_as'])?$val['_as']:$name; - $val = $this->_checkFields($name,$val); - if(false !== $_field = array_search($field,$val,true)) { + foreach ($this->viewFields as $name => $val) { + $k = isset($val['_as']) ? $val['_as'] : $name; + $val = $this->_checkFields($name, $val); + if (false !== $_field = array_search($field, $val, true)) { // 存在视图字段 - $field = is_numeric($_field)?$k.'.'.$field:$k.'.'.$_field; + $field = is_numeric($_field) ? $k . '.' . $field : $k . '.' . $_field; break; } } - $_order[] = $field.' '.$sort; + $_order[] = $field . ' ' . $sort; } - $order = implode(',',$_order); - } + $order = implode(',', $_order); + } return $order; } @@ -156,25 +175,26 @@ protected function checkOrder($order='') { * @param string $group 字段 * @return string */ - protected function checkGroup($group='') { - if(!empty($group)) { - $groups = explode(',',$group); + protected function checkGroup($group = '') + { + if (!empty($group)) { + $groups = explode(',', $group); $_group = array(); - foreach ($groups as $field){ + foreach ($groups as $field) { // 解析成视图字段 - foreach ($this->viewFields as $name=>$val){ - $k = isset($val['_as'])?$val['_as']:$name; - $val = $this->_checkFields($name,$val); - if(false !== $_field = array_search($field,$val,true)) { + foreach ($this->viewFields as $name => $val) { + $k = isset($val['_as']) ? $val['_as'] : $name; + $val = $this->_checkFields($name, $val); + if (false !== $_field = array_search($field, $val, true)) { // 存在视图字段 - $field = is_numeric($_field)?$k.'.'.$field:$k.'.'.$_field; + $field = is_numeric($_field) ? $k . '.' . $field : $k . '.' . $_field; break; } } $_group[] = $field; } - $group = implode(',',$_group); - } + $group = implode(',', $_group); + } return $group; } @@ -184,60 +204,66 @@ protected function checkGroup($group='') { * @param string $fields 字段 * @return string */ - protected function checkFields($fields='') { - if(empty($fields) || '*'==$fields ) { + protected function checkFields($fields = '') + { + if (empty($fields) || '*' == $fields) { // 获取全部视图字段 - $fields = array(); - foreach ($this->viewFields as $name=>$val){ - $k = isset($val['_as'])?$val['_as']:$name; - $val = $this->_checkFields($name,$val); - foreach ($val as $key=>$field){ - if(is_numeric($key)) { - $fields[] = $k.'.'.$field.' AS '.$field; - }elseif('_' != substr($key,0,1)) { + $fields = array(); + foreach ($this->viewFields as $name => $val) { + $k = isset($val['_as']) ? $val['_as'] : $name; + $val = $this->_checkFields($name, $val); + foreach ($val as $key => $field) { + if (is_numeric($key)) { + $fields[] = $k . '.' . $field . ' AS ' . $field; + } elseif ('_' != substr($key, 0, 1)) { // 以_开头的为特殊定义 - if( false !== strpos($key,'*') || false !== strpos($key,'(') || false !== strpos($key,'.')) { + if (false !== strpos($key, '*') || false !== strpos($key, '(') || false !== strpos($key, '.')) { //如果包含* 或者 使用了sql方法 则不再添加前面的表名 - $fields[] = $key.' AS '.$field; - }else{ - $fields[] = $k.'.'.$key.' AS '.$field; + $fields[] = $key . ' AS ' . $field; + } else { + $fields[] = $k . '.' . $key . ' AS ' . $field; } } } } - $fields = implode(',',$fields); - }else{ - if(!is_array($fields)) - $fields = explode(',',$fields); + $fields = implode(',', $fields); + } else { + if (!is_array($fields)) { + $fields = explode(',', $fields); + } + // 解析成视图字段 - $array = array(); - foreach ($fields as $key=>$field){ - if(strpos($field,'(') || strpos(strtolower($field),' as ')){ + $array = array(); + foreach ($fields as $key => $field) { + if (strpos($field, '(') || strpos(strtolower($field), ' as ')) { // 使用了函数或者别名 - $array[] = $field; + $array[] = $field; unset($fields[$key]); } } - foreach ($this->viewFields as $name=>$val){ - $k = isset($val['_as'])?$val['_as']:$name; - $val = $this->_checkFields($name,$val); - foreach ($fields as $key=>$field){ - if(false !== $_field = array_search($field,$val,true)) { + foreach ($this->viewFields as $name => $val) { + $k = isset($val['_as']) ? $val['_as'] : $name; + $val = $this->_checkFields($name, $val); + foreach ($fields as $key => $field) { + if (false !== $_field = array_search($field, $val, true)) { // 存在视图字段 - if(is_numeric($_field)) { - $array[] = $k.'.'.$field.' AS '.$field; - }elseif('_' != substr($_field,0,1)){ - if( false !== strpos($_field,'*') || false !== strpos($_field,'(') || false !== strpos($_field,'.')) - //如果包含* 或者 使用了sql方法 则不再添加前面的表名 - $array[] = $_field.' AS '.$field; - else - $array[] = $k.'.'.$_field.' AS '.$field; + if (is_numeric($_field)) { + $array[] = $k . '.' . $field . ' AS ' . $field; + } elseif ('_' != substr($_field, 0, 1)) { + if (false !== strpos($_field, '*') || false !== strpos($_field, '(') || false !== strpos($_field, '.')) + //如果包含* 或者 使用了sql方法 则不再添加前面的表名 + { + $array[] = $_field . ' AS ' . $field; + } else { + $array[] = $k . '.' . $_field . ' AS ' . $field; + } + } } } } - $fields = implode(',',$array); + $fields = implode(',', $array); } return $fields; } -} \ No newline at end of file +} diff --git a/ThinkPHP/Library/Think/Page.class.php b/ThinkPHP/Library/Think/Page.class.php index 7d85addb7..bf3d539db 100644 --- a/ThinkPHP/Library/Think/Page.class.php +++ b/ThinkPHP/Library/Think/Page.class.php @@ -10,20 +10,21 @@ // +---------------------------------------------------------------------- namespace Think; -class Page{ +class Page +{ public $firstRow; // 起始行数 public $listRows; // 列表每页显示行数 public $parameter; // 分页跳转时要带的参数 public $totalRows; // 总行数 public $totalPages; // 分页总页面数 - public $rollPage = 11;// 分页栏每页显示的页数 + public $rollPage = 11; // 分页栏每页显示的页数 private $p = 'p'; //分页参数名 private $url = ''; //当前链接URL private $nowPage = 1; - // 分页显示定制 - private $config = array( + // 分页显示定制 + private $config = array( 'header' => '共 %TOTAL_ROW% 条记录', 'prev' => '<<', 'next' => '>>', @@ -38,15 +39,16 @@ class Page{ * @param array $listRows 每页显示记录数 * @param array $parameter 分页跳转的参数 */ - public function __construct($totalRows, $listRows=20, $parameter = array()) { + public function __construct($totalRows, $listRows = 20, $parameter = array()) + { C('VAR_PAGE') && $this->p = C('VAR_PAGE'); //设置分页参数名称 /* 基础设置 */ - $this->totalRows = $totalRows; //设置总记录数 - $this->listRows = $listRows; //设置每页显示行数 - $this->parameter = empty($parameter) ? $_GET : $parameter; - $this->nowPage = empty($_GET[$this->p]) ? 1 : intval($_GET[$this->p]); - $this->nowPage = $this->nowPage>0 ? $this->nowPage : 1; - $this->firstRow = $this->listRows * ($this->nowPage - 1); + $this->totalRows = $totalRows; //设置总记录数 + $this->listRows = $listRows; //设置每页显示行数 + $this->parameter = empty($parameter) ? $_GET : $parameter; + $this->nowPage = empty($_GET[$this->p]) ? 1 : intval($_GET[$this->p]); + $this->nowPage = $this->nowPage > 0 ? $this->nowPage : 1; + $this->firstRow = $this->listRows * ($this->nowPage - 1); } /** @@ -54,8 +56,9 @@ public function __construct($totalRows, $listRows=20, $parameter = array()) { * @param string $name 设置名称 * @param string $value 设置值 */ - public function setConfig($name,$value) { - if(isset($this->config[$name])) { + public function setConfig($name, $value) + { + if (isset($this->config[$name])) { $this->config[$name] = $value; } } @@ -65,7 +68,8 @@ public function setConfig($name,$value) { * @param integer $page 页码 * @return string */ - private function url($page){ + private function url($page) + { return str_replace(urlencode('[PAGE]'), $page, $this->url); } @@ -73,21 +77,24 @@ private function url($page){ * 组装分页链接 * @return string */ - public function show() { - if(0 == $this->totalRows) return ''; + public function show() + { + if (0 == $this->totalRows) { + return ''; + } /* 生成URL */ $this->parameter[$this->p] = '[PAGE]'; - $this->url = U(ACTION_NAME, $this->parameter); + $this->url = U(ACTION_NAME, $this->parameter); /* 计算分页信息 */ $this->totalPages = ceil($this->totalRows / $this->listRows); //总页数 - if(!empty($this->totalPages) && $this->nowPage > $this->totalPages) { + if (!empty($this->totalPages) && $this->nowPage > $this->totalPages) { $this->nowPage = $this->totalPages; } /* 计算分页临时变量 */ - $now_cool_page = $this->rollPage/2; - $now_cool_page_ceil = ceil($now_cool_page); + $now_cool_page = $this->rollPage / 2; + $now_cool_page_ceil = ceil($now_cool_page); //上一页 $up_row = $this->nowPage - 1; @@ -99,35 +106,35 @@ public function show() { //第一页 $the_first = ''; - if($this->totalPages > $this->rollPage && ($this->nowPage - $now_cool_page) >= 1){ + if ($this->totalPages > $this->rollPage && ($this->nowPage - $now_cool_page) >= 1) { $the_first = '' . $this->config['first'] . ''; } //最后一页 $the_end = ''; - if($this->totalPages > $this->rollPage && ($this->nowPage + $now_cool_page) < $this->totalPages){ + if ($this->totalPages > $this->rollPage && ($this->nowPage + $now_cool_page) < $this->totalPages) { $the_end = '' . $this->config['last'] . ''; } //数字连接 $link_page = ""; - for($i = 1; $i <= $this->rollPage; $i++){ - if(($this->nowPage - $now_cool_page) <= 0 ){ - $page = $i; - }elseif(($this->nowPage + $now_cool_page - 1) >= $this->totalPages){ - $page = $this->totalPages - $this->rollPage + $i; - }else{ - $page = $this->nowPage - $now_cool_page_ceil + $i; - } - if($page > 0 && $page != $this->nowPage){ - - if($page <= $this->totalPages){ + for ($i = 1; $i <= $this->rollPage; $i++) { + if (($this->nowPage - $now_cool_page) <= 0) { + $page = $i; + } elseif (($this->nowPage + $now_cool_page - 1) >= $this->totalPages) { + $page = $this->totalPages - $this->rollPage + $i; + } else { + $page = $this->nowPage - $now_cool_page_ceil + $i; + } + if ($page > 0 && $page != $this->nowPage) { + + if ($page <= $this->totalPages) { $link_page .= '' . $page . ''; - }else{ + } else { break; } - }else{ - if($page > 0 && $this->totalPages != 1){ + } else { + if ($page > 0 && 1 != $this->totalPages) { $link_page .= '' . $page . ''; } } diff --git a/ThinkPHP/Library/Think/Route.class.php b/ThinkPHP/Library/Think/Route.class.php index c1bf8a53c..bdbd42817 100644 --- a/ThinkPHP/Library/Think/Route.class.php +++ b/ThinkPHP/Library/Think/Route.class.php @@ -9,81 +9,87 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think; + /** * ThinkPHP路由解析类 */ -class Route { - +class Route +{ + // 路由检测 - public static function check(){ - $depr = C('URL_PATHINFO_DEPR'); - $regx = preg_replace('/\.'.__EXT__.'$/i','',trim($_SERVER['PATH_INFO'],$depr)); + public static function check() + { + $depr = C('URL_PATHINFO_DEPR'); + $regx = preg_replace('/\.' . __EXT__ . '$/i', '', trim($_SERVER['PATH_INFO'], $depr)); // 分隔符替换 确保路由定义使用统一的分隔符 - if('/' != $depr){ - $regx = str_replace($depr,'/',$regx); + if ('/' != $depr) { + $regx = str_replace($depr, '/', $regx); } // URL映射定义(静态路由) - $maps = C('URL_MAP_RULES'); - if(isset($maps[$regx])) { - $var = self::parseUrl($maps[$regx]); - $_GET = array_merge($var, $_GET); - return true; - } + $maps = C('URL_MAP_RULES'); + if (isset($maps[$regx])) { + $var = self::parseUrl($maps[$regx]); + $_GET = array_merge($var, $_GET); + return true; + } // 动态路由处理 - $routes = C('URL_ROUTE_RULES'); - if(!empty($routes)) { - foreach ($routes as $rule=>$route){ - if(is_numeric($rule)){ + $routes = C('URL_ROUTE_RULES'); + if (!empty($routes)) { + foreach ($routes as $rule => $route) { + if (is_numeric($rule)) { // 支持 array('rule','adddress',...) 定义路由 - $rule = array_shift($route); + $rule = array_shift($route); } - if(is_array($route) && isset($route[2])){ + if (is_array($route) && isset($route[2])) { // 路由参数 - $options = $route[2]; - if(isset($options['ext']) && __EXT__ != $options['ext']){ + $options = $route[2]; + if (isset($options['ext']) && __EXT__ != $options['ext']) { // URL后缀检测 continue; } - if(isset($options['method']) && REQUEST_METHOD != strtoupper($options['method'])){ + if (isset($options['method']) && REQUEST_METHOD != strtoupper($options['method'])) { // 请求类型检测 continue; } // 自定义检测 - if(!empty($options['callback']) && is_callable($options['callback'])) { - if(false === call_user_func($options['callback'])) { + if (!empty($options['callback']) && is_callable($options['callback'])) { + if (false === call_user_func($options['callback'])) { continue; } - } + } } - if(0===strpos($rule,'/') && preg_match($rule,$regx,$matches)) { // 正则路由 - if($route instanceof \Closure) { + if (0 === strpos($rule, '/') && preg_match($rule, $regx, $matches)) { + // 正则路由 + if ($route instanceof \Closure) { // 执行闭包 $result = self::invokeRegx($route, $matches); // 如果返回布尔值 则继续执行 return is_bool($result) ? $result : exit; - }else{ - return self::parseRegex($matches,$route,$regx); + } else { + return self::parseRegex($matches, $route, $regx); } - }else{ // 规则路由 - $len1 = substr_count($regx,'/'); - $len2 = substr_count($rule,'/'); - if($len1>=$len2 || strpos($rule,'[')) { - if('$' == substr($rule,-1,1)) {// 完整匹配 - if($len1 != $len2) { + } else { + // 规则路由 + $len1 = substr_count($regx, '/'); + $len2 = substr_count($rule, '/'); + if ($len1 >= $len2 || strpos($rule, '[')) { + if ('$' == substr($rule, -1, 1)) { +// 完整匹配 + if ($len1 != $len2) { continue; - }else{ - $rule = substr($rule,0,-1); + } else { + $rule = substr($rule, 0, -1); } } - $match = self::checkUrlMatch($regx,$rule); - if(false !== $match) { - if($route instanceof \Closure) { + $match = self::checkUrlMatch($regx, $rule); + if (false !== $match) { + if ($route instanceof \Closure) { // 执行闭包 $result = self::invokeRule($route, $match); // 如果返回布尔值 则继续执行 return is_bool($result) ? $result : exit; - }else{ - return self::parseRule($rule,$route,$regx); + } else { + return self::parseRule($rule, $route, $regx); } } } @@ -94,38 +100,42 @@ public static function check(){ } // 检测URL和规则路由是否匹配 - private static function checkUrlMatch($regx,$rule) { - $m1 = explode('/',$regx); - $m2 = explode('/',$rule); - $var = array(); - foreach ($m2 as $key=>$val){ - if(0 === strpos($val,'[:')){ - $val = substr($val,1,-1); + private static function checkUrlMatch($regx, $rule) + { + $m1 = explode('/', $regx); + $m2 = explode('/', $rule); + $var = array(); + foreach ($m2 as $key => $val) { + if (0 === strpos($val, '[:')) { + $val = substr($val, 1, -1); } - - if(':' == substr($val,0,1)) {// 动态变量 - if($pos = strpos($val,'|')){ + + if (':' == substr($val, 0, 1)) { +// 动态变量 + if ($pos = strpos($val, '|')) { // 使用函数过滤 - $val = substr($val,1,$pos-1); + $val = substr($val, 1, $pos - 1); } - if(strpos($val,'\\')) { - $type = substr($val,-1); - if('d'==$type) { - if(isset($m1[$key]) && !is_numeric($m1[$key])) + if (strpos($val, '\\')) { + $type = substr($val, -1); + if ('d' == $type) { + if (isset($m1[$key]) && !is_numeric($m1[$key])) { return false; + } + } $name = substr($val, 1, -2); - }elseif($pos = strpos($val,'^')){ - $array = explode('-',substr(strstr($val,'^'),1)); - if(in_array($m1[$key],$array)) { + } elseif ($pos = strpos($val, '^')) { + $array = explode('-', substr(strstr($val, '^'), 1)); + if (in_array($m1[$key], $array)) { return false; } $name = substr($val, 1, $pos - 1); - }else{ + } else { $name = substr($val, 1); } - $var[$name] = isset($m1[$key])?$m1[$key]:''; - }elseif(0 !== strcasecmp($val,$m1[$key])){ + $var[$name] = isset($m1[$key]) ? $m1[$key] : ''; + } elseif (0 !== strcasecmp($val, $m1[$key])) { return false; } } @@ -135,24 +145,28 @@ private static function checkUrlMatch($regx,$rule) { // 解析规范的路由地址 // 地址格式 [控制器/操作?]参数1=值1&参数2=值2... - private static function parseUrl($url) { - $var = array(); - if(false !== strpos($url,'?')) { // [控制器/操作?]参数1=值1&参数2=值2... - $info = parse_url($url); - $path = explode('/',$info['path']); - parse_str($info['query'],$var); - }elseif(strpos($url,'/')){ // [控制器/操作] - $path = explode('/',$url); - }else{ // 参数1=值1&参数2=值2... - parse_str($url,$var); + private static function parseUrl($url) + { + $var = array(); + if (false !== strpos($url, '?')) { + // [控制器/操作?]参数1=值1&参数2=值2... + $info = parse_url($url); + $path = explode('/', $info['path']); + parse_str($info['query'], $var); + } elseif (strpos($url, '/')) { + // [控制器/操作] + $path = explode('/', $url); + } else { + // 参数1=值1&参数2=值2... + parse_str($url, $var); } - if(isset($path)) { + if (isset($path)) { $var[C('VAR_ACTION')] = array_pop($path); - if(!empty($path)) { + if (!empty($path)) { $var[C('VAR_CONTROLLER')] = array_pop($path); } - if(!empty($path)) { - $var[C('VAR_MODULE')] = array_pop($path); + if (!empty($path)) { + $var[C('VAR_MODULE')] = array_pop($path); } } return $var; @@ -167,70 +181,74 @@ private static function parseUrl($url) { // 外部地址中可以用动态变量 采用 :1 :2 的方式 // 'news/:month/:day/:id'=>array('News/read?cate=1','status=1'), // 'new/:id'=>array('/new.php?id=:1',301), 重定向 - private static function parseRule($rule,$route,$regx) { + private static function parseRule($rule, $route, $regx) + { // 获取路由地址规则 - $url = is_array($route)?$route[0]:$route; + $url = is_array($route) ? $route[0] : $route; // 获取URL地址中的参数 - $paths = explode('/',$regx); + $paths = explode('/', $regx); // 解析路由规则 - $matches = array(); - $rule = explode('/',$rule); - foreach ($rule as $item){ - $fun = ''; - if(0 === strpos($item,'[:')){ - $item = substr($item,1,-1); + $matches = array(); + $rule = explode('/', $rule); + foreach ($rule as $item) { + $fun = ''; + if (0 === strpos($item, '[:')) { + $item = substr($item, 1, -1); } - if(0===strpos($item,':')) { // 动态变量获取 - if($pos = strpos($item,'|')){ + if (0 === strpos($item, ':')) { + // 动态变量获取 + if ($pos = strpos($item, '|')) { // 支持函数过滤 - $fun = substr($item,$pos+1); - $item = substr($item,0,$pos); + $fun = substr($item, $pos + 1); + $item = substr($item, 0, $pos); } - if($pos = strpos($item,'^') ) { - $var = substr($item,1,$pos-1); - }elseif(strpos($item,'\\')){ - $var = substr($item,1,-2); - }else{ - $var = substr($item,1); + 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] = !empty($fun)? $fun(array_shift($paths)) : array_shift($paths); - }else{ // 过滤URL中的静态变量 + $matches[$var] = !empty($fun) ? $fun(array_shift($paths)) : array_shift($paths); + } else { + // 过滤URL中的静态变量 array_shift($paths); } } - if(0=== strpos($url,'/') || 0===strpos($url,'http')) { // 路由重定向跳转 - if(strpos($url,':')) { // 传递动态参数 + if (0 === strpos($url, '/') || 0 === strpos($url, 'http')) { + // 路由重定向跳转 + if (strpos($url, ':')) { // 传递动态参数 $values = array_values($matches); - $url = preg_replace_callback('/:(\d+)/', function($match) use($values){ return $values[$match[1] - 1]; }, $url); + $url = preg_replace_callback('/:(\d+)/', function ($match) use ($values) {return $values[$match[1] - 1];}, $url); } - header("Location: $url", true,(is_array($route) && isset($route[1]))?$route[1]:301); + header("Location: $url", true, (is_array($route) && isset($route[1])) ? $route[1] : 301); exit; - }else{ + } else { // 解析路由地址 - $var = self::parseUrl($url); + $var = self::parseUrl($url); // 解析路由地址里面的动态参数 - $values = array_values($matches); - foreach ($var as $key=>$val){ - if(0===strpos($val,':')) { - $var[$key] = $values[substr($val,1)-1]; + $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); + $var = array_merge($matches, $var); // 解析剩余的URL参数 - if(!empty($paths)) { - preg_replace_callback('/(\w+)\/([^\/]+)/', function($match) use(&$var){ $var[strtolower($match[1])]=strip_tags($match[2]);}, implode('/',$paths)); + if (!empty($paths)) { + preg_replace_callback('/(\w+)\/([^\/]+)/', function ($match) use (&$var) {$var[strtolower($match[1])] = strip_tags($match[2]);}, implode('/', $paths)); } // 解析路由自动传入参数 - if(is_array($route) && isset($route[1])) { - if(is_array($route[1])){ - $params = $route[1]; - }else{ - parse_str($route[1],$params); - } - $var = array_merge($var,$params); + if (is_array($route) && isset($route[1])) { + if (is_array($route[1])) { + $params = $route[1]; + } else { + parse_str($route[1], $params); + } + $var = array_merge($var, $params); } - $_GET = array_merge($var,$_GET); + $_GET = array_merge($var, $_GET); } return true; } @@ -243,54 +261,57 @@ private static function parseRule($rule,$route,$regx) { // 参数值和外部地址中可以用动态变量 采用 :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 static function parseRegex($matches,$route,$regx) { + private static function parseRegex($matches, $route, $regx) + { // 获取路由地址规则 - $url = is_array($route)?$route[0]:$route; - $url = preg_replace_callback('/:(\d+)/', function($match) use($matches){return $matches[$match[1]];}, $url); - if(0=== strpos($url,'/') || 0===strpos($url,'http')) { // 路由重定向跳转 - header("Location: $url", true,(is_array($route) && isset($route[1]))?$route[1]:301); + $url = is_array($route) ? $route[0] : $route; + $url = preg_replace_callback('/:(\d+)/', function ($match) use ($matches) {return $matches[$match[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{ + } else { // 解析路由地址 - $var = self::parseUrl($url); + $var = self::parseUrl($url); // 处理函数 - foreach($var as $key=>$val){ - if(strpos($val,'|')){ - list($val,$fun) = explode('|',$val); - $var[$key] = $fun($val); + foreach ($var as $key => $val) { + if (strpos($val, '|')) { + list($val, $fun) = explode('|', $val); + $var[$key] = $fun($val); } } // 解析剩余的URL参数 - $regx = substr_replace($regx,'',0,strlen($matches[0])); - if($regx) { - preg_replace_callback('/(\w+)\/([^\/]+)/', function($match) use(&$var){ + $regx = substr_replace($regx, '', 0, strlen($matches[0])); + if ($regx) { + preg_replace_callback('/(\w+)\/([^\/]+)/', function ($match) use (&$var) { $var[strtolower($match[1])] = strip_tags($match[2]); }, $regx); } // 解析路由自动传入参数 - if(is_array($route) && isset($route[1])) { - if(is_array($route[1])){ - $params = $route[1]; - }else{ - parse_str($route[1],$params); + if (is_array($route) && isset($route[1])) { + if (is_array($route[1])) { + $params = $route[1]; + } else { + parse_str($route[1], $params); } - $var = array_merge($var,$params); + $var = array_merge($var, $params); } - $_GET = array_merge($var,$_GET); + $_GET = array_merge($var, $_GET); } return true; } // 执行正则匹配下的闭包方法 支持参数调用 - static private function invokeRegx($closure, $var = array()) { + private static function invokeRegx($closure, $var = array()) + { $reflect = new \ReflectionFunction($closure); $params = $reflect->getParameters(); $args = array(); array_shift($var); - foreach ($params as $param){ - if(!empty($var)) { + foreach ($params as $param) { + if (!empty($var)) { $args[] = array_shift($var); - }elseif($param->isDefaultValueAvailable()){ + } elseif ($param->isDefaultValueAvailable()) { $args[] = $param->getDefaultValue(); } } @@ -298,19 +319,20 @@ static private function invokeRegx($closure, $var = array()) { } // 执行规则匹配下的闭包方法 支持参数调用 - static private function invokeRule($closure, $var = array()) { + private static function invokeRule($closure, $var = array()) + { $reflect = new \ReflectionFunction($closure); $params = $reflect->getParameters(); $args = array(); - foreach ($params as $param){ + foreach ($params as $param) { $name = $param->getName(); - if(isset($var[$name])) { + if (isset($var[$name])) { $args[] = $var[$name]; - }elseif($param->isDefaultValueAvailable()){ + } elseif ($param->isDefaultValueAvailable()) { $args[] = $param->getDefaultValue(); } } return $reflect->invokeArgs($args); } -} \ No newline at end of file +} diff --git a/ThinkPHP/Library/Think/Session/Driver/Db.class.php b/ThinkPHP/Library/Think/Session/Driver/Db.class.php index 76ab3be26..9e275989c 100644 --- a/ThinkPHP/Library/Think/Session/Driver/Db.class.php +++ b/ThinkPHP/Library/Think/Session/Driver/Db.class.php @@ -1,4 +1,5 @@ - // +---------------------------------------------------------------------- namespace Think\Session\Driver; + /** * 数据库方式Session驱动 * CREATE TABLE think_session ( @@ -18,156 +20,174 @@ * UNIQUE KEY `session_id` (`session_id`) * ); */ -class Db { +class Db +{ /** * Session有效时间 */ - protected $lifeTime = ''; + protected $lifeTime = ''; /** * session保存的数据库名 */ - protected $sessionTable = ''; + protected $sessionTable = ''; /** * 数据库句柄 */ - protected $hander = array(); + protected $hander = array(); /** - * 打开Session - * @access public - * @param string $savePath - * @param mixed $sessName + * 打开Session + * @access public + * @param string $savePath + * @param mixed $sessName */ - public function open($savePath, $sessName) { - $this->lifeTime = C('SESSION_EXPIRE')?C('SESSION_EXPIRE'):ini_get('session.gc_maxlifetime'); - $this->sessionTable = C('SESSION_TABLE')?C('SESSION_TABLE'):C("DB_PREFIX")."session"; - //分布式数据库 - $host = explode(',',C('DB_HOST')); - $port = explode(',',C('DB_PORT')); - $name = explode(',',C('DB_NAME')); - $user = explode(',',C('DB_USER')); - $pwd = explode(',',C('DB_PWD')); - if(1 == C('DB_DEPLOY_TYPE')){ - //读写分离 - if(C('DB_RW_SEPARATE')){ - $w = floor(mt_rand(0,C('DB_MASTER_NUM')-1)); - if(is_numeric(C('DB_SLAVE_NO'))){//指定服务器读 - $r = C('DB_SLAVE_NO'); - }else{ - $r = floor(mt_rand(C('DB_MASTER_NUM'),count($host)-1)); - } - //主数据库链接 - $hander = mysql_connect( - $host[$w].(isset($port[$w])?':'.$port[$w]:':'.$port[0]), - isset($user[$w])?$user[$w]:$user[0], - isset($pwd[$w])?$pwd[$w]:$pwd[0] - ); - $dbSel = mysql_select_db( - isset($name[$w])?$name[$w]:$name[0] - ,$hander); - if(!$hander || !$dbSel) - return false; - $this->hander[0] = $hander; - //从数据库链接 - $hander = mysql_connect( - $host[$r].(isset($port[$r])?':'.$port[$r]:':'.$port[0]), - isset($user[$r])?$user[$r]:$user[0], - isset($pwd[$r])?$pwd[$r]:$pwd[0] - ); - $dbSel = mysql_select_db( - isset($name[$r])?$name[$r]:$name[0] - ,$hander); - if(!$hander || !$dbSel) - return false; - $this->hander[1] = $hander; - return true; - } - } - //从数据库链接 - $r = floor(mt_rand(0,count($host)-1)); - $hander = mysql_connect( - $host[$r].(isset($port[$r])?':'.$port[$r]:':'.$port[0]), - isset($user[$r])?$user[$r]:$user[0], - isset($pwd[$r])?$pwd[$r]:$pwd[0] - ); - $dbSel = mysql_select_db( - isset($name[$r])?$name[$r]:$name[0] - ,$hander); - if(!$hander || !$dbSel) - return false; - $this->hander = $hander; - return true; - } + public function open($savePath, $sessName) + { + $this->lifeTime = C('SESSION_EXPIRE') ? C('SESSION_EXPIRE') : ini_get('session.gc_maxlifetime'); + $this->sessionTable = C('SESSION_TABLE') ? C('SESSION_TABLE') : C("DB_PREFIX") . "session"; + //分布式数据库 + $host = explode(',', C('DB_HOST')); + $port = explode(',', C('DB_PORT')); + $name = explode(',', C('DB_NAME')); + $user = explode(',', C('DB_USER')); + $pwd = explode(',', C('DB_PWD')); + if (1 == C('DB_DEPLOY_TYPE')) { + //读写分离 + if (C('DB_RW_SEPARATE')) { + $w = floor(mt_rand(0, C('DB_MASTER_NUM') - 1)); + if (is_numeric(C('DB_SLAVE_NO'))) { +//指定服务器读 + $r = C('DB_SLAVE_NO'); + } else { + $r = floor(mt_rand(C('DB_MASTER_NUM'), count($host) - 1)); + } + //主数据库链接 + $hander = mysql_connect( + $host[$w] . (isset($port[$w]) ? ':' . $port[$w] : ':' . $port[0]), + isset($user[$w]) ? $user[$w] : $user[0], + isset($pwd[$w]) ? $pwd[$w] : $pwd[0] + ); + $dbSel = mysql_select_db( + isset($name[$w]) ? $name[$w] : $name[0] + , $hander); + if (!$hander || !$dbSel) { + return false; + } + + $this->hander[0] = $hander; + //从数据库链接 + $hander = mysql_connect( + $host[$r] . (isset($port[$r]) ? ':' . $port[$r] : ':' . $port[0]), + isset($user[$r]) ? $user[$r] : $user[0], + isset($pwd[$r]) ? $pwd[$r] : $pwd[0] + ); + $dbSel = mysql_select_db( + isset($name[$r]) ? $name[$r] : $name[0] + , $hander); + if (!$hander || !$dbSel) { + return false; + } + + $this->hander[1] = $hander; + return true; + } + } + //从数据库链接 + $r = floor(mt_rand(0, count($host) - 1)); + $hander = mysql_connect( + $host[$r] . (isset($port[$r]) ? ':' . $port[$r] : ':' . $port[0]), + isset($user[$r]) ? $user[$r] : $user[0], + isset($pwd[$r]) ? $pwd[$r] : $pwd[0] + ); + $dbSel = mysql_select_db( + isset($name[$r]) ? $name[$r] : $name[0] + , $hander); + if (!$hander || !$dbSel) { + return false; + } + + $this->hander = $hander; + return true; + } /** - * 关闭Session - * @access public + * 关闭Session + * @access public */ - public function close() { - if(is_array($this->hander)){ - $this->gc($this->lifeTime); - return (mysql_close($this->hander[0]) && mysql_close($this->hander[1])); - } - $this->gc($this->lifeTime); - return mysql_close($this->hander); - } + public function close() + { + if (is_array($this->hander)) { + $this->gc($this->lifeTime); + return (mysql_close($this->hander[0]) && mysql_close($this->hander[1])); + } + $this->gc($this->lifeTime); + return mysql_close($this->hander); + } /** - * 读取Session - * @access public - * @param string $sessID + * 读取Session + * @access public + * @param string $sessID */ - public function read($sessID) { - $hander = is_array($this->hander)?$this->hander[1]:$this->hander; - $res = mysql_query('SELECT session_data AS data FROM '.$this->sessionTable." WHERE session_id = '$sessID' AND session_expire >".time(),$hander); - if($res) { - $row = mysql_fetch_assoc($res); - return $row['data']; - } - return ""; - } + public function read($sessID) + { + $hander = is_array($this->hander) ? $this->hander[1] : $this->hander; + $res = mysql_query('SELECT session_data AS data FROM ' . $this->sessionTable . " WHERE session_id = '$sessID' AND session_expire >" . time(), $hander); + if ($res) { + $row = mysql_fetch_assoc($res); + return $row['data']; + } + return ""; + } /** - * 写入Session - * @access public - * @param string $sessID - * @param String $sessData + * 写入Session + * @access public + * @param string $sessID + * @param String $sessData */ - public function write($sessID,$sessData) { - $hander = is_array($this->hander)?$this->hander[0]:$this->hander; - $expire = time() + $this->lifeTime; - $sessData = addslashes($sessData); - mysql_query('REPLACE INTO '.$this->sessionTable." ( session_id, session_expire, session_data) VALUES( '$sessID', '$expire', '$sessData')",$hander); - if(mysql_affected_rows($hander)) - return true; - return false; - } + public function write($sessID, $sessData) + { + $hander = is_array($this->hander) ? $this->hander[0] : $this->hander; + $expire = time() + $this->lifeTime; + $sessData = addslashes($sessData); + mysql_query('REPLACE INTO ' . $this->sessionTable . " ( session_id, session_expire, session_data) VALUES( '$sessID', '$expire', '$sessData')", $hander); + if (mysql_affected_rows($hander)) { + return true; + } + + return false; + } /** - * 删除Session - * @access public - * @param string $sessID + * 删除Session + * @access public + * @param string $sessID */ - public function destroy($sessID) { - $hander = is_array($this->hander)?$this->hander[0]:$this->hander; - mysql_query('DELETE FROM '.$this->sessionTable." WHERE session_id = '$sessID'",$hander); - if(mysql_affected_rows($hander)) - return true; - return false; - } + public function destroy($sessID) + { + $hander = is_array($this->hander) ? $this->hander[0] : $this->hander; + mysql_query('DELETE FROM ' . $this->sessionTable . " WHERE session_id = '$sessID'", $hander); + if (mysql_affected_rows($hander)) { + return true; + } + + return false; + } /** * Session 垃圾回收 - * @access public - * @param string $sessMaxLifeTime + * @access public + * @param string $sessMaxLifeTime */ - public function gc($sessMaxLifeTime) { - $hander = is_array($this->hander)?$this->hander[0]:$this->hander; - mysql_query('DELETE FROM '.$this->sessionTable.' WHERE session_expire < '.time(),$hander); - return mysql_affected_rows($hander); - } + public function gc($sessMaxLifeTime) + { + $hander = is_array($this->hander) ? $this->hander[0] : $this->hander; + mysql_query('DELETE FROM ' . $this->sessionTable . ' WHERE session_expire < ' . time(), $hander); + return mysql_affected_rows($hander); + } -} \ No newline at end of file +} diff --git a/ThinkPHP/Library/Think/Session/Driver/Memcache.class.php b/ThinkPHP/Library/Think/Session/Driver/Memcache.class.php index 4c80bbefe..574b504a9 100644 --- a/ThinkPHP/Library/Think/Session/Driver/Memcache.class.php +++ b/ThinkPHP/Library/Think/Session/Driver/Memcache.class.php @@ -1,79 +1,86 @@ lifeTime = C('SESSION_EXPIRE') ? C('SESSION_EXPIRE') : $this->lifeTime; - // $this->sessionName = $sessName; - $options = array( - 'timeout' => C('SESSION_TIMEOUT') ? C('SESSION_TIMEOUT') : 1, - 'persistent' => C('SESSION_PERSISTENT') ? C('SESSION_PERSISTENT') : 0 + public function open($savePath, $sessName) + { + $this->lifeTime = C('SESSION_EXPIRE') ? C('SESSION_EXPIRE') : $this->lifeTime; + // $this->sessionName = $sessName; + $options = array( + 'timeout' => C('SESSION_TIMEOUT') ? C('SESSION_TIMEOUT') : 1, + 'persistent' => C('SESSION_PERSISTENT') ? C('SESSION_PERSISTENT') : 0, ); - $this->handle = new \Memcache; - $hosts = explode(',', C('MEMCACHE_HOST')); - $ports = explode(',', C('MEMCACHE_PORT')); - foreach ($hosts as $i=>$host) { - $port = isset($ports[$i]) ? $ports[$i] : $ports[0]; + $this->handle = new \Memcache; + $hosts = explode(',', C('MEMCACHE_HOST')); + $ports = explode(',', C('MEMCACHE_PORT')); + foreach ($hosts as $i => $host) { + $port = isset($ports[$i]) ? $ports[$i] : $ports[0]; $this->handle->addServer($host, $port, true, 1, $options['timeout']); } - return true; - } + return true; + } /** - * 关闭Session - * @access public + * 关闭Session + * @access public */ - public function close() { - $this->gc(ini_get('session.gc_maxlifetime')); - $this->handle->close(); - $this->handle = null; - return true; - } + public function close() + { + $this->gc(ini_get('session.gc_maxlifetime')); + $this->handle->close(); + $this->handle = null; + return true; + } /** - * 读取Session - * @access public - * @param string $sessID + * 读取Session + * @access public + * @param string $sessID */ - public function read($sessID) { - return $this->handle->get($this->sessionName.$sessID); - } + public function read($sessID) + { + return $this->handle->get($this->sessionName . $sessID); + } /** - * 写入Session - * @access public - * @param string $sessID - * @param String $sessData + * 写入Session + * @access public + * @param string $sessID + * @param String $sessData */ - public function write($sessID, $sessData) { - return $this->handle->set($this->sessionName.$sessID, $sessData, 0, $this->lifeTime); - } + public function write($sessID, $sessData) + { + return $this->handle->set($this->sessionName . $sessID, $sessData, 0, $this->lifeTime); + } /** - * 删除Session - * @access public - * @param string $sessID + * 删除Session + * @access public + * @param string $sessID */ - public function destroy($sessID) { - return $this->handle->delete($this->sessionName.$sessID); - } + public function destroy($sessID) + { + return $this->handle->delete($this->sessionName . $sessID); + } /** * Session 垃圾回收 - * @access public - * @param string $sessMaxLifeTime + * @access public + * @param string $sessMaxLifeTime */ - public function gc($sessMaxLifeTime) { - return true; - } + public function gc($sessMaxLifeTime) + { + return true; + } } diff --git a/ThinkPHP/Library/Think/Session/Driver/Mysqli.class.php b/ThinkPHP/Library/Think/Session/Driver/Mysqli.class.php index b29ec2fbc..fd3ec06c9 100644 --- a/ThinkPHP/Library/Think/Session/Driver/Mysqli.class.php +++ b/ThinkPHP/Library/Think/Session/Driver/Mysqli.class.php @@ -11,6 +11,7 @@ // | change mysql to mysqli 解决php7没有mysql扩展时数据库存放session无法操作的问题 // +---------------------------------------------------------------------- namespace Think\Session\Driver; + /** * 数据库方式Session驱动 * CREATE TABLE think_session ( @@ -46,19 +47,20 @@ class Mysqli */ public function open($savePath, $sessName) { - $this->lifeTime = C('SESSION_EXPIRE') ? C('SESSION_EXPIRE') : ini_get('session.gc_maxlifetime'); + $this->lifeTime = C('SESSION_EXPIRE') ? C('SESSION_EXPIRE') : ini_get('session.gc_maxlifetime'); $this->sessionTable = C('SESSION_TABLE') ? C('SESSION_TABLE') : C("DB_PREFIX") . "session"; //分布式数据库 $host = explode(',', C('DB_HOST')); $port = explode(',', C('DB_PORT')); $name = explode(',', C('DB_NAME')); $user = explode(',', C('DB_USER')); - $pwd = explode(',', C('DB_PWD')); + $pwd = explode(',', C('DB_PWD')); if (1 == C('DB_DEPLOY_TYPE')) { //读写分离 if (C('DB_RW_SEPARATE')) { $w = floor(mt_rand(0, C('DB_MASTER_NUM') - 1)); - if (is_numeric(C('DB_SLAVE_NO'))) {//指定服务器读 + if (is_numeric(C('DB_SLAVE_NO'))) { +//指定服务器读 $r = C('DB_SLAVE_NO'); } else { $r = floor(mt_rand(C('DB_MASTER_NUM'), count($host) - 1)); @@ -73,8 +75,10 @@ public function open($savePath, $sessName) $hander, isset($name[$w]) ? $name[$w] : $name[0] ); - if (!$hander || !$dbSel) + if (!$hander || !$dbSel) { return false; + } + $this->hander[0] = $hander; //从数据库链接 $hander = mysqli_connect( @@ -86,14 +90,16 @@ public function open($savePath, $sessName) $hander, isset($name[$r]) ? $name[$r] : $name[0] ); - if (!$hander || !$dbSel) + if (!$hander || !$dbSel) { return false; + } + $this->hander[1] = $hander; return true; } } //从数据库链接 - $r = floor(mt_rand(0, count($host) - 1)); + $r = floor(mt_rand(0, count($host) - 1)); $hander = mysqli_connect( $host[$r] . (isset($port[$r]) ? ':' . $port[$r] : ':' . $port[0]), isset($user[$r]) ? $user[$r] : $user[0], @@ -103,8 +109,10 @@ public function open($savePath, $sessName) $hander, isset($name[$r]) ? $name[$r] : $name[0] ); - if (!$hander || !$dbSel) + if (!$hander || !$dbSel) { return false; + } + $this->hander = $hander; return true; } @@ -131,7 +139,7 @@ public function close() public function read($sessID) { $hander = is_array($this->hander) ? $this->hander[1] : $this->hander; - $res = mysqli_query($hander, "SELECT session_data AS data FROM " . $this->sessionTable . " WHERE session_id = '$sessID' AND session_expire >" . time()); + $res = mysqli_query($hander, "SELECT session_data AS data FROM " . $this->sessionTable . " WHERE session_id = '$sessID' AND session_expire >" . time()); if ($res) { $row = mysqli_fetch_assoc($res); return $row['data']; @@ -150,8 +158,10 @@ public function write($sessID, $sessData) $hander = is_array($this->hander) ? $this->hander[0] : $this->hander; $expire = time() + $this->lifeTime; mysqli_query($hander, "REPLACE INTO " . $this->sessionTable . " ( session_id, session_expire, session_data) VALUES( '$sessID', '$expire', '$sessData')"); - if (mysqli_affected_rows($hander)) + if (mysqli_affected_rows($hander)) { return true; + } + return false; } @@ -164,8 +174,10 @@ public function destroy($sessID) { $hander = is_array($this->hander) ? $this->hander[0] : $this->hander; mysqli_query($hander, "DELETE FROM " . $this->sessionTable . " WHERE session_id = '$sessID'"); - if (mysqli_affected_rows($hander)) + if (mysqli_affected_rows($hander)) { return true; + } + return false; } diff --git a/ThinkPHP/Library/Think/Storage.class.php b/ThinkPHP/Library/Think/Storage.class.php index 653e13688..df4bdabb5 100644 --- a/ThinkPHP/Library/Think/Storage.class.php +++ b/ThinkPHP/Library/Think/Storage.class.php @@ -9,15 +9,17 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think; + // 分布式文件存储类 -class Storage { +class Storage +{ /** * 操作句柄 * @var string * @access protected */ - static protected $handler ; + protected static $handler; /** * 连接分布式文件系统 @@ -26,15 +28,17 @@ class Storage { * @param array $options 配置数组 * @return void */ - static public function connect($type='File',$options=array()) { - $class = 'Think\\Storage\\Driver\\'.ucwords($type); + public static function connect($type = 'File', $options = array()) + { + $class = 'Think\\Storage\\Driver\\' . ucwords($type); self::$handler = new $class($options); } - static public function __callstatic($method,$args){ + public static function __callstatic($method, $args) + { //调用缓存驱动的方法 - if(method_exists(self::$handler, $method)){ - return call_user_func_array(array(self::$handler,$method), $args); + if (method_exists(self::$handler, $method)) { + return call_user_func_array(array(self::$handler, $method), $args); } } } diff --git a/ThinkPHP/Library/Think/Storage/Driver/File.class.php b/ThinkPHP/Library/Think/Storage/Driver/File.class.php index ea9d92572..2c71ca803 100644 --- a/ThinkPHP/Library/Think/Storage/Driver/File.class.php +++ b/ThinkPHP/Library/Think/Storage/Driver/File.class.php @@ -9,27 +9,32 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think\Storage\Driver; + use Think\Storage; + // 本地文件写入存储类 -class File extends Storage{ +class File extends Storage +{ - private $contents=array(); + private $contents = array(); /** * 架构函数 * @access public */ - public function __construct() { + public function __construct() + { } /** * 文件内容读取 * @access public * @param string $filename 文件名 - * @return string + * @return string */ - public function read($filename,$type=''){ - return $this->get($filename,'content',$type); + public function read($filename, $type = '') + { + return $this->get($filename, 'content', $type); } /** @@ -37,17 +42,18 @@ public function read($filename,$type=''){ * @access public * @param string $filename 文件名 * @param string $content 文件内容 - * @return boolean + * @return boolean */ - public function put($filename,$content,$type=''){ - $dir = dirname($filename); - if(!is_dir($dir)){ - mkdir($dir,0777,true); + public function put($filename, $content, $type = '') + { + $dir = dirname($filename); + if (!is_dir($dir)) { + mkdir($dir, 0777, true); } - if(false === file_put_contents($filename,$content)){ - E(L('_STORAGE_WRITE_ERROR_').':'.$filename); - }else{ - $this->contents[$filename]=$content; + if (false === file_put_contents($filename, $content)) { + E(L('_STORAGE_WRITE_ERROR_') . ':' . $filename); + } else { + $this->contents[$filename] = $content; return true; } } @@ -57,13 +63,14 @@ public function put($filename,$content,$type=''){ * @access public * @param string $filename 文件名 * @param string $content 追加的文件内容 - * @return boolean + * @return boolean */ - public function append($filename,$content,$type=''){ - if(is_file($filename)){ - $content = $this->read($filename,$type).$content; + public function append($filename, $content, $type = '') + { + if (is_file($filename)) { + $content = $this->read($filename, $type) . $content; } - return $this->put($filename,$content,$type); + return $this->put($filename, $content, $type); } /** @@ -71,10 +78,11 @@ public function append($filename,$content,$type=''){ * @access public * @param string $filename 文件名 * @param array $vars 传入变量 - * @return void + * @return void */ - public function load($_filename,$vars=null){ - if(!is_null($vars)){ + public function load($_filename, $vars = null) + { + if (!is_null($vars)) { extract($vars, EXTR_OVERWRITE); } include $_filename; @@ -84,9 +92,10 @@ public function load($_filename,$vars=null){ * 文件是否存在 * @access public * @param string $filename 文件名 - * @return boolean + * @return boolean */ - public function has($filename,$type=''){ + public function has($filename, $type = '') + { return is_file($filename); } @@ -94,11 +103,12 @@ public function has($filename,$type=''){ * 文件删除 * @access public * @param string $filename 文件名 - * @return boolean + * @return boolean */ - public function unlink($filename,$type=''){ + public function unlink($filename, $type = '') + { unset($this->contents[$filename]); - return is_file($filename) ? unlink($filename) : false; + return is_file($filename) ? unlink($filename) : false; } /** @@ -106,17 +116,21 @@ public function unlink($filename,$type=''){ * @access public * @param string $filename 文件名 * @param string $name 信息名 mtime或者content - * @return boolean + * @return boolean */ - public function get($filename,$name,$type=''){ - if(!isset($this->contents[$filename])){ - if(!is_file($filename)) return false; - $this->contents[$filename]=file_get_contents($filename); + public function get($filename, $name, $type = '') + { + if (!isset($this->contents[$filename])) { + if (!is_file($filename)) { + return false; + } + + $this->contents[$filename] = file_get_contents($filename); } - $content=$this->contents[$filename]; - $info = array( - 'mtime' => filemtime($filename), - 'content' => $content + $content = $this->contents[$filename]; + $info = array( + 'mtime' => filemtime($filename), + 'content' => $content, ); return $info[$name]; } diff --git a/ThinkPHP/Library/Think/Storage/Driver/Sae.class.php b/ThinkPHP/Library/Think/Storage/Driver/Sae.class.php index 3756115d0..2c2dbffa3 100644 --- a/ThinkPHP/Library/Think/Storage/Driver/Sae.class.php +++ b/ThinkPHP/Library/Think/Storage/Driver/Sae.class.php @@ -9,61 +9,68 @@ // | Author: luofei614 // +---------------------------------------------------------------------- namespace Think\Storage\Driver; + use Think\Storage; + // SAE环境文件写入存储类 -class Sae extends Storage{ +class Sae extends Storage +{ /** * 架构函数 * @access public */ private $mc; - private $kvs = array(); - private $htmls = array(); - private $contents = array(); - public function __construct() { - if(!function_exists('memcache_init')){ - header('Content-Type:text/html;charset=utf-8'); - exit('请在SAE平台上运行代码。'); + private $kvs = array(); + private $htmls = array(); + private $contents = array(); + public function __construct() + { + if (!function_exists('memcache_init')) { + header('Content-Type:text/html;charset=utf-8'); + exit('请在SAE平台上运行代码。'); } - $this->mc = @memcache_init(); - if(!$this->mc){ - header('Content-Type:text/html;charset=utf-8'); - exit('您未开通Memcache服务,请在SAE管理平台初始化Memcache服务'); + $this->mc = @memcache_init(); + if (!$this->mc) { + header('Content-Type:text/html;charset=utf-8'); + exit('您未开通Memcache服务,请在SAE管理平台初始化Memcache服务'); } } /** * 获得SaeKv对象 */ - private function getKv(){ + private function getKv() + { static $kv; - if(!$kv){ - $kv = new \SaeKV(); - if(!$kv->init()) - E('您没有初始化KVDB,请在SAE管理平台初始化KVDB服务'); + if (!$kv) { + $kv = new \SaeKV(); + if (!$kv->init()) { + E('您没有初始化KVDB,请在SAE管理平台初始化KVDB服务'); + } + } return $kv; } - /** * 文件内容读取 * @access public * @param string $filename 文件名 * @return string */ - public function read($filename,$type=''){ - switch(strtolower($type)){ - case 'f': - $kv = $this->getKv(); - if(!isset($this->kvs[$filename])){ - $this->kvs[$filename]=$kv->get($filename); + public function read($filename, $type = '') + { + switch (strtolower($type)) { + case 'f': + $kv = $this->getKv(); + if (!isset($this->kvs[$filename])) { + $this->kvs[$filename] = $kv->get($filename); } return $this->kvs[$filename]; default: - return $this->get($filename,'content',$type); - } + return $this->get($filename, 'content', $type); + } } /** @@ -73,25 +80,26 @@ public function read($filename,$type=''){ * @param string $content 文件内容 * @return boolean */ - public function put($filename,$content,$type=''){ - switch(strtolower($type)){ - case 'f': - $kv = $this->getKv(); + public function put($filename, $content, $type = '') + { + switch (strtolower($type)) { + case 'f': + $kv = $this->getKv(); $this->kvs[$filename] = $content; - return $kv->set($filename,$content); - case 'html': - $kv = $this->getKv(); - $content = time().$content; - $this->htmls[$filename] = $content; - return $kv->set($filename,$content); + return $kv->set($filename, $content); + case 'html': + $kv = $this->getKv(); + $content = time() . $content; + $this->htmls[$filename] = $content; + return $kv->set($filename, $content); default: - $content = time().$content; - if(!$this->mc->set($filename,$content,MEMCACHE_COMPRESSED,0)){ - E(L('_STORAGE_WRITE_ERROR_').':'.$filename); - }else{ + $content = time() . $content; + if (!$this->mc->set($filename, $content, MEMCACHE_COMPRESSED, 0)) { + E(L('_STORAGE_WRITE_ERROR_') . ':' . $filename); + } else { $this->contents[$filename] = $content; return true; - } + } } } @@ -102,11 +110,12 @@ public function put($filename,$content,$type=''){ * @param string $content 追加的文件内容 * @return boolean */ - public function append($filename,$content,$type=''){ - if($old_content = $this->read($filename,$type)){ - $content = $old_content.$content; + public function append($filename, $content, $type = '') + { + if ($old_content = $this->read($filename, $type)) { + $content = $old_content . $content; } - return $this->put($filename,$content,$type); + return $this->put($filename, $content, $type); } /** @@ -116,10 +125,13 @@ public function append($filename,$content,$type=''){ * @param array $vars 传入变量 * @return void */ - public function load($_filename,$vars=null){ - if(!is_null($vars)) + public function load($_filename, $vars = null) + { + if (!is_null($vars)) { extract($vars, EXTR_OVERWRITE); - eval('?>'.$this->read($_filename)); + } + + eval('?>' . $this->read($_filename)); } /** @@ -128,10 +140,11 @@ public function load($_filename,$vars=null){ * @param string $filename 文件名 * @return boolean */ - public function has($filename,$type=''){ - if($this->read($filename,$type)){ + public function has($filename, $type = '') + { + if ($this->read($filename, $type)) { return true; - }else{ + } else { return false; } } @@ -142,20 +155,21 @@ public function has($filename,$type=''){ * @param string $filename 文件名 * @return boolean */ - public function unlink($filename,$type=''){ - switch(strtolower($type)){ - case 'f': - $kv = $this->getKv(); + public function unlink($filename, $type = '') + { + switch (strtolower($type)) { + case 'f': + $kv = $this->getKv(); unset($this->kvs[$filename]); return $kv->delete($filename); - case 'html': - $kv = $this->getKv(); + case 'html': + $kv = $this->getKv(); unset($this->htmls[$filename]); return $kv->delete($filename); default: unset($this->contents[$filename]); - return $this->mc->delete($filename); - } + return $this->mc->delete($filename); + } } /** @@ -165,29 +179,30 @@ public function unlink($filename,$type=''){ * @param string $name 信息名 mtime或者content * @return boolean */ - public function get($filename,$name,$type=''){ - switch(strtolower($type)){ + public function get($filename, $name, $type = '') + { + switch (strtolower($type)) { case 'html': - if(!isset($this->htmls[$filename])){ - $kv = $this->getKv(); + if (!isset($this->htmls[$filename])) { + $kv = $this->getKv(); $this->htmls[$filename] = $kv->get($filename); } $content = $this->htmls[$filename]; break; default: - if(!isset($this->contents[$filename])){ + if (!isset($this->contents[$filename])) { $this->contents[$filename] = $this->mc->get($filename); } - $content = $this->contents[$filename]; + $content = $this->contents[$filename]; } - if(false===$content){ + if (false === $content) { return false; } - $info = array( - 'mtime' => substr($content,0,10), - 'content' => substr($content,10) + $info = array( + 'mtime' => substr($content, 0, 10), + 'content' => substr($content, 10), ); - return $info[$name]; + return $info[$name]; } -} \ No newline at end of file +} diff --git a/ThinkPHP/Library/Think/Template.class.php b/ThinkPHP/Library/Think/Template.class.php index c43a97a1b..3c82a798b 100644 --- a/ThinkPHP/Library/Think/Template.class.php +++ b/ThinkPHP/Library/Think/Template.class.php @@ -9,58 +9,71 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think; + /** * ThinkPHP内置模板引擎类 * 支持XML标签和普通标签的模板解析 * 编译型模板引擎 支持动态缓存 */ -class Template { +use Think\Hook as Hook; +//use Think\Crypt\Driver\Think as Think; +use Think\Storage as Storage; +use Think\Think as Think; + +class Template +{ // 模板页面中引入的标签库列表 - protected $tagLib = array(); + protected $tagLib = array(); // 当前模板文件 - protected $templateFile = ''; + protected $templateFile = ''; // 模板变量 - public $tVar = array(); - public $config = array(); - private $literal = array(); - private $block = array(); + public $tVar = array(); + public $config = array(); + private $literal = array(); + private $block = array(); /** * 架构函数 * @access public */ - public function __construct(){ - $this->config['cache_path'] = C('CACHE_PATH'); - $this->config['template_suffix'] = C('TMPL_TEMPLATE_SUFFIX'); - $this->config['cache_suffix'] = C('TMPL_CACHFILE_SUFFIX'); - $this->config['tmpl_cache'] = C('TMPL_CACHE_ON'); - $this->config['cache_time'] = C('TMPL_CACHE_TIME'); - $this->config['taglib_begin'] = $this->stripPreg(C('TAGLIB_BEGIN')); - $this->config['taglib_end'] = $this->stripPreg(C('TAGLIB_END')); - $this->config['tmpl_begin'] = $this->stripPreg(C('TMPL_L_DELIM')); - $this->config['tmpl_end'] = $this->stripPreg(C('TMPL_R_DELIM')); - $this->config['default_tmpl'] = C('TEMPLATE_NAME'); - $this->config['layout_item'] = C('TMPL_LAYOUT_ITEM'); + public function __construct() + { + $this->config['cache_path'] = C('CACHE_PATH'); + $this->config['template_suffix'] = C('TMPL_TEMPLATE_SUFFIX'); + $this->config['cache_suffix'] = C('TMPL_CACHFILE_SUFFIX'); + $this->config['tmpl_cache'] = C('TMPL_CACHE_ON'); + $this->config['cache_time'] = C('TMPL_CACHE_TIME'); + $this->config['taglib_begin'] = $this->stripPreg(C('TAGLIB_BEGIN')); + $this->config['taglib_end'] = $this->stripPreg(C('TAGLIB_END')); + $this->config['tmpl_begin'] = $this->stripPreg(C('TMPL_L_DELIM')); + $this->config['tmpl_end'] = $this->stripPreg(C('TMPL_R_DELIM')); + $this->config['default_tmpl'] = C('TEMPLATE_NAME'); + $this->config['layout_item'] = C('TMPL_LAYOUT_ITEM'); } - private function stripPreg($str) { + private function stripPreg($str) + { return str_replace( - array('{','}','(',')','|','[',']','-','+','*','.','^','?'), - array('\{','\}','\(','\)','\|','\[','\]','\-','\+','\*','\.','\^','\?'), - $str); + array('{', '}', '(', ')', '|', '[', ']', '-', '+', '*', '.', '^', '?'), + array('\{', '\}', '\(', '\)', '\|', '\[', '\]', '\-', '\+', '\*', '\.', '\^', '\?'), + $str); } // 模板变量获取和设置 - public function get($name) { - if(isset($this->tVar[$name])) + public function get($name) + { + if (isset($this->tVar[$name])) { return $this->tVar[$name]; - else + } else { return false; + } + } - public function set($name,$value) { - $this->tVar[$name]= $value; + public function set($name, $value) + { + $this->tVar[$name] = $value; } /** @@ -71,10 +84,11 @@ public function set($name,$value) { * @param string $prefix 模板标识前缀 * @return void */ - public function fetch($templateFile,$templateVar,$prefix='') { - $this->tVar = $templateVar; - $templateCacheFile = $this->loadTemplate($templateFile,$prefix); - Storage::load($templateCacheFile,$this->tVar,null,'tpl'); + public function fetch($templateFile, $templateVar, $prefix = '') + { + $this->tVar = $templateVar; + $templateCacheFile = $this->loadTemplate($templateFile, $prefix); + Storage::load($templateCacheFile, $this->tVar, null, 'tpl'); } /** @@ -85,33 +99,36 @@ public function fetch($templateFile,$templateVar,$prefix='') { * @return string * @throws ThinkExecption */ - public function loadTemplate ($templateFile,$prefix='') { - if(is_file($templateFile)) { - $this->templateFile = $templateFile; + public function loadTemplate($templateFile, $prefix = '') + { + if (is_file($templateFile)) { + $this->templateFile = $templateFile; // 读取模板文件内容 - $tmplContent = file_get_contents($templateFile); - }else{ - $tmplContent = $templateFile; + $tmplContent = file_get_contents($templateFile); + } else { + $tmplContent = $templateFile; } - // 根据模版文件名定位缓存文件 - $tmplCacheFile = $this->config['cache_path'].$prefix.md5($templateFile).$this->config['cache_suffix']; + // 根据模版文件名定位缓存文件 + $tmplCacheFile = $this->config['cache_path'] . $prefix . md5($templateFile) . $this->config['cache_suffix']; // 判断是否启用布局 - if(C('LAYOUT_ON')) { - if(false !== strpos($tmplContent,'{__NOLAYOUT__}')) { // 可以单独定义不使用布局 - $tmplContent = str_replace('{__NOLAYOUT__}','',$tmplContent); - }else{ // 替换布局的主体内容 - $layoutFile = THEME_PATH.C('LAYOUT_NAME').$this->config['template_suffix']; + if (C('LAYOUT_ON')) { + if (false !== strpos($tmplContent, '{__NOLAYOUT__}')) { + // 可以单独定义不使用布局 + $tmplContent = str_replace('{__NOLAYOUT__}', '', $tmplContent); + } else { + // 替换布局的主体内容 + $layoutFile = THEME_PATH . C('LAYOUT_NAME') . $this->config['template_suffix']; // 检查布局文件 - if(!is_file($layoutFile)) { - E(L('_TEMPLATE_NOT_EXIST_').':'.$layoutFile); + if (!is_file($layoutFile)) { + E(L('_TEMPLATE_NOT_EXIST_') . ':' . $layoutFile); } - $tmplContent = str_replace($this->config['layout_item'],$tmplContent,file_get_contents($layoutFile)); + $tmplContent = str_replace($this->config['layout_item'], $tmplContent, file_get_contents($layoutFile)); } } // 编译模板内容 - $tmplContent = $this->compiler($tmplContent); - Storage::put($tmplCacheFile,trim($tmplContent),'tpl'); + $tmplContent = $this->compiler($tmplContent); + Storage::put($tmplCacheFile, trim($tmplContent), 'tpl'); return $tmplCacheFile; } @@ -121,17 +138,18 @@ public function loadTemplate ($templateFile,$prefix='') { * @param mixed $tmplContent 模板内容 * @return string */ - protected function compiler($tmplContent) { + protected function compiler($tmplContent) + { //模板解析 - $tmplContent = $this->parse($tmplContent); + $tmplContent = $this->parse($tmplContent); // 还原被替换的Literal标签 - $tmplContent = preg_replace_callback('//is', array($this, 'restoreLiteral'), $tmplContent); + $tmplContent = preg_replace_callback('//is', array($this, 'restoreLiteral'), $tmplContent); // 添加安全代码 - $tmplContent = ''.$tmplContent; + $tmplContent = '' . $tmplContent; // 优化生成的php代码 - $tmplContent = str_replace('?>config['taglib_begin']; - $end = $this->config['taglib_end']; + if (empty($content)) { + return ''; + } + + $begin = $this->config['taglib_begin']; + $end = $this->config['taglib_end']; // 检查include语法 - $content = $this->parseInclude($content); + $content = $this->parseInclude($content); // 检查PHP语法 - $content = $this->parsePhp($content); + $content = $this->parsePhp($content); // 首先替换literal标签内容 - $content = preg_replace_callback('/'.$begin.'literal'.$end.'(.*?)'.$begin.'\/literal'.$end.'/is', array($this, 'parseLiteral'),$content); + $content = preg_replace_callback('/' . $begin . 'literal' . $end . '(.*?)' . $begin . '\/literal' . $end . '/is', array($this, 'parseLiteral'), $content); // 获取需要引入的标签库列表 // 标签库只需要定义一次,允许引入多个一次 // 一般放在文件的最前面 // 格式: // 当TAGLIB_LOAD配置为true时才会进行检测 - if(C('TAGLIB_LOAD')) { + if (C('TAGLIB_LOAD')) { $this->getIncludeTagLib($content); - if(!empty($this->tagLib)) { + if (!empty($this->tagLib)) { // 对导入的TagLib进行解析 - foreach($this->tagLib as $tagLibName) { - $this->parseTagLib($tagLibName,$content); + foreach ($this->tagLib as $tagLibName) { + $this->parseTagLib($tagLibName, $content); } } } // 预先加载的标签库 无需在每个模板中使用taglib标签加载 但必须使用标签库XML前缀 - if(C('TAGLIB_PRE_LOAD')) { - $tagLibs = explode(',',C('TAGLIB_PRE_LOAD')); - foreach ($tagLibs as $tag){ - $this->parseTagLib($tag,$content); + if (C('TAGLIB_PRE_LOAD')) { + $tagLibs = explode(',', C('TAGLIB_PRE_LOAD')); + foreach ($tagLibs as $tag) { + $this->parseTagLib($tag, $content); } } // 内置标签库 无需使用taglib标签导入就可以使用 并且不需使用标签库XML前缀 - $tagLibs = explode(',',C('TAGLIB_BUILD_IN')); - foreach ($tagLibs as $tag){ - $this->parseTagLib($tag,$content,true); + $tagLibs = explode(',', C('TAGLIB_BUILD_IN')); + foreach ($tagLibs as $tag) { + $this->parseTagLib($tag, $content, true); } //解析普通模板标签 {$tagName} - $content = preg_replace_callback('/('.$this->config['tmpl_begin'].')([^\d\w\s'.$this->config['tmpl_begin'].$this->config['tmpl_end'].'].+?)('.$this->config['tmpl_end'].')/is', array($this, 'parseTag'),$content); + $content = preg_replace_callback('/(' . $this->config['tmpl_begin'] . ')([^\d\w\s' . $this->config['tmpl_begin'] . $this->config['tmpl_end'] . '].+?)(' . $this->config['tmpl_end'] . ')/is', array($this, 'parseTag'), $content); return $content; } // 检查PHP语法 - protected function parsePhp($content) { - if(ini_get('short_open_tag')){ + protected function parsePhp($content) + { + if (ini_get('short_open_tag')) { // 开启短标签的情况要将'."\n", $content ); + $content = preg_replace('/(<\?(?!php|=|$))/i', '' . "\n", $content); } // PHP语法检查 - if(C('TMPL_DENY_PHP') && false !== strpos($content,'config['taglib_begin'].'layout\s(.+?)\s*?\/'.$this->config['taglib_end'].'/is',$content,$matches); - if($find) { + $find = preg_match('/' . $this->config['taglib_begin'] . 'layout\s(.+?)\s*?\/' . $this->config['taglib_end'] . '/is', $content, $matches); + if ($find) { //替换Layout标签 - $content = str_replace($matches[0],'',$content); + $content = str_replace($matches[0], '', $content); //解析Layout标签 - $array = $this->parseXmlAttrs($matches[1]); - if(!C('LAYOUT_ON') || C('LAYOUT_NAME') !=$array['name'] ) { + $array = $this->parseXmlAttrs($matches[1]); + if (!C('LAYOUT_ON') || C('LAYOUT_NAME') != $array['name']) { // 读取布局模板 - $layoutFile = THEME_PATH.$array['name'].$this->config['template_suffix']; - $replace = isset($array['replace'])?$array['replace']:$this->config['layout_item']; + $layoutFile = THEME_PATH . $array['name'] . $this->config['template_suffix']; + $replace = isset($array['replace']) ? $array['replace'] : $this->config['layout_item']; // 替换布局的主体内容 - $content = str_replace($replace,$content,file_get_contents($layoutFile)); + $content = str_replace($replace, $content, file_get_contents($layoutFile)); } - }else{ - $content = str_replace('{__NOLAYOUT__}','',$content); + } else { + $content = str_replace('{__NOLAYOUT__}', '', $content); } return $content; } // 解析模板中的include标签 - protected function parseInclude($content, $extend = true) { + protected function parseInclude($content, $extend = true) + { // 解析继承 - if($extend) - $content = $this->parseExtend($content); + if ($extend) { + $content = $this->parseExtend($content); + } + // 解析布局 - $content = $this->parseLayout($content); + $content = $this->parseLayout($content); // 读取模板中的include标签 - $find = preg_match_all('/'.$this->config['taglib_begin'].'include\s(.+?)\s*?\/'.$this->config['taglib_end'].'/is',$content,$matches); - if($find) { - for($i=0;$i<$find;$i++) { - $include = $matches[1][$i]; - $array = $this->parseXmlAttrs($include); - $file = $array['file']; + $find = preg_match_all('/' . $this->config['taglib_begin'] . 'include\s(.+?)\s*?\/' . $this->config['taglib_end'] . '/is', $content, $matches); + if ($find) { + for ($i = 0; $i < $find; $i++) { + $include = $matches[1][$i]; + $array = $this->parseXmlAttrs($include); + $file = $array['file']; unset($array['file']); - $content = str_replace($matches[0][$i],$this->parseIncludeItem($file,$array,$extend),$content); + $content = str_replace($matches[0][$i], $this->parseIncludeItem($file, $array, $extend), $content); } } return $content; } // 解析模板中的extend标签 - protected function parseExtend($content) { - $begin = $this->config['taglib_begin']; - $end = $this->config['taglib_end']; + protected function parseExtend($content) + { + $begin = $this->config['taglib_begin']; + $end = $this->config['taglib_end']; // 读取模板中的继承标签 - $find = preg_match('/'.$begin.'extend\s(.+?)\s*?\/'.$end.'/is',$content,$matches); - if($find) { + $find = preg_match('/' . $begin . 'extend\s(.+?)\s*?\/' . $end . '/is', $content, $matches); + if ($find) { //替换extend标签 - $content = str_replace($matches[0],'',$content); + $content = str_replace($matches[0], '', $content); // 记录页面中的block标签 - preg_replace_callback('/'.$begin.'block\sname=[\'"](.+?)[\'"]\s*?'.$end.'(.*?)'.$begin.'\/block'.$end.'/is', array($this, 'parseBlock'),$content); + preg_replace_callback('/' . $begin . 'block\sname=[\'"](.+?)[\'"]\s*?' . $end . '(.*?)' . $begin . '\/block' . $end . '/is', array($this, 'parseBlock'), $content); // 读取继承模板 - $array = $this->parseXmlAttrs($matches[1]); - $content = $this->parseTemplateName($array['name']); - $content = $this->parseInclude($content, false); //对继承模板中的include进行分析 + $array = $this->parseXmlAttrs($matches[1]); + $content = $this->parseTemplateName($array['name']); + $content = $this->parseInclude($content, false); //对继承模板中的include进行分析 // 替换block标签 $content = $this->replaceBlock($content); - }else{ - $content = preg_replace_callback('/'.$begin.'block\sname=[\'"](.+?)[\'"]\s*?'.$end.'(.*?)'.$begin.'\/block'.$end.'/is', function($match){return stripslashes($match[2]);}, $content); + } else { + $content = preg_replace_callback('/' . $begin . 'block\sname=[\'"](.+?)[\'"]\s*?' . $end . '(.*?)' . $begin . '\/block' . $end . '/is', function ($match) {return stripslashes($match[2]);}, $content); } return $content; } @@ -270,13 +298,16 @@ protected function parseExtend($content) { * @param string $attrs XML属性字符串 * @return array */ - private function parseXmlAttrs($attrs) { - $xml = ''; - $xml = simplexml_load_string($xml); - if(!$xml) + private function parseXmlAttrs($attrs) + { + $xml = ''; + $xml = simplexml_load_string($xml); + if (!$xml) { E(L('_XML_TAG_ERROR_')); - $xml = (array)($xml->tag->attributes()); - $array = array_change_key_case($xml['@attributes']); + } + + $xml = (array) ($xml->tag->attributes()); + $array = array_change_key_case($xml['@attributes']); return $array; } @@ -286,13 +317,20 @@ private function parseXmlAttrs($attrs) { * @param string $content 模板内容 * @return string|false */ - private function parseLiteral($content) { - if(is_array($content)) $content = $content[1]; - if(trim($content)=='') return ''; + private function parseLiteral($content) + { + if (is_array($content)) { + $content = $content[1]; + } + + if (trim($content) == '') { + return ''; + } + //$content = stripslashes($content); - $i = count($this->literal); - $parseStr = ""; - $this->literal[$i] = $content; + $i = count($this->literal); + $parseStr = ""; + $this->literal[$i] = $content; return $parseStr; } @@ -302,10 +340,14 @@ private function parseLiteral($content) { * @param string $tag literal标签序号 * @return string|false */ - private function restoreLiteral($tag) { - if(is_array($tag)) $tag = $tag[1]; + private function restoreLiteral($tag) + { + if (is_array($tag)) { + $tag = $tag[1]; + } + // 还原literal标签 - $parseStr = $this->literal[$tag]; + $parseStr = $this->literal[$tag]; // 销毁literal记录 unset($this->literal[$tag]); return $parseStr; @@ -318,12 +360,13 @@ private function restoreLiteral($tag) { * @param string $content 模板内容 * @return string */ - private function parseBlock($name,$content = '') { - if(is_array($name)){ + private function parseBlock($name, $content = '') + { + if (is_array($name)) { $content = $name[2]; $name = $name[1]; } - $this->block[$name] = $content; + $this->block[$name] = $content; return ''; } @@ -333,19 +376,21 @@ private function parseBlock($name,$content = '') { * @param string $content 模板内容 * @return string */ - private function replaceBlock($content){ + private function replaceBlock($content) + { static $parse = 0; - $begin = $this->config['taglib_begin']; - $end = $this->config['taglib_end']; - $reg = '/('.$begin.'block\sname=[\'"](.+?)[\'"]\s*?'.$end.')(.*?)'.$begin.'\/block'.$end.'/is'; - if(is_string($content)){ - do{ + $begin = $this->config['taglib_begin']; + $end = $this->config['taglib_end']; + $reg = '/(' . $begin . 'block\sname=[\'"](.+?)[\'"]\s*?' . $end . ')(.*?)' . $begin . '\/block' . $end . '/is'; + if (is_string($content)) { + do { $content = preg_replace_callback($reg, array($this, 'replaceBlock'), $content); } while ($parse && $parse--); return $content; - } elseif(is_array($content)){ - if(preg_match('/'.$begin.'block\sname=[\'"](.+?)[\'"]\s*?'.$end.'/is', $content[3])){ //存在嵌套,进一步解析 - $parse = 1; + } elseif (is_array($content)) { + if (preg_match('/' . $begin . 'block\sname=[\'"](.+?)[\'"]\s*?' . $end . '/is', $content[3])) { + //存在嵌套,进一步解析 + $parse = 1; $content[3] = preg_replace_callback($reg, array($this, 'replaceBlock'), "{$content[3]}{$begin}/block{$end}"); return $content[1] . $content[3]; } else { @@ -364,15 +409,16 @@ private function replaceBlock($content){ * @param string $content 模板内容 * @return string|false */ - public function getIncludeTagLib(& $content) { + public function getIncludeTagLib(&$content) + { //搜索是否有TagLib标签 - $find = preg_match('/'.$this->config['taglib_begin'].'taglib\s(.+?)(\s*?)\/'.$this->config['taglib_end'].'\W/is',$content,$matches); - if($find) { + $find = preg_match('/' . $this->config['taglib_begin'] . 'taglib\s(.+?)(\s*?)\/' . $this->config['taglib_end'] . '\W/is', $content, $matches); + if ($find) { //替换TagLib标签 - $content = str_replace($matches[0],'',$content); + $content = str_replace($matches[0], '', $content); //解析TagLib标签 - $array = $this->parseXmlAttrs($matches[1]); - $this->tagLib = explode(',',$array['name']); + $array = $this->parseXmlAttrs($matches[1]); + $this->tagLib = explode(',', $array['name']); } return; } @@ -385,46 +431,48 @@ public function getIncludeTagLib(& $content) { * @param boolean $hide 是否隐藏标签库前缀 * @return string */ - public function parseTagLib($tagLib,&$content,$hide=false) { - $begin = $this->config['taglib_begin']; - $end = $this->config['taglib_end']; - if(strpos($tagLib,'\\')){ + public function parseTagLib($tagLib, &$content, $hide = false) + { + $begin = $this->config['taglib_begin']; + $end = $this->config['taglib_end']; + if (strpos($tagLib, '\\')) { // 支持指定标签库的命名空间 - $className = $tagLib; - $tagLib = substr($tagLib,strrpos($tagLib,'\\')+1); - }else{ - $className = 'Think\\Template\TagLib\\'.ucwords($tagLib); - } - $tLib = \Think\Think::instance($className); - $that = $this; - foreach ($tLib->getTags() as $name=>$val){ + $className = $tagLib; + $tagLib = substr($tagLib, strrpos($tagLib, '\\') + 1); + } else { + $className = 'Think\\Template\TagLib\\' . ucwords($tagLib); + } + $tLib = \Think\Think::instance($className); + $that = $this; + foreach ($tLib->getTags() as $name => $val) { $tags = array($name); - if(isset($val['alias'])) {// 别名设置 - $tags = explode(',',$val['alias']); - $tags[] = $name; + if (isset($val['alias'])) { +// 别名设置 + $tags = explode(',', $val['alias']); + $tags[] = $name; } - $level = isset($val['level'])?$val['level']:1; - $closeTag = isset($val['close'])?$val['close']:true; - foreach ($tags as $tag){ - $parseTag = !$hide? $tagLib.':'.$tag: $tag;// 实际要解析的标签名称 - if(!method_exists($tLib,'_'.$tag)) { + $level = isset($val['level']) ? $val['level'] : 1; + $closeTag = isset($val['close']) ? $val['close'] : true; + foreach ($tags as $tag) { + $parseTag = !$hide ? $tagLib . ':' . $tag : $tag; // 实际要解析的标签名称 + if (!method_exists($tLib, '_' . $tag)) { // 别名可以无需定义解析方法 - $tag = $name; + $tag = $name; } - $n1 = empty($val['attr'])?'(\s*?)':'\s([^'.$end.']*)'; + $n1 = empty($val['attr']) ? '(\s*?)' : '\s([^' . $end . ']*)'; $this->tempVar = array($tagLib, $tag); - if (!$closeTag){ - $patterns = '/'.$begin.$parseTag.$n1.'\/(\s*?)'.$end.'/is'; - $content = preg_replace_callback($patterns, function($matches) use($tLib,$tag,$that){ - return $that->parseXmlTag($tLib,$tag,$matches[1],$matches[2]); - },$content); - }else{ - $patterns = '/'.$begin.$parseTag.$n1.$end.'(.*?)'.$begin.'\/'.$parseTag.'(\s*?)'.$end.'/is'; - for($i=0;$i<$level;$i++) { - $content=preg_replace_callback($patterns,function($matches) use($tLib,$tag,$that){ - return $that->parseXmlTag($tLib,$tag,$matches[1],$matches[2]); - },$content); + if (!$closeTag) { + $patterns = '/' . $begin . $parseTag . $n1 . '\/(\s*?)' . $end . '/is'; + $content = preg_replace_callback($patterns, function ($matches) use ($tLib, $tag, $that) { + return $that->parseXmlTag($tLib, $tag, $matches[1], $matches[2]); + }, $content); + } else { + $patterns = '/' . $begin . $parseTag . $n1 . $end . '(.*?)' . $begin . '\/' . $parseTag . '(\s*?)' . $end . '/is'; + for ($i = 0; $i < $level; $i++) { + $content = preg_replace_callback($patterns, function ($matches) use ($tLib, $tag, $that) { + return $that->parseXmlTag($tLib, $tag, $matches[1], $matches[2]); + }, $content); } } } @@ -441,13 +489,16 @@ public function parseTagLib($tagLib,&$content,$hide=false) { * @param string $content 标签内容 * @return string|false */ - public function parseXmlTag($tagLib,$tag,$attr,$content) { - if(ini_get('magic_quotes_sybase')) - $attr = str_replace('\"','\'',$attr); - $parse = '_'.$tag; - $content = trim($content); - $tags = $tagLib->parseXmlAttr($attr,$tag); - return $tagLib->$parse($tags,$content); + public function parseXmlTag($tagLib, $tag, $attr, $content) + { + if (ini_get('magic_quotes_sybase')) { + $attr = str_replace('\"', '\'', $attr); + } + + $parse = '_' . $tag; + $content = trim($content); + $tags = $tagLib->parseXmlAttr($attr, $tag); + return $tagLib->$parse($tags, $content); } /** @@ -457,28 +508,36 @@ public function parseXmlTag($tagLib,$tag,$attr,$content) { * @param string $tagStr 标签内容 * @return string */ - public function parseTag($tagStr){ - if(is_array($tagStr)) $tagStr = $tagStr[2]; + public function parseTag($tagStr) + { + if (is_array($tagStr)) { + $tagStr = $tagStr[2]; + } + //if (MAGIC_QUOTES_GPC) { - $tagStr = stripslashes($tagStr); + $tagStr = stripslashes($tagStr); //} - $flag = substr($tagStr,0,1); - $flag2 = substr($tagStr,1,1); - $name = substr($tagStr,1); - if('$' == $flag && '.' != $flag2 && '(' != $flag2){ //解析模板变量 格式 {$varName} + $flag = substr($tagStr, 0, 1); + $flag2 = substr($tagStr, 1, 1); + $name = substr($tagStr, 1); + if ('$' == $flag && '.' != $flag2 && '(' != $flag2) { + //解析模板变量 格式 {$varName} return $this->parseVar($name); - }elseif('-' == $flag || '+'== $flag){ // 输出计算 - return ''; - }elseif(':' == $flag){ // 输出某个函数的结果 - return ''; - }elseif('~' == $flag){ // 执行某个函数 - return ''; - }elseif(substr($tagStr,0,2)=='//' || (substr($tagStr,0,2)=='/*' && substr(rtrim($tagStr),-2)=='*/')){ + } elseif ('-' == $flag || '+' == $flag) { + // 输出计算 + return ''; + } elseif (':' == $flag) { + // 输出某个函数的结果 + return ''; + } elseif ('~' == $flag) { + // 执行某个函数 + return ''; + } elseif (substr($tagStr, 0, 2) == '//' || (substr($tagStr, 0, 2) == '/*' && substr(rtrim($tagStr), -2) == '*/')) { //注释标签 return ''; } // 未识别的标签直接返回 - return C('TMPL_L_DELIM') . $tagStr .C('TMPL_R_DELIM'); + return C('TMPL_L_DELIM') . $tagStr . C('TMPL_R_DELIM'); } /** @@ -488,56 +547,66 @@ public function parseTag($tagStr){ * @param string $varStr 变量数据 * @return string */ - public function parseVar($varStr){ - $varStr = trim($varStr); + public function parseVar($varStr) + { + $varStr = trim($varStr); static $_varParseList = array(); //如果已经解析过该变量字串,则直接返回变量值 - if(isset($_varParseList[$varStr])) return $_varParseList[$varStr]; - $parseStr = ''; - $varExists = true; - if(!empty($varStr)){ - $varArray = explode('|',$varStr); + if (isset($_varParseList[$varStr])) { + return $_varParseList[$varStr]; + } + + $parseStr = ''; + $varExists = true; + if (!empty($varStr)) { + $varArray = explode('|', $varStr); //取得变量名称 $var = array_shift($varArray); - if('Think.' == substr($var,0,6)){ + if ('Think.' == substr($var, 0, 6)) { // 所有以Think.打头的以特殊变量对待 无需模板赋值就可以输出 $name = $this->parseThinkVar($var); - }elseif( false !== strpos($var,'.')) { + } elseif (false !== strpos($var, '.')) { //支持 {$var.property} - $vars = explode('.',$var); - $var = array_shift($vars); - switch(strtolower(C('TMPL_VAR_IDENTIFY'))) { + $vars = explode('.', $var); + $var = array_shift($vars); + switch (strtolower(C('TMPL_VAR_IDENTIFY'))) { case 'array': // 识别为数组 - $name = '$'.$var; - foreach ($vars as $key=>$val) - $name .= '["'.$val.'"]'; + $name = '$' . $var; + foreach ($vars as $key => $val) { + $name .= '["' . $val . '"]'; + } + break; - case 'obj': // 识别为对象 - $name = '$'.$var; - foreach ($vars as $key=>$val) - $name .= '->'.$val; + case 'obj': // 识别为对象 + $name = '$' . $var; + foreach ($vars as $key => $val) { + $name .= '->' . $val; + } + break; - default: // 自动判断数组或对象 只支持二维 - $name = 'is_array($'.$var.')?$'.$var.'["'.$vars[0].'"]:$'.$var.'->'.$vars[0]; + default: // 自动判断数组或对象 只支持二维 + $name = 'is_array($' . $var . ')?$' . $var . '["' . $vars[0] . '"]:$' . $var . '->' . $vars[0]; } - }elseif(false !== strpos($var,'[')) { + } elseif (false !== strpos($var, '[')) { //支持 {$var['key']} 方式输出数组 - $name = "$".$var; - preg_match('/(.+?)\[(.+?)\]/is',$var,$match); + $name = "$" . $var; + preg_match('/(.+?)\[(.+?)\]/is', $var, $match); $var = $match[1]; - }elseif(false !==strpos($var,':') && false ===strpos($var,'(') && false ===strpos($var,'::') && false ===strpos($var,'?')){ + } elseif (false !== strpos($var, ':') && false === strpos($var, '(') && false === strpos($var, '::') && false === strpos($var, '?')) { //支持 {$var:property} 方式输出对象的属性 - $vars = explode(':',$var); - $var = str_replace(':','->',$var); - $name = "$".$var; + $vars = explode(':', $var); + $var = str_replace(':', '->', $var); + $name = "$" . $var; $var = $vars[0]; - }else { + } else { $name = "$$var"; } //对变量使用函数 - if(count($varArray)>0) - $name = $this->parseVarFunction($name,$varArray); - $parseStr = ''; + if (count($varArray) > 0) { + $name = $this->parseVarFunction($name, $varArray); + } + + $parseStr = ''; } $_varParseList[$varStr] = $parseStr; return $parseStr; @@ -551,32 +620,33 @@ public function parseVar($varStr){ * @param array $varArray 函数列表 * @return string */ - public function parseVarFunction($name,$varArray){ + public function parseVarFunction($name, $varArray) + { //对变量使用函数 $length = count($varArray); //取得模板禁止使用函数列表 - $template_deny_funs = explode(',',C('TMPL_DENY_FUNC_LIST')); - for($i=0;$i<$length ;$i++ ){ - $args = explode('=',$varArray[$i],2); + $template_deny_funs = explode(',', C('TMPL_DENY_FUNC_LIST')); + for ($i = 0; $i < $length; $i++) { + $args = explode('=', $varArray[$i], 2); //模板函数过滤 $fun = trim($args[0]); - switch($fun) { - case 'default': // 特殊模板函数 - $name = '(isset('.$name.') && ('.$name.' !== ""))?('.$name.'):'.$args[1]; - break; - default: // 通用模板函数 - if(!in_array($fun,$template_deny_funs)){ - if(isset($args[1])){ - if(strstr($args[1],'###')){ - $args[1] = str_replace('###',$name,$args[1]); - $name = "$fun($args[1])"; - }else{ - $name = "$fun($name,$args[1])"; + switch ($fun) { + case 'default': // 特殊模板函数 + $name = '(isset(' . $name . ') && (' . $name . ' !== ""))?(' . $name . '):' . $args[1]; + break; + default: // 通用模板函数 + if (!in_array($fun, $template_deny_funs)) { + if (isset($args[1])) { + if (strstr($args[1], '###')) { + $args[1] = str_replace('###', $name, $args[1]); + $name = "$fun($args[1])"; + } else { + $name = "$fun($name,$args[1])"; + } + } else if (!empty($args[0])) { + $name = "$fun($name)"; } - }else if(!empty($args[0])){ - $name = "$fun($name)"; } - } } } return $name; @@ -589,50 +659,59 @@ public function parseVarFunction($name,$varArray){ * @param string $varStr 变量字符串 * @return string */ - public function parseThinkVar($varStr){ - $vars = explode('.',$varStr); - $vars[1] = strtoupper(trim($vars[1])); + public function parseThinkVar($varStr) + { + $vars = explode('.', $varStr); + $vars[1] = strtoupper(trim($vars[1])); $parseStr = ''; - if(count($vars)>=3){ + if (count($vars) >= 3) { $vars[2] = trim($vars[2]); - switch($vars[1]){ + switch ($vars[1]) { case 'SERVER': - $parseStr = '$_SERVER[\''.strtoupper($vars[2]).'\']';break; + $parseStr = '$_SERVER[\'' . strtoupper($vars[2]) . '\']'; + break; case 'GET': - $parseStr = '$_GET[\''.$vars[2].'\']';break; + $parseStr = '$_GET[\'' . $vars[2] . '\']'; + break; case 'POST': - $parseStr = '$_POST[\''.$vars[2].'\']';break; + $parseStr = '$_POST[\'' . $vars[2] . '\']'; + break; case 'COOKIE': - if(isset($vars[3])) { - $parseStr = '$_COOKIE[\''.$vars[2].'\'][\''.$vars[3].'\']'; - }else{ - $parseStr = 'cookie(\''.$vars[2].'\')'; + if (isset($vars[3])) { + $parseStr = '$_COOKIE[\'' . $vars[2] . '\'][\'' . $vars[3] . '\']'; + } else { + $parseStr = 'cookie(\'' . $vars[2] . '\')'; } break; case 'SESSION': - if(isset($vars[3])) { - $parseStr = '$_SESSION[\''.$vars[2].'\'][\''.$vars[3].'\']'; - }else{ - $parseStr = 'session(\''.$vars[2].'\')'; + if (isset($vars[3])) { + $parseStr = '$_SESSION[\'' . $vars[2] . '\'][\'' . $vars[3] . '\']'; + } else { + $parseStr = 'session(\'' . $vars[2] . '\')'; } break; case 'ENV': - $parseStr = '$_ENV[\''.strtoupper($vars[2]).'\']';break; + $parseStr = '$_ENV[\'' . strtoupper($vars[2]) . '\']'; + break; case 'REQUEST': - $parseStr = '$_REQUEST[\''.$vars[2].'\']';break; + $parseStr = '$_REQUEST[\'' . $vars[2] . '\']'; + break; case 'CONST': - $parseStr = strtoupper($vars[2]);break; + $parseStr = strtoupper($vars[2]); + break; case 'LANG': - $parseStr = 'L("'.$vars[2].'")';break; + $parseStr = 'L("' . $vars[2] . '")'; + break; case 'CONFIG': - if(isset($vars[3])) { - $vars[2] .= '.'.$vars[3]; + if (isset($vars[3])) { + $vars[2] .= '.' . $vars[3]; } - $parseStr = 'C("'.$vars[2].'")';break; + $parseStr = 'C("' . $vars[2] . '")'; + break; default:break; } - }else if(count($vars)==2){ - switch($vars[1]){ + } else if (count($vars) == 2) { + switch ($vars[1]) { case 'NOW': $parseStr = "date('Y-m-d g:i a',time())"; break; @@ -640,7 +719,7 @@ public function parseThinkVar($varStr){ $parseStr = 'THINK_VERSION'; break; case 'TEMPLATE': - $parseStr = "'".$this->templateFile."'";//'C("TEMPLATE_NAME")'; + $parseStr = "'" . $this->templateFile . "'"; //'C("TEMPLATE_NAME")'; break; case 'LDELIM': $parseStr = 'C("TMPL_L_DELIM")'; @@ -649,8 +728,10 @@ public function parseThinkVar($varStr){ $parseStr = 'C("TMPL_R_DELIM")'; break; default: - if(defined($vars[1])) + if (defined($vars[1])) { $parseStr = $vars[1]; + } + } } return $parseStr; @@ -663,15 +744,16 @@ public function parseThinkVar($varStr){ * @param array $vars 要传递的变量列表 * @return string */ - private function parseIncludeItem($tmplPublicName,$vars=array(),$extend){ + private function parseIncludeItem($tmplPublicName, $vars = array(), $extend) + { // 分析模板文件名并读取内容 $parseStr = $this->parseTemplateName($tmplPublicName); // 替换变量 - foreach ($vars as $key=>$val) { - $parseStr = str_replace('['.$key.']',$val,$parseStr); + foreach ($vars as $key => $val) { + $parseStr = str_replace('[' . $key . ']', $val, $parseStr); } // 再次对包含文件进行模板分析 - return $this->parseInclude($parseStr,$extend); + return $this->parseInclude($parseStr, $extend); } /** @@ -679,22 +761,29 @@ private function parseIncludeItem($tmplPublicName,$vars=array(),$extend){ * @access private * @param string $tmplPublicName 模板文件名 * @return string - */ - private function parseTemplateName($templateName){ - if(substr($templateName,0,1)=='$') - //支持加载变量文件名 - $templateName = $this->get(substr($templateName,1)); - $array = explode(',',$templateName); - $parseStr = ''; - foreach ($array as $templateName){ - if(empty($templateName)) continue; - if(false === strpos($templateName,$this->config['template_suffix'])) { + */ + private function parseTemplateName($templateName) + { + if (substr($templateName, 0, 1) == '$') + //支持加载变量文件名 + { + $templateName = $this->get(substr($templateName, 1)); + } + + $array = explode(',', $templateName); + $parseStr = ''; + foreach ($array as $templateName) { + if (empty($templateName)) { + continue; + } + + if (false === strpos($templateName, $this->config['template_suffix'])) { // 解析规则为 模块@主题/控制器/操作 - $templateName = T($templateName); + $templateName = T($templateName); } // 获取模板文件内容 $parseStr .= file_get_contents($templateName); } return $parseStr; - } + } } diff --git a/ThinkPHP/Library/Think/Template/Driver/Ease.class.php b/ThinkPHP/Library/Think/Template/Driver/Ease.class.php index 192bde0e6..b0b4399d7 100644 --- a/ThinkPHP/Library/Think/Template/Driver/Ease.class.php +++ b/ThinkPHP/Library/Think/Template/Driver/Ease.class.php @@ -9,10 +9,12 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think\Template\Driver; + /** - * EaseTemplate模板引擎驱动 + * EaseTemplate模板引擎驱动 */ -class Ease { +class Ease +{ /** * 渲染模板输出 * @access public @@ -20,22 +22,23 @@ class Ease { * @param array $var 模板变量 * @return void */ - public function fetch($templateFile,$var) { - $templateFile = substr($templateFile,strlen(THEME_PATH),-5); - $CacheDir = substr(CACHE_PATH,0,-1); - $TemplateDir = substr(THEME_PATH,0,-1); + public function fetch($templateFile, $var) + { + $templateFile = substr($templateFile, strlen(THEME_PATH), -5); + $CacheDir = substr(CACHE_PATH, 0, -1); + $TemplateDir = substr(THEME_PATH, 0, -1); vendor('EaseTemplate.template#ease'); - $config = array( - 'CacheDir' => $CacheDir, - 'TemplateDir' => $TemplateDir, - 'TplType' => 'html' - ); - if(C('TMPL_ENGINE_CONFIG')) { - $config = array_merge($config,C('TMPL_ENGINE_CONFIG')); + $config = array( + 'CacheDir' => $CacheDir, + 'TemplateDir' => $TemplateDir, + 'TplType' => 'html', + ); + if (C('TMPL_ENGINE_CONFIG')) { + $config = array_merge($config, C('TMPL_ENGINE_CONFIG')); } $tpl = new \EaseTemplate($config); $tpl->set_var($var); $tpl->set_file($templateFile); $tpl->p(); } -} \ No newline at end of file +} diff --git a/ThinkPHP/Library/Think/Template/Driver/Lite.class.php b/ThinkPHP/Library/Think/Template/Driver/Lite.class.php index 5f73a02cb..c7a42a072 100644 --- a/ThinkPHP/Library/Think/Template/Driver/Lite.class.php +++ b/ThinkPHP/Library/Think/Template/Driver/Lite.class.php @@ -9,10 +9,12 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think\Template\Driver; + /** - * TemplateLite模板引擎驱动 + * TemplateLite模板引擎驱动 */ -class Lite { +class Lite +{ /** * 渲染模板输出 * @access public @@ -20,20 +22,21 @@ class Lite { * @param array $var 模板变量 * @return void */ - public function fetch($templateFile,$var) { + public function fetch($templateFile, $var) + { vendor("TemplateLite.class#template"); - $templateFile = substr($templateFile,strlen(THEME_PATH)); - $tpl = new \Template_Lite(); - $tpl->template_dir = THEME_PATH; - $tpl->compile_dir = CACHE_PATH ; - $tpl->cache_dir = TEMP_PATH ; - if(C('TMPL_ENGINE_CONFIG')) { - $config = C('TMPL_ENGINE_CONFIG'); - foreach ($config as $key=>$val){ - $tpl->{$key} = $val; + $templateFile = substr($templateFile, strlen(THEME_PATH)); + $tpl = new \Template_Lite(); + $tpl->template_dir = THEME_PATH; + $tpl->compile_dir = CACHE_PATH; + $tpl->cache_dir = TEMP_PATH; + if (C('TMPL_ENGINE_CONFIG')) { + $config = C('TMPL_ENGINE_CONFIG'); + foreach ($config as $key => $val) { + $tpl->{$key} = $val; } } $tpl->assign($var); $tpl->display($templateFile); } -} \ No newline at end of file +} diff --git a/ThinkPHP/Library/Think/Template/Driver/Mobile.class.php b/ThinkPHP/Library/Think/Template/Driver/Mobile.class.php index db39e7fda..671549619 100644 --- a/ThinkPHP/Library/Think/Template/Driver/Mobile.class.php +++ b/ThinkPHP/Library/Think/Template/Driver/Mobile.class.php @@ -9,10 +9,12 @@ // | Author: luofei614 // +---------------------------------------------------------------------- namespace Think\Template\Driver; + /** - * MobileTemplate模板引擎驱动 + * MobileTemplate模板引擎驱动 */ -class Mobile { +class Mobile +{ /** * 渲染模板输出 * @access public @@ -20,9 +22,10 @@ class Mobile { * @param array $var 模板变量 * @return void */ - public function fetch($templateFile,$var) { - $templateFile=substr($templateFile,strlen(THEME_PATH)); - $var['_think_template_path']=$templateFile; - exit(json_encode($var)); + public function fetch($templateFile, $var) + { + $templateFile = substr($templateFile, strlen(THEME_PATH)); + $var['_think_template_path'] = $templateFile; + exit(json_encode($var)); } } diff --git a/ThinkPHP/Library/Think/Template/Driver/Smart.class.php b/ThinkPHP/Library/Think/Template/Driver/Smart.class.php index 5a2eb1c88..c830f4565 100644 --- a/ThinkPHP/Library/Think/Template/Driver/Smart.class.php +++ b/ThinkPHP/Library/Think/Template/Driver/Smart.class.php @@ -9,10 +9,12 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think\Template\Driver; + /** - * Smart模板引擎驱动 + * Smart模板引擎驱动 */ -class Smart { +class Smart +{ /** * 渲染模板输出 * @access public @@ -20,21 +22,22 @@ class Smart { * @param array $var 模板变量 * @return void */ - public function fetch($templateFile,$var) { - $templateFile = substr($templateFile,strlen(THEME_PATH)); + public function fetch($templateFile, $var) + { + $templateFile = substr($templateFile, strlen(THEME_PATH)); vendor('SmartTemplate.class#smarttemplate'); - $tpl = new \SmartTemplate($templateFile); - $tpl->caching = C('TMPL_CACHE_ON'); - $tpl->template_dir = THEME_PATH; - $tpl->compile_dir = CACHE_PATH ; - $tpl->cache_dir = TEMP_PATH ; - if(C('TMPL_ENGINE_CONFIG')) { - $config = C('TMPL_ENGINE_CONFIG'); - foreach ($config as $key=>$val){ - $tpl->{$key} = $val; + $tpl = new \SmartTemplate($templateFile); + $tpl->caching = C('TMPL_CACHE_ON'); + $tpl->template_dir = THEME_PATH; + $tpl->compile_dir = CACHE_PATH; + $tpl->cache_dir = TEMP_PATH; + if (C('TMPL_ENGINE_CONFIG')) { + $config = C('TMPL_ENGINE_CONFIG'); + foreach ($config as $key => $val) { + $tpl->{$key} = $val; } } $tpl->assign($var); $tpl->output(); } -} \ No newline at end of file +} diff --git a/ThinkPHP/Library/Think/Template/Driver/Smarty.class.php b/ThinkPHP/Library/Think/Template/Driver/Smarty.class.php index aecdc100c..a6fa823c5 100644 --- a/ThinkPHP/Library/Think/Template/Driver/Smarty.class.php +++ b/ThinkPHP/Library/Think/Template/Driver/Smarty.class.php @@ -9,10 +9,12 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think\Template\Driver; + /** - * Smarty模板引擎驱动 + * Smarty模板引擎驱动 */ -class Smarty { +class Smarty +{ /** * 渲染模板输出 @@ -21,21 +23,22 @@ class Smarty { * @param array $var 模板变量 * @return void */ - public function fetch($templateFile,$var) { - $templateFile = substr($templateFile,strlen(THEME_PATH)); + public function fetch($templateFile, $var) + { + $templateFile = substr($templateFile, strlen(THEME_PATH)); vendor('Smarty.Smarty#class'); - $tpl = new \Smarty(); - $tpl->caching = C('TMPL_CACHE_ON'); - $tpl->template_dir = THEME_PATH; - $tpl->compile_dir = CACHE_PATH ; - $tpl->cache_dir = TEMP_PATH ; - if(C('TMPL_ENGINE_CONFIG')) { - $config = C('TMPL_ENGINE_CONFIG'); - foreach ($config as $key=>$val){ - $tpl->{$key} = $val; + $tpl = new \Smarty(); + $tpl->caching = C('TMPL_CACHE_ON'); + $tpl->template_dir = THEME_PATH; + $tpl->compile_dir = CACHE_PATH; + $tpl->cache_dir = TEMP_PATH; + if (C('TMPL_ENGINE_CONFIG')) { + $config = C('TMPL_ENGINE_CONFIG'); + foreach ($config as $key => $val) { + $tpl->{$key} = $val; } } $tpl->assign($var); $tpl->display($templateFile); } -} \ No newline at end of file +} diff --git a/ThinkPHP/Library/Think/Template/TagLib.class.php b/ThinkPHP/Library/Think/Template/TagLib.class.php index 18e3be8d4..1426212c8 100644 --- a/ThinkPHP/Library/Think/Template/TagLib.class.php +++ b/ThinkPHP/Library/Think/Template/TagLib.class.php @@ -9,45 +9,47 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think\Template; + /** * ThinkPHP标签库TagLib解析基类 */ -class TagLib { +class TagLib +{ /** * 标签库定义XML文件 * @var string * @access protected */ - protected $xml = ''; - protected $tags = array();// 标签定义 + protected $xml = ''; + protected $tags = array(); // 标签定义 /** * 标签库名称 * @var string * @access protected */ - protected $tagLib =''; + protected $tagLib = ''; /** * 标签库标签列表 * @var string * @access protected */ - protected $tagList = array(); + protected $tagList = array(); /** * 标签库分析数组 * @var string * @access protected */ - protected $parse = array(); + protected $parse = array(); /** * 标签库是否有效 * @var string * @access protected */ - protected $valid = false; + protected $valid = false; /** * 当前模板对象 @@ -56,15 +58,16 @@ class TagLib { */ protected $tpl; - protected $comparison = array(' nheq '=>' !== ',' heq '=>' === ',' neq '=>' != ',' eq '=>' == ',' egt '=>' >= ',' gt '=>' > ',' elt '=>' <= ',' lt '=>' < '); + protected $comparison = array(' nheq ' => ' !== ', ' heq ' => ' === ', ' neq ' => ' != ', ' eq ' => ' == ', ' egt ' => ' >= ', ' gt ' => ' > ', ' elt ' => ' <= ', ' lt ' => ' < '); /** * 架构函数 * @access public */ - public function __construct() { - $this->tagLib = strtolower(substr(get_class($this),6)); - $this->tpl = \Think\Think::instance('Think\\Template'); + public function __construct() + { + $this->tagLib = strtolower(substr(get_class($this), 6)); + $this->tpl = \Think\Think::instance('Think\\Template'); } /** @@ -73,46 +76,47 @@ public function __construct() { * @param string $tagStr 标签内容 * @return array */ - public function parseXmlAttr($attr,$tag) { + public function parseXmlAttr($attr, $tag) + { //XML解析安全过滤 - $attr = str_replace('&','___', $attr); - $xml = ''; - $xml = simplexml_load_string($xml); - if(!$xml) { - E(L('_XML_TAG_ERROR_').' : '.$attr); + $attr = str_replace('&', '___', $attr); + $xml = ''; + $xml = simplexml_load_string($xml); + if (!$xml) { + E(L('_XML_TAG_ERROR_') . ' : ' . $attr); } - $xml = (array)($xml->tag->attributes()); - if(isset($xml['@attributes'])){ - $array = array_change_key_case($xml['@attributes']); - if($array) { - $tag = strtolower($tag); - if(!isset($this->tags[$tag])){ + $xml = (array) ($xml->tag->attributes()); + if (isset($xml['@attributes'])) { + $array = array_change_key_case($xml['@attributes']); + if ($array) { + $tag = strtolower($tag); + if (!isset($this->tags[$tag])) { // 检测是否存在别名定义 - foreach($this->tags as $key=>$val){ - if(isset($val['alias']) && in_array($tag,explode(',',$val['alias']))){ - $item = $val; + foreach ($this->tags as $key => $val) { + if (isset($val['alias']) && in_array($tag, explode(',', $val['alias']))) { + $item = $val; break; } } - }else{ - $item = $this->tags[$tag]; - } - $attrs = explode(',',$item['attr']); - if(isset($item['must'])){ - $must = explode(',',$item['must']); - }else{ - $must = array(); + } else { + $item = $this->tags[$tag]; + } + $attrs = explode(',', $item['attr']); + if (isset($item['must'])) { + $must = explode(',', $item['must']); + } else { + $must = array(); } - foreach($attrs as $name) { - if( isset($array[$name])) { - $array[$name] = str_replace('___','&',$array[$name]); - }elseif(false !== array_search($name,$must)){ - E(L('_PARAM_ERROR_').':'.$name); + foreach ($attrs as $name) { + if (isset($array[$name])) { + $array[$name] = str_replace('___', '&', $array[$name]); + } elseif (false !== array_search($name, $must)) { + E(L('_PARAM_ERROR_') . ':' . $name); } } return $array; } - }else{ + } else { return array(); } } @@ -123,21 +127,24 @@ public function parseXmlAttr($attr,$tag) { * @param string $condition 表达式标签内容 * @return array */ - public function parseCondition($condition) { - $condition = str_ireplace(array_keys($this->comparison),array_values($this->comparison),$condition); - $condition = preg_replace('/\$(\w+):(\w+)\s/is','$\\1->\\2 ',$condition); - switch(strtolower(C('TMPL_VAR_IDENTIFY'))) { + public function parseCondition($condition) + { + $condition = str_ireplace(array_keys($this->comparison), array_values($this->comparison), $condition); + $condition = preg_replace('/\$(\w+):(\w+)\s/is', '$\\1->\\2 ', $condition); + switch (strtolower(C('TMPL_VAR_IDENTIFY'))) { case 'array': // 识别为数组 - $condition = preg_replace('/\$(\w+)\.(\w+)\s/is','$\\1["\\2"] ',$condition); + $condition = preg_replace('/\$(\w+)\.(\w+)\s/is', '$\\1["\\2"] ', $condition); break; - case 'obj': // 识别为对象 - $condition = preg_replace('/\$(\w+)\.(\w+)\s/is','$\\1->\\2 ',$condition); + case 'obj': // 识别为对象 + $condition = preg_replace('/\$(\w+)\.(\w+)\s/is', '$\\1->\\2 ', $condition); break; - default: // 自动判断数组或对象 只支持二维 - $condition = preg_replace('/\$(\w+)\.(\w+)\s/is','(is_array($\\1)?$\\1["\\2"]:$\\1->\\2) ',$condition); + default: // 自动判断数组或对象 只支持二维 + $condition = preg_replace('/\$(\w+)\.(\w+)\s/is', '(is_array($\\1)?$\\1["\\2"]:$\\1->\\2) ', $condition); + } + if (false !== strpos($condition, '$Think')) { + $condition = preg_replace_callback('/(\$Think.*?)\s/is', array($this, 'parseThinkVar'), $condition); } - if(false !== strpos($condition, '$Think')) - $condition = preg_replace_callback('/(\$Think.*?)\s/is', array($this, 'parseThinkVar'), $condition); + return $condition; } @@ -147,37 +154,40 @@ public function parseCondition($condition) { * @param string $name 变量描述 * @return string */ - public function autoBuildVar($name) { - if('Think.' == substr($name,0,6)){ + public function autoBuildVar($name) + { + if ('Think.' == substr($name, 0, 6)) { // 特殊变量 return $this->parseThinkVar($name); - }elseif(strpos($name,'.')) { - $vars = explode('.',$name); - $var = array_shift($vars); - switch(strtolower(C('TMPL_VAR_IDENTIFY'))) { + } elseif (strpos($name, '.')) { + $vars = explode('.', $name); + $var = array_shift($vars); + switch (strtolower(C('TMPL_VAR_IDENTIFY'))) { case 'array': // 识别为数组 - $name = '$'.$var; - foreach ($vars as $key=>$val){ - if(0===strpos($val,'$')) { - $name .= '["{'.$val.'}"]'; - }else{ - $name .= '["'.$val.'"]'; + $name = '$' . $var; + foreach ($vars as $key => $val) { + if (0 === strpos($val, '$')) { + $name .= '["{' . $val . '}"]'; + } else { + $name .= '["' . $val . '"]'; } } break; - case 'obj': // 识别为对象 - $name = '$'.$var; - foreach ($vars as $key=>$val) - $name .= '->'.$val; + case 'obj': // 识别为对象 + $name = '$' . $var; + foreach ($vars as $key => $val) { + $name .= '->' . $val; + } + break; - default: // 自动判断数组或对象 只支持二维 - $name = 'is_array($'.$var.')?$'.$var.'["'.$vars[0].'"]:$'.$var.'->'.$vars[0]; + default: // 自动判断数组或对象 只支持二维 + $name = 'is_array($' . $var . ')?$' . $var . '["' . $vars[0] . '"]:$' . $var . '->' . $vars[0]; } - }elseif(strpos($name,':')){ + } elseif (strpos($name, ':')) { // 额外的对象方式支持 - $name = '$'.str_replace(':','->',$name); - }elseif(!defined($name)) { - $name = '$'.$name; + $name = '$' . str_replace(':', '->', $name); + } elseif (!defined($name)) { + $name = '$' . $name; } return $name; } @@ -189,58 +199,77 @@ public function autoBuildVar($name) { * @param string $varStr 变量字符串 * @return string */ - public function parseThinkVar($varStr){ - if(is_array($varStr)){//用于正则替换回调函数 - $varStr = $varStr[1]; + public function parseThinkVar($varStr) + { + if (is_array($varStr)) { +//用于正则替换回调函数 + $varStr = $varStr[1]; } - $vars = explode('.',$varStr); - $vars[1] = strtoupper(trim($vars[1])); - $parseStr = ''; - if(count($vars)>=3){ + $vars = explode('.', $varStr); + $vars[1] = strtoupper(trim($vars[1])); + $parseStr = ''; + if (count($vars) >= 3) { $vars[2] = trim($vars[2]); - switch($vars[1]){ - case 'SERVER': $parseStr = '$_SERVER[\''.$vars[2].'\']';break; - case 'GET': $parseStr = '$_GET[\''.$vars[2].'\']';break; - case 'POST': $parseStr = '$_POST[\''.$vars[2].'\']';break; + switch ($vars[1]) { + case 'SERVER':$parseStr = '$_SERVER[\'' . $vars[2] . '\']'; + break; + case 'GET':$parseStr = '$_GET[\'' . $vars[2] . '\']'; + break; + case 'POST':$parseStr = '$_POST[\'' . $vars[2] . '\']'; + break; case 'COOKIE': - if(isset($vars[3])) { - $parseStr = '$_COOKIE[\''.$vars[2].'\'][\''.$vars[3].'\']'; - }elseif(C('COOKIE_PREFIX')){ - $parseStr = '$_COOKIE[\''.C('COOKIE_PREFIX').$vars[2].'\']'; - }else{ - $parseStr = '$_COOKIE[\''.$vars[2].'\']'; + if (isset($vars[3])) { + $parseStr = '$_COOKIE[\'' . $vars[2] . '\'][\'' . $vars[3] . '\']'; + } elseif (C('COOKIE_PREFIX')) { + $parseStr = '$_COOKIE[\'' . C('COOKIE_PREFIX') . $vars[2] . '\']'; + } else { + $parseStr = '$_COOKIE[\'' . $vars[2] . '\']'; } break; case 'SESSION': - if(isset($vars[3])) { - $parseStr = '$_SESSION[\''.$vars[2].'\'][\''.$vars[3].'\']'; - }elseif(C('SESSION_PREFIX')){ - $parseStr = '$_SESSION[\''.C('SESSION_PREFIX').'\'][\''.$vars[2].'\']'; - }else{ - $parseStr = '$_SESSION[\''.$vars[2].'\']'; + if (isset($vars[3])) { + $parseStr = '$_SESSION[\'' . $vars[2] . '\'][\'' . $vars[3] . '\']'; + } elseif (C('SESSION_PREFIX')) { + $parseStr = '$_SESSION[\'' . C('SESSION_PREFIX') . '\'][\'' . $vars[2] . '\']'; + } else { + $parseStr = '$_SESSION[\'' . $vars[2] . '\']'; } break; - case 'ENV': $parseStr = '$_ENV[\''.$vars[2].'\']';break; - case 'REQUEST': $parseStr = '$_REQUEST[\''.$vars[2].'\']';break; - case 'CONST': $parseStr = strtoupper($vars[2]);break; - case 'LANG': $parseStr = 'L("'.$vars[2].'")';break; - case 'CONFIG': $parseStr = 'C("'.$vars[2].'")';break; + case 'ENV':$parseStr = '$_ENV[\'' . $vars[2] . '\']'; + break; + case 'REQUEST':$parseStr = '$_REQUEST[\'' . $vars[2] . '\']'; + break; + case 'CONST':$parseStr = strtoupper($vars[2]); + break; + case 'LANG':$parseStr = 'L("' . $vars[2] . '")'; + break; + case 'CONFIG':$parseStr = 'C("' . $vars[2] . '")'; + break; } - }else if(count($vars)==2){ - switch($vars[1]){ - case 'NOW': $parseStr = "date('Y-m-d g:i a',time())";break; - case 'VERSION': $parseStr = 'THINK_VERSION';break; - case 'TEMPLATE':$parseStr = 'C("TEMPLATE_NAME")';break; - case 'LDELIM': $parseStr = 'C("TMPL_L_DELIM")';break; - case 'RDELIM': $parseStr = 'C("TMPL_R_DELIM")';break; - default: if(defined($vars[1])) $parseStr = $vars[1]; + } else if (count($vars) == 2) { + switch ($vars[1]) { + case 'NOW':$parseStr = "date('Y-m-d g:i a',time())"; + break; + case 'VERSION':$parseStr = 'THINK_VERSION'; + break; + case 'TEMPLATE':$parseStr = 'C("TEMPLATE_NAME")'; + break; + case 'LDELIM':$parseStr = 'C("TMPL_L_DELIM")'; + break; + case 'RDELIM':$parseStr = 'C("TMPL_R_DELIM")'; + break; + default:if (defined($vars[1])) { + $parseStr = $vars[1]; + } + } } return $parseStr; } // 获取标签定义 - public function getTags(){ + public function getTags() + { return $this->tags; } -} \ No newline at end of file +} diff --git a/ThinkPHP/Library/Think/Template/TagLib/Cx.class.php b/ThinkPHP/Library/Think/Template/TagLib/Cx.class.php index 67b5dd49e..901e20c49 100644 --- a/ThinkPHP/Library/Think/Template/TagLib/Cx.class.php +++ b/ThinkPHP/Library/Think/Template/TagLib/Cx.class.php @@ -9,37 +9,40 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think\Template\TagLib; + use Think\Template\TagLib; + /** * CX标签库解析类 */ -class Cx extends TagLib { +class Cx extends TagLib +{ // 标签定义 - protected $tags = array( + protected $tags = array( // 标签定义: attr 属性列表 close 是否闭合(0 或者1 默认1) alias 标签别名 level 嵌套层次 - 'php' => array(), - 'volist' => array('attr'=>'name,id,offset,length,key,mod','level'=>3,'alias'=>'iterate'), - 'foreach' => array('attr'=>'name,item,key','level'=>3), - 'if' => array('attr'=>'condition','level'=>2), - 'elseif' => array('attr'=>'condition','close'=>0), - 'else' => array('attr'=>'','close'=>0), - 'switch' => array('attr'=>'name','level'=>2), - 'case' => array('attr'=>'value,break'), - 'default' => array('attr'=>'','close'=>0), - 'compare' => array('attr'=>'name,value,type','level'=>3,'alias'=>'eq,equal,notequal,neq,gt,lt,egt,elt,heq,nheq'), - 'range' => array('attr'=>'name,value,type','level'=>3,'alias'=>'in,notin,between,notbetween'), - 'empty' => array('attr'=>'name','level'=>3), - 'notempty' => array('attr'=>'name','level'=>3), - 'present' => array('attr'=>'name','level'=>3), - 'notpresent'=> array('attr'=>'name','level'=>3), - 'defined' => array('attr'=>'name','level'=>3), - 'notdefined'=> array('attr'=>'name','level'=>3), - 'import' => array('attr'=>'file,href,type,value,basepath','close'=>0,'alias'=>'load,css,js'), - 'assign' => array('attr'=>'name,value','close'=>0), - 'define' => array('attr'=>'name,value','close'=>0), - 'for' => array('attr'=>'start,end,name,comparison,step', 'level'=>3), - ); + 'php' => array(), + 'volist' => array('attr' => 'name,id,offset,length,key,mod', 'level' => 3, 'alias' => 'iterate'), + 'foreach' => array('attr' => 'name,item,key', 'level' => 3), + 'if' => array('attr' => 'condition', 'level' => 2), + 'elseif' => array('attr' => 'condition', 'close' => 0), + 'else' => array('attr' => '', 'close' => 0), + 'switch' => array('attr' => 'name', 'level' => 2), + 'case' => array('attr' => 'value,break'), + 'default' => array('attr' => '', 'close' => 0), + 'compare' => array('attr' => 'name,value,type', 'level' => 3, 'alias' => 'eq,equal,notequal,neq,gt,lt,egt,elt,heq,nheq'), + 'range' => array('attr' => 'name,value,type', 'level' => 3, 'alias' => 'in,notin,between,notbetween'), + 'empty' => array('attr' => 'name', 'level' => 3), + 'notempty' => array('attr' => 'name', 'level' => 3), + 'present' => array('attr' => 'name', 'level' => 3), + 'notpresent' => array('attr' => 'name', 'level' => 3), + 'defined' => array('attr' => 'name', 'level' => 3), + 'notdefined' => array('attr' => 'name', 'level' => 3), + 'import' => array('attr' => 'file,href,type,value,basepath', 'close' => 0, 'alias' => 'load,css,js'), + 'assign' => array('attr' => 'name,value', 'close' => 0), + 'define' => array('attr' => 'name,value', 'close' => 0), + 'for' => array('attr' => 'start,end,name,comparison,step', 'level' => 3), + ); /** * php标签解析 @@ -48,8 +51,9 @@ class Cx extends TagLib { * @param string $content 标签内容 * @return string */ - public function _php($tag,$content) { - $parseStr = ''; + public function _php($tag, $content) + { + $parseStr = ''; return $parseStr; } @@ -65,40 +69,41 @@ public function _php($tag,$content) { * @param string $content 标签内容 * @return string|void */ - public function _volist($tag,$content) { - $name = $tag['name']; - $id = $tag['id']; - $empty = isset($tag['empty'])?$tag['empty']:''; - $key = !empty($tag['key'])?$tag['key']:'i'; - $mod = isset($tag['mod'])?$tag['mod']:'2'; + public function _volist($tag, $content) + { + $name = $tag['name']; + $id = $tag['id']; + $empty = isset($tag['empty']) ? $tag['empty'] : ''; + $key = !empty($tag['key']) ? $tag['key'] : 'i'; + $mod = isset($tag['mod']) ? $tag['mod'] : '2'; // 允许使用函数设定数据集 {$vo.name} - $parseStr = 'autoBuildVar($name); + $parseStr = 'autoBuildVar($name); } - $parseStr .= 'if(is_array('.$name.')): $'.$key.' = 0;'; - if(isset($tag['length']) && '' !=$tag['length'] ) { - $parseStr .= ' $__LIST__ = array_slice('.$name.','.$tag['offset'].','.$tag['length'].',true);'; - }elseif(isset($tag['offset']) && '' !=$tag['offset']){ - $parseStr .= ' $__LIST__ = array_slice('.$name.','.$tag['offset'].',null,true);'; - }else{ - $parseStr .= ' $__LIST__ = '.$name.';'; + $parseStr .= 'if(is_array(' . $name . ')): $' . $key . ' = 0;'; + if (isset($tag['length']) && '' != $tag['length']) { + $parseStr .= ' $__LIST__ = array_slice(' . $name . ',' . $tag['offset'] . ',' . $tag['length'] . ',true);'; + } elseif (isset($tag['offset']) && '' != $tag['offset']) { + $parseStr .= ' $__LIST__ = array_slice(' . $name . ',' . $tag['offset'] . ',null,true);'; + } else { + $parseStr .= ' $__LIST__ = ' . $name . ';'; } - $parseStr .= 'if( count($__LIST__)==0 ) : echo "'.$empty.'" ;'; + $parseStr .= 'if( count($__LIST__)==0 ) : echo "' . $empty . '" ;'; $parseStr .= 'else: '; - $parseStr .= 'foreach($__LIST__ as $key=>$'.$id.'): '; - $parseStr .= '$mod = ($'.$key.' % '.$mod.' );'; - $parseStr .= '++$'.$key.';?>'; + $parseStr .= 'foreach($__LIST__ as $key=>$' . $id . '): '; + $parseStr .= '$mod = ($' . $key . ' % ' . $mod . ' );'; + $parseStr .= '++$' . $key . ';?>'; $parseStr .= $this->tpl->parse($content); - $parseStr .= ''; + $parseStr .= ''; - if(!empty($parseStr)) { + if (!empty($parseStr)) { return $parseStr; } - return ; + return; } /** @@ -108,19 +113,20 @@ public function _volist($tag,$content) { * @param string $content 标签内容 * @return string|void */ - public function _foreach($tag,$content) { - $name = $tag['name']; - $item = $tag['item']; - $key = !empty($tag['key'])?$tag['key']:'key'; - $name = $this->autoBuildVar($name); - $parseStr = '$'.$item.'): ?>'; - $parseStr .= $this->tpl->parse($content); - $parseStr .= ''; - - if(!empty($parseStr)) { + public function _foreach($tag, $content) + { + $name = $tag['name']; + $item = $tag['item']; + $key = !empty($tag['key']) ? $tag['key'] : 'key'; + $name = $this->autoBuildVar($name); + $parseStr = '$' . $item . '): ?>'; + $parseStr .= $this->tpl->parse($content); + $parseStr .= ''; + + if (!empty($parseStr)) { return $parseStr; } - return ; + return; } /** @@ -136,9 +142,10 @@ public function _foreach($tag,$content) { * @param string $content 标签内容 * @return string */ - public function _if($tag,$content) { - $condition = $this->parseCondition($tag['condition']); - $parseStr = ''.$content.''; + public function _if($tag, $content) + { + $condition = $this->parseCondition($tag['condition']); + $parseStr = '' . $content . ''; return $parseStr; } @@ -150,9 +157,10 @@ public function _if($tag,$content) { * @param string $content 标签内容 * @return string */ - public function _elseif($tag,$content) { - $condition = $this->parseCondition($tag['condition']); - $parseStr = ''; + public function _elseif($tag, $content) + { + $condition = $this->parseCondition($tag['condition']); + $parseStr = ''; return $parseStr; } @@ -162,7 +170,8 @@ public function _elseif($tag,$content) { * @param array $tag 标签属性 * @return string */ - public function _else($tag) { + public function _else($tag) + { $parseStr = ''; return $parseStr; } @@ -180,14 +189,17 @@ public function _else($tag) { * @param string $content 标签内容 * @return string */ - public function _switch($tag,$content) { - $name = $tag['name']; - $varArray = explode('|',$name); - $name = array_shift($varArray); - $name = $this->autoBuildVar($name); - if(count($varArray)>0) - $name = $this->tpl->parseVarFunction($name,$varArray); - $parseStr = ''.$content.''; + public function _switch($tag, $content) + { + $name = $tag['name']; + $varArray = explode('|', $name); + $name = array_shift($varArray); + $name = $this->autoBuildVar($name); + if (count($varArray) > 0) { + $name = $this->tpl->parseVarFunction($name, $varArray); + } + + $parseStr = '' . $content . ''; return $parseStr; } @@ -198,27 +210,30 @@ public function _switch($tag,$content) { * @param string $content 标签内容 * @return string */ - public function _case($tag,$content) { - $value = $tag['value']; - if('$' == substr($value,0,1)) { - $varArray = explode('|',$value); - $value = array_shift($varArray); - $value = $this->autoBuildVar(substr($value,1)); - if(count($varArray)>0) - $value = $this->tpl->parseVarFunction($value,$varArray); - $value = 'case '.$value.': '; - }elseif(strpos($value,'|')){ - $values = explode('|',$value); - $value = ''; - foreach ($values as $val){ - $value .= 'case "'.addslashes($val).'": '; + public function _case($tag, $content) + { + $value = $tag['value']; + if ('$' == substr($value, 0, 1)) { + $varArray = explode('|', $value); + $value = array_shift($varArray); + $value = $this->autoBuildVar(substr($value, 1)); + if (count($varArray) > 0) { + $value = $this->tpl->parseVarFunction($value, $varArray); + } + + $value = 'case ' . $value . ': '; + } elseif (strpos($value, '|')) { + $values = explode('|', $value); + $value = ''; + foreach ($values as $val) { + $value .= 'case "' . addslashes($val) . '": '; } - }else{ - $value = 'case "'.$value.'": '; + } else { + $value = 'case "' . $value . '": '; } - $parseStr = ''.$content; + $parseStr = '' . $content; $isBreak = isset($tag['break']) ? $tag['break'] : ''; - if('' ==$isBreak || $isBreak) { + if ('' == $isBreak || $isBreak) { $parseStr .= ''; } return $parseStr; @@ -232,7 +247,8 @@ public function _case($tag,$content) { * @param string $content 标签内容 * @return string */ - public function _default($tag) { + public function _default($tag) + { $parseStr = ''; return $parseStr; } @@ -246,63 +262,76 @@ public function _default($tag) { * @param string $content 标签内容 * @return string */ - public function _compare($tag,$content,$type='eq') { - $name = $tag['name']; - $value = $tag['value']; - $type = isset($tag['type'])?$tag['type']:$type; - $type = $this->parseCondition(' '.$type.' '); - $varArray = explode('|',$name); - $name = array_shift($varArray); - $name = $this->autoBuildVar($name); - if(count($varArray)>0) - $name = $this->tpl->parseVarFunction($name,$varArray); - if('$' == substr($value,0,1)) { - $value = $this->autoBuildVar(substr($value,1)); - }else { - $value = '"'.$value.'"'; + public function _compare($tag, $content, $type = 'eq') + { + $name = $tag['name']; + $value = $tag['value']; + $type = isset($tag['type']) ? $tag['type'] : $type; + $type = $this->parseCondition(' ' . $type . ' '); + $varArray = explode('|', $name); + $name = array_shift($varArray); + $name = $this->autoBuildVar($name); + if (count($varArray) > 0) { + $name = $this->tpl->parseVarFunction($name, $varArray); } - $parseStr = ''.$content.''; + + if ('$' == substr($value, 0, 1)) { + $value = $this->autoBuildVar(substr($value, 1)); + } else { + $value = '"' . $value . '"'; + } + $parseStr = '' . $content . ''; return $parseStr; } - public function _eq($tag,$content) { - return $this->_compare($tag,$content,'eq'); + public function _eq($tag, $content) + { + return $this->_compare($tag, $content, 'eq'); } - public function _equal($tag,$content) { - return $this->_compare($tag,$content,'eq'); + public function _equal($tag, $content) + { + return $this->_compare($tag, $content, 'eq'); } - public function _neq($tag,$content) { - return $this->_compare($tag,$content,'neq'); + public function _neq($tag, $content) + { + return $this->_compare($tag, $content, 'neq'); } - public function _notequal($tag,$content) { - return $this->_compare($tag,$content,'neq'); + public function _notequal($tag, $content) + { + return $this->_compare($tag, $content, 'neq'); } - public function _gt($tag,$content) { - return $this->_compare($tag,$content,'gt'); + public function _gt($tag, $content) + { + return $this->_compare($tag, $content, 'gt'); } - public function _lt($tag,$content) { - return $this->_compare($tag,$content,'lt'); + public function _lt($tag, $content) + { + return $this->_compare($tag, $content, 'lt'); } - public function _egt($tag,$content) { - return $this->_compare($tag,$content,'egt'); + public function _egt($tag, $content) + { + return $this->_compare($tag, $content, 'egt'); } - public function _elt($tag,$content) { - return $this->_compare($tag,$content,'elt'); + public function _elt($tag, $content) + { + return $this->_compare($tag, $content, 'elt'); } - public function _heq($tag,$content) { - return $this->_compare($tag,$content,'heq'); + public function _heq($tag, $content) + { + return $this->_compare($tag, $content, 'heq'); } - public function _nheq($tag,$content) { - return $this->_compare($tag,$content,'nheq'); + public function _nheq($tag, $content) + { + return $this->_compare($tag, $content, 'nheq'); } /** @@ -316,51 +345,57 @@ public function _nheq($tag,$content) { * @param string $type 比较类型 * @return string */ - public function _range($tag,$content,$type='in') { - $name = $tag['name']; - $value = $tag['value']; - $varArray = explode('|',$name); - $name = array_shift($varArray); - $name = $this->autoBuildVar($name); - if(count($varArray)>0) - $name = $this->tpl->parseVarFunction($name,$varArray); - - $type = isset($tag['type'])?$tag['type']:$type; - - if('$' == substr($value,0,1)) { - $value = $this->autoBuildVar(substr($value,1)); - $str = 'is_array('.$value.')?'.$value.':explode(\',\','.$value.')'; - }else{ - $value = '"'.$value.'"'; - $str = 'explode(\',\','.$value.')'; + public function _range($tag, $content, $type = 'in') + { + $name = $tag['name']; + $value = $tag['value']; + $varArray = explode('|', $name); + $name = array_shift($varArray); + $name = $this->autoBuildVar($name); + if (count($varArray) > 0) { + $name = $this->tpl->parseVarFunction($name, $varArray); } - if($type=='between') { - $parseStr = '= $_RANGE_VAR_[0] && '.$name.'<= $_RANGE_VAR_[1]):?>'.$content.''; - }elseif($type=='notbetween'){ - $parseStr = '$_RANGE_VAR_[1]):?>'.$content.''; - }else{ - $fun = ($type == 'in')? 'in_array' : '!in_array'; - $parseStr = ''.$content.''; + + $type = isset($tag['type']) ? $tag['type'] : $type; + + if ('$' == substr($value, 0, 1)) { + $value = $this->autoBuildVar(substr($value, 1)); + $str = 'is_array(' . $value . ')?' . $value . ':explode(\',\',' . $value . ')'; + } else { + $value = '"' . $value . '"'; + $str = 'explode(\',\',' . $value . ')'; + } + if ('between' == $type) { + $parseStr = '= $_RANGE_VAR_[0] && ' . $name . '<= $_RANGE_VAR_[1]):?>' . $content . ''; + } elseif ('notbetween' == $type) { + $parseStr = '$_RANGE_VAR_[1]):?>' . $content . ''; + } else { + $fun = ('in' == $type) ? 'in_array' : '!in_array'; + $parseStr = '' . $content . ''; } return $parseStr; } // range标签的别名 用于in判断 - public function _in($tag,$content) { - return $this->_range($tag,$content,'in'); + public function _in($tag, $content) + { + return $this->_range($tag, $content, 'in'); } // range标签的别名 用于notin判断 - public function _notin($tag,$content) { - return $this->_range($tag,$content,'notin'); + public function _notin($tag, $content) + { + return $this->_range($tag, $content, 'notin'); } - public function _between($tag,$content){ - return $this->_range($tag,$content,'between'); + public function _between($tag, $content) + { + return $this->_range($tag, $content, 'between'); } - public function _notbetween($tag,$content){ - return $this->_range($tag,$content,'notbetween'); + public function _notbetween($tag, $content) + { + return $this->_range($tag, $content, 'notbetween'); } /** @@ -372,10 +407,11 @@ public function _notbetween($tag,$content){ * @param string $content 标签内容 * @return string */ - public function _present($tag,$content) { - $name = $tag['name']; - $name = $this->autoBuildVar($name); - $parseStr = ''.$content.''; + public function _present($tag, $content) + { + $name = $tag['name']; + $name = $this->autoBuildVar($name); + $parseStr = '' . $content . ''; return $parseStr; } @@ -388,10 +424,11 @@ public function _present($tag,$content) { * @param string $content 标签内容 * @return string */ - public function _notpresent($tag,$content) { - $name = $tag['name']; - $name = $this->autoBuildVar($name); - $parseStr = ''.$content.''; + public function _notpresent($tag, $content) + { + $name = $tag['name']; + $name = $this->autoBuildVar($name); + $parseStr = '' . $content . ''; return $parseStr; } @@ -404,17 +441,19 @@ public function _notpresent($tag,$content) { * @param string $content 标签内容 * @return string */ - public function _empty($tag,$content) { - $name = $tag['name']; - $name = $this->autoBuildVar($name); - $parseStr = ''.$content.''; + public function _empty($tag, $content) + { + $name = $tag['name']; + $name = $this->autoBuildVar($name); + $parseStr = '' . $content . ''; return $parseStr; } - public function _notempty($tag,$content) { - $name = $tag['name']; - $name = $this->autoBuildVar($name); - $parseStr = ''.$content.''; + public function _notempty($tag, $content) + { + $name = $tag['name']; + $name = $this->autoBuildVar($name); + $parseStr = '' . $content . ''; return $parseStr; } @@ -425,20 +464,22 @@ public function _notempty($tag,$content) { * @param $content * @return string */ - public function _defined($tag,$content) { - $name = $tag['name']; - $parseStr = ''.$content.''; + public function _defined($tag, $content) + { + $name = $tag['name']; + $parseStr = '' . $content . ''; return $parseStr; } - public function _notdefined($tag,$content) { - $name = $tag['name']; - $parseStr = ''.$content.''; + public function _notdefined($tag, $content) + { + $name = $tag['name']; + $parseStr = '' . $content . ''; return $parseStr; } /** - * import 标签解析 + * import 标签解析 * * @access public * @param array $tag 标签属性 @@ -447,84 +488,90 @@ public function _notdefined($tag,$content) { * @param string $type 类型 * @return string */ - public function _import($tag,$content,$isFile=false,$type='') { - $file = isset($tag['file'])?$tag['file']:$tag['href']; - $parseStr = ''; - $endStr = ''; + public function _import($tag, $content, $isFile = false, $type = '') + { + $file = isset($tag['file']) ? $tag['file'] : $tag['href']; + $parseStr = ''; + $endStr = ''; // 判断是否存在加载条件 允许使用函数判断(默认为isset) if (isset($tag['value'])) { - $varArray = explode('|',$tag['value']); - $name = array_shift($varArray); - $name = $this->autoBuildVar($name); - if (!empty($varArray)) - $name = $this->tpl->parseVarFunction($name,$varArray); - else - $name = 'isset('.$name.')'; - $parseStr .= ''; - $endStr = ''; + $varArray = explode('|', $tag['value']); + $name = array_shift($varArray); + $name = $this->autoBuildVar($name); + if (!empty($varArray)) { + $name = $this->tpl->parseVarFunction($name, $varArray); + } else { + $name = 'isset(' . $name . ')'; + } + + $parseStr .= ''; + $endStr = ''; } - if($isFile) { + if ($isFile) { // 根据文件名后缀自动识别 - $type = $type?$type:(!empty($tag['type'])?strtolower($tag['type']):null); + $type = $type ? $type : (!empty($tag['type']) ? strtolower($tag['type']) : null); // 文件方式导入 - $array = explode(',',$file); - foreach ($array as $val){ + $array = explode(',', $file); + foreach ($array as $val) { if (!$type || isset($reset)) { - $type = $reset = strtolower(substr(strrchr($val, '.'),1)); + $type = $reset = strtolower(substr(strrchr($val, '.'), 1)); } - switch($type) { - case 'js': - $parseStr .= ''; - break; - case 'css': - $parseStr .= ''; - break; - case 'php': - $parseStr .= ''; - break; + switch ($type) { + case 'js': + $parseStr .= ''; + break; + case 'css': + $parseStr .= ''; + break; + case 'php': + $parseStr .= ''; + break; } } - }else{ + } else { // 命名空间导入模式 默认是js - $type = $type?$type:(!empty($tag['type'])?strtolower($tag['type']):'js'); - $basepath = !empty($tag['basepath'])?$tag['basepath']:__ROOT__.'/Public'; + $type = $type ? $type : (!empty($tag['type']) ? strtolower($tag['type']) : 'js'); + $basepath = !empty($tag['basepath']) ? $tag['basepath'] : __ROOT__ . '/Public'; // 命名空间方式导入外部文件 - $array = explode(',',$file); - foreach ($array as $val){ - if(strpos ($val, '?')) { - list($val,$version) = explode('?',$val); + $array = explode(',', $file); + foreach ($array as $val) { + if (strpos($val, '?')) { + list($val, $version) = explode('?', $val); } else { $version = ''; } - switch($type) { - case 'js': - $parseStr .= ''; - break; - case 'css': - $parseStr .= ''; - break; - case 'php': - $parseStr .= ''; - break; + switch ($type) { + case 'js': + $parseStr .= ''; + break; + case 'css': + $parseStr .= ''; + break; + case 'php': + $parseStr .= ''; + break; } } } - return $parseStr.$endStr; + return $parseStr . $endStr; } // import别名 采用文件方式加载(要使用命名空间必须用import) 例如 - public function _load($tag,$content) { - return $this->_import($tag,$content,true); + public function _load($tag, $content) + { + return $this->_import($tag, $content, true); } // import别名使用 导入css文件 - public function _css($tag,$content) { - return $this->_import($tag,$content,true,'css'); + public function _css($tag, $content) + { + return $this->_import($tag, $content, true, 'css'); } // import别名使用 导入js文件 - public function _js($tag,$content) { - return $this->_import($tag,$content,true,'js'); + public function _js($tag, $content) + { + return $this->_import($tag, $content, true, 'js'); } /** @@ -536,14 +583,15 @@ public function _js($tag,$content) { * @param string $content 标签内容 * @return string */ - public function _assign($tag,$content) { - $name = $this->autoBuildVar($tag['name']); - if('$'==substr($tag['value'],0,1)) { - $value = $this->autoBuildVar(substr($tag['value'],1)); - }else{ - $value = '\''.$tag['value']. '\''; + public function _assign($tag, $content) + { + $name = $this->autoBuildVar($tag['name']); + if ('$' == substr($tag['value'], 0, 1)) { + $value = $this->autoBuildVar(substr($tag['value'], 1)); + } else { + $value = '\'' . $tag['value'] . '\''; } - $parseStr = ''; + $parseStr = ''; return $parseStr; } @@ -556,17 +604,18 @@ public function _assign($tag,$content) { * @param string $content 标签内容 * @return string */ - public function _define($tag,$content) { - $name = '\''.$tag['name']. '\''; - if('$'==substr($tag['value'],0,1)) { - $value = $this->autoBuildVar(substr($tag['value'],1)); - }else{ - $value = '\''.$tag['value']. '\''; + public function _define($tag, $content) + { + $name = '\'' . $tag['name'] . '\''; + if ('$' == substr($tag['value'], 0, 1)) { + $value = $this->autoBuildVar(substr($tag['value'], 1)); + } else { + $value = '\'' . $tag['value'] . '\''; } - $parseStr = ''; + $parseStr = ''; return $parseStr; } - + /** * for标签解析 * 格式: @@ -575,39 +624,47 @@ public function _define($tag,$content) { * @param string $content 标签内容 * @return string */ - public function _for($tag, $content){ + public function _for($tag, $content) + { //设置默认值 - $start = 0; - $end = 0; - $step = 1; + $start = 0; + $end = 0; + $step = 1; $comparison = 'lt'; - $name = 'i'; + $name = 'i'; $rand = rand(); //添加随机数,防止嵌套变量冲突 //获取属性 - foreach ($tag as $key => $value){ + foreach ($tag as $key => $value) { $value = trim($value); - if(':'==substr($value,0,1)) - $value = substr($value,1); - elseif('$'==substr($value,0,1)) - $value = $this->autoBuildVar(substr($value,1)); - switch ($key){ - case 'start': - $start = $value; break; - case 'end' : - $end = $value; break; - case 'step': - $step = $value; break; + if (':' == substr($value, 0, 1)) { + $value = substr($value, 1); + } elseif ('$' == substr($value, 0, 1)) { + $value = $this->autoBuildVar(substr($value, 1)); + } + + switch ($key) { + case 'start': + $start = $value; + break; + case 'end': + $end = $value; + break; + case 'step': + $step = $value; + break; case 'comparison': - $comparison = $value; break; + $comparison = $value; + break; case 'name': - $name = $value; break; + $name = $value; + break; } } - - $parseStr = 'parseCondition('$'.$name.' '.$comparison.' $__FOR_END_'.$rand.'__').';$'.$name.'+='.$step.'){ ?>'; - $parseStr .= $content; - $parseStr .= ''; + + $parseStr = 'parseCondition('$' . $name . ' ' . $comparison . ' $__FOR_END_' . $rand . '__') . ';$' . $name . '+=' . $step . '){ ?>'; + $parseStr .= $content; + $parseStr .= ''; return $parseStr; } diff --git a/ThinkPHP/Library/Think/Template/TagLib/Html.class.php b/ThinkPHP/Library/Think/Template/TagLib/Html.class.php index 4b3949968..cbcf2c780 100644 --- a/ThinkPHP/Library/Think/Template/TagLib/Html.class.php +++ b/ThinkPHP/Library/Think/Template/TagLib/Html.class.php @@ -9,22 +9,25 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think\Template\TagLib; + use Think\Template\TagLib; + /** * Html标签库驱动 */ -class Html extends TagLib{ +class Html extends TagLib +{ // 标签定义 - protected $tags = array( + protected $tags = array( // 标签定义: attr 属性列表 close 是否闭合(0 或者1 默认1) alias 标签别名 level 嵌套层次 - 'editor' => array('attr'=>'id,name,style,width,height,type','close'=>1), - 'select' => array('attr'=>'name,options,values,output,multiple,id,size,first,change,selected,dblclick','close'=>0), - 'grid' => array('attr'=>'id,pk,style,action,actionlist,show,datasource','close'=>0), - 'list' => array('attr'=>'id,pk,style,action,actionlist,show,datasource,checkbox','close'=>0), - 'imagebtn' => array('attr'=>'id,name,value,type,style,click','close'=>0), - 'checkbox' => array('attr'=>'name,checkboxes,checked,separator','close'=>0), - 'radio' => array('attr'=>'name,radios,checked,separator','close'=>0) - ); + 'editor' => array('attr' => 'id,name,style,width,height,type', 'close' => 1), + 'select' => array('attr' => 'name,options,values,output,multiple,id,size,first,change,selected,dblclick', 'close' => 0), + 'grid' => array('attr' => 'id,pk,style,action,actionlist,show,datasource', 'close' => 0), + 'list' => array('attr' => 'id,pk,style,action,actionlist,show,datasource,checkbox', 'close' => 0), + 'imagebtn' => array('attr' => 'id,name,value,type,style,click', 'close' => 0), + 'checkbox' => array('attr' => 'name,checkboxes,checked,separator', 'close' => 0), + 'radio' => array('attr' => 'name,radios,checked,separator', 'close' => 0), + ); /** * editor标签解析 插入可视化编辑器 @@ -33,35 +36,36 @@ class Html extends TagLib{ * @param array $tag 标签属性 * @return string|void */ - public function _editor($tag,$content) { - $id = !empty($tag['id'])?$tag['id']: '_editor'; - $name = $tag['name']; - $style = !empty($tag['style'])?$tag['style']:''; - $width = !empty($tag['width'])?$tag['width']: '100%'; - $height = !empty($tag['height'])?$tag['height'] :'320px'; - // $content = $tag['content']; - $type = $tag['type'] ; - switch(strtoupper($type)) { + public function _editor($tag, $content) + { + $id = !empty($tag['id']) ? $tag['id'] : '_editor'; + $name = $tag['name']; + $style = !empty($tag['style']) ? $tag['style'] : ''; + $width = !empty($tag['width']) ? $tag['width'] : '100%'; + $height = !empty($tag['height']) ? $tag['height'] : '320px'; + // $content = $tag['content']; + $type = $tag['type']; + switch (strtoupper($type)) { case 'FCKEDITOR': - $parseStr = ' '; + $parseStr = ' '; break; case 'FCKMINI': - $parseStr = ' '; + $parseStr = ' '; break; case 'EWEBEDITOR': - $parseStr = ""; + $parseStr = ""; break; case 'NETEASE': - $parseStr = ''; + $parseStr = ''; break; case 'UBB': - $parseStr = '
'; + $parseStr = '
'; break; case 'KINDEDITOR': - $parseStr = ''; + $parseStr = ''; break; - default : - $parseStr = ''; + default: + $parseStr = ''; } return $parseStr; @@ -74,18 +78,19 @@ public function _editor($tag,$content) { * @param array $tag 标签属性 * @return string|void */ - public function _imageBtn($tag) { - $name = $tag['name']; //名称 - $value = $tag['value']; //文字 - $id = isset($tag['id'])?$tag['id']:''; //ID - $style = isset($tag['style'])?$tag['style']:''; //样式名 - $click = isset($tag['click'])?$tag['click']:''; //点击 - $type = empty($tag['type'])?'button':$tag['type']; //按钮类型 + public function _imageBtn($tag) + { + $name = $tag['name']; //名称 + $value = $tag['value']; //文字 + $id = isset($tag['id']) ? $tag['id'] : ''; //ID + $style = isset($tag['style']) ? $tag['style'] : ''; //样式名 + $click = isset($tag['click']) ? $tag['click'] : ''; //点击 + $type = empty($tag['type']) ? 'button' : $tag['type']; //按钮类型 - if(!empty($name)) { - $parseStr = '
'; - }else { - $parseStr = '
'; + if (!empty($name)) { + $parseStr = '
'; + } else { + $parseStr = '
'; } return $parseStr; @@ -98,17 +103,18 @@ public function _imageBtn($tag) { * @param array $tag 标签属性 * @return string|void */ - public function _imgLink($tag) { - $name = $tag['name']; //名称 - $alt = $tag['alt']; //文字 - $id = $tag['id']; //ID - $style = $tag['style']; //样式名 - $click = $tag['click']; //点击 - $type = $tag['type']; //点击 - if(empty($type)) { + public function _imgLink($tag) + { + $name = $tag['name']; //名称 + $alt = $tag['alt']; //文字 + $id = $tag['id']; //ID + $style = $tag['style']; //样式名 + $click = $tag['click']; //点击 + $type = $tag['type']; //点击 + if (empty($type)) { $type = 'button'; } - $parseStr = ''; + $parseStr = ''; return $parseStr; } @@ -120,7 +126,8 @@ public function _imgLink($tag) { * @param array $tag 标签属性 * @return string|void */ - public function _select($tag) { + public function _select($tag) + { $name = $tag['name']; $options = $tag['options']; $values = $tag['values']; @@ -132,40 +139,40 @@ public function _select($tag) { $selected = $tag['selected']; $style = $tag['style']; $ondblclick = $tag['dblclick']; - $onchange = $tag['change']; + $onchange = $tag['change']; - if(!empty($multiple)) { - $parseStr = ''; - } - if(!empty($first)) { - $parseStr .= ''; - } - if(!empty($options)) { - $parseStr .= '$val) { ?>'; - if(!empty($selected)) { - $parseStr .= ''; - $parseStr .= ''; - $parseStr .= ''; - $parseStr .= ''; - }else { - $parseStr .= ''; + if (!empty($multiple)) { + $parseStr = ''; + } + if (!empty($first)) { + $parseStr .= ''; + } + if (!empty($options)) { + $parseStr .= '$val) { ?>'; + if (!empty($selected)) { + $parseStr .= ''; + $parseStr .= ''; + $parseStr .= ''; + $parseStr .= ''; + } else { + $parseStr .= ''; } - $parseStr .= ''; - }else if(!empty($values)) { - $parseStr .= ''; - if(!empty($selected)) { - $parseStr .= ''; - $parseStr .= ''; - $parseStr .= ''; - $parseStr .= ''; - }else { - $parseStr .= ''; + $parseStr .= ''; + } else if (!empty($values)) { + $parseStr .= ''; + if (!empty($selected)) { + $parseStr .= ''; + $parseStr .= ''; + $parseStr .= ''; + $parseStr .= ''; + } else { + $parseStr .= ''; } - $parseStr .= ''; + $parseStr .= ''; } - $parseStr .= ''; + $parseStr .= ''; return $parseStr; } @@ -176,19 +183,20 @@ public function _select($tag) { * @param array $tag 标签属性 * @return string|void */ - public function _checkbox($tag) { + public function _checkbox($tag) + { $name = $tag['name']; $checkboxes = $tag['checkboxes']; $checked = $tag['checked']; $separator = $tag['separator']; $checkboxes = $this->tpl->get($checkboxes); - $checked = $this->tpl->get($checked)?$this->tpl->get($checked):$checked; + $checked = $this->tpl->get($checked) ? $this->tpl->get($checked) : $checked; $parseStr = ''; - foreach($checkboxes as $key=>$val) { - if($checked == $key || in_array($key,$checked) ) { - $parseStr .= ''.$val.$separator; - }else { - $parseStr .= ''.$val.$separator; + foreach ($checkboxes as $key => $val) { + if ($checked == $key || in_array($key, $checked)) { + $parseStr .= '' . $val . $separator; + } else { + $parseStr .= '' . $val . $separator; } } return $parseStr; @@ -201,19 +209,20 @@ public function _checkbox($tag) { * @param array $tag 标签属性 * @return string|void */ - public function _radio($tag) { - $name = $tag['name']; - $radios = $tag['radios']; - $checked = $tag['checked']; - $separator = $tag['separator']; - $radios = $this->tpl->get($radios); - $checked = $this->tpl->get($checked)?$this->tpl->get($checked):$checked; - $parseStr = ''; - foreach($radios as $key=>$val) { - if($checked == $key ) { - $parseStr .= ''.$val.$separator; - }else { - $parseStr .= ''.$val.$separator; + public function _radio($tag) + { + $name = $tag['name']; + $radios = $tag['radios']; + $checked = $tag['checked']; + $separator = $tag['separator']; + $radios = $this->tpl->get($radios); + $checked = $this->tpl->get($checked) ? $this->tpl->get($checked) : $checked; + $parseStr = ''; + foreach ($radios as $key => $val) { + if ($checked == $key) { + $parseStr .= '' . $val . $separator; + } else { + $parseStr .= '' . $val . $separator; } } @@ -227,135 +236,144 @@ public function _radio($tag) { * @param array $tag 标签属性 * @return string */ - public function _grid($tag) { - $id = $tag['id']; //表格ID - $datasource = $tag['datasource']; //列表显示的数据源VoList名称 - $pk = empty($tag['pk'])?'id':$tag['pk'];//主键名,默认为id - $style = $tag['style']; //样式名 - $name = !empty($tag['name'])?$tag['name']:'vo'; //Vo对象名 - $action = !empty($tag['action'])?$tag['action']:false; //是否显示功能操作 - $key = !empty($tag['key'])?true:false; - if(isset($tag['actionlist'])) { - $actionlist = explode(',',trim($tag['actionlist'])); //指定功能列表 + public function _grid($tag) + { + $id = $tag['id']; //表格ID + $datasource = $tag['datasource']; //列表显示的数据源VoList名称 + $pk = empty($tag['pk']) ? 'id' : $tag['pk']; //主键名,默认为id + $style = $tag['style']; //样式名 + $name = !empty($tag['name']) ? $tag['name'] : 'vo'; //Vo对象名 + $action = !empty($tag['action']) ? $tag['action'] : false; //是否显示功能操作 + $key = !empty($tag['key']) ? true : false; + if (isset($tag['actionlist'])) { + $actionlist = explode(',', trim($tag['actionlist'])); //指定功能列表 } - if(substr($tag['show'],0,1)=='$') { - $show = $this->tpl->get(substr($tag['show'],1)); - }else { - $show = $tag['show']; + if (substr($tag['show'], 0, 1) == '$') { + $show = $this->tpl->get(substr($tag['show'], 1)); + } else { + $show = $tag['show']; } - $show = explode(',',$show); //列表显示字段列表 + $show = explode(',', $show); //列表显示字段列表 //计算表格的列数 - $colNum = count($show); - if(!empty($action)) $colNum++; - if(!empty($key)) $colNum++; + $colNum = count($show); + if (!empty($action)) { + $colNum++; + } + + if (!empty($key)) { + $colNum++; + } //显示开始 - $parseStr = "\n"; - $parseStr .= ''; - $parseStr .= ''; - $parseStr .= ''; + $parseStr = "\n"; + $parseStr .= '
'; + $parseStr .= ''; + $parseStr .= ''; //列表需要显示的字段 $fields = array(); - foreach($show as $val) { - $fields[] = explode(':',$val); + foreach ($show as $val) { + $fields[] = explode(':', $val); } - if(!empty($key)) { + if (!empty($key)) { $parseStr .= ''; } - foreach($fields as $field) {//显示指定的字段 - $property = explode('|',$field[0]); - $showname = explode('|',$field[1]); - if(isset($showname[1])) { - $parseStr .= ''; + $parseStr .= $showname[0] . ''; } - if(!empty($action)) {//如果指定显示操作功能列 + if (!empty($action)) { +//如果指定显示操作功能列 $parseStr .= ''; } $parseStr .= ''; - $parseStr .= ''; //支持鼠标移动单元行颜色变化 具体方法在js中定义 + $parseStr .= ''; //支持鼠标移动单元行颜色变化 具体方法在js中定义 - if(!empty($key)) { + if (!empty($key)) { $parseStr .= ''; } - foreach($fields as $field) { + foreach ($fields as $field) { //显示定义的列表字段 - $parseStr .= ''; } - if(!empty($action)) {//显示功能操作 - if(!empty($actionlist[0])) {//显示指定的功能项 + if (!empty($action)) { +//显示功能操作 + if (!empty($actionlist[0])) { //显示指定的功能项 $parseStr .= ''; } } - $parseStr .= '
No'; - }else { + foreach ($fields as $field) { +//显示指定的字段 + $property = explode('|', $field[0]); + $showname = explode('|', $field[1]); + if (isset($showname[1])) { + $parseStr .= ''; + } else { $parseStr .= ''; } - $parseStr .= $showname[0].'操作
{$i}'; - if(!empty($field[2])) { + $parseStr .= ''; + if (!empty($field[2])) { // 支持列表字段链接功能 具体方法由JS函数实现 - $href = explode('|',$field[2]); - if(count($href)>1) { + $href = explode('|', $field[2]); + if (count($href) > 1) { //指定链接传的字段值 // 支持多个字段传递 - $array = explode('^',$href[1]); - if(count($array)>1) { - foreach ($array as $a){ - $temp[] = '\'{$'.$name.'.'.$a.'|addslashes}\''; + $array = explode('^', $href[1]); + if (count($array) > 1) { + foreach ($array as $a) { + $temp[] = '\'{$' . $name . '.' . $a . '|addslashes}\''; } - $parseStr .= ''; - }else{ - $parseStr .= ''; + $parseStr .= ''; + } else { + $parseStr .= ''; } - }else { + } else { //如果没有指定默认传编号值 - $parseStr .= ''; + $parseStr .= ''; } } - if(strpos($field[0],'^')) { - $property = explode('^',$field[0]); - foreach ($property as $p){ - $unit = explode('|',$p); - if(count($unit)>1) { - $parseStr .= '{$'.$name.'.'.$unit[0].'|'.$unit[1].'} '; - }else { - $parseStr .= '{$'.$name.'.'.$p.'} '; + if (strpos($field[0], '^')) { + $property = explode('^', $field[0]); + foreach ($property as $p) { + $unit = explode('|', $p); + if (count($unit) > 1) { + $parseStr .= '{$' . $name . '.' . $unit[0] . '|' . $unit[1] . '} '; + } else { + $parseStr .= '{$' . $name . '.' . $p . '} '; } } - }else{ - $property = explode('|',$field[0]); - if(count($property)>1) { - $parseStr .= '{$'.$name.'.'.$property[0].'|'.$property[1].'}'; - }else { - $parseStr .= '{$'.$name.'.'.$field[0].'}'; + } else { + $property = explode('|', $field[0]); + if (count($property) > 1) { + $parseStr .= '{$' . $name . '.' . $property[0] . '|' . $property[1] . '}'; + } else { + $parseStr .= '{$' . $name . '.' . $field[0] . '}'; } } - if(!empty($field[2])) { + if (!empty($field[2])) { $parseStr .= ''; } $parseStr .= ''; - foreach($actionlist as $val) { - if(strpos($val,':')) { - $a = explode(':',$val); - if(count($a)>2) { - $parseStr .= ''.$a[1].' '; - }else { - $parseStr .= ''.$a[1].' '; - } - }else{ - $array = explode('|',$val); - if(count($array)>2) { - $parseStr .= ' '.$array[2].' '; - }else{ - $parseStr .= ' {$'.$name.'.'.$val.'} '; - } - } + foreach ($actionlist as $val) { + if (strpos($val, ':')) { + $a = explode(':', $val); + if (count($a) > 2) { + $parseStr .= '' . $a[1] . ' '; + } else { + $parseStr .= '' . $a[1] . ' '; + } + } else { + $array = explode('|', $val); + if (count($array) > 2) { + $parseStr .= ' ' . $array[2] . ' '; + } else { + $parseStr .= ' {$' . $name . '.' . $val . '} '; + } + } } $parseStr .= '
'; - $parseStr .= "\n\n"; + $parseStr .= ''; + $parseStr .= "\n\n"; return $parseStr; } @@ -366,158 +384,172 @@ public function _grid($tag) { * @param array $tag 标签属性 * @return string */ - public function _list($tag) { - $id = $tag['id']; //表格ID - $datasource = $tag['datasource']; //列表显示的数据源VoList名称 - $pk = empty($tag['pk'])?'id':$tag['pk'];//主键名,默认为id - $style = $tag['style']; //样式名 - $name = !empty($tag['name'])?$tag['name']:'vo'; //Vo对象名 - $action = $tag['action']=='true'?true:false; //是否显示功能操作 - $key = !empty($tag['key'])?true:false; - $sort = $tag['sort']=='false'?false:true; - $checkbox = $tag['checkbox']; //是否显示Checkbox - if(isset($tag['actionlist'])) { - if(substr($tag['actionlist'],0,1)=='$') { - $actionlist = $this->tpl->get(substr($tag['actionlist'],1)); - }else { - $actionlist = $tag['actionlist']; + public function _list($tag) + { + $id = $tag['id']; //表格ID + $datasource = $tag['datasource']; //列表显示的数据源VoList名称 + $pk = empty($tag['pk']) ? 'id' : $tag['pk']; //主键名,默认为id + $style = $tag['style']; //样式名 + $name = !empty($tag['name']) ? $tag['name'] : 'vo'; //Vo对象名 + $action = 'true' == $tag['action'] ? true : false; //是否显示功能操作 + $key = !empty($tag['key']) ? true : false; + $sort = 'false' == $tag['sort'] ? false : true; + $checkbox = $tag['checkbox']; //是否显示Checkbox + if (isset($tag['actionlist'])) { + if (substr($tag['actionlist'], 0, 1) == '$') { + $actionlist = $this->tpl->get(substr($tag['actionlist'], 1)); + } else { + $actionlist = $tag['actionlist']; } - $actionlist = explode(',',trim($actionlist)); //指定功能列表 + $actionlist = explode(',', trim($actionlist)); //指定功能列表 } - if(substr($tag['show'],0,1)=='$') { - $show = $this->tpl->get(substr($tag['show'],1)); - }else { - $show = $tag['show']; + if (substr($tag['show'], 0, 1) == '$') { + $show = $this->tpl->get(substr($tag['show'], 1)); + } else { + $show = $tag['show']; } - $show = explode(',',$show); //列表显示字段列表 + $show = explode(',', $show); //列表显示字段列表 //计算表格的列数 - $colNum = count($show); - if(!empty($checkbox)) $colNum++; - if(!empty($action)) $colNum++; - if(!empty($key)) $colNum++; + $colNum = count($show); + if (!empty($checkbox)) { + $colNum++; + } + + if (!empty($action)) { + $colNum++; + } + + if (!empty($key)) { + $colNum++; + } //显示开始 - $parseStr = "\n"; - $parseStr .= ''; - $parseStr .= ''; - $parseStr .= ''; + $parseStr = "\n"; + $parseStr .= '
'; + $parseStr .= ''; + $parseStr .= ''; //列表需要显示的字段 $fields = array(); - foreach($show as $val) { - $fields[] = explode(':',$val); + foreach ($show as $val) { + $fields[] = explode(':', $val); } - if(!empty($checkbox) && 'true'==strtolower($checkbox)) {//如果指定需要显示checkbox列 - $parseStr .=''; + if (!empty($checkbox) && 'true' == strtolower($checkbox)) { +//如果指定需要显示checkbox列 + $parseStr .= ''; } - if(!empty($key)) { + if (!empty($key)) { $parseStr .= ''; } - foreach($fields as $field) {//显示指定的字段 - $property = explode('|',$field[0]); - $showname = explode('|',$field[1]); - if(isset($showname[1])) { - $parseStr .= ''; - }else{ - $parseStr .= $showname[0].''; + $showname[2] = isset($showname[2]) ? $showname[2] : $showname[0]; + if ($sort) { + $parseStr .= '' . $showname[0] . ''; + } else { + $parseStr .= $showname[0] . ''; } } - if(!empty($action)) {//如果指定显示操作功能列 + if (!empty($action)) { +//如果指定显示操作功能列 $parseStr .= ''; } $parseStr .= ''; - $parseStr .= ''; + if (!empty($checkbox)) { +//如果需要显示checkbox 则在每行开头显示checkbox + $parseStr .= ''; } - if(!empty($key)) { + if (!empty($key)) { $parseStr .= ''; } - foreach($fields as $field) { + foreach ($fields as $field) { //显示定义的列表字段 - $parseStr .= ''; } - if(!empty($action)) {//显示功能操作 - if(!empty($actionlist[0])) {//显示指定的功能项 + if (!empty($action)) { +//显示功能操作 + if (!empty($actionlist[0])) { //显示指定的功能项 $parseStr .= ''; } } - $parseStr .= '
No'; - }else { + foreach ($fields as $field) { +//显示指定的字段 + $property = explode('|', $field[0]); + $showname = explode('|', $field[1]); + if (isset($showname[1])) { + $parseStr .= ''; + } else { $parseStr .= ''; } - $showname[2] = isset($showname[2])?$showname[2]:$showname[0]; - if($sort) { - $parseStr .= ''.$showname[0].'操作
{$i}'; - if(!empty($field[2])) { + $parseStr .= ''; + if (!empty($field[2])) { // 支持列表字段链接功能 具体方法由JS函数实现 - $href = explode('|',$field[2]); - if(count($href)>1) { + $href = explode('|', $field[2]); + if (count($href) > 1) { //指定链接传的字段值 // 支持多个字段传递 - $array = explode('^',$href[1]); - if(count($array)>1) { - foreach ($array as $a){ - $temp[] = '\'{$'.$name.'.'.$a.'|addslashes}\''; + $array = explode('^', $href[1]); + if (count($array) > 1) { + foreach ($array as $a) { + $temp[] = '\'{$' . $name . '.' . $a . '|addslashes}\''; } - $parseStr .= ''; - }else{ - $parseStr .= ''; + $parseStr .= ''; + } else { + $parseStr .= ''; } - }else { + } else { //如果没有指定默认传编号值 - $parseStr .= ''; + $parseStr .= ''; } } - if(strpos($field[0],'^')) { - $property = explode('^',$field[0]); - foreach ($property as $p){ - $unit = explode('|',$p); - if(count($unit)>1) { - $parseStr .= '{$'.$name.'.'.$unit[0].'|'.$unit[1].'} '; - }else { - $parseStr .= '{$'.$name.'.'.$p.'} '; + if (strpos($field[0], '^')) { + $property = explode('^', $field[0]); + foreach ($property as $p) { + $unit = explode('|', $p); + if (count($unit) > 1) { + $parseStr .= '{$' . $name . '.' . $unit[0] . '|' . $unit[1] . '} '; + } else { + $parseStr .= '{$' . $name . '.' . $p . '} '; } } - }else{ - $property = explode('|',$field[0]); - if(count($property)>1) { - $parseStr .= '{$'.$name.'.'.$property[0].'|'.$property[1].'}'; - }else { - $parseStr .= '{$'.$name.'.'.$field[0].'}'; + } else { + $property = explode('|', $field[0]); + if (count($property) > 1) { + $parseStr .= '{$' . $name . '.' . $property[0] . '|' . $property[1] . '}'; + } else { + $parseStr .= '{$' . $name . '.' . $field[0] . '}'; } } - if(!empty($field[2])) { + if (!empty($field[2])) { $parseStr .= ''; } $parseStr .= ''; - foreach($actionlist as $val) { - if(strpos($val,':')) { - $a = explode(':',$val); - if(count($a)>2) { - $parseStr .= ''.$a[1].' '; - }else { - $parseStr .= ''.$a[1].' '; + foreach ($actionlist as $val) { + if (strpos($val, ':')) { + $a = explode(':', $val); + if (count($a) > 2) { + $parseStr .= '' . $a[1] . ' '; + } else { + $parseStr .= '' . $a[1] . ' '; } - }else{ - $array = explode('|',$val); - if(count($array)>2) { - $parseStr .= ' '.$array[2].' '; - }else{ - $parseStr .= ' {$'.$name.'.'.$val.'} '; + } else { + $array = explode('|', $val); + if (count($array) > 2) { + $parseStr .= ' ' . $array[2] . ' '; + } else { + $parseStr .= ' {$' . $name . '.' . $val . '} '; } } } $parseStr .= '
'; - $parseStr .= "\n\n"; + $parseStr .= ''; + $parseStr .= "\n\n"; return $parseStr; } -} \ No newline at end of file +} diff --git a/ThinkPHP/Library/Think/Think.class.php b/ThinkPHP/Library/Think/Think.class.php index 34c8459f2..8ae9fca82 100644 --- a/ThinkPHP/Library/Think/Think.class.php +++ b/ThinkPHP/Library/Think/Think.class.php @@ -10,13 +10,15 @@ // +---------------------------------------------------------------------- namespace Think; + /** * ThinkPHP 引导类 */ -class Think { +class Think +{ // 类映射 - private static $_map = array(); + private static $_map = array(); // 实例化对象 private static $_instance = array(); @@ -26,116 +28,131 @@ class Think { * @access public * @return void */ - static public function start() { - // 注册AUTOLOAD方法 - spl_autoload_register('Think\Think::autoload'); - // 设定错误和异常处理 - register_shutdown_function('Think\Think::fatalError'); - set_error_handler('Think\Think::appError'); - set_exception_handler('Think\Think::appException'); - - // 初始化文件存储方式 - Storage::connect(STORAGE_TYPE); - - $runtimefile = RUNTIME_PATH.APP_MODE.'~runtime.php'; - if(!APP_DEBUG && Storage::has($runtimefile)){ - Storage::load($runtimefile); - }else{ - if(Storage::has($runtimefile)) - Storage::unlink($runtimefile); - $content = ''; - // 读取应用模式 - $mode = include is_file(CONF_PATH.'core.php')?CONF_PATH.'core.php':MODE_PATH.APP_MODE.'.php'; - // 加载核心文件 - foreach ($mode['core'] as $file){ - if(is_file($file)) { - include $file; - if(!APP_DEBUG) $content .= compile($file); - } - } - - // 加载应用模式配置文件 - foreach ($mode['config'] as $key=>$file){ - is_numeric($key)?C(load_config($file)):C($key,load_config($file)); - } - - // 读取当前应用模式对应的配置文件 - if('common' != APP_MODE && is_file(CONF_PATH.'config_'.APP_MODE.CONF_EXT)) - C(load_config(CONF_PATH.'config_'.APP_MODE.CONF_EXT)); - - // 加载模式别名定义 - if(isset($mode['alias'])){ - self::addMap(is_array($mode['alias'])?$mode['alias']:include $mode['alias']); - } - - // 加载应用别名定义文件 - if(is_file(CONF_PATH.'alias.php')) - self::addMap(include CONF_PATH.'alias.php'); - - // 加载模式行为定义 - if(isset($mode['tags'])) { - Hook::import(is_array($mode['tags'])?$mode['tags']:include $mode['tags']); - } - - // 加载应用行为定义 - if(is_file(CONF_PATH.'tags.php')) - // 允许应用增加开发模式配置定义 - Hook::import(include CONF_PATH.'tags.php'); - - // 加载框架底层语言包 - L(include THINK_PATH.'Lang/'.strtolower(C('DEFAULT_LANG')).'.php'); - - if(!APP_DEBUG){ - $content .= "\nnamespace { Think\\Think::addMap(".var_export(self::$_map,true).");"; - $content .= "\nL(".var_export(L(),true).");\nC(".var_export(C(),true).');Think\Hook::import('.var_export(Hook::get(),true).');}'; - Storage::put($runtimefile,strip_whitespace(' $file) { + is_numeric($key) ? C(load_config($file)) : C($key, load_config($file)); + } + + // 读取当前应用模式对应的配置文件 + if ('common' != APP_MODE && is_file(CONF_PATH . 'config_' . APP_MODE . CONF_EXT)) { + C(load_config(CONF_PATH . 'config_' . APP_MODE . CONF_EXT)); + } + + // 加载模式别名定义 + if (isset($mode['alias'])) { + self::addMap(is_array($mode['alias']) ? $mode['alias'] : include $mode['alias']); + } + + // 加载应用别名定义文件 + if (is_file(CONF_PATH . 'alias.php')) { + self::addMap(include CONF_PATH . 'alias.php'); + } + + // 加载模式行为定义 + if (isset($mode['tags'])) { + Hook::import(is_array($mode['tags']) ? $mode['tags'] : include $mode['tags']); + } + + // 加载应用行为定义 + if (is_file(CONF_PATH . 'tags.php')) + // 允许应用增加开发模式配置定义 + { + Hook::import(include CONF_PATH . 'tags.php'); + } + + // 加载框架底层语言包 + L(include THINK_PATH . 'Lang/' . strtolower(C('DEFAULT_LANG')) . '.php'); + + if (!APP_DEBUG) { + $content .= "\nnamespace { Think\\Think::addMap(" . var_export(self::$_map, true) . ");"; + $content .= "\nL(" . var_export(L(), true) . ");\nC(" . var_export(C(), true) . ');Think\Hook::import(' . var_export(Hook::get(), true) . ');}'; + Storage::put($runtimefile, strip_whitespace('getMessage(); - $trace = $e->getTrace(); - if('E'==$trace[0]['function']) { - $error['file'] = $trace[0]['file']; - $error['line'] = $trace[0]['line']; - }else{ - $error['file'] = $e->getFile(); - $error['line'] = $e->getLine(); + public static function appException($e) + { + $error = array(); + $error['message'] = $e->getMessage(); + $trace = $e->getTrace(); + if ('E' == $trace[0]['function']) { + $error['file'] = $trace[0]['file']; + $error['line'] = $trace[0]['line']; + } else { + $error['file'] = $e->getFile(); + $error['line'] = $e->getLine(); } - $error['trace'] = $e->getTraceAsString(); - Log::record($error['message'],Log::ERR); + $error['trace'] = $e->getTraceAsString(); + Log::record($error['message'], Log::ERR); // 发送404信息 header('HTTP/1.1 404 Not Found'); header('Status:404 Not Found'); @@ -240,38 +266,43 @@ static public function appException($e) { * @param int $errline 错误行数 * @return void */ - static public function appError($errno, $errstr, $errfile, $errline) { - switch ($errno) { - case E_ERROR: - case E_PARSE: - case E_CORE_ERROR: - case E_COMPILE_ERROR: - case E_USER_ERROR: - ob_end_clean(); - $errorStr = "$errstr ".$errfile." 第 $errline 行."; - if(C('LOG_RECORD')) Log::write("[$errno] ".$errorStr,Log::ERR); - self::halt($errorStr); - break; - default: - $errorStr = "[$errno] $errstr ".$errfile." 第 $errline 行."; - self::trace($errorStr,'','NOTIC'); - break; - } + public static function appError($errno, $errstr, $errfile, $errline) + { + switch ($errno) { + case E_ERROR: + case E_PARSE: + case E_CORE_ERROR: + case E_COMPILE_ERROR: + case E_USER_ERROR: + ob_end_clean(); + $errorStr = "$errstr " . $errfile . " 第 $errline 行."; + if (C('LOG_RECORD')) { + Log::write("[$errno] " . $errorStr, Log::ERR); + } + + self::halt($errorStr); + break; + default: + $errorStr = "[$errno] $errstr " . $errfile . " 第 $errline 行."; + self::trace($errorStr, '', 'NOTIC'); + break; + } } - + // 致命错误捕获 - static public function fatalError() { + public static function fatalError() + { Log::save(); if ($e = error_get_last()) { - switch($e['type']){ - case E_ERROR: - case E_PARSE: - case E_CORE_ERROR: - case E_COMPILE_ERROR: - case E_USER_ERROR: - ob_end_clean(); - self::halt($e); - break; + switch ($e['type']) { + case E_ERROR: + case E_PARSE: + case E_CORE_ERROR: + case E_COMPILE_ERROR: + case E_USER_ERROR: + ob_end_clean(); + self::halt($e); + break; } } } @@ -281,36 +312,37 @@ static public function fatalError() { * @param mixed $error 错误 * @return void */ - static public function halt($error) { + public static function halt($error) + { $e = array(); if (APP_DEBUG || IS_CLI) { //调试模式下输出错误信息 if (!is_array($error)) { - $trace = debug_backtrace(); - $e['message'] = $error; - $e['file'] = $trace[0]['file']; - $e['line'] = $trace[0]['line']; + $trace = debug_backtrace(); + $e['message'] = $error; + $e['file'] = $trace[0]['file']; + $e['line'] = $trace[0]['line']; ob_start(); debug_print_backtrace(); - $e['trace'] = ob_get_clean(); + $e['trace'] = ob_get_clean(); } else { - $e = $error; + $e = $error; } - if(IS_CLI){ - exit((IS_WIN? iconv('UTF-8','gbk',$e['message']) : $e['message']).PHP_EOL.'FILE: '.$e['file'].'('.$e['line'].')'.PHP_EOL.$e['trace']); + if (IS_CLI) { + exit((IS_WIN ? iconv('UTF-8', 'gbk', $e['message']) : $e['message']) . PHP_EOL . 'FILE: ' . $e['file'] . '(' . $e['line'] . ')' . PHP_EOL . $e['trace']); } } else { //否则定向到错误页面 - $error_page = C('ERROR_PAGE'); + $error_page = C('ERROR_PAGE'); if (!empty($error_page)) { redirect($error_page); } else { - $message = is_array($error) ? $error['message'] : $error; - $e['message'] = C('SHOW_ERROR_MSG')? $message : C('ERROR_MESSAGE'); + $message = is_array($error) ? $error['message'] : $error; + $e['message'] = C('SHOW_ERROR_MSG') ? $message : C('ERROR_MESSAGE'); } } // 包含异常页面模板 - $exceptionFile = C('TMPL_EXCEPTION_FILE',null,THINK_PATH.'Tpl/think_exception.tpl'); + $exceptionFile = C('TMPL_EXCEPTION_FILE', null, THINK_PATH . 'Tpl/think_exception.tpl'); include $exceptionFile; exit; } @@ -323,21 +355,23 @@ static public function halt($error) { * @param boolean $record 是否记录日志 * @return void|array */ - static public function trace($value='[think]',$label='',$level='DEBUG',$record=false) { - static $_trace = array(); - if('[think]' === $value){ // 获取trace信息 + public static function trace($value = '[think]', $label = '', $level = 'DEBUG', $record = false) + { + static $_trace = array(); + if ('[think]' === $value) { + // 获取trace信息 return $_trace; - }else{ - $info = ($label?$label.':':'').print_r($value,true); - $level = strtoupper($level); - - if((defined('IS_AJAX') && IS_AJAX) || !C('SHOW_PAGE_TRACE') || $record) { - Log::record($info,$level,$record); - }else{ - if(!isset($_trace[$level]) || count($_trace[$level])>C('TRACE_MAX_RECORD')) { - $_trace[$level] = array(); + } else { + $info = ($label ? $label . ':' : '') . print_r($value, true); + $level = strtoupper($level); + + if ((defined('IS_AJAX') && IS_AJAX) || !C('SHOW_PAGE_TRACE') || $record) { + Log::record($info, $level, $record); + } else { + if (!isset($_trace[$level]) || count($_trace[$level]) > C('TRACE_MAX_RECORD')) { + $_trace[$level] = array(); } - $_trace[$level][] = $info; + $_trace[$level][] = $info; } } } diff --git a/ThinkPHP/Library/Think/Upload.class.php b/ThinkPHP/Library/Think/Upload.class.php index 89a04ac5c..3dd4cf5b2 100644 --- a/ThinkPHP/Library/Think/Upload.class.php +++ b/ThinkPHP/Library/Think/Upload.class.php @@ -9,26 +9,28 @@ // | Author: 麦当苗儿 // +---------------------------------------------------------------------- namespace Think; -class Upload { + +class Upload +{ /** * 默认上传配置 * @var array */ private $config = array( - 'mimes' => array(), //允许上传的文件MiMe类型 - 'maxSize' => 0, //上传的文件大小限制 (0-不做限制) - 'exts' => array(), //允许上传的文件后缀 - 'autoSub' => true, //自动子目录保存文件 - 'subName' => array('date', 'Y-m-d'), //子目录创建方式,[0]-函数名,[1]-参数,多个参数使用数组 - 'rootPath' => './Uploads/', //保存根路径 - 'savePath' => '', //保存路径 - 'saveName' => array('uniqid', ''), //上传文件命名规则,[0]-函数名,[1]-参数,多个参数使用数组 - 'saveExt' => '', //文件保存后缀,空则使用原后缀 - 'replace' => false, //存在同名是否覆盖 - 'hash' => true, //是否生成hash编码 - 'callback' => false, //检测文件是否存在回调,如果存在返回文件信息数组 - 'driver' => '', // 文件上传驱动 - 'driverConfig' => array(), // 上传驱动配置 + 'mimes' => array(), //允许上传的文件MiMe类型 + 'maxSize' => 0, //上传的文件大小限制 (0-不做限制) + 'exts' => array(), //允许上传的文件后缀 + 'autoSub' => true, //自动子目录保存文件 + 'subName' => array('date', 'Y-m-d'), //子目录创建方式,[0]-函数名,[1]-参数,多个参数使用数组 + 'rootPath' => './Uploads/', //保存根路径 + 'savePath' => '', //保存路径 + 'saveName' => array('uniqid', ''), //上传文件命名规则,[0]-函数名,[1]-参数,多个参数使用数组 + 'saveExt' => '', //文件保存后缀,空则使用原后缀 + 'replace' => false, //存在同名是否覆盖 + 'hash' => true, //是否生成hash编码 + 'callback' => false, //检测文件是否存在回调,如果存在返回文件信息数组 + 'driver' => '', // 文件上传驱动 + 'driverConfig' => array(), // 上传驱动配置 ); /** @@ -48,22 +50,23 @@ class Upload { * @param array $config 配置 * @param string $driver 要使用的上传驱动 LOCAL-本地上传驱动,FTP-FTP上传驱动 */ - public function __construct($config = array(), $driver = '', $driverConfig = null){ + public function __construct($config = array(), $driver = '', $driverConfig = null) + { /* 获取配置 */ - $this->config = array_merge($this->config, $config); + $this->config = array_merge($this->config, $config); /* 设置上传驱动 */ $this->setDriver($driver, $driverConfig); /* 调整配置,把字符串配置参数转换为数组 */ - if(!empty($this->config['mimes'])){ - if(is_string($this->mimes)) { + if (!empty($this->config['mimes'])) { + if (is_string($this->mimes)) { $this->config['mimes'] = explode(',', $this->mimes); } $this->config['mimes'] = array_map('strtolower', $this->mimes); } - if(!empty($this->config['exts'])){ - if (is_string($this->exts)){ + if (!empty($this->config['exts'])) { + if (is_string($this->exts)) { $this->config['exts'] = explode(',', $this->exts); } $this->config['exts'] = array_map('strtolower', $this->exts); @@ -75,22 +78,25 @@ public function __construct($config = array(), $driver = '', $driverConfig = nul * @param string $name 配置名称 * @return multitype 配置值 */ - public function __get($name) { + public function __get($name) + { return $this->config[$name]; } - public function __set($name,$value){ - if(isset($this->config[$name])) { + public function __set($name, $value) + { + if (isset($this->config[$name])) { $this->config[$name] = $value; - if($name == 'driverConfig'){ + if ('driverConfig' == $name) { //改变驱动配置后重置上传驱动 //注意:必须选改变驱动然后再改变驱动配置 - $this->setDriver(); + $this->setDriver(); } } } - public function __isset($name){ + public function __isset($name) + { return isset($this->config[$name]); } @@ -98,7 +104,8 @@ public function __isset($name){ * 获取最后一次上传错误信息 * @return string 错误信息 */ - public function getError(){ + public function getError() + { return $this->error; } @@ -107,7 +114,8 @@ public function getError(){ * @param array $file 文件数组 * @return array 上传成功后的文件信息 */ - public function uploadOne($file){ + public function uploadOne($file) + { $info = $this->upload(array($file)); return $info ? $info[0] : $info; } @@ -116,70 +124,74 @@ public function uploadOne($file){ * 上传文件 * @param 文件信息数组 $files ,通常是 $_FILES数组 */ - public function upload($files='') { - if('' === $files){ - $files = $_FILES; + public function upload($files = '') + { + if ('' === $files) { + $files = $_FILES; } - if(empty($files)){ + if (empty($files)) { $this->error = '没有上传的文件!'; return false; } /* 检测上传根目录 */ - if(!$this->uploader->checkRootPath($this->rootPath)){ + if (!$this->uploader->checkRootPath($this->rootPath)) { $this->error = $this->uploader->getError(); return false; } /* 检查上传目录 */ - if(!$this->uploader->checkSavePath($this->savePath)){ + if (!$this->uploader->checkSavePath($this->savePath)) { $this->error = $this->uploader->getError(); return false; } /* 逐个检测并上传文件 */ - $info = array(); - if(function_exists('finfo_open')){ - $finfo = finfo_open ( FILEINFO_MIME_TYPE ); + $info = array(); + if (function_exists('finfo_open')) { + $finfo = finfo_open(FILEINFO_MIME_TYPE); } // 对上传文件数组信息处理 - $files = $this->dealFiles($files); + $files = $this->dealFiles($files); foreach ($files as $key => $file) { - $file['name'] = strip_tags($file['name']); - if(!isset($file['key'])) $file['key'] = $key; + $file['name'] = strip_tags($file['name']); + if (!isset($file['key'])) { + $file['key'] = $key; + } + /* 通过扩展获取文件类型,可解决FLASH上传$FILES数组返回文件类型错误的问题 */ - if(isset($finfo)){ - $file['type'] = finfo_file ( $finfo , $file['tmp_name'] ); + if (isset($finfo)) { + $file['type'] = finfo_file($finfo, $file['tmp_name']); } /* 获取上传文件后缀,允许上传无后缀文件 */ - $file['ext'] = pathinfo($file['name'], PATHINFO_EXTENSION); + $file['ext'] = pathinfo($file['name'], PATHINFO_EXTENSION); /* 文件上传检测 */ - if (!$this->check($file)){ + if (!$this->check($file)) { continue; } /* 获取文件hash */ - if($this->hash){ + if ($this->hash) { $file['md5'] = md5_file($file['tmp_name']); $file['sha1'] = sha1_file($file['tmp_name']); } /* 调用回调函数检测文件是否存在 */ $data = call_user_func($this->callback, $file); - if( $this->callback && $data ){ - if ( file_exists('.'.$data['path']) ) { + if ($this->callback && $data) { + if (file_exists('.' . $data['path'])) { $info[$key] = $data; continue; - }elseif($this->removeTrash){ - call_user_func($this->removeTrash,$data);//删除垃圾据 + } elseif ($this->removeTrash) { + call_user_func($this->removeTrash, $data); //删除垃圾据 } } /* 生成保存文件名 */ $savename = $this->getSaveName($file); - if(false == $savename){ + if (false == $savename) { continue; } else { $file['savename'] = $savename; @@ -187,7 +199,7 @@ public function upload($files='') { /* 检测并创建子目录 */ $subpath = $this->getSubPath($file['name']); - if(false === $subpath){ + if (false === $subpath) { continue; } else { $file['savepath'] = $this->savePath . $subpath; @@ -195,23 +207,23 @@ public function upload($files='') { /* 对图像文件进行严格检测 */ $ext = strtolower($file['ext']); - if(in_array($ext, array('gif','jpg','jpeg','bmp','png','swf'))) { + if (in_array($ext, array('gif', 'jpg', 'jpeg', 'bmp', 'png', 'swf'))) { $imginfo = getimagesize($file['tmp_name']); - if(empty($imginfo) || ($ext == 'gif' && empty($imginfo['bits']))){ + if (empty($imginfo) || ('gif' == $ext && empty($imginfo['bits']))) { $this->error = '非法图像文件!'; continue; } } /* 保存文件 并记录保存成功的文件 */ - if ($this->uploader->save($file,$this->replace)) { + if ($this->uploader->save($file, $this->replace)) { unset($file['error'], $file['tmp_name']); $info[$key] = $file; } else { $this->error = $this->uploader->getError(); } } - if(isset($finfo)){ + if (isset($finfo)) { finfo_close($finfo); } return empty($info) ? false : $info; @@ -223,39 +235,41 @@ public function upload($files='') { * @param array $files 上传的文件变量 * @return array */ - private function dealFiles($files) { - $fileArray = array(); - $n = 0; - foreach ($files as $key=>$file){ - if(is_array($file['name'])) { - $keys = array_keys($file); - $count = count($file['name']); - for ($i=0; $i<$count; $i++) { + private function dealFiles($files) + { + $fileArray = array(); + $n = 0; + foreach ($files as $key => $file) { + if (is_array($file['name'])) { + $keys = array_keys($file); + $count = count($file['name']); + for ($i = 0; $i < $count; $i++) { $fileArray[$n]['key'] = $key; - foreach ($keys as $_key){ + foreach ($keys as $_key) { $fileArray[$n][$_key] = $file[$_key][$i]; } $n++; } - }else{ - $fileArray = $files; - break; + } else { + $fileArray = $files; + break; } } - return $fileArray; + return $fileArray; } /** * 设置上传驱动 * @param string $driver 驱动名称 - * @param array $config 驱动配置 + * @param array $config 驱动配置 */ - private function setDriver($driver = null, $config = null){ - $driver = $driver ? : ($this->driver ? : C('FILE_UPLOAD_TYPE')); - $config = $config ? : ($this->driverConfig ? : C('UPLOAD_TYPE_CONFIG')); - $class = strpos($driver,'\\')? $driver : 'Think\\Upload\\Driver\\'.ucfirst(strtolower($driver)); + private function setDriver($driver = null, $config = null) + { + $driver = $driver ?: ($this->driver ?: C('FILE_UPLOAD_TYPE')); + $config = $config ?: ($this->driverConfig ?: C('UPLOAD_TYPE_CONFIG')); + $class = strpos($driver, '\\') ? $driver : 'Think\\Upload\\Driver\\' . ucfirst(strtolower($driver)); $this->uploader = new $class($config); - if(!$this->uploader){ + if (!$this->uploader) { E("不存在上传驱动:{$name}"); } } @@ -264,7 +278,8 @@ private function setDriver($driver = null, $config = null){ * 检查上传的文件 * @param array $file 文件信息 */ - private function check($file) { + private function check($file) + { /* 文件上传失败,捕获错误代码 */ if ($file['error']) { $this->error($file['error']); @@ -272,7 +287,7 @@ private function check($file) { } /* 无效上传 */ - if (empty($file['name'])){ + if (empty($file['name'])) { $this->error = '未知上传错误!'; } @@ -305,12 +320,12 @@ private function check($file) { return true; } - /** * 获取错误代码信息 * @param string $errorNo 错误号 */ - private function error($errorNo) { + private function error($errorNo) + { switch ($errorNo) { case 1: $this->error = '上传的文件超过了 php.ini 中 upload_max_filesize 选项限制的值!'; @@ -339,7 +354,8 @@ private function error($errorNo) { * 检查文件大小是否合法 * @param integer $size 数据 */ - private function checkSize($size) { + private function checkSize($size) + { return !($size > $this->maxSize) || (0 == $this->maxSize); } @@ -347,7 +363,8 @@ private function checkSize($size) { * 检查上传的文件MIME类型是否合法 * @param string $mime 数据 */ - private function checkMime($mime) { + private function checkMime($mime) + { return empty($this->config['mimes']) ? true : in_array(strtolower($mime), $this->mimes); } @@ -355,7 +372,8 @@ private function checkMime($mime) { * 检查上传的文件后缀是否合法 * @param string $ext 后缀 */ - private function checkExt($ext) { + private function checkExt($ext) + { return empty($this->config['exts']) ? true : in_array(strtolower($ext), $this->exts); } @@ -363,15 +381,17 @@ private function checkExt($ext) { * 根据上传文件命名规则取得保存文件名 * @param string $file 文件信息 */ - private function getSaveName($file) { + private function getSaveName($file) + { $rule = $this->saveName; - if (empty($rule)) { //保持文件名不变 + if (empty($rule)) { + //保持文件名不变 /* 解决pathinfo中文文件名BUG */ $filename = substr(pathinfo("_{$file['name']}", PATHINFO_FILENAME), 1); $savename = $filename; } else { $savename = $this->getName($rule, $file['name']); - if(empty($savename)){ + if (empty($savename)) { $this->error = '文件命名规则错误!'; return false; } @@ -387,13 +407,14 @@ private function getSaveName($file) { * 获取子目录的名称 * @param array $file 上传的文件信息 */ - private function getSubPath($filename) { + private function getSubPath($filename) + { $subpath = ''; $rule = $this->subName; if ($this->autoSub && !empty($rule)) { $subpath = $this->getName($rule, $filename) . '/'; - if(!empty($subpath) && !$this->uploader->mkdir($this->savePath . $subpath)){ + if (!empty($subpath) && !$this->uploader->mkdir($this->savePath . $subpath)) { $this->error = $this->uploader->getError(); return false; } @@ -407,17 +428,20 @@ private function getSubPath($filename) { * @param string $filename 原文件名 * @return string 文件或目录名称 */ - private function getName($rule, $filename){ + private function getName($rule, $filename) + { $name = ''; - if(is_array($rule)){ //数组规则 - $func = $rule[0]; - $param = (array)$rule[1]; + if (is_array($rule)) { + //数组规则 + $func = $rule[0]; + $param = (array) $rule[1]; foreach ($param as &$value) { - $value = str_replace('__FILE__', $filename, $value); + $value = str_replace('__FILE__', $filename, $value); } $name = call_user_func_array($func, $param); - } elseif (is_string($rule)){ //字符串规则 - if(function_exists($rule)){ + } elseif (is_string($rule)) { + //字符串规则 + if (function_exists($rule)) { $name = call_user_func($rule); } else { $name = $rule; diff --git a/ThinkPHP/Library/Think/Upload/Driver/Bcs.class.php b/ThinkPHP/Library/Think/Upload/Driver/Bcs.class.php index 437fefd58..6a968f598 100644 --- a/ThinkPHP/Library/Think/Upload/Driver/Bcs.class.php +++ b/ThinkPHP/Library/Think/Upload/Driver/Bcs.class.php @@ -9,8 +9,11 @@ // | Author: Jay // +---------------------------------------------------------------------- namespace Think\Upload\Driver; + use Think\Upload\Driver\Bcs\BaiduBcs; -class Bcs { + +class Bcs +{ /** * 上传文件根目录 * @var string @@ -25,11 +28,11 @@ class Bcs { private $error = ''; public $config = array( - 'AccessKey'=> '', - 'SecretKey'=> '', //百度云服务器 - 'bucket' => '', //空间名称 - 'rename' => false, - 'timeout' => 3600, //超时时间 + 'AccessKey' => '', + 'SecretKey' => '', //百度云服务器 + 'bucket' => '', //空间名称 + 'rename' => false, + 'timeout' => 3600, //超时时间 ); public $bcs = null; @@ -38,14 +41,17 @@ class Bcs { * 构造函数,用于设置上传根路径 * @param array $config FTP配置 */ - public function __construct($config){ + public function __construct($config) + { /* 默认FTP配置 */ $this->config = array_merge($this->config, $config); - - $bcsClass = dirname(__FILE__). "/Bcs/bcs.class.php"; - if(is_file($bcsClass)) - require_once($bcsClass); - $this->bcs = new BaiduBCS ( $this->config['AccessKey'], $this->config['SecretKey'], self:: DEFAULT_URL ); + + $bcsClass = dirname(__FILE__) . "/Bcs/bcs.class.php"; + if (is_file($bcsClass)) { + require_once $bcsClass; + } + + $this->bcs = new BaiduBCS($this->config['AccessKey'], $this->config['SecretKey'], self::DEFAULT_URL); } /** @@ -53,10 +59,11 @@ public function __construct($config){ * @param string $rootpath 根目录 * @return boolean true-检测通过,false-检测失败 */ - public function checkRootPath($rootpath){ + public function checkRootPath($rootpath) + { /* 设置根目录 */ $this->rootPath = str_replace('./', '/', $rootpath); - return true; + return true; } /** @@ -64,8 +71,9 @@ public function checkRootPath($rootpath){ * @param string $savepath 上传目录 * @return boolean 检测结果,true-通过,false-失败 */ - public function checkSavePath($savepath){ - return true; + public function checkSavePath($savepath) + { + return true; } /** @@ -73,8 +81,9 @@ public function checkSavePath($savepath){ * @param string $savepath 目录名称 * @return boolean true-创建成功,false-创建失败 */ - public function mkdir($savepath){ - return true; + public function mkdir($savepath) + { + return true; } /** @@ -83,25 +92,27 @@ public function mkdir($savepath){ * @param boolean $replace 同名文件是否覆盖 * @return boolean 保存状态,true-成功,false-失败 */ - public function save(&$file,$replace=true) { - $opt = array (); - $opt ['acl'] = BaiduBCS::BCS_SDK_ACL_TYPE_PUBLIC_WRITE; - $opt ['curlopts'] = array ( + public function save(&$file, $replace = true) + { + $opt = array(); + $opt['acl'] = BaiduBCS::BCS_SDK_ACL_TYPE_PUBLIC_WRITE; + $opt['curlopts'] = array( CURLOPT_CONNECTTIMEOUT => 10, - CURLOPT_TIMEOUT => 1800 + CURLOPT_TIMEOUT => 1800, ); - $object = "/{$file['savepath']}{$file['savename']}"; - $response = $this->bcs->create_object ( $this->config['bucket'], $object, $file['tmp_name'], $opt ); - $url = $this->download($object); + $object = "/{$file['savepath']}{$file['savename']}"; + $response = $this->bcs->create_object($this->config['bucket'], $object, $file['tmp_name'], $opt); + $url = $this->download($object); $file['url'] = $url; return $response->isOK() ? true : false; } - public function download($file){ - $file = str_replace('./', '/', $file); - $opt = array(); + public function download($file) + { + $file = str_replace('./', '/', $file); + $opt = array(); $opt['time'] = mktime('2049-12-31'); //这是最长有效时间!-- - $response = $this->bcs->generate_get_object_url ( $this->config['bucket'], $file, $opt ); + $response = $this->bcs->generate_get_object_url($this->config['bucket'], $file, $opt); return $response; } @@ -109,7 +120,8 @@ public function download($file){ * 获取最后一次上传错误信息 * @return string 错误信息 */ - public function getError(){ + public function getError() + { return $this->error; } @@ -121,12 +133,13 @@ public function getError(){ * @param resource $body 上传文件资源 * @return boolean */ - private function request($path, $method, $headers = null, $body = null){ - $ch = curl_init($path); + private function request($path, $method, $headers = null, $body = null) + { + $ch = curl_init($path); $_headers = array('Expect:'); - if (!is_null($headers) && is_array($headers)){ - foreach($headers as $k => $v) { + if (!is_null($headers) && is_array($headers)) { + foreach ($headers as $k => $v) { array_push($_headers, "{$k}: {$v}"); } } @@ -135,7 +148,7 @@ private function request($path, $method, $headers = null, $body = null){ $date = gmdate('D, d M Y H:i:s \G\M\T'); if (!is_null($body)) { - if(is_resource($body)){ + if (is_resource($body)) { fseek($body, 0, SEEK_END); $length = ftell($body); fseek($body, 0); @@ -162,13 +175,13 @@ private function request($path, $method, $headers = null, $body = null){ curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); - if ($method == 'PUT' || $method == 'POST') { + if ('PUT' == $method || 'POST' == $method) { curl_setopt($ch, CURLOPT_POST, 1); } else { curl_setopt($ch, CURLOPT_POST, 0); } - if ($method == 'HEAD') { + if ('HEAD' == $method) { curl_setopt($ch, CURLOPT_NOBODY, true); } @@ -177,8 +190,8 @@ private function request($path, $method, $headers = null, $body = null){ curl_close($ch); list($header, $body) = explode("\r\n\r\n", $response, 2); - if ($status == 200) { - if ($method == 'GET') { + if (200 == $status) { + if ('GET' == $method) { return $body; } else { $data = $this->response($header); @@ -195,7 +208,8 @@ private function request($path, $method, $headers = null, $body = null){ * @param string $text 响应头字符串 * @return array 响应数据列表 */ - private function response($text){ + private function response($text) + { $items = json_decode($text, true); return $items; } @@ -204,35 +218,40 @@ private function response($text){ * 生成请求签名 * @return string 请求签名 */ - private function sign($method, $Bucket, $object='/', $size=''){ - if(!$size) + private function sign($method, $Bucket, $object = '/', $size = '') + { + if (!$size) { $size = $this->config['size']; + } + $param = array( - 'ak'=>$this->config['AccessKey'], - 'sk'=>$this->config['SecretKey'], - 'size'=>$size, - 'bucket'=>$Bucket, - 'host'=>self :: DEFAULT_URL, - 'date'=>time()+$this->config['timeout'], - 'ip'=>'', - 'object'=>$object + 'ak' => $this->config['AccessKey'], + 'sk' => $this->config['SecretKey'], + 'size' => $size, + 'bucket' => $Bucket, + 'host' => self::DEFAULT_URL, + 'date' => time() + $this->config['timeout'], + 'ip' => '', + 'object' => $object, ); - $response = $this->request($this->apiurl.'?'.http_build_query($param), 'POST'); - if($response) + $response = $this->request($this->apiurl . '?' . http_build_query($param), 'POST'); + if ($response) { $response = json_decode($response, true); + } + return $response['content'][$method]; } - /** * 获取请求错误信息 * @param string $header 请求返回头信息 */ - private function error($header) { - list($status, $stash) = explode("\r\n", $header, 2); + private function error($header) + { + list($status, $stash) = explode("\r\n", $header, 2); list($v, $code, $message) = explode(" ", $status, 3); - $message = is_null($message) ? 'File Not Found' : "[{$status}]:{$message}"; - $this->error = $message; + $message = is_null($message) ? 'File Not Found' : "[{$status}]:{$message}"; + $this->error = $message; } } diff --git a/ThinkPHP/Library/Think/Upload/Driver/Bcs/bcs.class.php b/ThinkPHP/Library/Think/Upload/Driver/Bcs/bcs.class.php index a990aecbf..d41b0cd8c 100644 --- a/ThinkPHP/Library/Think/Upload/Driver/Bcs/bcs.class.php +++ b/ThinkPHP/Library/Think/Upload/Driver/Bcs/bcs.class.php @@ -1,1318 +1,1364 @@ ak = $ak; - $this->sk = $sk; - } elseif (defined ( 'BCS_AK' ) && defined ( 'BCS_SK' ) && strlen ( BCS_AK ) > 0 && strlen ( BCS_SK ) > 0) { - $this->ak = BCS_AK; - $this->sk = BCS_SK; - } elseif (false !== getenv ( 'HTTP_BAE_ENV_AK' ) && false !== getenv ( 'HTTP_BAE_ENV_SK' )) { - $this->ak = getenv ( 'HTTP_BAE_ENV_AK' ); - $this->sk = getenv ( 'HTTP_BAE_ENV_SK' ); - } else { - throw new BCS_Exception ( 'Construct can not get ak &sk pair, please check!' ); - } - //valid $hostname - if (NULL !== $hostname) { - $this->hostname = $hostname; - } elseif (false !== getenv ( 'HTTP_BAE_ENV_ADDR_BCS' )) { - $this->hostname = getenv ( 'HTTP_BAE_ENV_ADDR_BCS' ); - } else { - $this->hostname = self::DEFAULT_URL; - } - } + /** + * 构造函数 + * @param string $ak 云存储公钥 + * @param string $sk 云存储私钥 + * @param string $hostname 云存储Api访问地址 + * @throws BCS_Exception + */ + public function __construct($ak = null, $sk = null, $hostname = null) + { + //valid ak & sk + if (!$ak && !defined('BCS_AK') && false === getenv('HTTP_BAE_ENV_AK')) { + throw new BCS_Exception('No account key was passed into the constructor.'); + } + if (!$sk && !defined('BCS_SK') && false === getenv('HTTP_BAE_ENV_SK')) { + throw new BCS_Exception('No secret key was passed into the constructor.'); + } + if ($ak && $sk) { + $this->ak = $ak; + $this->sk = $sk; + } elseif (defined('BCS_AK') && defined('BCS_SK') && strlen(BCS_AK) > 0 && strlen(BCS_SK) > 0) { + $this->ak = BCS_AK; + $this->sk = BCS_SK; + } elseif (false !== getenv('HTTP_BAE_ENV_AK') && false !== getenv('HTTP_BAE_ENV_SK')) { + $this->ak = getenv('HTTP_BAE_ENV_AK'); + $this->sk = getenv('HTTP_BAE_ENV_SK'); + } else { + throw new BCS_Exception('Construct can not get ak &sk pair, please check!'); + } + //valid $hostname + if (null !== $hostname) { + $this->hostname = $hostname; + } elseif (false !== getenv('HTTP_BAE_ENV_ADDR_BCS')) { + $this->hostname = getenv('HTTP_BAE_ENV_ADDR_BCS'); + } else { + $this->hostname = self::DEFAULT_URL; + } + } - /** - * 将消息发往Baidu BCS. - * @param array $opt - * @return BCS_ResponseCore - */ - private function authenticate($opt) { - //set common param into opt - $opt [self::AK] = $this->ak; - $opt [self::SK] = $this->sk; + /** + * 将消息发往Baidu BCS. + * @param array $opt + * @return BCS_ResponseCore + */ + private function authenticate($opt) + { + //set common param into opt + $opt[self::AK] = $this->ak; + $opt[self::SK] = $this->sk; - // Validate the S3 bucket name, only list_bucket didnot need validate_bucket - if (! ('/' == $opt [self::OBJECT] && '' == $opt [self::BUCKET] && 'GET' == $opt [self::METHOD] && ! isset ( $opt [self::QUERY_STRING] [self::ACL] )) && ! self::validate_bucket ( $opt [self::BUCKET] )) { - throw new BCS_Exception ( $opt [self::BUCKET] . 'is not valid, please check!' ); - } - //Validate object - if (isset ( $opt [self::OBJECT] ) && ! self::validate_object ( $opt [self::OBJECT] )) { - throw new BCS_Exception ( "Invalid object param[" . $opt [self::OBJECT] . "], please check.", - 1 ); - } - //construct url - $url = $this->format_url ( $opt ); - if ($url === false) { - throw new BCS_Exception ( 'Can not format url, please check your param!', - 1 ); - } - $opt ['url'] = $url; - $this->log ( "[method:" . $opt [self::METHOD] . "][url:$url]", $opt ); - //build request - $request = new BCS_RequestCore ( $opt ['url'] ); - $headers = array ( - 'Content-Type' => 'application/x-www-form-urlencoded' ); + // Validate the S3 bucket name, only list_bucket didnot need validate_bucket + if (!('/' == $opt[self::OBJECT] && '' == $opt[self::BUCKET] && 'GET' == $opt[self::METHOD] && !isset($opt[self::QUERY_STRING][self::ACL])) && !self::validateBucket($opt[self::BUCKET])) { + throw new BCS_Exception($opt[self::BUCKET] . 'is not valid, please check!'); + } + //Validate object + if (isset($opt[self::OBJECT]) && !self::validateObject($opt[self::OBJECT])) { + throw new BCS_Exception("Invalid object param[" . $opt[self::OBJECT] . "], please check.", -1); + } + //construct url + $url = $this->formatUrl($opt); + if (false === $url) { + throw new BCS_Exception('Can not format url, please check your param!', -1); + } + $opt['url'] = $url; + $this->log("[method:" . $opt[self::METHOD] . "][url:$url]", $opt); + //build request + $request = new BCS_RequestCore($opt['url']); + $headers = array( + 'Content-Type' => 'application/x-www-form-urlencoded'); - $request->set_method ( $opt [self::METHOD] ); - //Write get_object content to fileWriteTo - if (isset ( $opt ['fileWriteTo'] )) { - $request->set_write_file ( $opt ['fileWriteTo'] ); - } - // Merge the HTTP headers - if (isset ( $opt [self::HEADERS] )) { - $headers = array_merge ( $headers, $opt [self::HEADERS] ); - } - // Set content to Http-Body - if (isset ( $opt ['content'] )) { - $request->set_body ( $opt ['content'] ); - } - // Upload file - if (isset ( $opt ['fileUpload'] )) { - if (! file_exists ( $opt ['fileUpload'] )) { - throw new BCS_Exception ( 'File[' . $opt ['fileUpload'] . '] not found!', - 1 ); - } - $request->set_read_file ( $opt ['fileUpload'] ); - // Determine the length to read from the file - $length = $request->read_stream_size; // The file size by default - $file_size = $length; - if (isset ( $opt ["length"] )) { - if ($opt ["length"] > $file_size) { - throw new BCS_Exception ( "Input opt[length] invalid! It can not bigger than file-size", - 1 ); - } - $length = $opt ['length']; - } - if (isset ( $opt ['seekTo'] ) && ! isset ( $opt ["length"] )) { - // Read from seekTo until EOF by default, when set seekTo but not set $opt["length"] - $length -= ( integer ) $opt ['seekTo']; - } - $request->set_read_stream_size ( $length ); - // Attempt to guess the correct mime-type - if ($headers ['Content-Type'] === 'application/x-www-form-urlencoded') { - $extension = explode ( '.', $opt ['fileUpload'] ); - $extension = array_pop ( $extension ); - $mime_type = BCS_MimeTypes::get_mimetype ( $extension ); - $headers ['Content-Type'] = $mime_type; - } - $headers ['Content-MD5'] = ''; - } - // Handle streaming file offsets - if (isset ( $opt ['seekTo'] )) { - // Pass the seek position to BCS_RequestCore - $request->set_seek_position ( ( integer ) $opt ['seekTo'] ); - } - // Add headers to request and compute the string to sign - foreach ( $headers as $header_key => $header_value ) { - // Strip linebreaks from header values as they're illegal and can allow for security issues - $header_value = str_replace ( array ( - "\r", - "\n" ), '', $header_value ); - // Add the header if it has a value - if ($header_value !== '') { - $request->add_header ( $header_key, $header_value ); - } - } - // Set the curl options. - if (isset ( $opt ['curlopts'] ) && count ( $opt ['curlopts'] )) { - $request->set_curlopts ( $opt ['curlopts'] ); - } - $request->send_request (); - require_once(dirname(__FILE__). "/requestcore.class.php"); - return new BCS_ResponseCore ( $request->get_response_header (), $request->get_response_body (), $request->get_response_code () ); - } + $request->set_method($opt[self::METHOD]); + //Write get_object content to fileWriteTo + if (isset($opt['fileWriteTo'])) { + $request->set_write_file($opt['fileWriteTo']); + } + // Merge the HTTP headers + if (isset($opt[self::HEADERS])) { + $headers = array_merge($headers, $opt[self::HEADERS]); + } + // Set content to Http-Body + if (isset($opt['content'])) { + $request->set_body($opt['content']); + } + // Upload file + if (isset($opt['fileUpload'])) { + if (!file_exists($opt['fileUpload'])) { + throw new BCS_Exception('File[' . $opt['fileUpload'] . '] not found!', -1); + } + $request->set_read_file($opt['fileUpload']); + // Determine the length to read from the file + $length = $request->read_stream_size; // The file size by default + $file_size = $length; + if (isset($opt["length"])) { + if ($opt["length"] > $file_size) { + throw new BCS_Exception("Input opt[length] invalid! It can not bigger than file-size", -1); + } + $length = $opt['length']; + } + if (isset($opt['seekTo']) && !isset($opt["length"])) { + // Read from seekTo until EOF by default, when set seekTo but not set $opt["length"] + $length -= (integer) $opt['seekTo']; + } + $request->set_read_stream_size($length); + // Attempt to guess the correct mime-type + if ('application/x-www-form-urlencoded' === $headers['Content-Type']) { + $extension = explode('.', $opt['fileUpload']); + $extension = array_pop($extension); + $mime_type = BCS_MimeTypes::get_mimetype($extension); + $headers['Content-Type'] = $mime_type; + } + $headers['Content-MD5'] = ''; + } + // Handle streaming file offsets + if (isset($opt['seekTo'])) { + // Pass the seek position to BCS_RequestCore + $request->set_seek_position((integer) $opt['seekTo']); + } + // Add headers to request and compute the string to sign + foreach ($headers as $header_key => $header_value) { + // Strip linebreaks from header values as they're illegal and can allow for security issues + $header_value = str_replace(array( + "\r", + "\n"), '', $header_value); + // Add the header if it has a value + if ('' !== $header_value) { + $request->add_header($header_key, $header_value); + } + } + // Set the curl options. + if (isset($opt['curlopts']) && count($opt['curlopts'])) { + $request->set_curlopts($opt['curlopts']); + } + $request->send_request(); + require_once dirname(__FILE__) . "/requestcore.class.php"; + return new BCS_ResponseCore($request->get_response_header(), $request->get_response_body(), $request->get_response_code()); + } - /** - * 获取当前密钥对拥有者的bucket列表 - * @param array $opt (Optional) - * BaiduBCS::IMPORT_BCS_LOG_METHOD - String - Optional: 支持用户传入日志处理函数,函数定义如 function f($log) - * @throws BCS_Exception - * @return BCS_ResponseCore - */ - public function list_bucket($opt = array()) { - $this->assertParameterArray ( $opt ); - $opt [self::BUCKET] = ''; - $opt [self::METHOD] = 'GET'; - $opt [self::OBJECT] = '/'; - $response = $this->authenticate ( $opt ); - $this->log ( $response->isOK () ? "List bucket success!" : "List bucket failed! Response: [" . $response->body . "]", $opt ); - return $response; - } + /** + * 获取当前密钥对拥有者的bucket列表 + * @param array $opt (Optional) + * BaiduBCS::IMPORT_BCS_LOG_METHOD - String - Optional: 支持用户传入日志处理函数,函数定义如 function f($log) + * @throws BCS_Exception + * @return BCS_ResponseCore + */ + public function listBucket($opt = array()) + { + $this->assertParameterArray($opt); + $opt[self::BUCKET] = ''; + $opt[self::METHOD] = 'GET'; + $opt[self::OBJECT] = '/'; + $response = $this->authenticate($opt); + $this->log($response->isOK() ? "List bucket success!" : "List bucket failed! Response: [" . $response->body . "]", $opt); + return $response; + } - /** - * 创建 bucket - * @param string $bucket (Required) bucket名称 - * @param string $acl (Optional) bucket权限设置,若为null,使用server分配的默认权限 - * @param array $opt (Optional) - * @throws BCS_Exception - * @return BCS_ResponseCore - */ - public function create_bucket($bucket, $acl = NULL, $opt = array()) { - $this->assertParameterArray ( $opt ); - $opt [self::BUCKET] = $bucket; - $opt [self::METHOD] = 'PUT'; - $opt [self::OBJECT] = '/'; - if (NULL !== $acl) { - if (! in_array ( $acl, self::$ACL_TYPES )) { - throw new BCS_Exception ( "Invalid acl_type[" . $acl . "], please check!", - 1 ); - } - self::set_header_into_opt ( "x-bs-acl", $acl, $opt ); - } - $response = $this->authenticate ( $opt ); - $this->log ( $response->isOK () ? "Create bucket success!" : "Create bucket failed! Response: [" . $response->body . "]", $opt ); - return $response; - } + /** + * 创建 bucket + * @param string $bucket (Required) bucket名称 + * @param string $acl (Optional) bucket权限设置,若为null,使用server分配的默认权限 + * @param array $opt (Optional) + * @throws BCS_Exception + * @return BCS_ResponseCore + */ + public function createBucket($bucket, $acl = null, $opt = array()) + { + $this->assertParameterArray($opt); + $opt[self::BUCKET] = $bucket; + $opt[self::METHOD] = 'PUT'; + $opt[self::OBJECT] = '/'; + if (null !== $acl) { + if (!in_array($acl, self::$ACL_TYPES)) { + throw new BCS_Exception("Invalid acl_type[" . $acl . "], please check!", -1); + } + self::setHeaderIntoOpt("x-bs-acl", $acl, $opt); + } + $response = $this->authenticate($opt); + $this->log($response->isOK() ? "Create bucket success!" : "Create bucket failed! Response: [" . $response->body . "]", $opt); + return $response; + } - /** - * 删除bucket - * @param string $bucket (Required) - * @param array $opt (Optional) - * @return boolean|BCS_ResponseCore - */ - public function delete_bucket($bucket, $opt = array()) { - $this->assertParameterArray ( $opt ); - $opt [self::BUCKET] = $bucket; - $opt [self::METHOD] = 'DELETE'; - $opt [self::OBJECT] = '/'; - $response = $this->authenticate ( $opt ); - $this->log ( $response->isOK () ? "Delete bucket success!" : "Delete bucket failed! Response: [" . $response->body . "]", $opt ); - return $response; - } + /** + * 删除bucket + * @param string $bucket (Required) + * @param array $opt (Optional) + * @return boolean|BCS_ResponseCore + */ + public function deleteBucket($bucket, $opt = array()) + { + $this->assertParameterArray($opt); + $opt[self::BUCKET] = $bucket; + $opt[self::METHOD] = 'DELETE'; + $opt[self::OBJECT] = '/'; + $response = $this->authenticate($opt); + $this->log($response->isOK() ? "Delete bucket success!" : "Delete bucket failed! Response: [" . $response->body . "]", $opt); + return $response; + } - /** - * 设置bucket的acl,有三种模式, - * (1).设置详细json格式的acl; - * a. $acl 为json的array - * b. $acl 为json的string - * (2).通过acl_type字段进行设置 - * a. $acl 为BaiduBCS::$ACL_TYPES中的字段 - * @param string $bucket (Required) - * @param string $acl (Required) - * @param array $opt (Optional) - * @return boolean|BCS_ResponseCore - */ - public function set_bucket_acl($bucket, $acl, $opt = array()) { - $this->assertParameterArray ( $opt ); - $result = $this->analyze_user_acl ( $acl ); - $opt = array_merge ( $opt, $result ); - $opt [self::BUCKET] = $bucket; - $opt [self::METHOD] = 'PUT'; - $opt [self::OBJECT] = '/'; - $opt [self::QUERY_STRING] = array ( - self::ACL => 1 ); - $response = $this->authenticate ( $opt ); - $this->log ( $response->isOK () ? "Set bucket acl success!" : "Set bucket acl failed! Response: [" . $response->body . "]", $opt ); - return $response; - } + /** + * 设置bucket的acl,有三种模式, + * (1).设置详细json格式的acl; + * a. $acl 为json的array + * b. $acl 为json的string + * (2).通过acl_type字段进行设置 + * a. $acl 为BaiduBCS::$ACL_TYPES中的字段 + * @param string $bucket (Required) + * @param string $acl (Required) + * @param array $opt (Optional) + * @return boolean|BCS_ResponseCore + */ + public function setBucketAcl($bucket, $acl, $opt = array()) + { + $this->assertParameterArray($opt); + $result = $this->analyzeUserAcl($acl); + $opt = array_merge($opt, $result); + $opt[self::BUCKET] = $bucket; + $opt[self::METHOD] = 'PUT'; + $opt[self::OBJECT] = '/'; + $opt[self::QUERY_STRING] = array( + self::ACL => 1); + $response = $this->authenticate($opt); + $this->log($response->isOK() ? "Set bucket acl success!" : "Set bucket acl failed! Response: [" . $response->body . "]", $opt); + return $response; + } - /** - * 获取bucket的acl - * @param string $bucket (Required) - * @param array $opt (Optional) - * @return BCS_ResponseCore - */ - public function get_bucket_acl($bucket, $opt = array()) { - $this->assertParameterArray ( $opt ); - $opt [self::BUCKET] = $bucket; - $opt [self::METHOD] = 'GET'; - $opt [self::OBJECT] = '/'; - $opt [self::QUERY_STRING] = array ( - self::ACL => 1 ); - $response = $this->authenticate ( $opt ); - $this->log ( $response->isOK () ? "Get bucket acl success!" : "Get bucket acl failed! Response: [" . $response->body . "]", $opt ); - return $response; - } + /** + * 获取bucket的acl + * @param string $bucket (Required) + * @param array $opt (Optional) + * @return BCS_ResponseCore + */ + public function getBucketAcl($bucket, $opt = array()) + { + $this->assertParameterArray($opt); + $opt[self::BUCKET] = $bucket; + $opt[self::METHOD] = 'GET'; + $opt[self::OBJECT] = '/'; + $opt[self::QUERY_STRING] = array( + self::ACL => 1); + $response = $this->authenticate($opt); + $this->log($response->isOK() ? "Get bucket acl success!" : "Get bucket acl failed! Response: [" . $response->body . "]", $opt); + return $response; + } - /** - * 获取bucket中object列表 - * @param string $bucket (Required) - * @param array $opt (Optional) - * start : 主要用于翻页功能,用法同mysql中start的用法 - * limit : 主要用于翻页功能,用法同mysql中limit的用法 - * prefix: 只返回以prefix为前缀的object,此处prefix必须以'/'开头 - * @throws BCS_Exception - * @return BCS_ResponseCore - */ - public function list_object($bucket, $opt = array()) { - $this->assertParameterArray ( $opt ); - $opt [self::BUCKET] = $bucket; - if (empty ( $opt [self::BUCKET] )) { - throw new BCS_Exception ( "Bucket should not be empty, please check", - 1 ); - } - $opt [self::METHOD] = 'GET'; - $opt [self::OBJECT] = '/'; - $opt [self::QUERY_STRING] = array (); - if (isset ( $opt ['start'] ) && is_int ( $opt ['start'] )) { - $opt [self::QUERY_STRING] ['start'] = $opt ['start']; - } - if (isset ( $opt ['limit'] ) && is_int ( $opt ['limit'] )) { - $opt [self::QUERY_STRING] ['limit'] = $opt ['limit']; - } - if (isset ( $opt ['prefix'] )) { - $opt [self::QUERY_STRING] ['prefix'] = rawurlencode ( $opt ['prefix'] ); - } - $response = $this->authenticate ( $opt ); - $this->log ( $response->isOK () ? "List object success!" : "Lit object failed! Response: [" . $response->body . "]", $opt ); - return $response; - } + /** + * 获取bucket中object列表 + * @param string $bucket (Required) + * @param array $opt (Optional) + * start : 主要用于翻页功能,用法同mysql中start的用法 + * limit : 主要用于翻页功能,用法同mysql中limit的用法 + * prefix: 只返回以prefix为前缀的object,此处prefix必须以'/'开头 + * @throws BCS_Exception + * @return BCS_ResponseCore + */ + public function listObject($bucket, $opt = array()) + { + $this->assertParameterArray($opt); + $opt[self::BUCKET] = $bucket; + if (empty($opt[self::BUCKET])) { + throw new BCS_Exception("Bucket should not be empty, please check", -1); + } + $opt[self::METHOD] = 'GET'; + $opt[self::OBJECT] = '/'; + $opt[self::QUERY_STRING] = array(); + if (isset($opt['start']) && is_int($opt['start'])) { + $opt[self::QUERY_STRING]['start'] = $opt['start']; + } + if (isset($opt['limit']) && is_int($opt['limit'])) { + $opt[self::QUERY_STRING]['limit'] = $opt['limit']; + } + if (isset($opt['prefix'])) { + $opt[self::QUERY_STRING]['prefix'] = rawurlencode($opt['prefix']); + } + $response = $this->authenticate($opt); + $this->log($response->isOK() ? "List object success!" : "Lit object failed! Response: [" . $response->body . "]", $opt); + return $response; + } - /** - * 以目录形式获取bucket中object列表 - * @param string $bucket (Required) - * @param $dir (Required) - * 目录名,格式为必须以'/'开头和结尾,默认为'/' - * @param string $list_model (Required) - * 目录展现形式,值可以为0,1,2,默认为2,以下对各个值的功能进行介绍: - * 0->只返回object列表,不返回子目录列表 - * 1->只返回子目录列表,不返回object列表 - * 2->同时返回子目录列表和object列表 - * @param array $opt (Optional) - * start : 主要用于翻页功能,用法同mysql中start的用法 - * limit : 主要用于翻页功能,用法同mysql中limit的用法 - * @throws BCS_Exception - * @return BCS_ResponseCore - */ - public function list_object_by_dir($bucket, $dir = '/', $list_model = 2, $opt = array()) { - $this->assertParameterArray ( $opt ); - $opt [self::BUCKET] = $bucket; - if (empty ( $opt [self::BUCKET] )) { - throw new BCS_Exception ( "Bucket should not be empty, please check", - 1 ); - } - $opt [self::METHOD] = 'GET'; - $opt [self::OBJECT] = '/'; - $opt [self::QUERY_STRING] = array (); - if (isset ( $opt ['start'] ) && is_int ( $opt ['start'] )) { - $opt [self::QUERY_STRING] ['start'] = $opt ['start']; - } - if (isset ( $opt ['limit'] ) && is_int ( $opt ['limit'] )) { - $opt [self::QUERY_STRING] ['limit'] = $opt ['limit']; - } + /** + * 以目录形式获取bucket中object列表 + * @param string $bucket (Required) + * @param $dir (Required) + * 目录名,格式为必须以'/'开头和结尾,默认为'/' + * @param string $list_model (Required) + * 目录展现形式,值可以为0,1,2,默认为2,以下对各个值的功能进行介绍: + * 0->只返回object列表,不返回子目录列表 + * 1->只返回子目录列表,不返回object列表 + * 2->同时返回子目录列表和object列表 + * @param array $opt (Optional) + * start : 主要用于翻页功能,用法同mysql中start的用法 + * limit : 主要用于翻页功能,用法同mysql中limit的用法 + * @throws BCS_Exception + * @return BCS_ResponseCore + */ + public function listObjectByDir($bucket, $dir = '/', $list_model = 2, $opt = array()) + { + $this->assertParameterArray($opt); + $opt[self::BUCKET] = $bucket; + if (empty($opt[self::BUCKET])) { + throw new BCS_Exception("Bucket should not be empty, please check", -1); + } + $opt[self::METHOD] = 'GET'; + $opt[self::OBJECT] = '/'; + $opt[self::QUERY_STRING] = array(); + if (isset($opt['start']) && is_int($opt['start'])) { + $opt[self::QUERY_STRING]['start'] = $opt['start']; + } + if (isset($opt['limit']) && is_int($opt['limit'])) { + $opt[self::QUERY_STRING]['limit'] = $opt['limit']; + } - $opt [self::QUERY_STRING] ['prefix'] = rawurlencode ( $dir ); - $opt [self::QUERY_STRING] ['dir'] = $list_model; + $opt[self::QUERY_STRING]['prefix'] = rawurlencode($dir); + $opt[self::QUERY_STRING]['dir'] = $list_model; - $response = $this->authenticate ( $opt ); - $this->log ( $response->isOK () ? "List object success!" : "Lit object failed! Response: [" . $response->body . "]", $opt ); - return $response; - } + $response = $this->authenticate($opt); + $this->log($response->isOK() ? "List object success!" : "Lit object failed! Response: [" . $response->body . "]", $opt); + return $response; + } - /** - * 上传文件 - * @param string $bucket (Required) - * @param string $object (Required) - * @param string $file (Required); 需要上传的文件的文件路径 - * @param array $opt (Optional) - * filename - Optional; 指定文件名 - * acl - Optional ; 上传文件的acl,只能使用acl_type - * seekTo - Optional; 上传文件的偏移位置 - * length - Optional; 待上传长度 - * @return BCS_ResponseCore - */ - public function create_object($bucket, $object, $file, $opt = array()) { - $this->assertParameterArray ( $opt ); - $opt [self::BUCKET] = $bucket; - $opt [self::OBJECT] = $object; - $opt ['fileUpload'] = $file; - $opt [self::METHOD] = 'PUT'; - if (isset ( $opt ['acl'] )) { - if (in_array ( $opt ['acl'], self::$ACL_TYPES )) { - self::set_header_into_opt ( "x-bs-acl", $opt ['acl'], $opt ); - } else { - throw new BCS_Exception ( "Invalid acl string, it should be acl_type", - 1 ); - } - unset ( $opt ['acl'] ); - } - if (isset ( $opt ['filename'] )) { - self::set_header_into_opt ( "Content-Disposition", 'attachment; filename=' . $opt ['filename'], $opt ); - } - $response = $this->authenticate ( $opt ); - $this->log ( $response->isOK () ? "Create object[$object] file[$file] success!" : "Create object[$object] file[$file] failed! Response: [" . $response->body . "] Logid[" . $response->header ["x-bs-request-id"] . "]", $opt ); - return $response; - } + /** + * 上传文件 + * @param string $bucket (Required) + * @param string $object (Required) + * @param string $file (Required); 需要上传的文件的文件路径 + * @param array $opt (Optional) + * filename - Optional; 指定文件名 + * acl - Optional ; 上传文件的acl,只能使用acl_type + * seekTo - Optional; 上传文件的偏移位置 + * length - Optional; 待上传长度 + * @return BCS_ResponseCore + */ + public function createObject($bucket, $object, $file, $opt = array()) + { + $this->assertParameterArray($opt); + $opt[self::BUCKET] = $bucket; + $opt[self::OBJECT] = $object; + $opt['fileUpload'] = $file; + $opt[self::METHOD] = 'PUT'; + if (isset($opt['acl'])) { + if (in_array($opt['acl'], self::$ACL_TYPES)) { + self::setHeaderIntoOpt("x-bs-acl", $opt['acl'], $opt); + } else { + throw new BCS_Exception("Invalid acl string, it should be acl_type", -1); + } + unset($opt['acl']); + } + if (isset($opt['filename'])) { + self::setHeaderIntoOpt("Content-Disposition", 'attachment; filename=' . $opt['filename'], $opt); + } + $response = $this->authenticate($opt); + $this->log($response->isOK() ? "Create object[$object] file[$file] success!" : "Create object[$object] file[$file] failed! Response: [" . $response->body . "] Logid[" . $response->header["x-bs-request-id"] . "]", $opt); + return $response; + } - /** - * 上传文件 - * @param string $bucket (Required) - * @param string $object (Required) - * @param string $file (Required); 需要上传的文件的文件路径 - * @param array $opt (Optional) - * filename - Optional; 指定文件名 - * acl - Optional ; 上传文件的acl,只能使用acl_type - * @return BCS_ResponseCore - */ - public function create_object_by_content($bucket, $object, $content, $opt = array()) { - $this->assertParameterArray ( $opt ); - $opt [self::BUCKET] = $bucket; - $opt [self::OBJECT] = $object; - $opt [self::METHOD] = 'PUT'; - if ($content !== NULL && is_string ( $content )) { - $opt ['content'] = $content; - } else { - throw new BCS_Exception ( "Invalid object content, please check.", - 1 ); - } - if (isset ( $opt ['acl'] )) { - if (in_array ( $opt ['acl'], self::$ACL_TYPES )) { - self::set_header_into_opt ( "x-bs-acl", $opt ['acl'], $opt ); - } else { - throw new BCS_Exception ( "Invalid acl string, it should be acl_type", - 1 ); - } - unset ( $opt ['acl'] ); - } - if (isset ( $opt ['filename'] )) { - self::set_header_into_opt ( "Content-Disposition", 'attachment; filename=' . $opt ['filename'], $opt ); - } - $response = $this->authenticate ( $opt ); - $this->log ( $response->isOK () ? "Create object[$object] success!" : "Create object[$object] failed! Response: [" . $response->body . "] Logid[" . $response->header ["x-bs-request-id"] . "]", $opt ); - return $response; - } + /** + * 上传文件 + * @param string $bucket (Required) + * @param string $object (Required) + * @param string $file (Required); 需要上传的文件的文件路径 + * @param array $opt (Optional) + * filename - Optional; 指定文件名 + * acl - Optional ; 上传文件的acl,只能使用acl_type + * @return BCS_ResponseCore + */ + public function createObjectByContent($bucket, $object, $content, $opt = array()) + { + $this->assertParameterArray($opt); + $opt[self::BUCKET] = $bucket; + $opt[self::OBJECT] = $object; + $opt[self::METHOD] = 'PUT'; + if (null !== $content && is_string($content)) { + $opt['content'] = $content; + } else { + throw new BCS_Exception("Invalid object content, please check.", -1); + } + if (isset($opt['acl'])) { + if (in_array($opt['acl'], self::$ACL_TYPES)) { + self::setHeaderIntoOpt("x-bs-acl", $opt['acl'], $opt); + } else { + throw new BCS_Exception("Invalid acl string, it should be acl_type", -1); + } + unset($opt['acl']); + } + if (isset($opt['filename'])) { + self::setHeaderIntoOpt("Content-Disposition", 'attachment; filename=' . $opt['filename'], $opt); + } + $response = $this->authenticate($opt); + $this->log($response->isOK() ? "Create object[$object] success!" : "Create object[$object] failed! Response: [" . $response->body . "] Logid[" . $response->header["x-bs-request-id"] . "]", $opt); + return $response; + } - /** - * 通过superfile的方式上传文件 - * @param string $bucket (Required) - * @param string $object (Required) - * @param string $file (Required); 需要上传的文件的文件路径 - * @param array $opt (Optional) - * filename - Optional; 指定文件名 - * sub_object_size - Optional; 指定子文件的划分大小,单位B,建议以256KB为单位进行子object划分,默认为1MB进行划分 - * @return BCS_ResponseCore - */ - public function create_object_superfile($bucket, $object, $file, $opt = array()) { - if (isset ( $opt ['length'] ) || isset ( $opt ['seekTo'] )) { - throw new BCS_Exception ( "Temporary unsupport opt of length and seekTo of superfile.", - 1 ); - } - //$opt array - $this->assertParameterArray ( $opt ); - $opt [self::BUCKET] = $bucket; - $opt ['fileUpload'] = $file; - $opt [self::METHOD] = 'PUT'; - if (isset ( $opt ['acl'] )) { - if (in_array ( $opt ['acl'], self::$ACL_TYPES )) { - self::set_header_into_opt ( "x-bs-acl", $opt ['acl'], $opt ); - } else { - throw new BCS_Exception ( "Invalid acl string, it should be acl_type", - 1 ); - } - unset ( $opt ['acl'] ); - } - //切片上传 - if (! file_exists ( $opt ['fileUpload'] )) { - throw new BCS_Exception ( 'File not found!', - 1 ); - } - $fileSize = filesize ( $opt ['fileUpload'] ); - $sub_object_size = 1024 * 1024; //default 1MB - if (defined ( "BCS_SUPERFILE_SLICE_SIZE" )) { - $sub_object_size = BCS_SUPERFILE_SLICE_SIZE; - } - if (isset ( $opt ["sub_object_size"] )) { - if (is_int ( $opt ["sub_object_size"] ) && $opt ["sub_object_size"] > 0) { - $sub_object_size = $opt ["sub_object_size"]; - } else { - throw new BCS_Exception ( "Param [sub_object_size] invalid ,please check!", - 1 ); - } - } - $sliceNum = intval ( ceil ( $fileSize / $sub_object_size ) ); - $this->log ( "File[" . $opt ['fileUpload'] . "], size=[$fileSize], sub_object_size=[$sub_object_size], sub_object_num=[$sliceNum]", $opt ); - $object_list = array ( - 'object_list' => array () ); - for($i = 0; $i < $sliceNum; $i ++) { - //send slice - $opt ['seekTo'] = $i * $sub_object_size; + /** + * 通过superfile的方式上传文件 + * @param string $bucket (Required) + * @param string $object (Required) + * @param string $file (Required); 需要上传的文件的文件路径 + * @param array $opt (Optional) + * filename - Optional; 指定文件名 + * sub_object_size - Optional; 指定子文件的划分大小,单位B,建议以256KB为单位进行子object划分,默认为1MB进行划分 + * @return BCS_ResponseCore + */ + public function createObjectSuperfile($bucket, $object, $file, $opt = array()) + { + if (isset($opt['length']) || isset($opt['seekTo'])) { + throw new BCS_Exception("Temporary unsupport opt of length and seekTo of superfile.", -1); + } + //$opt array + $this->assertParameterArray($opt); + $opt[self::BUCKET] = $bucket; + $opt['fileUpload'] = $file; + $opt[self::METHOD] = 'PUT'; + if (isset($opt['acl'])) { + if (in_array($opt['acl'], self::$ACL_TYPES)) { + self::setHeaderIntoOpt("x-bs-acl", $opt['acl'], $opt); + } else { + throw new BCS_Exception("Invalid acl string, it should be acl_type", -1); + } + unset($opt['acl']); + } + //切片上传 + if (!file_exists($opt['fileUpload'])) { + throw new BCS_Exception('File not found!', -1); + } + $fileSize = filesize($opt['fileUpload']); + $sub_object_size = 1024 * 1024; //default 1MB + if (defined("BCS_SUPERFILE_SLICE_SIZE")) { + $sub_object_size = BCS_SUPERFILE_SLICE_SIZE; + } + if (isset($opt["sub_object_size"])) { + if (is_int($opt["sub_object_size"]) && $opt["sub_object_size"] > 0) { + $sub_object_size = $opt["sub_object_size"]; + } else { + throw new BCS_Exception("Param [sub_object_size] invalid ,please check!", -1); + } + } + $sliceNum = intval(ceil($fileSize / $sub_object_size)); + $this->log("File[" . $opt['fileUpload'] . "], size=[$fileSize], sub_object_size=[$sub_object_size], sub_object_num=[$sliceNum]", $opt); + $object_list = array( + 'object_list' => array()); + for ($i = 0; $i < $sliceNum; $i++) { + //send slice + $opt['seekTo'] = $i * $sub_object_size; - if (($i + 1) === $sliceNum) { - //last sub object - $opt ['length'] = (0 === $fileSize % $sub_object_size) ? $sub_object_size : $fileSize % $sub_object_size; - } else { - $opt ['length'] = $sub_object_size; - } - $opt [self::OBJECT] = $object . BCS_SUPERFILE_POSTFIX . $i; - $object_list ['object_list'] ['part_' . $i] = array (); - $object_list ['object_list'] ['part_' . $i] ['url'] = 'bs://' . $bucket . $opt [self::OBJECT]; - $this->log ( "Begin to upload Sub-object[" . $opt [self::OBJECT] . "][$i/$sliceNum][seekto:" . $opt ['seekTo'] . "][Length:" . $opt ['length'] . "]", $opt ); - $response = $this->create_object ( $bucket, $opt [self::OBJECT], $file, $opt ); - if ($response->isOK ()) { - $this->log ( "Sub-object upload[" . $opt [self::OBJECT] . "][$i/$sliceNum][seekto:" . $opt ['seekTo'] . "][Length:" . $opt ['length'] . "]success! ", $opt ); - $object_list ['object_list'] ['part_' . $i] ['etag'] = $response->header ['Content-MD5']; - continue; - } else { - $this->log ( "Sub-object upload[" . $opt [self::OBJECT] . "][$i/$sliceNum] failed! ", $opt ); - return $response; - } - } - //将子文件分片的列表构造成 superfile - unset ( $opt ['fileUpload'] ); - unset ( $opt ['length'] ); - unset ( $opt ['seekTo'] ); - $opt ['content'] = self::array_to_json ( $object_list ); - $opt [self::QUERY_STRING] = array ( - "superfile" => 1 ); - $opt [self::OBJECT] = $object; - if (isset ( $opt ['filename'] )) { - self::set_header_into_opt ( "Content-Disposition", 'attachment; filename=' . $opt ['filename'], $opt ); - } - $response = $this->authenticate ( $opt ); - $this->log ( $response->isOK () ? "Create object-superfile success!" : "Create object-superfile failed! Response: [" . $response->body . "]", $opt ); - return $response; - } + if (($i + 1) === $sliceNum) { + //last sub object + $opt['length'] = (0 === $fileSize % $sub_object_size) ? $sub_object_size : $fileSize % $sub_object_size; + } else { + $opt['length'] = $sub_object_size; + } + $opt[self::OBJECT] = $object . BCS_SUPERFILE_POSTFIX . $i; + $object_list['object_list']['part_' . $i] = array(); + $object_list['object_list']['part_' . $i]['url'] = 'bs://' . $bucket . $opt[self::OBJECT]; + $this->log("Begin to upload Sub-object[" . $opt[self::OBJECT] . "][$i/$sliceNum][seekto:" . $opt['seekTo'] . "][Length:" . $opt['length'] . "]", $opt); + $response = $this->createObject($bucket, $opt[self::OBJECT], $file, $opt); + if ($response->isOK()) { + $this->log("Sub-object upload[" . $opt[self::OBJECT] . "][$i/$sliceNum][seekto:" . $opt['seekTo'] . "][Length:" . $opt['length'] . "]success! ", $opt); + $object_list['object_list']['part_' . $i]['etag'] = $response->header['Content-MD5']; + continue; + } else { + $this->log("Sub-object upload[" . $opt[self::OBJECT] . "][$i/$sliceNum] failed! ", $opt); + return $response; + } + } + //将子文件分片的列表构造成 superfile + unset($opt['fileUpload']); + unset($opt['length']); + unset($opt['seekTo']); + $opt['content'] = self::arrayToJson($object_list); + $opt[self::QUERY_STRING] = array( + "superfile" => 1); + $opt[self::OBJECT] = $object; + if (isset($opt['filename'])) { + self::setHeaderIntoOpt("Content-Disposition", 'attachment; filename=' . $opt['filename'], $opt); + } + $response = $this->authenticate($opt); + $this->log($response->isOK() ? "Create object-superfile success!" : "Create object-superfile failed! Response: [" . $response->body . "]", $opt); + return $response; + } - /** - * 将目录中的所有文件进行上传,每个文件为单独object,object命名方式下详: - * 如有 /home/worker/a/b/c.txt 需上传目录为$dir=/home/worker/a - * object命令方式为 - * 1. object默认命名方式为 “子目录名 +文件名”,如上述文件c.txt,默认为 '/b/c.txt' - * 2. 增强命名模式,在$opt中有可选参数进行配置 - * 举例说明 :prefix . has_sub_directory?"/b":"" . '/c.txt' - * @param string $bucket (Required) - * @param string $dir (Required) - * @param array $opt(Optional) - * string prefix 文件object前缀 - * boolean has_sub_directory(default=true) object命名中是否携带文件的子目录结构,若置为false,请确认待上传的目录和所有子目录中没有重名文件,否则会产生object覆盖问题 - * BaiduBCS::IMPORT_BCS_PRE_FILTER 用户可自定义上传文件前的操作函数 - * 1. 函数参数列表顺序需为 ($bucket,$object,$file,&$opt),注意$opt为upload_directory函数传入的$opt的拷贝,只对当前object生效 - * 2. 函数返回值必须为boolean,当true该文件进行上传,若false跳过上传 - * 3. 如果函数返回false,将不会进行post_filter的调用 - * BaiduBCS::IMPORT_BCS_POST_FILTER 用户可自定义上传文件后的操作函数 - * 1. 函数参数列表顺序需为 ($bucket,$object,$file,&$opt,$response),注意$opt为upload_directory函数传入的$opt的拷贝,只对当前object生效 - * 2. 函数返回值无要求 - * string seek_object 用户断点续传,需要为object名称,如果该object在目录中不存在,抛出异常,若存在则将该object和此后的object进行上传 - * string seek_object_id 作用同seek_object,只需要传入上传过程中日志中展示的[a/b]中object序号即可,注意object序号是以1开始计算的 - * @return array 数组形式的上传结果 - * 'success' => int 上传成功的文件数目 - * 'skipped' => int 被跳过的文件 - * 'failed' => array() 上传失败的文件 - * - */ - public function upload_directory($bucket, $dir, $opt = array()) { - $this->assertParameterArray ( $opt ); - if (! is_dir ( $dir )) { - throw new BCS_Exception ( "$dir is not a dir!", - 1 ); - } - $result = array ( - "success" => 0, - "failed" => array (), - "skipped" => 0 ); - $prefix = ""; - if (isset ( $opt ['prefix'] )) { - $prefix = $opt ['prefix']; - } - $has_sub_directory = true; - if (isset ( $opt ['has_sub_directory'] ) && is_bool ( $opt ['has_sub_directory'] )) { - $has_sub_directory = $opt ['has_sub_directory']; - } - //获取文件树和构造object名 - $file_tree = self::get_filetree ( $dir ); - $objects = array (); - foreach ( $file_tree as $file ) { - $object = $has_sub_directory == true ? substr ( $file, strlen ( $dir ) ) : "/" . basename ( $file ); - $objects [$prefix . $object] = $file; - } - $objectCount = count ( $objects ); - $before_upload_log = "Upload directory: bucket[$bucket] upload_dir[$dir] file_sum[$objectCount]"; - if (isset ( $opt ["seek_object_id"] )) { - $before_upload_log .= " seek_object_id[" . $opt ["seek_object_id"] . "/$objectCount]"; - } - if (isset ( $opt ["seek_object"] )) { - $before_upload_log .= " seek_object[" . $opt ["seek_object"] . "]"; - } - $this->log ( $before_upload_log, $opt ); - //查看是否需要查询断点,进行断点续传 - if (isset ( $opt ["seek_object_id"] ) && isset ( $opt ["seek_object"] )) { - throw new BCS_Exception ( "Can not set see_object_id and seek_object at the same time!", - 1 ); - } + /** + * 将目录中的所有文件进行上传,每个文件为单独object,object命名方式下详: + * 如有 /home/worker/a/b/c.txt 需上传目录为$dir=/home/worker/a + * object命令方式为 + * 1. object默认命名方式为 “子目录名 +文件名”,如上述文件c.txt,默认为 '/b/c.txt' + * 2. 增强命名模式,在$opt中有可选参数进行配置 + * 举例说明 :prefix . has_sub_directory?"/b":"" . '/c.txt' + * @param string $bucket (Required) + * @param string $dir (Required) + * @param array $opt(Optional) + * string prefix 文件object前缀 + * boolean has_sub_directory(default=true) object命名中是否携带文件的子目录结构,若置为false,请确认待上传的目录和所有子目录中没有重名文件,否则会产生object覆盖问题 + * BaiduBCS::IMPORT_BCS_PRE_FILTER 用户可自定义上传文件前的操作函数 + * 1. 函数参数列表顺序需为 ($bucket,$object,$file,&$opt),注意$opt为upload_directory函数传入的$opt的拷贝,只对当前object生效 + * 2. 函数返回值必须为boolean,当true该文件进行上传,若false跳过上传 + * 3. 如果函数返回false,将不会进行post_filter的调用 + * BaiduBCS::IMPORT_BCS_POST_FILTER 用户可自定义上传文件后的操作函数 + * 1. 函数参数列表顺序需为 ($bucket,$object,$file,&$opt,$response),注意$opt为upload_directory函数传入的$opt的拷贝,只对当前object生效 + * 2. 函数返回值无要求 + * string seek_object 用户断点续传,需要为object名称,如果该object在目录中不存在,抛出异常,若存在则将该object和此后的object进行上传 + * string seek_object_id 作用同seek_object,只需要传入上传过程中日志中展示的[a/b]中object序号即可,注意object序号是以1开始计算的 + * @return array 数组形式的上传结果 + * 'success' => int 上传成功的文件数目 + * 'skipped' => int 被跳过的文件 + * 'failed' => array() 上传失败的文件 + * + */ + public function uploadDirectory($bucket, $dir, $opt = array()) + { + $this->assertParameterArray($opt); + if (!is_dir($dir)) { + throw new BCS_Exception("$dir is not a dir!", -1); + } + $result = array( + "success" => 0, + "failed" => array(), + "skipped" => 0); + $prefix = ""; + if (isset($opt['prefix'])) { + $prefix = $opt['prefix']; + } + $has_sub_directory = true; + if (isset($opt['has_sub_directory']) && is_bool($opt['has_sub_directory'])) { + $has_sub_directory = $opt['has_sub_directory']; + } + //获取文件树和构造object名 + $file_tree = self::getFiletree($dir); + $objects = array(); + foreach ($file_tree as $file) { + $object = true == $has_sub_directory ? substr($file, strlen($dir)) : "/" . basename($file); + $objects[$prefix . $object] = $file; + } + $objectCount = count($objects); + $before_upload_log = "Upload directory: bucket[$bucket] upload_dir[$dir] file_sum[$objectCount]"; + if (isset($opt["seek_object_id"])) { + $before_upload_log .= " seek_object_id[" . $opt["seek_object_id"] . "/$objectCount]"; + } + if (isset($opt["seek_object"])) { + $before_upload_log .= " seek_object[" . $opt["seek_object"] . "]"; + } + $this->log($before_upload_log, $opt); + //查看是否需要查询断点,进行断点续传 + if (isset($opt["seek_object_id"]) && isset($opt["seek_object"])) { + throw new BCS_Exception("Can not set see_object_id and seek_object at the same time!", -1); + } - $num = 1; - if (isset ( $opt ["seek_object"] )) { - if (isset ( $objects [$opt ["seek_object"]] )) { - foreach ( $objects as $object => $file ) { - if ($object != $opt ["seek_object"]) { - //当非断点文件,该object已完成上传 - $this->log ( "Seeking[" . $opt ["seek_object"] . "]. Skip id[$num/$objectCount]object[$object]file[$file].", $opt ); - //$result ['skipped'] [] = "[$num/$objectCount] " . $file; - $result ['skipped'] ++; - unset ( $objects [$object] ); - } else { - //当找到断点文件,停止循环,从断点文件重新上传 - //当非断点文件,该object已完成上传 - $this->log ( "Found seek id[$num/$objectCount]object[$object]file[$file], begin from here.", $opt ); - break; - } - $num ++; - } - } else { - throw new BCS_Exception ( "Can not find you seek object, please check!", - 1 ); - } - } - if (isset ( $opt ["seek_object_id"] )) { - if (is_int ( $opt ["seek_object_id"] ) && $opt ["seek_object_id"] <= $objectCount) { - foreach ( $objects as $object => $file ) { - if ($num < $opt ["seek_object_id"]) { - $this->log ( "Seeking object of [" . $opt ["seek_object_id"] . "/$objectCount]. Skip id[$num/$objectCount]object[$object]file[$file].", $opt ); - //$result ['skipped'] [] = "[$num/$objectCount] " . $file; - $result ['skipped'] ++; - unset ( $objects [$object] ); - } else { - break; - } - $num ++; - } - } else { - throw new BCS_Exception ( "Param seek_object_id not valid, please check!", - 1 ); - } - } - //上传objects - $objectCount = count ( $objects ); - foreach ( $objects as $object => $file ) { - $tmp_opt = array_merge ( $opt ); - if (isset ( $opt [self::IMPORT_BCS_PRE_FILTER] ) && function_exists ( $opt [self::IMPORT_BCS_PRE_FILTER] )) { - $bolRes = $opt [self::IMPORT_BCS_PRE_FILTER] ( $bucket, $object, $file, $tmp_opt ); - if ($bolRes !== true) { - $this->log ( "User pre_filter_function return un-true. Skip id[$num/$objectCount]object[$object]file[$file].", $opt ); - //$result ['skipped'] [] = "id[$num/$objectCount]object[$object]file[$file]"; - $result ['skipped'] ++; - $num ++; - continue; - } - } - try { - $response = $this->create_object ( $bucket, $object, $file, $tmp_opt ); - } catch ( Exception $e ) { - $this->log ( $e->getMessage (), $opt ); - $this->log ( "Upload Failed id[$num/$objectCount]object[$object]file[$file].", $opt ); - $num ++; - continue; - } - if ($response->isOK ()) { - $result ["success"] ++; - $this->log ( "Upload Success id[$num/$objectCount]object[$object]file[$file].", $opt ); - } else { - $result ["failed"] [] = "id[$num/$objectCount]object[$object]file[$file]"; - $this->log ( "Upload Failed id[$num/$objectCount]object[$object]file[$file].", $opt ); - } - if (isset ( $opt [self::IMPORT_BCS_POST_FILTER] ) && function_exists ( $opt [self::IMPORT_BCS_POST_FILTER] )) { - $opt [self::IMPORT_BCS_POST_FILTER] ( $bucket, $object, $file, $tmp_opt, $response ); - } - $num ++; - } - //打印日志并返回结果数组 - $result_str = "\r\n\r\nUpload $dir to $bucket finished!\r\n"; - $result_str .= "**********************************************************\r\n"; - $result_str .= "**********************Result Summary**********************\r\n"; - $result_str .= "**********************************************************\r\n"; - $result_str .= "Upload directory : [$dir]\r\n"; - $result_str .= "File num : [$objectCount]\r\n"; - $result_str .= "Success: \r\n\tNum: " . $result ["success"] . "\r\n"; - $result_str .= "Skipped:\r\n\tNum:" . $result ["skipped"] . "\r\n"; - // foreach ( $result ["skipped"] as $skip ) { - // $result_str .= "\t$skip\r\n"; - // } - $result_str .= "Failed:\r\n\tNum:" . count ( $result ["failed"] ) . "\r\n"; - foreach ( $result ["failed"] as $fail ) { - $result_str .= "\t$fail\r\n"; - } - if (isset ( $opt [self::IMPORT_BCS_LOG_METHOD] )) { - $this->log ( $result_str, $opt ); - } else { - echo $result_str; - } - return $result; - } + $num = 1; + if (isset($opt["seek_object"])) { + if (isset($objects[$opt["seek_object"]])) { + foreach ($objects as $object => $file) { + if ($object != $opt["seek_object"]) { + //当非断点文件,该object已完成上传 + $this->log("Seeking[" . $opt["seek_object"] . "]. Skip id[$num/$objectCount]object[$object]file[$file].", $opt); + //$result ['skipped'] [] = "[$num/$objectCount] " . $file; + $result['skipped']++; + unset($objects[$object]); + } else { + //当找到断点文件,停止循环,从断点文件重新上传 + //当非断点文件,该object已完成上传 + $this->log("Found seek id[$num/$objectCount]object[$object]file[$file], begin from here.", $opt); + break; + } + $num++; + } + } else { + throw new BCS_Exception("Can not find you seek object, please check!", -1); + } + } + if (isset($opt["seek_object_id"])) { + if (is_int($opt["seek_object_id"]) && $opt["seek_object_id"] <= $objectCount) { + foreach ($objects as $object => $file) { + if ($num < $opt["seek_object_id"]) { + $this->log("Seeking object of [" . $opt["seek_object_id"] . "/$objectCount]. Skip id[$num/$objectCount]object[$object]file[$file].", $opt); + //$result ['skipped'] [] = "[$num/$objectCount] " . $file; + $result['skipped']++; + unset($objects[$object]); + } else { + break; + } + $num++; + } + } else { + throw new BCS_Exception("Param seek_object_id not valid, please check!", -1); + } + } + //上传objects + $objectCount = count($objects); + foreach ($objects as $object => $file) { + $tmp_opt = array_merge($opt); + if (isset($opt[self::IMPORT_BCS_PRE_FILTER]) && function_exists($opt[self::IMPORT_BCS_PRE_FILTER])) { + $bolRes = $opt[self::IMPORT_BCS_PRE_FILTER]($bucket, $object, $file, $tmp_opt); + if (true !== $bolRes) { + $this->log("User pre_filter_function return un-true. Skip id[$num/$objectCount]object[$object]file[$file].", $opt); + //$result ['skipped'] [] = "id[$num/$objectCount]object[$object]file[$file]"; + $result['skipped']++; + $num++; + continue; + } + } + try { + $response = $this->createObject($bucket, $object, $file, $tmp_opt); + } catch (Exception $e) { + $this->log($e->getMessage(), $opt); + $this->log("Upload Failed id[$num/$objectCount]object[$object]file[$file].", $opt); + $num++; + continue; + } + if ($response->isOK()) { + $result["success"]++; + $this->log("Upload Success id[$num/$objectCount]object[$object]file[$file].", $opt); + } else { + $result["failed"][] = "id[$num/$objectCount]object[$object]file[$file]"; + $this->log("Upload Failed id[$num/$objectCount]object[$object]file[$file].", $opt); + } + if (isset($opt[self::IMPORT_BCS_POST_FILTER]) && function_exists($opt[self::IMPORT_BCS_POST_FILTER])) { + $opt[self::IMPORT_BCS_POST_FILTER]($bucket, $object, $file, $tmp_opt, $response); + } + $num++; + } + //打印日志并返回结果数组 + $result_str = "\r\n\r\nUpload $dir to $bucket finished!\r\n"; + $result_str .= "**********************************************************\r\n"; + $result_str .= "**********************Result Summary**********************\r\n"; + $result_str .= "**********************************************************\r\n"; + $result_str .= "Upload directory : [$dir]\r\n"; + $result_str .= "File num : [$objectCount]\r\n"; + $result_str .= "Success: \r\n\tNum: " . $result["success"] . "\r\n"; + $result_str .= "Skipped:\r\n\tNum:" . $result["skipped"] . "\r\n"; + // foreach ( $result ["skipped"] as $skip ) { + // $result_str .= "\t$skip\r\n"; + // } + $result_str .= "Failed:\r\n\tNum:" . count($result["failed"]) . "\r\n"; + foreach ($result["failed"] as $fail) { + $result_str .= "\t$fail\r\n"; + } + if (isset($opt[self::IMPORT_BCS_LOG_METHOD])) { + $this->log($result_str, $opt); + } else { + echo $result_str; + } + return $result; + } - /** - * 通过此方法以拷贝的方式创建object,object来源为$source - * @param array $source (Required) object 来源 - * bucket(Required) - * object(Required) - * @param array $dest (Required) 待拷贝的目标object - * bucket(Required) - * object(Required) - * @param array $opt (Optional) - * source_tag 指定拷贝对象的版本号 - * @throws BCS_Exception - * @return BCS_ResponseCore - */ - public function copy_object($source, $dest, $opt = array()) { - $this->assertParameterArray ( $opt ); - //valid source and dest - if (empty ( $source ) || ! is_array ( $source ) || ! isset ( $source [self::BUCKET] ) || ! isset ( $source [self::OBJECT] )) { - throw new BCS_Exception ( '$source invalid, please check!', - 1 ); - } - if (empty ( $dest ) || ! is_array ( $dest ) || ! isset ( $dest [self::BUCKET] ) || ! isset ( $dest [self::OBJECT] ) || ! self::validate_bucket ( $dest [self::BUCKET] ) || ! self::validate_object ( $dest [self::OBJECT] )) { - throw new BCS_Exception ( '$dest invalid, please check!', - 1 ); - } - $opt [self::BUCKET] = $dest [self::BUCKET]; - $opt [self::OBJECT] = $dest [self::OBJECT]; - $opt [self::METHOD] = 'PUT'; - self::set_header_into_opt ( 'x-bs-copy-source', 'bs://' . $source [self::BUCKET] . $source [self::OBJECT], $opt ); - if (isset ( $opt ['source_tag'] )) { - self::set_header_into_opt ( 'x-bs-copy-source-tag', $opt ['source_tag'], $opt ); - } - $response = $this->authenticate ( $opt ); - $this->log ( $response->isOK () ? "Copy object success!" : "Copy object failed! Response: [" . $response->body . "]", $opt ); - return $response; - } + /** + * 通过此方法以拷贝的方式创建object,object来源为$source + * @param array $source (Required) object 来源 + * bucket(Required) + * object(Required) + * @param array $dest (Required) 待拷贝的目标object + * bucket(Required) + * object(Required) + * @param array $opt (Optional) + * source_tag 指定拷贝对象的版本号 + * @throws BCS_Exception + * @return BCS_ResponseCore + */ + public function copyObject($source, $dest, $opt = array()) + { + $this->assertParameterArray($opt); + //valid source and dest + if (empty($source) || !is_array($source) || !isset($source[self::BUCKET]) || !isset($source[self::OBJECT])) { + throw new BCS_Exception('$source invalid, please check!', -1); + } + if (empty($dest) || !is_array($dest) || !isset($dest[self::BUCKET]) || !isset($dest[self::OBJECT]) || !self::validateBucket($dest[self::BUCKET]) || !self::validateObject($dest[self::OBJECT])) { + throw new BCS_Exception('$dest invalid, please check!', -1); + } + $opt[self::BUCKET] = $dest[self::BUCKET]; + $opt[self::OBJECT] = $dest[self::OBJECT]; + $opt[self::METHOD] = 'PUT'; + self::setHeaderIntoOpt('x-bs-copy-source', 'bs://' . $source[self::BUCKET] . $source[self::OBJECT], $opt); + if (isset($opt['source_tag'])) { + self::setHeaderIntoOpt('x-bs-copy-source-tag', $opt['source_tag'], $opt); + } + $response = $this->authenticate($opt); + $this->log($response->isOK() ? "Copy object success!" : "Copy object failed! Response: [" . $response->body . "]", $opt); + return $response; + } - /** - * 设置object的meta信息 - * @param string $bucket (Required) - * @param string $object (Required) - * @param array $opt (Optional) - * 目前支持的meta信息如下: - * Content-Type - * Cache-Control - * Content-Disposition - * Content-Encoding - * Content-MD5 - * Expires - * @return BCS_ResponseCore - */ - public function set_object_meta($bucket, $object, $meta, $opt = array()) { - $this->assertParameterArray ( $opt ); - $this->assertParameterArray ( $meta ); - $opt [self::BUCKET] = $bucket; - $opt [self::OBJECT] = $object; - $opt [self::METHOD] = 'PUT'; - //利用copy_object接口来设置meta信息 - $source = "bs://$bucket$object"; - if (empty ( $meta )) { - throw new BCS_Exception ( '$meta can not be empty! And $meta must be array.', - 1 ); - } - foreach ( $meta as $header => $value ) { - self::set_header_into_opt ( $header, $value, $opt ); - } - $source = array ( - self::BUCKET => $bucket, - self::OBJECT => $object ); - $response = $this->copy_object ( $source, $source, $opt ); - $this->log ( $response->isOK () ? "Set object meta success!" : "Set object meta failed! Response: [" . $response->body . "]", $opt ); - return $response; - } + /** + * 设置object的meta信息 + * @param string $bucket (Required) + * @param string $object (Required) + * @param array $opt (Optional) + * 目前支持的meta信息如下: + * Content-Type + * Cache-Control + * Content-Disposition + * Content-Encoding + * Content-MD5 + * Expires + * @return BCS_ResponseCore + */ + public function setObjectMeta($bucket, $object, $meta, $opt = array()) + { + $this->assertParameterArray($opt); + $this->assertParameterArray($meta); + $opt[self::BUCKET] = $bucket; + $opt[self::OBJECT] = $object; + $opt[self::METHOD] = 'PUT'; + //利用copy_object接口来设置meta信息 + $source = "bs://$bucket$object"; + if (empty($meta)) { + throw new BCS_Exception('$meta can not be empty! And $meta must be array.', -1); + } + foreach ($meta as $header => $value) { + self::setHeaderIntoOpt($header, $value, $opt); + } + $source = array( + self::BUCKET => $bucket, + self::OBJECT => $object); + $response = $this->copyObject($source, $source, $opt); + $this->log($response->isOK() ? "Set object meta success!" : "Set object meta failed! Response: [" . $response->body . "]", $opt); + return $response; + } - /** - * 获取object的acl - * @param string $bucket (Required) - * @param string $object (Required) - * @param array $opt (Optional) - * @throws BCS_Exception - * @return BCS_ResponseCore - */ - public function get_object_acl($bucket, $object, $opt = array()) { - $this->assertParameterArray ( $opt ); - $opt [self::BUCKET] = $bucket; - $opt [self::METHOD] = 'GET'; - $opt [self::OBJECT] = $object; - $opt [self::QUERY_STRING] = array ( - self::ACL => 1 ); - $response = $this->authenticate ( $opt ); - $this->log ( $response->isOK () ? "Get object acl success!" : "Get object acl failed! Response: [" . $response->body . "]", $opt ); - return $response; - } + /** + * 获取object的acl + * @param string $bucket (Required) + * @param string $object (Required) + * @param array $opt (Optional) + * @throws BCS_Exception + * @return BCS_ResponseCore + */ + public function getObjectAcl($bucket, $object, $opt = array()) + { + $this->assertParameterArray($opt); + $opt[self::BUCKET] = $bucket; + $opt[self::METHOD] = 'GET'; + $opt[self::OBJECT] = $object; + $opt[self::QUERY_STRING] = array( + self::ACL => 1); + $response = $this->authenticate($opt); + $this->log($response->isOK() ? "Get object acl success!" : "Get object acl failed! Response: [" . $response->body . "]", $opt); + return $response; + } - /** - * 设置object的acl,有三种模式, - * (1).设置详细json格式的acl; - * a. $acl 为json的array - * b. $acl 为json的string - * (2).通过acl_type字段进行设置 - * a. $acl 为BaiduBCS::$ACL_ACTIONS中的字段 - * @param string $bucket (Required) - * @param string $object (Required) - * @param string|array $acl (Required) - * @param array $opt (Optional) - * @return BCS_ResponseCore - */ - public function set_object_acl($bucket, $object, $acl, $opt = array()) { - $this->assertParameterArray ( $opt ); - //analyze acl - $result = $this->analyze_user_acl ( $acl ); - $opt = array_merge ( $opt, $result ); - $opt [self::BUCKET] = $bucket; - $opt [self::METHOD] = 'PUT'; - $opt [self::OBJECT] = $object; - $opt [self::QUERY_STRING] = array ( - self::ACL => 1 ); - $response = $this->authenticate ( $opt ); - $this->log ( $response->isOK () ? "Set object acl success!" : "Set object acl failed! Response: [" . $response->body . "]", $opt ); - return $response; - } + /** + * 设置object的acl,有三种模式, + * (1).设置详细json格式的acl; + * a. $acl 为json的array + * b. $acl 为json的string + * (2).通过acl_type字段进行设置 + * a. $acl 为BaiduBCS::$ACL_ACTIONS中的字段 + * @param string $bucket (Required) + * @param string $object (Required) + * @param string|array $acl (Required) + * @param array $opt (Optional) + * @return BCS_ResponseCore + */ + public function setObjectAcl($bucket, $object, $acl, $opt = array()) + { + $this->assertParameterArray($opt); + //analyze acl + $result = $this->analyzeUserAcl($acl); + $opt = array_merge($opt, $result); + $opt[self::BUCKET] = $bucket; + $opt[self::METHOD] = 'PUT'; + $opt[self::OBJECT] = $object; + $opt[self::QUERY_STRING] = array( + self::ACL => 1); + $response = $this->authenticate($opt); + $this->log($response->isOK() ? "Set object acl success!" : "Set object acl failed! Response: [" . $response->body . "]", $opt); + return $response; + } - /** - * 删除object - * @param string $bucket (Required) - * @param string $object (Required) - * @param array $opt (Optional) - * @throws BCS_Exception - * @return BCS_ResponseCore - */ - public function delete_object($bucket, $object, $opt = array()) { - $this->assertParameterArray ( $opt ); - $opt [self::BUCKET] = $bucket; - $opt [self::METHOD] = 'DELETE'; - $opt [self::OBJECT] = $object; - $response = $this->authenticate ( $opt ); - $this->log ( $response->isOK () ? "Delete object success!" : "Delete object failed! Response: [" . $response->body . "]", $opt ); - return $response; - } + /** + * 删除object + * @param string $bucket (Required) + * @param string $object (Required) + * @param array $opt (Optional) + * @throws BCS_Exception + * @return BCS_ResponseCore + */ + public function deleteObject($bucket, $object, $opt = array()) + { + $this->assertParameterArray($opt); + $opt[self::BUCKET] = $bucket; + $opt[self::METHOD] = 'DELETE'; + $opt[self::OBJECT] = $object; + $response = $this->authenticate($opt); + $this->log($response->isOK() ? "Delete object success!" : "Delete object failed! Response: [" . $response->body . "]", $opt); + return $response; + } - /** - * 判断object是否存在 - * @param string $bucket (Required) - * @param string $object (Required) - * @param array $opt (Optional) - * @throws BCS_Exception - * @return boolean true|boolean false|BCS_ResponseCore - * true:object存在 - * false:不存在 - * BCS_ResponseCore其他错误 - */ - public function is_object_exist($bucket, $object, $opt = array()) { - $this->assertParameterArray ( $opt ); - $opt [self::BUCKET] = $bucket; - $opt [self::METHOD] = 'HEAD'; - $opt [self::OBJECT] = $object; - $response = $this->get_object_info ( $bucket, $object, $opt ); - if ($response->isOK ()) { - return true; - } elseif ($response->status === 404) { - return false; - } - return $response; - } + /** + * 判断object是否存在 + * @param string $bucket (Required) + * @param string $object (Required) + * @param array $opt (Optional) + * @throws BCS_Exception + * @return boolean true|boolean false|BCS_ResponseCore + * true:object存在 + * false:不存在 + * BCS_ResponseCore其他错误 + */ + public function isObjectExist($bucket, $object, $opt = array()) + { + $this->assertParameterArray($opt); + $opt[self::BUCKET] = $bucket; + $opt[self::METHOD] = 'HEAD'; + $opt[self::OBJECT] = $object; + $response = $this->getObjectInfo($bucket, $object, $opt); + if ($response->isOK()) { + return true; + } elseif (404 === $response->status) { + return false; + } + return $response; + } - /** - * 获取文件信息,发送的为HTTP HEAD请求,文件信息都在http response的header中,不会提取文件的内容 - * @param string $bucket (Required) - * @param string $object (Required) - * @param array $opt (Optional) - * @throws BCS_Exception - * @return array BCS_ResponseCore - */ - public function get_object_info($bucket, $object, $opt = array()) { - $this->assertParameterArray ( $opt ); - $opt [self::BUCKET] = $bucket; - $opt [self::METHOD] = 'HEAD'; - $opt [self::OBJECT] = $object; - $response = $this->authenticate ( $opt ); - $this->log ( $response->isOK () ? "Get object info success!" : "Get object info failed! Response: [" . $response->body . "]", $opt ); - return $response; - } + /** + * 获取文件信息,发送的为HTTP HEAD请求,文件信息都在http response的header中,不会提取文件的内容 + * @param string $bucket (Required) + * @param string $object (Required) + * @param array $opt (Optional) + * @throws BCS_Exception + * @return array BCS_ResponseCore + */ + public function getObjectInfo($bucket, $object, $opt = array()) + { + $this->assertParameterArray($opt); + $opt[self::BUCKET] = $bucket; + $opt[self::METHOD] = 'HEAD'; + $opt[self::OBJECT] = $object; + $response = $this->authenticate($opt); + $this->log($response->isOK() ? "Get object info success!" : "Get object info failed! Response: [" . $response->body . "]", $opt); + return $response; + } - /** - * 下载object - * @param string $bucket (Required) - * @param string $object (Required) - * @param array $opt (Optional) - * fileWriteTo (Optional)直接将请求结果写入该文件,如果fileWriteTo文件存在,sdk进行重命名再存储 - * @throws BCS_Exception - * @return BCS_ResponseCore - */ - public function get_object($bucket, $object, $opt = array()) { - $this->assertParameterArray ( $opt ); - //若fileWriteTo待写入的文件已经存在,需要进行重命名 - if (isset ( $opt ["fileWriteTo"] ) && file_exists ( $opt ["fileWriteTo"] )) { - $original_file_write_to = $opt ["fileWriteTo"]; - $arr = explode ( DIRECTORY_SEPARATOR, $opt ["fileWriteTo"] ); - $file_name = $arr [count ( $arr ) - 1]; - $num = 1; - while ( file_exists ( $opt ["fileWriteTo"] ) ) { - $new_name_arr = explode ( ".", $file_name ); - if (count ( $new_name_arr ) > 1) { - $new_name_arr [count ( $new_name_arr ) - 2] .= " ($num)"; - } else { - $new_name_arr [0] .= " ($num)"; - } - $arr [count ( $arr ) - 1] = implode ( ".", $new_name_arr ); - $opt ["fileWriteTo"] = implode ( DIRECTORY_SEPARATOR, $arr ); - $num ++; - } - $this->log ( "[$original_file_write_to] already exist, rename it to [" . $opt ["fileWriteTo"] . "]", $opt ); - } - $opt [self::BUCKET] = $bucket; - $opt [self::METHOD] = 'GET'; - $opt [self::OBJECT] = $object; - $response = $this->authenticate ( $opt ); - $this->log ( $response->isOK () ? "Get object success!" : "Get object failed! Response: [" . $response->body . "]", $opt ); - if (! $response->isOK () && isset ( $opt ["fileWriteTo"] )) { - unlink ( $opt ["fileWriteTo"] ); - } - return $response; - } + /** + * 下载object + * @param string $bucket (Required) + * @param string $object (Required) + * @param array $opt (Optional) + * fileWriteTo (Optional)直接将请求结果写入该文件,如果fileWriteTo文件存在,sdk进行重命名再存储 + * @throws BCS_Exception + * @return BCS_ResponseCore + */ + public function getObject($bucket, $object, $opt = array()) + { + $this->assertParameterArray($opt); + //若fileWriteTo待写入的文件已经存在,需要进行重命名 + if (isset($opt["fileWriteTo"]) && file_exists($opt["fileWriteTo"])) { + $original_file_write_to = $opt["fileWriteTo"]; + $arr = explode(DIRECTORY_SEPARATOR, $opt["fileWriteTo"]); + $file_name = $arr[count($arr) - 1]; + $num = 1; + while (file_exists($opt["fileWriteTo"])) { + $new_name_arr = explode(".", $file_name); + if (count($new_name_arr) > 1) { + $new_name_arr[count($new_name_arr) - 2] .= " ($num)"; + } else { + $new_name_arr[0] .= " ($num)"; + } + $arr[count($arr) - 1] = implode(".", $new_name_arr); + $opt["fileWriteTo"] = implode(DIRECTORY_SEPARATOR, $arr); + $num++; + } + $this->log("[$original_file_write_to] already exist, rename it to [" . $opt["fileWriteTo"] . "]", $opt); + } + $opt[self::BUCKET] = $bucket; + $opt[self::METHOD] = 'GET'; + $opt[self::OBJECT] = $object; + $response = $this->authenticate($opt); + $this->log($response->isOK() ? "Get object success!" : "Get object failed! Response: [" . $response->body . "]", $opt); + if (!$response->isOK() && isset($opt["fileWriteTo"])) { + unlink($opt["fileWriteTo"]); + } + return $response; + } - /** - * 生成签名链接 - */ - private function generate_user_url($method, $bucket, $object, $opt = array()) { - $opt [self::AK] = $this->ak; - $opt [self::SK] = $this->sk; - $opt [self::BUCKET] = $bucket; - $opt [self::METHOD] = $method; - $opt [self::OBJECT] = $object; - $opt [self::QUERY_STRING] = array (); - if (isset ( $opt ["time"] )) { - $opt [self::QUERY_STRING] ["time"] = $opt ["time"]; - } - if (isset ( $opt ["size"] )) { - $opt [self::QUERY_STRING] ["size"] = $opt ["size"]; - } - return $this->format_url ( $opt ); - } + /** + * 生成签名链接 + */ + private function generateUserUrl($method, $bucket, $object, $opt = array()) + { + $opt[self::AK] = $this->ak; + $opt[self::SK] = $this->sk; + $opt[self::BUCKET] = $bucket; + $opt[self::METHOD] = $method; + $opt[self::OBJECT] = $object; + $opt[self::QUERY_STRING] = array(); + if (isset($opt["time"])) { + $opt[self::QUERY_STRING]["time"] = $opt["time"]; + } + if (isset($opt["size"])) { + $opt[self::QUERY_STRING]["size"] = $opt["size"]; + } + return $this->formatUrl($opt); + } - /** - * 生成get_object的url - * @param string $bucket (Required) - * @param string $object (Required) - * return false| string url - */ - public function generate_get_object_url($bucket, $object, $opt = array()) { - $this->assertParameterArray ( $opt ); - return $this->generate_user_url ( "GET", $bucket, $object, $opt ); - } + /** + * 生成get_object的url + * @param string $bucket (Required) + * @param string $object (Required) + * return false| string url + */ + public function generateGetObjectUrl($bucket, $object, $opt = array()) + { + $this->assertParameterArray($opt); + return $this->generateUserUrl("GET", $bucket, $object, $opt); + } - /** - * 生成put_object的url - * @param string $bucket (Required) - * @param string $object (Required) - * return false| string url - */ - public function generate_put_object_url($bucket, $object, $opt = array()) { - $this->assertParameterArray ( $opt ); - return $this->generate_user_url ( "PUT", $bucket, $object, $opt ); - } + /** + * 生成put_object的url + * @param string $bucket (Required) + * @param string $object (Required) + * return false| string url + */ + public function generatePutObjectUrl($bucket, $object, $opt = array()) + { + $this->assertParameterArray($opt); + return $this->generateUserUrl("PUT", $bucket, $object, $opt); + } - /** - * 生成post_object的url - * @param string $bucket (Required) - * @param string $object (Required) - * return false| string url - */ - public function generate_post_object_url($bucket, $object, $opt = array()) { - $this->assertParameterArray ( $opt ); - return $this->generate_user_url ( "POST", $bucket, $object, $opt ); - } + /** + * 生成post_object的url + * @param string $bucket (Required) + * @param string $object (Required) + * return false| string url + */ + public function generatePostObjectUrl($bucket, $object, $opt = array()) + { + $this->assertParameterArray($opt); + return $this->generateUserUrl("POST", $bucket, $object, $opt); + } - /** - * 生成delete_object的url - * @param string $bucket (Required) - * @param string $object (Required) - * return false| string url - */ - public function generate_delete_object_url($bucket, $object, $opt = array()) { - $this->assertParameterArray ( $opt ); - return $this->generate_user_url ( "DELETE", $bucket, $object, $opt ); - } + /** + * 生成delete_object的url + * @param string $bucket (Required) + * @param string $object (Required) + * return false| string url + */ + public function generateDeleteObjectUrl($bucket, $object, $opt = array()) + { + $this->assertParameterArray($opt); + return $this->generateUserUrl("DELETE", $bucket, $object, $opt); + } - /** - * 生成head_object的url - * @param string $bucket (Required) - * @param string $object (Required) - * return false| string url - */ - public function generate_head_object_url($bucket, $object, $opt = array()) { - $this->assertParameterArray ( $opt ); - return $this->generate_user_url ( "HEAD", $bucket, $object, $opt ); - } + /** + * 生成head_object的url + * @param string $bucket (Required) + * @param string $object (Required) + * return false| string url + */ + public function generateHeadObjectUrl($bucket, $object, $opt = array()) + { + $this->assertParameterArray($opt); + return $this->generateUserUrl("HEAD", $bucket, $object, $opt); + } - /** - * @return the $use_ssl - */ - public function getUse_ssl() { - return $this->use_ssl; - } + /** + * @return the $use_ssl + */ + public function getuseSsl() + { + return $this->use_ssl; + } - /** - * @param boolean $use_ssl - */ - public function setUse_ssl($use_ssl) { - $this->use_ssl = $use_ssl; - } + /** + * @param boolean $use_ssl + */ + public function setuseSsl($use_ssl) + { + $this->use_ssl = $use_ssl; + } - /** - * 校验bucket是否合法,bucket规范 - * 1. 由小写字母,数字和横线'-'组成,长度为6~63位 - * 2. 不能以数字作为Bucket开头 - * 3. 不能以'-'作为Bucket的开头或者结尾 - * @param string $bucket - * @return boolean - */ - public static function validate_bucket($bucket) { - //bucket 正则 - $pattern1 = '/^[a-z][-a-z0-9]{4,61}[a-z0-9]$/'; - if (! preg_match ( $pattern1, $bucket )) { - return false; - } - return true; - } + /** + * 校验bucket是否合法,bucket规范 + * 1. 由小写字母,数字和横线'-'组成,长度为6~63位 + * 2. 不能以数字作为Bucket开头 + * 3. 不能以'-'作为Bucket的开头或者结尾 + * @param string $bucket + * @return boolean + */ + public static function validateBucket($bucket) + { + //bucket 正则 + $pattern1 = '/^[a-z][-a-z0-9]{4,61}[a-z0-9]$/'; + if (!preg_match($pattern1, $bucket)) { + return false; + } + return true; + } - /** - * 校验object是否合法,object命名规范 - * 1. object必须以'/'开头 - * @param string $object - * @return boolean - */ - public static function validate_object($object) { - $pattern = '/^\//'; - if (empty ( $object ) || ! preg_match ( $pattern, $object )) { - return false; - } - return true; - } + /** + * 校验object是否合法,object命名规范 + * 1. object必须以'/'开头 + * @param string $object + * @return boolean + */ + public static function validateObject($object) + { + $pattern = '/^\//'; + if (empty($object) || !preg_match($pattern, $object)) { + return false; + } + return true; + } - /** - * 将常用set http-header的动作抽离出来 - * @param string $header - * @param string $value - * @param array $opt - * @throws BCS_Exception - * @return void - */ - private static function set_header_into_opt($header, $value, &$opt) { - if (isset ( $opt [self::HEADERS] )) { - if (! is_array ( $opt [self::HEADERS] )) { - trigger_error ( 'Invalid $opt[\'headers\'], please check.' ); - throw new BCS_Exception ( 'Invalid $opt[\'headers\'], please check.', - 1 ); - } - } else { - $opt [self::HEADERS] = array (); - } - $opt [self::HEADERS] [$header] = $value; - } + /** + * 将常用set http-header的动作抽离出来 + * @param string $header + * @param string $value + * @param array $opt + * @throws BCS_Exception + * @return void + */ + private static function setHeaderIntoOpt($header, $value, &$opt) + { + if (isset($opt[self::HEADERS])) { + if (!is_array($opt[self::HEADERS])) { + trigger_error('Invalid $opt[\'headers\'], please check.'); + throw new BCS_Exception('Invalid $opt[\'headers\'], please check.', -1); + } + } else { + $opt[self::HEADERS] = array(); + } + $opt[self::HEADERS][$header] = $value; + } - /** - * 使用特定function对数组中所有元素做处理 - * @param string &$array 要处理的字符串 - * @param string $function 要执行的函数 - * @param boolean $apply_to_keys_also 是否也应用到key上 - */ - private static function array_recursive(&$array, $function, $apply_to_keys_also = false) { - foreach ( $array as $key => $value ) { - if (is_array ( $value )) { - self::array_recursive ( $array [$key], $function, $apply_to_keys_also ); - } else { - $array [$key] = $function ( $value ); - } + /** + * 使用特定function对数组中所有元素做处理 + * @param string &$array 要处理的字符串 + * @param string $function 要执行的函数 + * @param boolean $apply_to_keys_also 是否也应用到key上 + */ + private static function arrayRecursive(&$array, $function, $apply_to_keys_also = false) + { + foreach ($array as $key => $value) { + if (is_array($value)) { + self::arrayRecursive($array[$key], $function, $apply_to_keys_also); + } else { + $array[$key] = $function($value); + } - if ($apply_to_keys_also && is_string ( $key )) { - $new_key = $function ( $key ); - if ($new_key != $key) { - $array [$new_key] = $array [$key]; - unset ( $array [$key] ); - } - } - } - } + if ($apply_to_keys_also && is_string($key)) { + $new_key = $function($key); + if ($new_key != $key) { + $array[$new_key] = $array[$key]; + unset($array[$key]); + } + } + } + } - /** - * 由数组构造json字符串,增加了一些特殊处理以支持特殊字符和不同编码的中文 - * @param array $array - */ - private static function array_to_json($array) { - if (! is_array ( $array )) { - throw new BCS_Exception ( "Param must be array in function array_to_json()", - 1 ); - } - self::array_recursive ( $array, 'addslashes', false ); - self::array_recursive ( $array, 'rawurlencode', false ); - return rawurldecode ( json_encode ( $array ) ); - } + /** + * 由数组构造json字符串,增加了一些特殊处理以支持特殊字符和不同编码的中文 + * @param array $array + */ + private static function arrayToJson($array) + { + if (!is_array($array)) { + throw new BCS_Exception("Param must be array in function array_to_json()", -1); + } + self::arrayRecursive($array, 'addslashes', false); + self::arrayRecursive($array, 'rawurlencode', false); + return rawurldecode(json_encode($array)); + } - /** - * 根据用户传入的acl,进行相应的处理 - * (1).设置详细json格式的acl; - * a. $acl 为json的array - * b. $acl 为json的string - * (2).通过acl_type字段进行设置 - * @param string|array $acl - * @throws BCS_Exception - * @return array - */ - private function analyze_user_acl($acl) { - $result = array (); - if (is_array ( $acl )) { - //(1).a - $result ['content'] = $this->check_user_acl ( $acl ); - } else if (is_string ( $acl )) { - if (in_array ( $acl, self::$ACL_TYPES )) { - //(2).a - $result ["headers"] = array ( - "x-bs-acl" => $acl ); - } else { - //(1).b - $result ['content'] = $acl; - } - } else { - throw new BCS_Exception ( "Invalid acl.", - 1 ); - } - return $result; - } + /** + * 根据用户传入的acl,进行相应的处理 + * (1).设置详细json格式的acl; + * a. $acl 为json的array + * b. $acl 为json的string + * (2).通过acl_type字段进行设置 + * @param string|array $acl + * @throws BCS_Exception + * @return array + */ + private function analyzeUserAcl($acl) + { + $result = array(); + if (is_array($acl)) { + //(1).a + $result['content'] = $this->checkUserAcl($acl); + } else if (is_string($acl)) { + if (in_array($acl, self::$ACL_TYPES)) { + //(2).a + $result["headers"] = array( + "x-bs-acl" => $acl); + } else { + //(1).b + $result['content'] = $acl; + } + } else { + throw new BCS_Exception("Invalid acl.", -1); + } + return $result; + } - /** - * 生成签名 - * @param array $opt - * @return boolean|string - */ - private function format_signature($opt) { - $flags = ""; - $content = ''; - if (! isset ( $opt [self::AK] ) || ! isset ( $opt [self::SK] )) { - trigger_error ( 'ak or sk is not in the array when create factor!' ); - return false; - } - if (isset ( $opt [self::BUCKET] ) && isset ( $opt [self::METHOD] ) && isset ( $opt [self::OBJECT] )) { - $flags .= 'MBO'; - $content .= "Method=" . $opt [self::METHOD] . "\n"; //method - $content .= "Bucket=" . $opt [self::BUCKET] . "\n"; //bucket - $content .= "Object=" . self::trimUrl ( $opt [self::OBJECT] ) . "\n"; //object - } else { - trigger_error ( 'bucket、method and object cann`t be NULL!' ); - return false; - } - if (isset ( $opt ['ip'] )) { - $flags .= 'I'; - $content .= "Ip=" . $opt ['ip'] . "\n"; - } - if (isset ( $opt ['time'] )) { - $flags .= 'T'; - $content .= "Time=" . $opt ['time'] . "\n"; - } - if (isset ( $opt ['size'] )) { - $flags .= 'S'; - $content .= "Size=" . $opt ['size'] . "\n"; - } - $content = $flags . "\n" . $content; - $sign = base64_encode ( hash_hmac ( 'sha1', $content, $opt [self::SK], true ) ); - return 'sign=' . $flags . ':' . $opt [self::AK] . ':' . urlencode ( $sign ); - } + /** + * 生成签名 + * @param array $opt + * @return boolean|string + */ + private function formatSignature($opt) + { + $flags = ""; + $content = ''; + if (!isset($opt[self::AK]) || !isset($opt[self::SK])) { + trigger_error('ak or sk is not in the array when create factor!'); + return false; + } + if (isset($opt[self::BUCKET]) && isset($opt[self::METHOD]) && isset($opt[self::OBJECT])) { + $flags .= 'MBO'; + $content .= "Method=" . $opt[self::METHOD] . "\n"; //method + $content .= "Bucket=" . $opt[self::BUCKET] . "\n"; //bucket + $content .= "Object=" . self::trimUrl($opt[self::OBJECT]) . "\n"; //object + } else { + trigger_error('bucket、method and object cann`t be NULL!'); + return false; + } + if (isset($opt['ip'])) { + $flags .= 'I'; + $content .= "Ip=" . $opt['ip'] . "\n"; + } + if (isset($opt['time'])) { + $flags .= 'T'; + $content .= "Time=" . $opt['time'] . "\n"; + } + if (isset($opt['size'])) { + $flags .= 'S'; + $content .= "Size=" . $opt['size'] . "\n"; + } + $content = $flags . "\n" . $content; + $sign = base64_encode(hash_hmac('sha1', $content, $opt[self::SK], true)); + return 'sign=' . $flags . ':' . $opt[self::AK] . ':' . urlencode($sign); + } - /** - * 检查用户输入的acl array是否合法,并转为json - * @param array $acl - * @throws BCS_Exception - * @return string acl-json - */ - private function check_user_acl($acl) { - if (! is_array ( $acl )) { - throw new BCS_Exception ( "Invalid acl array" ); - } - foreach ( $acl ['statements'] as $key => $statement ) { - // user resource action effect must in statement - if (! isset ( $statement ['user'] ) || ! isset ( $statement ['resource'] ) || ! isset ( $statement ['action'] ) || ! isset ( $statement ['effect'] )) { - throw new BCS_Exception ( 'Param miss: format acl error, please check your param!' ); - } - if (! is_array ( $statement ['user'] ) || ! is_array ( $statement ['resource'] )) { - throw new BCS_Exception ( 'Param error: user or resource must be array, please check your param!' ); - } - if (! is_array ( $statement ['action'] ) || ! count ( array_diff ( $statement ['action'], self::$ACL_ACTIONS ) ) == 0) { - throw new BCS_Exception ( 'Param error: action, please check your param!' ); - } - if (! in_array ( $statement ['effect'], self::$ACL_EFFECTS )) { - throw new BCS_Exception ( 'Param error: effect, please check your param!' ); - } - if (isset ( $statement ['time'] )) { - if (! is_array ( $statement ['time'] )) { - throw new BCS_Exception ( 'Param error: time, please check your param!' ); - } - } - } + /** + * 检查用户输入的acl array是否合法,并转为json + * @param array $acl + * @throws BCS_Exception + * @return string acl-json + */ + private function checkUserAcl($acl) + { + if (!is_array($acl)) { + throw new BCS_Exception("Invalid acl array"); + } + foreach ($acl['statements'] as $key => $statement) { + // user resource action effect must in statement + if (!isset($statement['user']) || !isset($statement['resource']) || !isset($statement['action']) || !isset($statement['effect'])) { + throw new BCS_Exception('Param miss: format acl error, please check your param!'); + } + if (!is_array($statement['user']) || !is_array($statement['resource'])) { + throw new BCS_Exception('Param error: user or resource must be array, please check your param!'); + } + if (!is_array($statement['action']) || !count(array_diff($statement['action'], self::$ACL_ACTIONS)) == 0) { + throw new BCS_Exception('Param error: action, please check your param!'); + } + if (!in_array($statement['effect'], self::$ACL_EFFECTS)) { + throw new BCS_Exception('Param error: effect, please check your param!'); + } + if (isset($statement['time'])) { + if (!is_array($statement['time'])) { + throw new BCS_Exception('Param error: time, please check your param!'); + } + } + } - return self::array_to_json ( $acl ); - } + return self::arrayToJson($acl); + } - /** - * 构造url - * @param array $opt - * @return boolean|string - */ - private function format_url($opt) { - $sign = $this->format_signature ( $opt ); - if ($sign === false) { - trigger_error ( "Format signature failed, please check!" ); - return false; - } - $opt ['sign'] = $sign; - $url = ""; - $url .= $this->use_ssl ? 'https://' : 'http://'; - $url .= $this->hostname; - $url .= '/' . $opt [self::BUCKET]; - if (isset ( $opt [self::OBJECT] ) && '/' !== $opt [self::OBJECT]) { - $url .= "/" . rawurlencode ( $opt [self::OBJECT] ); - } - $url .= '?' . $sign; - if (isset ( $opt [self::QUERY_STRING] )) { - foreach ( $opt [self::QUERY_STRING] as $key => $value ) { - $url .= '&' . $key . '=' . $value; - } - } - return $url; - } + /** + * 构造url + * @param array $opt + * @return boolean|string + */ + private function formatUrl($opt) + { + $sign = $this->formatSignature($opt); + if (false === $sign) { + trigger_error("Format signature failed, please check!"); + return false; + } + $opt['sign'] = $sign; + $url = ""; + $url .= $this->use_ssl ? 'https://' : 'http://'; + $url .= $this->hostname; + $url .= '/' . $opt[self::BUCKET]; + if (isset($opt[self::OBJECT]) && '/' !== $opt[self::OBJECT]) { + $url .= "/" . rawurlencode($opt[self::OBJECT]); + } + $url .= '?' . $sign; + if (isset($opt[self::QUERY_STRING])) { + foreach ($opt[self::QUERY_STRING] as $key => $value) { + $url .= '&' . $key . '=' . $value; + } + } + return $url; + } - /** - * 将url中 '//' 替换为 '/' - * @param $url - * @return string - */ - public static function trimUrl($url) { - $result = str_replace ( "//", "/", $url ); - while ( $result !== $url ) { - $url = $result; - $result = str_replace ( "//", "/", $url ); - } - return $result; - } + /** + * 将url中 '//' 替换为 '/' + * @param $url + * @return string + */ + public static function trimUrl($url) + { + $result = str_replace("//", "/", $url); + while ($result !== $url) { + $url = $result; + $result = str_replace("//", "/", $url); + } + return $result; + } - /** - * 获取传入目录的文件列表 - * @param string $dir 文件目录 - * @return array 文件树 - */ - public static function get_filetree($dir, $file_prefix = "/*") { - $tree = array (); - foreach ( glob ( $dir . $file_prefix ) as $single ) { - if (is_dir ( $single )) { - $tree = array_merge ( $tree, self::get_filetree ( $single ) ); - } else { - $tree [] = $single; - } - } - return $tree; - } + /** + * 获取传入目录的文件列表 + * @param string $dir 文件目录 + * @return array 文件树 + */ + public static function getFiletree($dir, $file_prefix = "/*") + { + $tree = array(); + foreach (glob($dir . $file_prefix) as $single) { + if (is_dir($single)) { + $tree = array_merge($tree, self::getFiletree($single)); + } else { + $tree[] = $single; + } + } + return $tree; + } - /** - * 内置的日志函数,可以根据用户传入的log函数,进行日志输出 - * @param string $log - * @param array $opt - */ - public function log($log, $opt) { - if (isset ( $opt [self::IMPORT_BCS_LOG_METHOD] ) && function_exists ( $opt [self::IMPORT_BCS_LOG_METHOD] )) { - $opt [self::IMPORT_BCS_LOG_METHOD] ( $log ); - } else { - trigger_error ( $log ); - } - } + /** + * 内置的日志函数,可以根据用户传入的log函数,进行日志输出 + * @param string $log + * @param array $opt + */ + public function log($log, $opt) + { + if (isset($opt[self::IMPORT_BCS_LOG_METHOD]) && function_exists($opt[self::IMPORT_BCS_LOG_METHOD])) { + $opt[self::IMPORT_BCS_LOG_METHOD]($log); + } else { + trigger_error($log); + } + } - /** - * make sure $opt is an array - * @param $opt - */ - private function assertParameterArray($opt) { - if (! is_array ( $opt )) { - throw new BCS_Exception ( 'Parameter must be array, please check!', - 1 ); - } - } -} \ No newline at end of file + /** + * make sure $opt is an array + * @param $opt + */ + private function assertParameterArray($opt) + { + if (!is_array($opt)) { + throw new BCS_Exception('Parameter must be array, please check!', -1); + } + } +} diff --git a/ThinkPHP/Library/Think/Upload/Driver/Bcs/mimetypes.class.php b/ThinkPHP/Library/Think/Upload/Driver/Bcs/mimetypes.class.php index 61c06c0b4..a9d0961c2 100644 --- a/ThinkPHP/Library/Think/Upload/Driver/Bcs/mimetypes.class.php +++ b/ThinkPHP/Library/Think/Upload/Driver/Bcs/mimetypes.class.php @@ -1,137 +1,140 @@ 'video/3gpp', 'ai' => 'application/postscript', - 'aif' => 'audio/x-aiff', 'aifc' => 'audio/x-aiff', - 'aiff' => 'audio/x-aiff', 'asc' => 'text/plain', - 'atom' => 'application/atom+xml', 'au' => 'audio/basic', - 'avi' => 'video/x-msvideo', 'bcpio' => 'application/x-bcpio', - 'bin' => 'application/octet-stream', 'bmp' => 'image/bmp', - 'cdf' => 'application/x-netcdf', 'cgm' => 'image/cgm', - 'class' => 'application/octet-stream', - 'cpio' => 'application/x-cpio', - 'cpt' => 'application/mac-compactpro', - 'csh' => 'application/x-csh', 'css' => 'text/css', - 'dcr' => 'application/x-director', 'dif' => 'video/x-dv', - 'dir' => 'application/x-director', 'djv' => 'image/vnd.djvu', - 'djvu' => 'image/vnd.djvu', - 'dll' => 'application/octet-stream', - 'dmg' => 'application/octet-stream', - 'dms' => 'application/octet-stream', - 'doc' => 'application/msword', 'dtd' => 'application/xml-dtd', - 'dv' => 'video/x-dv', 'dvi' => 'application/x-dvi', - 'dxr' => 'application/x-director', - 'eps' => 'application/postscript', 'etx' => 'text/x-setext', - 'exe' => 'application/octet-stream', - 'ez' => 'application/andrew-inset', 'flv' => 'video/x-flv', - 'gif' => 'image/gif', 'gram' => 'application/srgs', - 'grxml' => 'application/srgs+xml', - 'gtar' => 'application/x-gtar', 'gz' => 'application/x-gzip', - 'hdf' => 'application/x-hdf', - 'hqx' => 'application/mac-binhex40', 'htm' => 'text/html', - 'html' => 'text/html', 'ice' => 'x-conference/x-cooltalk', - 'ico' => 'image/x-icon', 'ics' => 'text/calendar', - 'ief' => 'image/ief', 'ifb' => 'text/calendar', - 'iges' => 'model/iges', 'igs' => 'model/iges', - 'jnlp' => 'application/x-java-jnlp-file', 'jp2' => 'image/jp2', - 'jpe' => 'image/jpeg', 'jpeg' => 'image/jpeg', - 'jpg' => 'image/jpeg', 'js' => 'application/x-javascript', - 'kar' => 'audio/midi', 'latex' => 'application/x-latex', - 'lha' => 'application/octet-stream', - 'lzh' => 'application/octet-stream', - 'm3u' => 'audio/x-mpegurl', 'm4a' => 'audio/mp4a-latm', - 'm4p' => 'audio/mp4a-latm', 'm4u' => 'video/vnd.mpegurl', - 'm4v' => 'video/x-m4v', 'mac' => 'image/x-macpaint', - 'man' => 'application/x-troff-man', - 'mathml' => 'application/mathml+xml', - 'me' => 'application/x-troff-me', 'mesh' => 'model/mesh', - 'mid' => 'audio/midi', 'midi' => 'audio/midi', - 'mif' => 'application/vnd.mif', 'mov' => 'video/quicktime', - 'movie' => 'video/x-sgi-movie', 'mp2' => 'audio/mpeg', - 'mp3' => 'audio/mpeg', 'mp4' => 'video/mp4', - 'mpe' => 'video/mpeg', 'mpeg' => 'video/mpeg', - 'mpg' => 'video/mpeg', 'mpga' => 'audio/mpeg', - 'ms' => 'application/x-troff-ms', 'msh' => 'model/mesh', - 'mxu' => 'video/vnd.mpegurl', 'nc' => 'application/x-netcdf', - 'oda' => 'application/oda', 'ogg' => 'application/ogg', - 'ogv' => 'video/ogv', 'pbm' => 'image/x-portable-bitmap', - 'pct' => 'image/pict', 'pdb' => 'chemical/x-pdb', - 'pdf' => 'application/pdf', - 'pgm' => 'image/x-portable-graymap', - 'pgn' => 'application/x-chess-pgn', 'pic' => 'image/pict', - 'pict' => 'image/pict', 'png' => 'image/png', - 'pnm' => 'image/x-portable-anymap', - 'pnt' => 'image/x-macpaint', 'pntg' => 'image/x-macpaint', - 'ppm' => 'image/x-portable-pixmap', - 'ppt' => 'application/vnd.ms-powerpoint', - 'ps' => 'application/postscript', 'qt' => 'video/quicktime', - 'qti' => 'image/x-quicktime', 'qtif' => 'image/x-quicktime', - 'ra' => 'audio/x-pn-realaudio', - 'ram' => 'audio/x-pn-realaudio', 'ras' => 'image/x-cmu-raster', - 'rdf' => 'application/rdf+xml', 'rgb' => 'image/x-rgb', - 'rm' => 'application/vnd.rn-realmedia', - 'roff' => 'application/x-troff', 'rtf' => 'text/rtf', - 'rtx' => 'text/richtext', 'sgm' => 'text/sgml', - 'sgml' => 'text/sgml', 'sh' => 'application/x-sh', - 'shar' => 'application/x-shar', 'silo' => 'model/mesh', - 'sit' => 'application/x-stuffit', - 'skd' => 'application/x-koan', 'skm' => 'application/x-koan', - 'skp' => 'application/x-koan', 'skt' => 'application/x-koan', - 'smi' => 'application/smil', 'smil' => 'application/smil', - 'snd' => 'audio/basic', 'so' => 'application/octet-stream', - 'spl' => 'application/x-futuresplash', - 'src' => 'application/x-wais-source', - 'sv4cpio' => 'application/x-sv4cpio', - 'sv4crc' => 'application/x-sv4crc', 'svg' => 'image/svg+xml', - 'swf' => 'application/x-shockwave-flash', - 't' => 'application/x-troff', 'tar' => 'application/x-tar', - 'tcl' => 'application/x-tcl', 'tex' => 'application/x-tex', - 'texi' => 'application/x-texinfo', - 'texinfo' => 'application/x-texinfo', 'tif' => 'image/tiff', - 'tiff' => 'image/tiff', 'tr' => 'application/x-troff', - 'tsv' => 'text/tab-separated-values', 'txt' => 'text/plain', - 'ustar' => 'application/x-ustar', - 'vcd' => 'application/x-cdlink', 'vrml' => 'model/vrml', - 'vxml' => 'application/voicexml+xml', 'wav' => 'audio/x-wav', - 'wbmp' => 'image/vnd.wap.wbmp', - 'wbxml' => 'application/vnd.wap.wbxml', 'webm' => 'video/webm', - 'wml' => 'text/vnd.wap.wml', - 'wmlc' => 'application/vnd.wap.wmlc', - 'wmls' => 'text/vnd.wap.wmlscript', - 'wmlsc' => 'application/vnd.wap.wmlscriptc', - 'wmv' => 'video/x-ms-wmv', 'wrl' => 'model/vrml', - 'xbm' => 'image/x-xbitmap', 'xht' => 'application/xhtml+xml', - 'xhtml' => 'application/xhtml+xml', - 'xls' => 'application/vnd.ms-excel', - 'xml' => 'application/xml', 'xpm' => 'image/x-xpixmap', - 'xsl' => 'application/xml', 'xslt' => 'application/xslt+xml', - 'xul' => 'application/vnd.mozilla.xul+xml', - 'xwd' => 'image/x-xwindowdump', 'xyz' => 'chemical/x-xyz', - 'zip' => 'application/zip', - //add by zhengkan 20110905 - "apk" => "application/vnd.android.package-archive", - "bin" => "application/octet-stream", - "cab" => "application/vnd.ms-cab-compressed", - "gb" => "application/chinese-gb", - "gba" => "application/octet-stream", - "gbc" => "application/octet-stream", - "jad" => "text/vnd.sun.j2me.app-descriptor", - "jar" => "application/java-archive", - "nes" => "application/octet-stream", - "rar" => "application/x-rar-compressed", - "sis" => "application/vnd.symbian.install", - "sisx" => "x-epoc/x-sisx-app", - "smc" => "application/octet-stream", - "smd" => "application/octet-stream", - "swf" => "application/x-shockwave-flash", - "zip" => "application/x-zip-compressed", - "wap" => "text/vnd.wap.wml wml", "mrp" => "application/mrp", - //add by zhengkan 20110914 - "wma" => "audio/x-ms-wma", - "lrc" => "application/lrc" ); - public static function get_mimetype($ext) { - $ext = strtolower ( $ext ); - return (isset ( self::$mime_types [$ext] ) ? self::$mime_types [$ext] : 'application/octet-stream'); - } + +class BcsMimetypes +{ + public static $mime_types = array( + '3gp' => 'video/3gpp', 'ai' => 'application/postscript', + 'aif' => 'audio/x-aiff', 'aifc' => 'audio/x-aiff', + 'aiff' => 'audio/x-aiff', 'asc' => 'text/plain', + 'atom' => 'application/atom+xml', 'au' => 'audio/basic', + 'avi' => 'video/x-msvideo', 'bcpio' => 'application/x-bcpio', + 'bin' => 'application/octet-stream', 'bmp' => 'image/bmp', + 'cdf' => 'application/x-netcdf', 'cgm' => 'image/cgm', + 'class' => 'application/octet-stream', + 'cpio' => 'application/x-cpio', + 'cpt' => 'application/mac-compactpro', + 'csh' => 'application/x-csh', 'css' => 'text/css', + 'dcr' => 'application/x-director', 'dif' => 'video/x-dv', + 'dir' => 'application/x-director', 'djv' => 'image/vnd.djvu', + 'djvu' => 'image/vnd.djvu', + 'dll' => 'application/octet-stream', + 'dmg' => 'application/octet-stream', + 'dms' => 'application/octet-stream', + 'doc' => 'application/msword', 'dtd' => 'application/xml-dtd', + 'dv' => 'video/x-dv', 'dvi' => 'application/x-dvi', + 'dxr' => 'application/x-director', + 'eps' => 'application/postscript', 'etx' => 'text/x-setext', + 'exe' => 'application/octet-stream', + 'ez' => 'application/andrew-inset', 'flv' => 'video/x-flv', + 'gif' => 'image/gif', 'gram' => 'application/srgs', + 'grxml' => 'application/srgs+xml', + 'gtar' => 'application/x-gtar', 'gz' => 'application/x-gzip', + 'hdf' => 'application/x-hdf', + 'hqx' => 'application/mac-binhex40', 'htm' => 'text/html', + 'html' => 'text/html', 'ice' => 'x-conference/x-cooltalk', + 'ico' => 'image/x-icon', 'ics' => 'text/calendar', + 'ief' => 'image/ief', 'ifb' => 'text/calendar', + 'iges' => 'model/iges', 'igs' => 'model/iges', + 'jnlp' => 'application/x-java-jnlp-file', 'jp2' => 'image/jp2', + 'jpe' => 'image/jpeg', 'jpeg' => 'image/jpeg', + 'jpg' => 'image/jpeg', 'js' => 'application/x-javascript', + 'kar' => 'audio/midi', 'latex' => 'application/x-latex', + 'lha' => 'application/octet-stream', + 'lzh' => 'application/octet-stream', + 'm3u' => 'audio/x-mpegurl', 'm4a' => 'audio/mp4a-latm', + 'm4p' => 'audio/mp4a-latm', 'm4u' => 'video/vnd.mpegurl', + 'm4v' => 'video/x-m4v', 'mac' => 'image/x-macpaint', + 'man' => 'application/x-troff-man', + 'mathml' => 'application/mathml+xml', + 'me' => 'application/x-troff-me', 'mesh' => 'model/mesh', + 'mid' => 'audio/midi', 'midi' => 'audio/midi', + 'mif' => 'application/vnd.mif', 'mov' => 'video/quicktime', + 'movie' => 'video/x-sgi-movie', 'mp2' => 'audio/mpeg', + 'mp3' => 'audio/mpeg', 'mp4' => 'video/mp4', + 'mpe' => 'video/mpeg', 'mpeg' => 'video/mpeg', + 'mpg' => 'video/mpeg', 'mpga' => 'audio/mpeg', + 'ms' => 'application/x-troff-ms', 'msh' => 'model/mesh', + 'mxu' => 'video/vnd.mpegurl', 'nc' => 'application/x-netcdf', + 'oda' => 'application/oda', 'ogg' => 'application/ogg', + 'ogv' => 'video/ogv', 'pbm' => 'image/x-portable-bitmap', + 'pct' => 'image/pict', 'pdb' => 'chemical/x-pdb', + 'pdf' => 'application/pdf', + 'pgm' => 'image/x-portable-graymap', + 'pgn' => 'application/x-chess-pgn', 'pic' => 'image/pict', + 'pict' => 'image/pict', 'png' => 'image/png', + 'pnm' => 'image/x-portable-anymap', + 'pnt' => 'image/x-macpaint', 'pntg' => 'image/x-macpaint', + 'ppm' => 'image/x-portable-pixmap', + 'ppt' => 'application/vnd.ms-powerpoint', + 'ps' => 'application/postscript', 'qt' => 'video/quicktime', + 'qti' => 'image/x-quicktime', 'qtif' => 'image/x-quicktime', + 'ra' => 'audio/x-pn-realaudio', + 'ram' => 'audio/x-pn-realaudio', 'ras' => 'image/x-cmu-raster', + 'rdf' => 'application/rdf+xml', 'rgb' => 'image/x-rgb', + 'rm' => 'application/vnd.rn-realmedia', + 'roff' => 'application/x-troff', 'rtf' => 'text/rtf', + 'rtx' => 'text/richtext', 'sgm' => 'text/sgml', + 'sgml' => 'text/sgml', 'sh' => 'application/x-sh', + 'shar' => 'application/x-shar', 'silo' => 'model/mesh', + 'sit' => 'application/x-stuffit', + 'skd' => 'application/x-koan', 'skm' => 'application/x-koan', + 'skp' => 'application/x-koan', 'skt' => 'application/x-koan', + 'smi' => 'application/smil', 'smil' => 'application/smil', + 'snd' => 'audio/basic', 'so' => 'application/octet-stream', + 'spl' => 'application/x-futuresplash', + 'src' => 'application/x-wais-source', + 'sv4cpio' => 'application/x-sv4cpio', + 'sv4crc' => 'application/x-sv4crc', 'svg' => 'image/svg+xml', + 'swf' => 'application/x-shockwave-flash', + 't' => 'application/x-troff', 'tar' => 'application/x-tar', + 'tcl' => 'application/x-tcl', 'tex' => 'application/x-tex', + 'texi' => 'application/x-texinfo', + 'texinfo' => 'application/x-texinfo', 'tif' => 'image/tiff', + 'tiff' => 'image/tiff', 'tr' => 'application/x-troff', + 'tsv' => 'text/tab-separated-values', 'txt' => 'text/plain', + 'ustar' => 'application/x-ustar', + 'vcd' => 'application/x-cdlink', 'vrml' => 'model/vrml', + 'vxml' => 'application/voicexml+xml', 'wav' => 'audio/x-wav', + 'wbmp' => 'image/vnd.wap.wbmp', + 'wbxml' => 'application/vnd.wap.wbxml', 'webm' => 'video/webm', + 'wml' => 'text/vnd.wap.wml', + 'wmlc' => 'application/vnd.wap.wmlc', + 'wmls' => 'text/vnd.wap.wmlscript', + 'wmlsc' => 'application/vnd.wap.wmlscriptc', + 'wmv' => 'video/x-ms-wmv', 'wrl' => 'model/vrml', + 'xbm' => 'image/x-xbitmap', 'xht' => 'application/xhtml+xml', + 'xhtml' => 'application/xhtml+xml', + 'xls' => 'application/vnd.ms-excel', + 'xml' => 'application/xml', 'xpm' => 'image/x-xpixmap', + 'xsl' => 'application/xml', 'xslt' => 'application/xslt+xml', + 'xul' => 'application/vnd.mozilla.xul+xml', + 'xwd' => 'image/x-xwindowdump', 'xyz' => 'chemical/x-xyz', + 'zip' => 'application/zip', + //add by zhengkan 20110905 + "apk" => "application/vnd.android.package-archive", + "bin" => "application/octet-stream", + "cab" => "application/vnd.ms-cab-compressed", + "gb" => "application/chinese-gb", + "gba" => "application/octet-stream", + "gbc" => "application/octet-stream", + "jad" => "text/vnd.sun.j2me.app-descriptor", + "jar" => "application/java-archive", + "nes" => "application/octet-stream", + "rar" => "application/x-rar-compressed", + "sis" => "application/vnd.symbian.install", + "sisx" => "x-epoc/x-sisx-app", + "smc" => "application/octet-stream", + "smd" => "application/octet-stream", + "swf" => "application/x-shockwave-flash", + "zip" => "application/x-zip-compressed", + "wap" => "text/vnd.wap.wml wml", "mrp" => "application/mrp", + //add by zhengkan 20110914 + "wma" => "audio/x-ms-wma", + "lrc" => "application/lrc"); + public static function getMimetype($ext) + { + $ext = strtolower($ext); + return (isset(self::$mime_types[$ext]) ? self::$mime_types[$ext] : 'application/octet-stream'); + } } diff --git a/ThinkPHP/Library/Think/Upload/Driver/Bcs/requestcore.class.php b/ThinkPHP/Library/Think/Upload/Driver/Bcs/requestcore.class.php index 283f23e80..4f8110219 100644 --- a/ThinkPHP/Library/Think/Upload/Driver/Bcs/requestcore.class.php +++ b/ThinkPHP/Library/Think/Upload/Driver/Bcs/requestcore.class.php @@ -11,827 +11,869 @@ * @copyright 2008-2011 Contributors * @license http://opensource.org/licenses/bsd-license.php Simplified BSD License */ -class BCS_RequestCore { - /** - * The URL being requested. - */ - public $request_url; - /** - * The headers being sent in the request. - */ - public $request_headers; - /** - * The body being sent in the request. - */ - public $request_body; - /** - * The response returned by the request. - */ - public $response; - /** - * The headers returned by the request. - */ - public $response_headers; - /** - * The body returned by the request. - */ - public $response_body; - /** - * The HTTP status code returned by the request. - */ - public $response_code; - /** - * Additional response data. - */ - public $response_info; - /** - * The handle for the cURL object. - */ - public $curl_handle; - /** - * The method by which the request is being made. - */ - public $method; - /** - * Stores the proxy settings to use for the request. - */ - public $proxy = null; - /** - * The username to use for the request. - */ - public $username = null; - /** - * The password to use for the request. - */ - public $password = null; - /** - * Custom CURLOPT settings. - */ - public $curlopts = null; - /** - * The state of debug mode. - */ - public $debug_mode = false; - /** - * The default class to use for HTTP Requests (defaults to ). - */ - public $request_class = 'BCS_RequestCore'; - /** - * The default class to use for HTTP Responses (defaults to ). - */ - public $response_class = 'BCS_ResponseCore'; - /** - * Default useragent string to use. - */ - public $useragent = 'BCS_RequestCore/1.4.2'; - /** - * File to read from while streaming up. - */ - public $read_file = null; - /** - * The resource to read from while streaming up. - */ - public $read_stream = null; - /** - * The size of the stream to read from. - */ - public $read_stream_size = null; - /** - * The length already read from the stream. - */ - public $read_stream_read = 0; - /** - * File to write to while streaming down. - */ - public $write_file = null; - /** - * The resource to write to while streaming down. - */ - public $write_stream = null; - /** - * Stores the intended starting seek position. - */ - public $seek_position = null; - /** - * The user-defined callback function to call when a stream is read from. - */ - public $registered_streaming_read_callback = null; - /** - * The user-defined callback function to call when a stream is written to. - */ - public $registered_streaming_write_callback = null; - /*%******************************************************************************************%*/ - // CONSTANTS - /** - * GET HTTP Method - */ - const HTTP_GET = 'GET'; - /** - * POST HTTP Method - */ - const HTTP_POST = 'POST'; - /** - * PUT HTTP Method - */ - const HTTP_PUT = 'PUT'; - /** - * DELETE HTTP Method - */ - const HTTP_DELETE = 'DELETE'; - /** - * HEAD HTTP Method - */ - const HTTP_HEAD = 'HEAD'; - - /*%******************************************************************************************%*/ - // CONSTRUCTOR/DESTRUCTOR - /** - * Constructs a new instance of this class. - * - * @param string $url (Optional) The URL to request or service endpoint to query. - * @param string $proxy (Optional) The faux-url to use for proxy settings. Takes the following format: `proxy://user:pass@hostname:port` - * @param array $helpers (Optional) An associative array of classnames to use for request, and response functionality. Gets passed in automatically by the calling class. - * @return $this A reference to the current instance. - */ - public function __construct($url = null, $proxy = null, $helpers = null) { - // Set some default values. - $this->request_url = $url; - $this->method = self::HTTP_GET; - $this->request_headers = array (); - $this->request_body = ''; - // Set a new Request class if one was set. - if (isset ( $helpers ['request'] ) && ! empty ( $helpers ['request'] )) { - $this->request_class = $helpers ['request']; - } - // Set a new Request class if one was set. - if (isset ( $helpers ['response'] ) && ! empty ( $helpers ['response'] )) { - $this->response_class = $helpers ['response']; - } - if ($proxy) { - $this->set_proxy ( $proxy ); - } - return $this; - } - - /** - * Destructs the instance. Closes opened file handles. - * - * @return $this A reference to the current instance. - */ - public function __destruct() { - if (isset ( $this->read_file ) && isset ( $this->read_stream )) { - fclose ( $this->read_stream ); - } - if (isset ( $this->write_file ) && isset ( $this->write_stream )) { - fclose ( $this->write_stream ); - } - return $this; - } - - /*%******************************************************************************************%*/ - // REQUEST METHODS - /** - * Sets the credentials to use for authentication. - * - * @param string $user (Required) The username to authenticate with. - * @param string $pass (Required) The password to authenticate with. - * @return $this A reference to the current instance. - */ - public function set_credentials($user, $pass) { - $this->username = $user; - $this->password = $pass; - return $this; - } - - /** - * Adds a custom HTTP header to the cURL request. - * - * @param string $key (Required) The custom HTTP header to set. - * @param mixed $value (Required) The value to assign to the custom HTTP header. - * @return $this A reference to the current instance. - */ - public function add_header($key, $value) { - $this->request_headers [$key] = $value; - return $this; - } - - /** - * Removes an HTTP header from the cURL request. - * - * @param string $key (Required) The custom HTTP header to set. - * @return $this A reference to the current instance. - */ - public function remove_header($key) { - if (isset ( $this->request_headers [$key] )) { - unset ( $this->request_headers [$key] ); - } - return $this; - } - - /** - * Set the method type for the request. - * - * @param string $method (Required) One of the following constants: , , , , . - * @return $this A reference to the current instance. - */ - public function set_method($method) { - $this->method = strtoupper ( $method ); - return $this; - } - - /** - * Sets a custom useragent string for the class. - * - * @param string $ua (Required) The useragent string to use. - * @return $this A reference to the current instance. - */ - public function set_useragent($ua) { - $this->useragent = $ua; - return $this; - } - - /** - * Set the body to send in the request. - * - * @param string $body (Required) The textual content to send along in the body of the request. - * @return $this A reference to the current instance. - */ - public function set_body($body) { - $this->request_body = $body; - return $this; - } - - /** - * Set the URL to make the request to. - * - * @param string $url (Required) The URL to make the request to. - * @return $this A reference to the current instance. - */ - public function set_request_url($url) { - $this->request_url = $url; - return $this; - } - - /** - * Set additional CURLOPT settings. These will merge with the default settings, and override if - * there is a duplicate. - * - * @param array $curlopts (Optional) A set of key-value pairs that set `CURLOPT` options. These will merge with the existing CURLOPTs, and ones passed here will override the defaults. Keys should be the `CURLOPT_*` constants, not strings. - * @return $this A reference to the current instance. - */ - public function set_curlopts($curlopts) { - $this->curlopts = $curlopts; - return $this; - } - - /** - * Sets the length in bytes to read from the stream while streaming up. - * - * @param integer $size (Required) The length in bytes to read from the stream. - * @return $this A reference to the current instance. - */ - public function set_read_stream_size($size) { - $this->read_stream_size = $size; - return $this; - } - - /** - * Sets the resource to read from while streaming up. Reads the stream from its current position until - * EOF or `$size` bytes have been read. If `$size` is not given it will be determined by and - * . - * - * @param resource $resource (Required) The readable resource to read from. - * @param integer $size (Optional) The size of the stream to read. - * @return $this A reference to the current instance. - */ - public function set_read_stream($resource, $size = null) { - if (! isset ( $size ) || $size < 0) { - $stats = fstat ( $resource ); - if ($stats && $stats ['size'] >= 0) { - $position = ftell ( $resource ); - if ($position !== false && $position >= 0) { - $size = $stats ['size'] - $position; - } - } - } - $this->read_stream = $resource; - return $this->set_read_stream_size ( $size ); - } - - /** - * Sets the file to read from while streaming up. - * - * @param string $location (Required) The readable location to read from. - * @return $this A reference to the current instance. - */ - public function set_read_file($location) { - $this->read_file = $location; - $read_file_handle = fopen ( $location, 'r' ); - return $this->set_read_stream ( $read_file_handle ); - } - - /** - * Sets the resource to write to while streaming down. - * - * @param resource $resource (Required) The writeable resource to write to. - * @return $this A reference to the current instance. - */ - public function set_write_stream($resource) { - $this->write_stream = $resource; - return $this; - } - - /** - * Sets the file to write to while streaming down. - * - * @param string $location (Required) The writeable location to write to. - * @return $this A reference to the current instance. - */ - public function set_write_file($location) { - $this->write_file = $location; - $write_file_handle = fopen ( $location, 'w' ); - return $this->set_write_stream ( $write_file_handle ); - } - - /** - * Set the proxy to use for making requests. - * - * @param string $proxy (Required) The faux-url to use for proxy settings. Takes the following format: `proxy://user:pass@hostname:port` - * @return $this A reference to the current instance. - */ - public function set_proxy($proxy) { - $proxy = parse_url ( $proxy ); - $proxy ['user'] = isset ( $proxy ['user'] ) ? $proxy ['user'] : null; - $proxy ['pass'] = isset ( $proxy ['pass'] ) ? $proxy ['pass'] : null; - $proxy ['port'] = isset ( $proxy ['port'] ) ? $proxy ['port'] : null; - $this->proxy = $proxy; - return $this; - } - - /** - * Set the intended starting seek position. - * - * @param integer $position (Required) The byte-position of the stream to begin reading from. - * @return $this A reference to the current instance. - */ - public function set_seek_position($position) { - $this->seek_position = isset ( $position ) ? ( integer ) $position : null; - return $this; - } - - /** - * Register a callback function to execute whenever a data stream is read from using - * . - * - * The user-defined callback function should accept three arguments: - * - *
    - *
  • $curl_handle - resource - Required - The cURL handle resource that represents the in-progress transfer.
  • - *
  • $file_handle - resource - Required - The file handle resource that represents the file on the local file system.
  • - *
  • $length - integer - Required - The length in kilobytes of the data chunk that was transferred.
  • - *
- * - * @param string|array|function $callback (Required) The callback function is called by , so you can pass the following values:
    - *
  • The name of a global function to execute, passed as a string.
  • - *
  • A method to execute, passed as array('ClassName', 'MethodName').
  • - *
  • An anonymous function (PHP 5.3+).
- * @return $this A reference to the current instance. - */ - public function register_streaming_read_callback($callback) { - $this->registered_streaming_read_callback = $callback; - return $this; - } - - /** - * Register a callback function to execute whenever a data stream is written to using - * . - * - * The user-defined callback function should accept two arguments: - * - *
    - *
  • $curl_handle - resource - Required - The cURL handle resource that represents the in-progress transfer.
  • - *
  • $length - integer - Required - The length in kilobytes of the data chunk that was transferred.
  • - *
- * - * @param string|array|function $callback (Required) The callback function is called by , so you can pass the following values:
    - *
  • The name of a global function to execute, passed as a string.
  • - *
  • A method to execute, passed as array('ClassName', 'MethodName').
  • - *
  • An anonymous function (PHP 5.3+).
- * @return $this A reference to the current instance. - */ - public function register_streaming_write_callback($callback) { - $this->registered_streaming_write_callback = $callback; - return $this; - } - - /*%******************************************************************************************%*/ - // PREPARE, SEND, AND PROCESS REQUEST - /** - * A callback function that is invoked by cURL for streaming up. - * - * @param resource $curl_handle (Required) The cURL handle for the request. - * @param resource $file_handle (Required) The open file handle resource. - * @param integer $length (Required) The maximum number of bytes to read. - * @return binary Binary data from a stream. - */ - public function streaming_read_callback($curl_handle, $file_handle, $length) { - // Once we've sent as much as we're supposed to send... - if ($this->read_stream_read >= $this->read_stream_size) { - // Send EOF - return ''; - } - // If we're at the beginning of an upload and need to seek... - if ($this->read_stream_read == 0 && isset ( $this->seek_position ) && $this->seek_position !== ftell ( $this->read_stream )) { - if (fseek ( $this->read_stream, $this->seek_position ) !== 0) { - throw new BCS_RequestCore_Exception ( 'The stream does not support seeking and is either not at the requested position or the position is unknown.' ); - } - } - $read = fread ( $this->read_stream, min ( $this->read_stream_size - $this->read_stream_read, $length ) ); // Remaining upload data or cURL's requested chunk size - $this->read_stream_read += strlen ( $read ); - $out = $read === false ? '' : $read; - // Execute callback function - if ($this->registered_streaming_read_callback) { - call_user_func ( $this->registered_streaming_read_callback, $curl_handle, $file_handle, $out ); - } - return $out; - } - - /** - * A callback function that is invoked by cURL for streaming down. - * - * @param resource $curl_handle (Required) The cURL handle for the request. - * @param binary $data (Required) The data to write. - * @return integer The number of bytes written. - */ - public function streaming_write_callback($curl_handle, $data) { - $length = strlen ( $data ); - $written_total = 0; - $written_last = 0; - while ( $written_total < $length ) { - $written_last = fwrite ( $this->write_stream, substr ( $data, $written_total ) ); - if ($written_last === false) { - return $written_total; - } - $written_total += $written_last; - } - // Execute callback function - if ($this->registered_streaming_write_callback) { - call_user_func ( $this->registered_streaming_write_callback, $curl_handle, $written_total ); - } - return $written_total; - } - - /** - * Prepares and adds the details of the cURL request. This can be passed along to a - * function. - * - * @return resource The handle for the cURL object. - */ - public function prep_request() { - $curl_handle = curl_init (); - // Set default options. - curl_setopt ( $curl_handle, CURLOPT_URL, $this->request_url ); - curl_setopt ( $curl_handle, CURLOPT_FILETIME, true ); - curl_setopt ( $curl_handle, CURLOPT_FRESH_CONNECT, false ); - curl_setopt ( $curl_handle, CURLOPT_SSL_VERIFYPEER, false ); - curl_setopt ( $curl_handle, CURLOPT_SSL_VERIFYHOST, true ); - curl_setopt ( $curl_handle, CURLOPT_CLOSEPOLICY, CURLCLOSEPOLICY_LEAST_RECENTLY_USED ); - curl_setopt ( $curl_handle, CURLOPT_MAXREDIRS, 5 ); - curl_setopt ( $curl_handle, CURLOPT_HEADER, true ); - curl_setopt ( $curl_handle, CURLOPT_RETURNTRANSFER, true ); - curl_setopt ( $curl_handle, CURLOPT_TIMEOUT, 5184000 ); - curl_setopt ( $curl_handle, CURLOPT_CONNECTTIMEOUT, 120 ); - curl_setopt ( $curl_handle, CURLOPT_NOSIGNAL, true ); - curl_setopt ( $curl_handle, CURLOPT_REFERER, $this->request_url ); - curl_setopt ( $curl_handle, CURLOPT_USERAGENT, $this->useragent ); - curl_setopt ( $curl_handle, CURLOPT_READFUNCTION, array ( - $this, - 'streaming_read_callback' ) ); - if ($this->debug_mode) { - curl_setopt ( $curl_handle, CURLOPT_VERBOSE, true ); - } - //if (! ini_get ( 'safe_mode' )) { - //modify by zhengkan - //curl_setopt($curl_handle, CURLOPT_FOLLOWLOCATION, true); - //} - // Enable a proxy connection if requested. - if ($this->proxy) { - curl_setopt ( $curl_handle, CURLOPT_HTTPPROXYTUNNEL, true ); - $host = $this->proxy ['host']; - $host .= ($this->proxy ['port']) ? ':' . $this->proxy ['port'] : ''; - curl_setopt ( $curl_handle, CURLOPT_PROXY, $host ); - if (isset ( $this->proxy ['user'] ) && isset ( $this->proxy ['pass'] )) { - curl_setopt ( $curl_handle, CURLOPT_PROXYUSERPWD, $this->proxy ['user'] . ':' . $this->proxy ['pass'] ); - } - } - // Set credentials for HTTP Basic/Digest Authentication. - if ($this->username && $this->password) { - curl_setopt ( $curl_handle, CURLOPT_HTTPAUTH, CURLAUTH_ANY ); - curl_setopt ( $curl_handle, CURLOPT_USERPWD, $this->username . ':' . $this->password ); - } - // Handle the encoding if we can. - if (extension_loaded ( 'zlib' )) { - curl_setopt ( $curl_handle, CURLOPT_ENCODING, '' ); - } - // Process custom headers - if (isset ( $this->request_headers ) && count ( $this->request_headers )) { - $temp_headers = array (); - foreach ( $this->request_headers as $k => $v ) { - $temp_headers [] = $k . ': ' . $v; - } - curl_setopt ( $curl_handle, CURLOPT_HTTPHEADER, $temp_headers ); - } - switch ($this->method) { - case self::HTTP_PUT : - curl_setopt ( $curl_handle, CURLOPT_CUSTOMREQUEST, 'PUT' ); - if (isset ( $this->read_stream )) { - if (! isset ( $this->read_stream_size ) || $this->read_stream_size < 0) { - throw new BCS_RequestCore_Exception ( 'The stream size for the streaming upload cannot be determined.' ); - } - curl_setopt ( $curl_handle, CURLOPT_INFILESIZE, $this->read_stream_size ); - curl_setopt ( $curl_handle, CURLOPT_UPLOAD, true ); - } else { - curl_setopt ( $curl_handle, CURLOPT_POSTFIELDS, $this->request_body ); - } - break; - case self::HTTP_POST : - curl_setopt ( $curl_handle, CURLOPT_POST, true ); - curl_setopt ( $curl_handle, CURLOPT_POSTFIELDS, $this->request_body ); - break; - case self::HTTP_HEAD : - curl_setopt ( $curl_handle, CURLOPT_CUSTOMREQUEST, self::HTTP_HEAD ); - curl_setopt ( $curl_handle, CURLOPT_NOBODY, 1 ); - break; - default : // Assumed GET - curl_setopt ( $curl_handle, CURLOPT_CUSTOMREQUEST, $this->method ); - if (isset ( $this->write_stream )) { - curl_setopt ( $curl_handle, CURLOPT_WRITEFUNCTION, array ( - $this, - 'streaming_write_callback' ) ); - curl_setopt ( $curl_handle, CURLOPT_HEADER, false ); - } else { - curl_setopt ( $curl_handle, CURLOPT_POSTFIELDS, $this->request_body ); - } - break; - } - // Merge in the CURLOPTs - if (isset ( $this->curlopts ) && sizeof ( $this->curlopts ) > 0) { - foreach ( $this->curlopts as $k => $v ) { - curl_setopt ( $curl_handle, $k, $v ); - } - } - return $curl_handle; - } - - /** - * is the environment BAE? - * @return boolean the result of the answer - */ - private function isBaeEnv() { - if (isset ( $_SERVER ['HTTP_HOST'] )) { - $host = $_SERVER ['HTTP_HOST']; - $pos = strpos ( $host, '.' ); - if ($pos !== false) { - $substr = substr ( $host, $pos + 1 ); - if ($substr == 'duapp.com') { - return true; - } - } - } - if (isset ( $_SERVER ["HTTP_BAE_LOGID"] )) { - return true; - } - - return false; - } - - /** - * Take the post-processed cURL data and break it down into useful header/body/info chunks. Uses the - * data stored in the `curl_handle` and `response` properties unless replacement data is passed in via - * parameters. - * - * @param resource $curl_handle (Optional) The reference to the already executed cURL request. - * @param string $response (Optional) The actual response content itself that needs to be parsed. - * @return BCS_ResponseCore A object containing a parsed HTTP response. - */ - public function process_response($curl_handle = null, $response = null) { - // Accept a custom one if it's passed. - if ($curl_handle && $response) { - $this->curl_handle = $curl_handle; - $this->response = $response; - } - // As long as this came back as a valid resource... - if (is_resource ( $this->curl_handle )) { - // Determine what's what. - $header_size = curl_getinfo ( $this->curl_handle, CURLINFO_HEADER_SIZE ); - $this->response_headers = substr ( $this->response, 0, $header_size ); - $this->response_body = substr ( $this->response, $header_size ); - $this->response_code = curl_getinfo ( $this->curl_handle, CURLINFO_HTTP_CODE ); - $this->response_info = curl_getinfo ( $this->curl_handle ); - // Parse out the headers - $this->response_headers = explode ( "\r\n\r\n", trim ( $this->response_headers ) ); - $this->response_headers = array_pop ( $this->response_headers ); - $this->response_headers = explode ( "\r\n", $this->response_headers ); - array_shift ( $this->response_headers ); - // Loop through and split up the headers. - $header_assoc = array (); - foreach ( $this->response_headers as $header ) { - $kv = explode ( ': ', $header ); - //$header_assoc [strtolower ( $kv [0] )] = $kv [1]; - $header_assoc [$kv [0]] = $kv [1]; - } - // Reset the headers to the appropriate property. - $this->response_headers = $header_assoc; - $this->response_headers ['_info'] = $this->response_info; - $this->response_headers ['_info'] ['method'] = $this->method; - if ($curl_handle && $response) { - $class='\Think\Upload\Driver\Bcs\\'. $this->response_class; - return new $class ( $this->response_headers, $this->response_body, $this->response_code, $this->curl_handle ); - } - } - // Return false - return false; - } - - /** - * Sends the request, calling necessary utility functions to update built-in properties. - * - * @param boolean $parse (Optional) Whether to parse the response with BCS_ResponseCore or not. - * @return string The resulting unparsed data from the request. - */ - public function send_request($parse = false) { - if (false === $this->isBaeEnv ()) { - set_time_limit ( 0 ); - } - $curl_handle = $this->prep_request (); - $this->response = curl_exec ( $curl_handle ); - if ($this->response === false || - ($this->method === self::HTTP_GET && - curl_errno($curl_handle) === CURLE_PARTIAL_FILE)) { - throw new BCS_RequestCore_Exception ( 'cURL resource: ' . ( string ) $curl_handle . '; cURL error: ' . curl_error ( $curl_handle ) . ' (' . curl_errno ( $curl_handle ) . ')' ); - } - $parsed_response = $this->process_response ( $curl_handle, $this->response ); - curl_close ( $curl_handle ); - if ($parse) { - return $parsed_response; - } - return $this->response; - } - - /** - * Sends the request using , enabling parallel requests. Uses the "rolling" method. - * - * @param array $handles (Required) An indexed array of cURL handles to process simultaneously. - * @param array $opt (Optional) An associative array of parameters that can have the following keys:
    - *
  • callback - string|array - Optional - The string name of a function to pass the response data to. If this is a method, pass an array where the [0] index is the class and the [1] index is the method name.
  • - *
  • limit - integer - Optional - The number of simultaneous requests to make. This can be useful for scaling around slow server responses. Defaults to trusting cURLs judgement as to how many to use.
- * @return array Post-processed cURL responses. - */ - public function send_multi_request($handles, $opt = null) { - if (false === $this->isBaeEnv ()) { - set_time_limit ( 0 ); - } - // Skip everything if there are no handles to process. - if (count ( $handles ) === 0) - return array (); - if (! $opt) - $opt = array (); - - // Initialize any missing options - $limit = isset ( $opt ['limit'] ) ? $opt ['limit'] : - 1; - // Initialize - $handle_list = $handles; - $http = new $this->request_class (); - $multi_handle = curl_multi_init (); - $handles_post = array (); - $added = count ( $handles ); - $last_handle = null; - $count = 0; - $i = 0; - // Loop through the cURL handles and add as many as it set by the limit parameter. - while ( $i < $added ) { - if ($limit > 0 && $i >= $limit) - break; - curl_multi_add_handle ( $multi_handle, array_shift ( $handles ) ); - $i ++; - } - do { - $active = false; - // Start executing and wait for a response. - while ( ($status = curl_multi_exec ( $multi_handle, $active )) === CURLM_CALL_MULTI_PERFORM ) { - // Start looking for possible responses immediately when we have to add more handles - if (count ( $handles ) > 0) - break; - } - // Figure out which requests finished. - $to_process = array (); - while ( $done = curl_multi_info_read ( $multi_handle ) ) { - // Since curl_errno() isn't reliable for handles that were in multirequests, we check the 'result' of the info read, which contains the curl error number, (listed here http://curl.haxx.se/libcurl/c/libcurl-errors.html ) - if ($done ['result'] > 0) { - throw new BCS_RequestCore_Exception ( 'cURL resource: ' . ( string ) $done ['handle'] . '; cURL error: ' . curl_error ( $done ['handle'] ) . ' (' . $done ['result'] . ')' ); - } // Because curl_multi_info_read() might return more than one message about a request, we check to see if this request is already in our array of completed requests -elseif (! isset ( $to_process [( int ) $done ['handle']] )) { - $to_process [( int ) $done ['handle']] = $done; - } - } - // Actually deal with the request - foreach ( $to_process as $pkey => $done ) { - $response = $http->process_response ( $done ['handle'], curl_multi_getcontent ( $done ['handle'] ) ); - $key = array_search ( $done ['handle'], $handle_list, true ); - $handles_post [$key] = $response; - if (count ( $handles ) > 0) { - curl_multi_add_handle ( $multi_handle, array_shift ( $handles ) ); - } - curl_multi_remove_handle ( $multi_handle, $done ['handle'] ); - curl_close ( $done ['handle'] ); - } - } while ( $active || count ( $handles_post ) < $added ); - curl_multi_close ( $multi_handle ); - ksort ( $handles_post, SORT_NUMERIC ); - return $handles_post; - } - - /*%******************************************************************************************%*/ - // RESPONSE METHODS - /** - * Get the HTTP response headers from the request. - * - * @param string $header (Optional) A specific header value to return. Defaults to all headers. - * @return string|array All or selected header values. - */ - public function get_response_header($header = null) { - if ($header) { - // return $this->response_headers [strtolower ( $header )]; - return $this->response_headers [$header]; - } - return $this->response_headers; - } - - /** - * Get the HTTP response body from the request. - * - * @return string The response body. - */ - public function get_response_body() { - return $this->response_body; - } - - /** - * Get the HTTP response code from the request. - * - * @return string The HTTP response code. - */ - public function get_response_code() { - return $this->response_code; - } +use Think\Upload\Driver\Bcs\BCS_RequestCore_Exception as BCS_RequestCore_Exception; +class BcsRequestcore +{ + /** + * The URL being requested. + */ + public $request_url; + /** + * The headers being sent in the request. + */ + public $request_headers; + /** + * The body being sent in the request. + */ + public $request_body; + /** + * The response returned by the request. + */ + public $response; + /** + * The headers returned by the request. + */ + public $response_headers; + /** + * The body returned by the request. + */ + public $response_body; + /** + * The HTTP status code returned by the request. + */ + public $response_code; + /** + * Additional response data. + */ + public $response_info; + /** + * The handle for the cURL object. + */ + public $curl_handle; + /** + * The method by which the request is being made. + */ + public $method; + /** + * Stores the proxy settings to use for the request. + */ + public $proxy = null; + /** + * The username to use for the request. + */ + public $username = null; + /** + * The password to use for the request. + */ + public $password = null; + /** + * Custom CURLOPT settings. + */ + public $curlopts = null; + /** + * The state of debug mode. + */ + public $debug_mode = false; + /** + * The default class to use for HTTP Requests (defaults to ). + */ + public $request_class = 'BCS_RequestCore'; + /** + * The default class to use for HTTP Responses (defaults to ). + */ + public $response_class = 'BCS_ResponseCore'; + /** + * Default useragent string to use. + */ + public $useragent = 'BCS_RequestCore/1.4.2'; + /** + * File to read from while streaming up. + */ + public $read_file = null; + /** + * The resource to read from while streaming up. + */ + public $read_stream = null; + /** + * The size of the stream to read from. + */ + public $read_stream_size = null; + /** + * The length already read from the stream. + */ + public $read_stream_read = 0; + /** + * File to write to while streaming down. + */ + public $write_file = null; + /** + * The resource to write to while streaming down. + */ + public $write_stream = null; + /** + * Stores the intended starting seek position. + */ + public $seek_position = null; + /** + * The user-defined callback function to call when a stream is read from. + */ + public $registered_streaming_read_callback = null; + /** + * The user-defined callback function to call when a stream is written to. + */ + public $registered_streaming_write_callback = null; + /*%******************************************************************************************%*/ + // CONSTANTS + /** + * GET HTTP Method + */ + const HTTP_GET = 'GET'; + /** + * POST HTTP Method + */ + const HTTP_POST = 'POST'; + /** + * PUT HTTP Method + */ + const HTTP_PUT = 'PUT'; + /** + * DELETE HTTP Method + */ + const HTTP_DELETE = 'DELETE'; + /** + * HEAD HTTP Method + */ + const HTTP_HEAD = 'HEAD'; + + /*%******************************************************************************************%*/ + // CONSTRUCTOR/DESTRUCTOR + /** + * Constructs a new instance of this class. + * + * @param string $url (Optional) The URL to request or service endpoint to query. + * @param string $proxy (Optional) The faux-url to use for proxy settings. Takes the following format: `proxy://user:pass@hostname:port` + * @param array $helpers (Optional) An associative array of classnames to use for request, and response functionality. Gets passed in automatically by the calling class. + * @return $this A reference to the current instance. + */ + public function __construct($url = null, $proxy = null, $helpers = null) + { + // Set some default values. + $this->request_url = $url; + $this->method = self::HTTP_GET; + $this->request_headers = array(); + $this->request_body = ''; + // Set a new Request class if one was set. + if (isset($helpers['request']) && !empty($helpers['request'])) { + $this->request_class = $helpers['request']; + } + // Set a new Request class if one was set. + if (isset($helpers['response']) && !empty($helpers['response'])) { + $this->response_class = $helpers['response']; + } + if ($proxy) { + $this->setProxy($proxy); + } + return $this; + } + + /** + * Destructs the instance. Closes opened file handles. + * + * @return $this A reference to the current instance. + */ + public function __destruct() + { + if (isset($this->read_file) && isset($this->read_stream)) { + fclose($this->read_stream); + } + if (isset($this->write_file) && isset($this->write_stream)) { + fclose($this->write_stream); + } + return $this; + } + + /*%******************************************************************************************%*/ + // REQUEST METHODS + /** + * Sets the credentials to use for authentication. + * + * @param string $user (Required) The username to authenticate with. + * @param string $pass (Required) The password to authenticate with. + * @return $this A reference to the current instance. + */ + public function setCredentials($user, $pass) + { + $this->username = $user; + $this->password = $pass; + return $this; + } + + /** + * Adds a custom HTTP header to the cURL request. + * + * @param string $key (Required) The custom HTTP header to set. + * @param mixed $value (Required) The value to assign to the custom HTTP header. + * @return $this A reference to the current instance. + */ + public function addHeader($key, $value) + { + $this->request_headers[$key] = $value; + return $this; + } + + /** + * Removes an HTTP header from the cURL request. + * + * @param string $key (Required) The custom HTTP header to set. + * @return $this A reference to the current instance. + */ + public function removeHeader($key) + { + if (isset($this->request_headers[$key])) { + unset($this->request_headers[$key]); + } + return $this; + } + + /** + * Set the method type for the request. + * + * @param string $method (Required) One of the following constants: , , , , . + * @return $this A reference to the current instance. + */ + public function setMethod($method) + { + $this->method = strtoupper($method); + return $this; + } + + /** + * Sets a custom useragent string for the class. + * + * @param string $ua (Required) The useragent string to use. + * @return $this A reference to the current instance. + */ + public function setUseragent($ua) + { + $this->useragent = $ua; + return $this; + } + + /** + * Set the body to send in the request. + * + * @param string $body (Required) The textual content to send along in the body of the request. + * @return $this A reference to the current instance. + */ + public function setBody($body) + { + $this->request_body = $body; + return $this; + } + + /** + * Set the URL to make the request to. + * + * @param string $url (Required) The URL to make the request to. + * @return $this A reference to the current instance. + */ + public function setRequestUrl($url) + { + $this->request_url = $url; + return $this; + } + + /** + * Set additional CURLOPT settings. These will merge with the default settings, and override if + * there is a duplicate. + * + * @param array $curlopts (Optional) A set of key-value pairs that set `CURLOPT` options. These will merge with the existing CURLOPTs, and ones passed here will override the defaults. Keys should be the `CURLOPT_*` constants, not strings. + * @return $this A reference to the current instance. + */ + public function setCurlopts($curlopts) + { + $this->curlopts = $curlopts; + return $this; + } + + /** + * Sets the length in bytes to read from the stream while streaming up. + * + * @param integer $size (Required) The length in bytes to read from the stream. + * @return $this A reference to the current instance. + */ + public function setReadStreamSize($size) + { + $this->read_stream_size = $size; + return $this; + } + + /** + * Sets the resource to read from while streaming up. Reads the stream from its current position until + * EOF or `$size` bytes have been read. If `$size` is not given it will be determined by and + * . + * + * @param resource $resource (Required) The readable resource to read from. + * @param integer $size (Optional) The size of the stream to read. + * @return $this A reference to the current instance. + */ + public function setReadStream($resource, $size = null) + { + if (!isset($size) || $size < 0) { + $stats = fstat($resource); + if ($stats && $stats['size'] >= 0) { + $position = ftell($resource); + if (false !== $position && $position >= 0) { + $size = $stats['size'] - $position; + } + } + } + $this->read_stream = $resource; + return $this->setReadStreamSize($size); + } + + /** + * Sets the file to read from while streaming up. + * + * @param string $location (Required) The readable location to read from. + * @return $this A reference to the current instance. + */ + public function setReadFile($location) + { + $this->read_file = $location; + $read_file_handle = fopen($location, 'r'); + return $this->setReadStream($read_file_handle); + } + + /** + * Sets the resource to write to while streaming down. + * + * @param resource $resource (Required) The writeable resource to write to. + * @return $this A reference to the current instance. + */ + public function setWriteStream($resource) + { + $this->write_stream = $resource; + return $this; + } + + /** + * Sets the file to write to while streaming down. + * + * @param string $location (Required) The writeable location to write to. + * @return $this A reference to the current instance. + */ + public function setWriteFile($location) + { + $this->write_file = $location; + $write_file_handle = fopen($location, 'w'); + return $this->setWriteStream($write_file_handle); + } + + /** + * Set the proxy to use for making requests. + * + * @param string $proxy (Required) The faux-url to use for proxy settings. Takes the following format: `proxy://user:pass@hostname:port` + * @return $this A reference to the current instance. + */ + public function setProxy($proxy) + { + $proxy = parse_url($proxy); + $proxy['user'] = isset($proxy['user']) ? $proxy['user'] : null; + $proxy['pass'] = isset($proxy['pass']) ? $proxy['pass'] : null; + $proxy['port'] = isset($proxy['port']) ? $proxy['port'] : null; + $this->proxy = $proxy; + return $this; + } + + /** + * Set the intended starting seek position. + * + * @param integer $position (Required) The byte-position of the stream to begin reading from. + * @return $this A reference to the current instance. + */ + public function setSeekPosition($position) + { + $this->seek_position = isset($position) ? (integer) $position : null; + return $this; + } + + /** + * Register a callback function to execute whenever a data stream is read from using + * . + * + * The user-defined callback function should accept three arguments: + * + *
    + *
  • $curl_handle - resource - Required - The cURL handle resource that represents the in-progress transfer.
  • + *
  • $file_handle - resource - Required - The file handle resource that represents the file on the local file system.
  • + *
  • $length - integer - Required - The length in kilobytes of the data chunk that was transferred.
  • + *
+ * + * @param string|array|function $callback (Required) The callback function is called by , so you can pass the following values:
    + *
  • The name of a global function to execute, passed as a string.
  • + *
  • A method to execute, passed as array('ClassName', 'MethodName').
  • + *
  • An anonymous function (PHP 5.3+).
+ * @return $this A reference to the current instance. + */ + public function registerStreamingReadCallback($callback) + { + $this->registered_streaming_read_callback = $callback; + return $this; + } + + /** + * Register a callback function to execute whenever a data stream is written to using + * . + * + * The user-defined callback function should accept two arguments: + * + *
    + *
  • $curl_handle - resource - Required - The cURL handle resource that represents the in-progress transfer.
  • + *
  • $length - integer - Required - The length in kilobytes of the data chunk that was transferred.
  • + *
+ * + * @param string|array|function $callback (Required) The callback function is called by , so you can pass the following values:
    + *
  • The name of a global function to execute, passed as a string.
  • + *
  • A method to execute, passed as array('ClassName', 'MethodName').
  • + *
  • An anonymous function (PHP 5.3+).
+ * @return $this A reference to the current instance. + */ + public function registerStreamingWriteCallback($callback) + { + $this->registered_streaming_write_callback = $callback; + return $this; + } + + /*%******************************************************************************************%*/ + // PREPARE, SEND, AND PROCESS REQUEST + /** + * A callback function that is invoked by cURL for streaming up. + * + * @param resource $curl_handle (Required) The cURL handle for the request. + * @param resource $file_handle (Required) The open file handle resource. + * @param integer $length (Required) The maximum number of bytes to read. + * @return binary Binary data from a stream. + */ + public function streamingReadCallback($curl_handle, $file_handle, $length) + { + // Once we've sent as much as we're supposed to send... + if ($this->read_stream_read >= $this->read_stream_size) { + // Send EOF + return ''; + } + // If we're at the beginning of an upload and need to seek... + if (0 == $this->read_stream_read && isset($this->seek_position) && ftell($this->read_stream) !== $this->seek_position) { + if (fseek($this->read_stream, $this->seek_position) !== 0) { + throw new BCS_RequestCore_Exception('The stream does not support seeking and is either not at the requested position or the position is unknown.'); + } + } + $read = fread($this->read_stream, min($this->read_stream_size - $this->read_stream_read, $length)); // Remaining upload data or cURL's requested chunk size + $this->read_stream_read += strlen($read); + $out = false === $read ? '' : $read; + // Execute callback function + if ($this->registered_streaming_read_callback) { + call_user_func($this->registered_streaming_read_callback, $curl_handle, $file_handle, $out); + } + return $out; + } + + /** + * A callback function that is invoked by cURL for streaming down. + * + * @param resource $curl_handle (Required) The cURL handle for the request. + * @param binary $data (Required) The data to write. + * @return integer The number of bytes written. + */ + public function streamingWriteCallback($curl_handle, $data) + { + $length = strlen($data); + $written_total = 0; + $written_last = 0; + while ($written_total < $length) { + $written_last = fwrite($this->write_stream, substr($data, $written_total)); + if (false === $written_last) { + return $written_total; + } + $written_total += $written_last; + } + // Execute callback function + if ($this->registered_streaming_write_callback) { + call_user_func($this->registered_streaming_write_callback, $curl_handle, $written_total); + } + return $written_total; + } + + /** + * Prepares and adds the details of the cURL request. This can be passed along to a + * function. + * + * @return resource The handle for the cURL object. + */ + public function prepRequest() + { + $curl_handle = curl_init(); + // Set default options. + curl_setopt($curl_handle, CURLOPT_URL, $this->request_url); + curl_setopt($curl_handle, CURLOPT_FILETIME, true); + curl_setopt($curl_handle, CURLOPT_FRESH_CONNECT, false); + curl_setopt($curl_handle, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($curl_handle, CURLOPT_SSL_VERIFYHOST, true); + curl_setopt($curl_handle, CURLOPT_CLOSEPOLICY, CURLCLOSEPOLICY_LEAST_RECENTLY_USED); + curl_setopt($curl_handle, CURLOPT_MAXREDIRS, 5); + curl_setopt($curl_handle, CURLOPT_HEADER, true); + curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, true); + curl_setopt($curl_handle, CURLOPT_TIMEOUT, 5184000); + curl_setopt($curl_handle, CURLOPT_CONNECTTIMEOUT, 120); + curl_setopt($curl_handle, CURLOPT_NOSIGNAL, true); + curl_setopt($curl_handle, CURLOPT_REFERER, $this->request_url); + curl_setopt($curl_handle, CURLOPT_USERAGENT, $this->useragent); + curl_setopt($curl_handle, CURLOPT_READFUNCTION, array( + $this, + 'streaming_read_callback')); + if ($this->debug_mode) { + curl_setopt($curl_handle, CURLOPT_VERBOSE, true); + } + //if (! ini_get ( 'safe_mode' )) { + //modify by zhengkan + //curl_setopt($curl_handle, CURLOPT_FOLLOWLOCATION, true); + //} + // Enable a proxy connection if requested. + if ($this->proxy) { + curl_setopt($curl_handle, CURLOPT_HTTPPROXYTUNNEL, true); + $host = $this->proxy['host']; + $host .= ($this->proxy['port']) ? ':' . $this->proxy['port'] : ''; + curl_setopt($curl_handle, CURLOPT_PROXY, $host); + if (isset($this->proxy['user']) && isset($this->proxy['pass'])) { + curl_setopt($curl_handle, CURLOPT_PROXYUSERPWD, $this->proxy['user'] . ':' . $this->proxy['pass']); + } + } + // Set credentials for HTTP Basic/Digest Authentication. + if ($this->username && $this->password) { + curl_setopt($curl_handle, CURLOPT_HTTPAUTH, CURLAUTH_ANY); + curl_setopt($curl_handle, CURLOPT_USERPWD, $this->username . ':' . $this->password); + } + // Handle the encoding if we can. + if (extension_loaded('zlib')) { + curl_setopt($curl_handle, CURLOPT_ENCODING, ''); + } + // Process custom headers + if (isset($this->request_headers) && count($this->request_headers)) { + $temp_headers = array(); + foreach ($this->request_headers as $k => $v) { + $temp_headers[] = $k . ': ' . $v; + } + curl_setopt($curl_handle, CURLOPT_HTTPHEADER, $temp_headers); + } + switch ($this->method) { + case self::HTTP_PUT: + curl_setopt($curl_handle, CURLOPT_CUSTOMREQUEST, 'PUT'); + if (isset($this->read_stream)) { + if (!isset($this->read_stream_size) || $this->read_stream_size < 0) { + throw new BCS_RequestCore_Exception('The stream size for the streaming upload cannot be determined.'); + } + curl_setopt($curl_handle, CURLOPT_INFILESIZE, $this->read_stream_size); + curl_setopt($curl_handle, CURLOPT_UPLOAD, true); + } else { + curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $this->request_body); + } + break; + case self::HTTP_POST: + curl_setopt($curl_handle, CURLOPT_POST, true); + curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $this->request_body); + break; + case self::HTTP_HEAD: + curl_setopt($curl_handle, CURLOPT_CUSTOMREQUEST, self::HTTP_HEAD); + curl_setopt($curl_handle, CURLOPT_NOBODY, 1); + break; + default: // Assumed GET + curl_setopt($curl_handle, CURLOPT_CUSTOMREQUEST, $this->method); + if (isset($this->write_stream)) { + curl_setopt($curl_handle, CURLOPT_WRITEFUNCTION, array( + $this, + 'streaming_write_callback')); + curl_setopt($curl_handle, CURLOPT_HEADER, false); + } else { + curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $this->request_body); + } + break; + } + // Merge in the CURLOPTs + if (isset($this->curlopts) && sizeof($this->curlopts) > 0) { + foreach ($this->curlopts as $k => $v) { + curl_setopt($curl_handle, $k, $v); + } + } + return $curl_handle; + } + + /** + * is the environment BAE? + * @return boolean the result of the answer + */ + private function isBaeEnv() + { + if (isset($_SERVER['HTTP_HOST'])) { + $host = $_SERVER['HTTP_HOST']; + $pos = strpos($host, '.'); + if (false !== $pos) { + $substr = substr($host, $pos + 1); + if ('duapp.com' == $substr) { + return true; + } + } + } + if (isset($_SERVER["HTTP_BAE_LOGID"])) { + return true; + } + + return false; + } + + /** + * Take the post-processed cURL data and break it down into useful header/body/info chunks. Uses the + * data stored in the `curl_handle` and `response` properties unless replacement data is passed in via + * parameters. + * + * @param resource $curl_handle (Optional) The reference to the already executed cURL request. + * @param string $response (Optional) The actual response content itself that needs to be parsed. + * @return BCS_ResponseCore A object containing a parsed HTTP response. + */ + public function processResponse($curl_handle = null, $response = null) + { + // Accept a custom one if it's passed. + if ($curl_handle && $response) { + $this->curl_handle = $curl_handle; + $this->response = $response; + } + // As long as this came back as a valid resource... + if (is_resource($this->curl_handle)) { + // Determine what's what. + $header_size = curl_getinfo($this->curl_handle, CURLINFO_HEADER_SIZE); + $this->response_headers = substr($this->response, 0, $header_size); + $this->response_body = substr($this->response, $header_size); + $this->response_code = curl_getinfo($this->curl_handle, CURLINFO_HTTP_CODE); + $this->response_info = curl_getinfo($this->curl_handle); + // Parse out the headers + $this->response_headers = explode("\r\n\r\n", trim($this->response_headers)); + $this->response_headers = array_pop($this->response_headers); + $this->response_headers = explode("\r\n", $this->response_headers); + array_shift($this->response_headers); + // Loop through and split up the headers. + $header_assoc = array(); + foreach ($this->response_headers as $header) { + $kv = explode(': ', $header); + //$header_assoc [strtolower ( $kv [0] )] = $kv [1]; + $header_assoc[$kv[0]] = $kv[1]; + } + // Reset the headers to the appropriate property. + $this->response_headers = $header_assoc; + $this->response_headers['_info'] = $this->response_info; + $this->response_headers['_info']['method'] = $this->method; + if ($curl_handle && $response) { + $class = '\Think\Upload\Driver\Bcs\\' . $this->response_class; + return new $class($this->response_headers, $this->response_body, $this->response_code, $this->curl_handle); + } + } + // Return false + return false; + } + + /** + * Sends the request, calling necessary utility functions to update built-in properties. + * + * @param boolean $parse (Optional) Whether to parse the response with BCS_ResponseCore or not. + * @return string The resulting unparsed data from the request. + */ + public function sendRequest($parse = false) + { + if (false === $this->isBaeEnv()) { + set_time_limit(0); + } + $curl_handle = $this->prepRequest(); + $this->response = curl_exec($curl_handle); + if (false === $this->response || + (self::HTTP_GET === $this->method && + curl_errno($curl_handle) === CURLE_PARTIAL_FILE)) { + throw new BCS_RequestCore_Exception('cURL resource: ' . (string) $curl_handle . '; cURL error: ' . curl_error($curl_handle) . ' (' . curl_errno($curl_handle) . ')'); + } + $parsed_response = $this->processResponse($curl_handle, $this->response); + curl_close($curl_handle); + if ($parse) { + return $parsed_response; + } + return $this->response; + } + + /** + * Sends the request using , enabling parallel requests. Uses the "rolling" method. + * + * @param array $handles (Required) An indexed array of cURL handles to process simultaneously. + * @param array $opt (Optional) An associative array of parameters that can have the following keys:
    + *
  • callback - string|array - Optional - The string name of a function to pass the response data to. If this is a method, pass an array where the [0] index is the class and the [1] index is the method name.
  • + *
  • limit - integer - Optional - The number of simultaneous requests to make. This can be useful for scaling around slow server responses. Defaults to trusting cURLs judgement as to how many to use.
+ * @return array Post-processed cURL responses. + */ + public function sendMultiRequest($handles, $opt = null) + { + if (false === $this->isBaeEnv()) { + set_time_limit(0); + } + // Skip everything if there are no handles to process. + if (count($handles) === 0) { + return array(); + } + + if (!$opt) { + $opt = array(); + } + + // Initialize any missing options + $limit = isset($opt['limit']) ? $opt['limit'] : -1; + // Initialize + $handle_list = $handles; + $http = new $this->request_class(); + $multi_handle = curl_multi_init(); + $handles_post = array(); + $added = count($handles); + $last_handle = null; + $count = 0; + $i = 0; + // Loop through the cURL handles and add as many as it set by the limit parameter. + while ($i < $added) { + if ($limit > 0 && $i >= $limit) { + break; + } + + curl_multi_add_handle($multi_handle, array_shift($handles)); + $i++; + } + do { + $active = false; + // Start executing and wait for a response. + while (($status = curl_multi_exec($multi_handle, $active)) === CURLM_CALL_MULTI_PERFORM) { + // Start looking for possible responses immediately when we have to add more handles + if (count($handles) > 0) { + break; + } + + } + // Figure out which requests finished. + $to_process = array(); + while ($done = curl_multi_info_read($multi_handle)) { + // Since curl_errno() isn't reliable for handles that were in multirequests, we check the 'result' of the info read, which contains the curl error number, (listed here http://curl.haxx.se/libcurl/c/libcurl-errors.html ) + if ($done['result'] > 0) { + throw new BCS_RequestCore_Exception('cURL resource: ' . (string) $done['handle'] . '; cURL error: ' . curl_error($done['handle']) . ' (' . $done['result'] . ')'); + } // Because curl_multi_info_read() might return more than one message about a request, we check to see if this request is already in our array of completed requests + elseif (!isset($to_process[(int) $done['handle']])) { + $to_process[(int) $done['handle']] = $done; + } + } + // Actually deal with the request + foreach ($to_process as $pkey => $done) { + $response = $http->processResponse($done['handle'], curl_multi_getcontent($done['handle'])); + $key = array_search($done['handle'], $handle_list, true); + $handles_post[$key] = $response; + if (count($handles) > 0) { + curl_multi_add_handle($multi_handle, array_shift($handles)); + } + curl_multi_remove_handle($multi_handle, $done['handle']); + curl_close($done['handle']); + } + } while ($active || count($handles_post) < $added); + curl_multi_close($multi_handle); + ksort($handles_post, SORT_NUMERIC); + return $handles_post; + } + + /*%******************************************************************************************%*/ + // RESPONSE METHODS + /** + * Get the HTTP response headers from the request. + * + * @param string $header (Optional) A specific header value to return. Defaults to all headers. + * @return string|array All or selected header values. + */ + public function getResponseHeader($header = null) + { + if ($header) { + // return $this->response_headers [strtolower ( $header )]; + return $this->response_headers[$header]; + } + return $this->response_headers; + } + + /** + * Get the HTTP response body from the request. + * + * @return string The response body. + */ + public function getResponseBody() + { + return $this->response_body; + } + + /** + * Get the HTTP response code from the request. + * + * @return string The HTTP response code. + */ + public function getResponseCode() + { + return $this->response_code; + } } /** * Container for all response-related methods. */ -class BCS_ResponseCore { - /** - * Stores the HTTP header information. - */ - public $header; - /** - * Stores the SimpleXML response. - */ - public $body; - /** - * Stores the HTTP response code. - */ - public $status; - - /** - * Constructs a new instance of this class. - * - * @param array $header (Required) Associative array of HTTP headers (typically returned by ). - * @param string $body (Required) XML-formatted response from AWS. - * @param integer $status (Optional) HTTP response status code from the request. - * @return object Contains an `header` property (HTTP headers as an associative array), a or `body` property, and an `status` code. - */ - public function __construct($header, $body, $status = null) { - $this->header = $header; - $this->body = $body; - $this->status = $status; - return $this; - } - - /** - * Did we receive the status code we expected? - * - * @param integer|array $codes (Optional) The status code(s) to expect. Pass an for a single acceptable value, or an of integers for multiple acceptable values. - * @return boolean Whether we received the expected status code or not. - */ - public function isOK($codes = array(200, 201, 204, 206)) { - if (is_array ( $codes )) { - return in_array ( $this->status, $codes ); - } - return $this->status === $codes; - } +class BcsResponsecore +{ + /** + * Stores the HTTP header information. + */ + public $header; + /** + * Stores the SimpleXML response. + */ + public $body; + /** + * Stores the HTTP response code. + */ + public $status; + + /** + * Constructs a new instance of this class. + * + * @param array $header (Required) Associative array of HTTP headers (typically returned by ). + * @param string $body (Required) XML-formatted response from AWS. + * @param integer $status (Optional) HTTP response status code from the request. + * @return object Contains an `header` property (HTTP headers as an associative array), a or `body` property, and an `status` code. + */ + public function __construct($header, $body, $status = null) + { + $this->header = $header; + $this->body = $body; + $this->status = $status; + return $this; + } + + /** + * Did we receive the status code we expected? + * + * @param integer|array $codes (Optional) The status code(s) to expect. Pass an for a single acceptable value, or an of integers for multiple acceptable values. + * @return boolean Whether we received the expected status code or not. + */ + public function isOK($codes = array(200, 201, 204, 206)) + { + if (is_array($codes)) { + return in_array($this->status, $codes); + } + return $this->status === $codes; + } } /** * Default BCS_RequestCore Exception. */ -class BCS_RequestCore_Exception extends \Exception { +class BcsRequestcoreException extends \Exception +{ } diff --git a/ThinkPHP/Library/Think/Upload/Driver/Ftp.class.php b/ThinkPHP/Library/Think/Upload/Driver/Ftp.class.php index fccf9a640..967e69284 100644 --- a/ThinkPHP/Library/Think/Upload/Driver/Ftp.class.php +++ b/ThinkPHP/Library/Think/Upload/Driver/Ftp.class.php @@ -10,7 +10,9 @@ // +---------------------------------------------------------------------- namespace Think\Upload\Driver; -class Ftp { + +class Ftp +{ /** * 上传文件根目录 * @var string @@ -41,12 +43,13 @@ class Ftp { * 构造函数,用于设置上传根路径 * @param array $config FTP配置 */ - public function __construct($config){ + public function __construct($config) + { /* 默认FTP配置 */ $this->config = array_merge($this->config, $config); /* 登录FTP服务器 */ - if(!$this->login()){ + if (!$this->login()) { E($this->error); } } @@ -56,11 +59,12 @@ public function __construct($config){ * @param string $rootpath 根目录 * @return boolean true-检测通过,false-检测失败 */ - public function checkRootPath($rootpath){ + public function checkRootPath($rootpath) + { /* 设置根目录 */ $this->rootPath = ftp_pwd($this->link) . '/' . ltrim($rootpath, '/'); - if(!@ftp_chdir($this->link, $this->rootPath)){ + if (!@ftp_chdir($this->link, $this->rootPath)) { $this->error = '上传根目录不存在!'; return false; } @@ -72,7 +76,8 @@ public function checkRootPath($rootpath){ * @param string $savepath 上传目录 * @return boolean 检测结果,true-通过,false-失败 */ - public function checkSavePath($savepath){ + public function checkSavePath($savepath) + { /* 检测并创建目录 */ if (!$this->mkdir($savepath)) { return false; @@ -88,7 +93,8 @@ public function checkSavePath($savepath){ * @param boolean $replace 同名文件是否覆盖 * @return boolean 保存状态,true-成功,false-失败 */ - public function save($file, $replace=true) { + public function save($file, $replace = true) + { $filename = $this->rootPath . $file['savepath'] . $file['savename']; /* 不覆盖同名文件 */ @@ -110,15 +116,16 @@ public function save($file, $replace=true) { * @param string $savepath 要创建的目录 * @return boolean 创建状态,true-成功,false-失败 */ - public function mkdir($savepath){ + public function mkdir($savepath) + { $dir = $this->rootPath . $savepath; - if(ftp_chdir($this->link, $dir)){ + if (ftp_chdir($this->link, $dir)) { return true; } - if(ftp_mkdir($this->link, $dir)){ + if (ftp_mkdir($this->link, $dir)) { return true; - } elseif($this->mkdir(dirname($savepath)) && ftp_mkdir($this->link, $dir)) { + } elseif ($this->mkdir(dirname($savepath)) && ftp_mkdir($this->link, $dir)) { return true; } else { $this->error = "目录 {$savepath} 创建失败!"; @@ -130,7 +137,8 @@ public function mkdir($savepath){ * 获取最后一次上传错误信息 * @return string 错误信息 */ - public function getError(){ + public function getError() + { return $this->error; } @@ -138,12 +146,13 @@ public function getError(){ * 登录到FTP服务器 * @return boolean true-登录成功,false-登录失败 */ - private function login(){ + private function login() + { extract($this->config); $this->link = ftp_connect($host, $port, $timeout); - if($this->link) { + if ($this->link) { if (ftp_login($this->link, $username, $password)) { - return true; + return true; } else { $this->error = "无法登录到FTP服务器:username - {$username}"; } @@ -156,7 +165,8 @@ private function login(){ /** * 析构方法,用于断开当前FTP连接 */ - public function __destruct() { + public function __destruct() + { ftp_close($this->link); } diff --git a/ThinkPHP/Library/Think/Upload/Driver/Local.class.php b/ThinkPHP/Library/Think/Upload/Driver/Local.class.php index 756b09193..6e78ce77a 100644 --- a/ThinkPHP/Library/Think/Upload/Driver/Local.class.php +++ b/ThinkPHP/Library/Think/Upload/Driver/Local.class.php @@ -10,7 +10,9 @@ // +---------------------------------------------------------------------- namespace Think\Upload\Driver; -class Local{ + +class Local +{ /** * 上传文件根目录 * @var string @@ -26,7 +28,8 @@ class Local{ /** * 构造函数,用于设置上传根路径 */ - public function __construct($config = null){ + public function __construct($config = null) + { } @@ -35,9 +38,10 @@ public function __construct($config = null){ * @param string $rootpath 根目录 * @return boolean true-检测通过,false-检测失败 */ - public function checkRootPath($rootpath){ - if(!(is_dir($rootpath) && is_writable($rootpath))){ - $this->error = '上传根目录不存在!请尝试手动创建:'.$rootpath; + public function checkRootPath($rootpath) + { + if (!(is_dir($rootpath) && is_writable($rootpath))) { + $this->error = '上传根目录不存在!请尝试手动创建:' . $rootpath; return false; } $this->rootPath = $rootpath; @@ -49,7 +53,8 @@ public function checkRootPath($rootpath){ * @param string $savepath 上传目录 * @return boolean 检测结果,true-通过,false-失败 */ - public function checkSavePath($savepath){ + public function checkSavePath($savepath) + { /* 检测并创建目录 */ if (!$this->mkdir($savepath)) { return false; @@ -70,10 +75,11 @@ public function checkSavePath($savepath){ * @param boolean $replace 同名文件是否覆盖 * @return boolean 保存状态,true-成功,false-失败 */ - public function save($file, $replace=true) { + public function save($file, $replace = true) + { $filename = $this->rootPath . $file['savepath'] . $file['savename']; - /* 不覆盖同名文件 */ + /* 不覆盖同名文件 */ if (!$replace && is_file($filename)) { $this->error = '存在同名文件' . $file['savename']; return false; @@ -84,7 +90,7 @@ public function save($file, $replace=true) { $this->error = '文件上传保存错误!'; return false; } - + return true; } @@ -93,13 +99,14 @@ public function save($file, $replace=true) { * @param string $savepath 要创建的目录 * @return boolean 创建状态,true-成功,false-失败 */ - public function mkdir($savepath){ + public function mkdir($savepath) + { $dir = $this->rootPath . $savepath; - if(is_dir($dir)){ + if (is_dir($dir)) { return true; } - if(mkdir($dir, 0777, true)){ + if (mkdir($dir, 0777, true)) { return true; } else { $this->error = "目录 {$savepath} 创建失败!"; @@ -111,7 +118,8 @@ public function mkdir($savepath){ * 获取最后一次上传错误信息 * @return string 错误信息 */ - public function getError(){ + public function getError() + { return $this->error; } diff --git a/ThinkPHP/Library/Think/Upload/Driver/Qiniu.class.php b/ThinkPHP/Library/Think/Upload/Driver/Qiniu.class.php index c745f9f0b..48f6c2e17 100644 --- a/ThinkPHP/Library/Think/Upload/Driver/Qiniu.class.php +++ b/ThinkPHP/Library/Think/Upload/Driver/Qiniu.class.php @@ -10,9 +10,11 @@ // +---------------------------------------------------------------------- namespace Think\Upload\Driver; + use Think\Upload\Driver\Qiniu\QiniuStorage; -class Qiniu{ +class Qiniu +{ /** * 上传文件根目录 * @var string @@ -26,18 +28,19 @@ class Qiniu{ private $error = ''; private $config = array( - 'secretKey' => '', //七牛服务器 - 'accessKey' => '', //七牛用户 - 'domain' => '', //七牛密码 - 'bucket' => '', //空间名称 - 'timeout' => 300, //超时时间 + 'secretKey' => '', //七牛服务器 + 'accessKey' => '', //七牛用户 + 'domain' => '', //七牛密码 + 'bucket' => '', //空间名称 + 'timeout' => 300, //超时时间 ); /** * 构造函数,用于设置上传根路径 * @param array $config FTP配置 */ - public function __construct($config){ + public function __construct($config) + { $this->config = array_merge($this->config, $config); /* 设置根目录 */ $this->qiniu = new QiniuStorage($config); @@ -48,7 +51,8 @@ public function __construct($config){ * @param string $rootpath 根目录 * @return boolean true-检测通过,false-检测失败 */ - public function checkRootPath($rootpath){ + public function checkRootPath($rootpath) + { $this->rootPath = trim($rootpath, './') . '/'; return true; } @@ -58,7 +62,8 @@ public function checkRootPath($rootpath){ * @param string $savepath 上传目录 * @return boolean 检测结果,true-通过,false-失败 */ - public function checkSavePath($savepath){ + public function checkSavePath($savepath) + { return true; } @@ -67,7 +72,8 @@ public function checkSavePath($savepath){ * @param string $savepath 目录名称 * @return boolean true-创建成功,false-创建失败 */ - public function mkdir($savepath){ + public function mkdir($savepath) + { return true; } @@ -77,26 +83,28 @@ public function mkdir($savepath){ * @param boolean $replace 同名文件是否覆盖 * @return boolean 保存状态,true-成功,false-失败 */ - public function save(&$file,$replace=true) { + public function save(&$file, $replace = true) + { $file['name'] = $file['savepath'] . $file['savename']; - $key = str_replace('/', '_', $file['name']); - $upfile = array( - 'name'=>'file', - 'fileName'=>$key, - 'fileBody'=>file_get_contents($file['tmp_name']) + $key = str_replace('/', '_', $file['name']); + $upfile = array( + 'name' => 'file', + 'fileName' => $key, + 'fileBody' => file_get_contents($file['tmp_name']), ); - $config = array(); - $result = $this->qiniu->upload($config, $upfile); - $url = $this->qiniu->downlink($key); + $config = array(); + $result = $this->qiniu->upload($config, $upfile); + $url = $this->qiniu->downlink($key); $file['url'] = $url; - return false ===$result ? false : true; + return false === $result ? false : true; } /** * 获取最后一次上传错误信息 * @return string 错误信息 */ - public function getError(){ + public function getError() + { return $this->qiniu->errorStr; } } diff --git a/ThinkPHP/Library/Think/Upload/Driver/Qiniu/QiniuStorage.class.php b/ThinkPHP/Library/Think/Upload/Driver/Qiniu/QiniuStorage.class.php index 472e0b46a..e6756c15c 100644 --- a/ThinkPHP/Library/Think/Upload/Driver/Qiniu/QiniuStorage.class.php +++ b/ThinkPHP/Library/Think/Upload/Driver/Qiniu/QiniuStorage.class.php @@ -1,333 +1,366 @@ sk = $config['secretKey']; - $this->ak = $config['accessKey']; - $this->domain = $config['domain']; - $this->bucket = $config['bucket']; - $this->timeout = isset($config['timeout'])? $config['timeout'] : 3600; - } - - static function sign($sk, $ak, $data){ - $sign = hash_hmac('sha1', $data, $sk, true); - return $ak . ':' . self::Qiniu_Encode($sign); - } - - static function signWithData($sk, $ak, $data){ - $data = self::Qiniu_Encode($data); - return self::sign($sk, $ak, $data) . ':' . $data; - } - - public function accessToken($url, $body=''){ - $parsed_url = parse_url($url); - $path = $parsed_url['path']; - $access = $path; - if (isset($parsed_url['query'])) { - $access .= "?" . $parsed_url['query']; - } - $access .= "\n"; - - if($body){ - $access .= $body; - } - return self::sign($this->sk, $this->ak, $access); - } - - public function UploadToken($sk ,$ak ,$param){ - $param['deadline'] = $param['Expires'] == 0? 3600: $param['Expires']; - $param['deadline'] += time(); - $data = array('scope'=> $this->bucket, 'deadline'=>$param['deadline']); - if (!empty($param['CallbackUrl'])) { - $data['callbackUrl'] = $param['CallbackUrl']; - } - if (!empty($param['CallbackBody'])) { - $data['callbackBody'] = $param['CallbackBody']; - } - if (!empty($param['ReturnUrl'])) { - $data['returnUrl'] = $param['ReturnUrl']; - } - if (!empty($param['ReturnBody'])) { - $data['returnBody'] = $param['ReturnBody']; - } - if (!empty($param['AsyncOps'])) { - $data['asyncOps'] = $param['AsyncOps']; - } - if (!empty($param['EndUser'])) { - $data['endUser'] = $param['EndUser']; - } - $data = json_encode($data); - return self::SignWithData($sk, $ak, $data); - } - - public function upload($config, $file){ - $uploadToken = $this->UploadToken($this->sk, $this->ak, $config); - - $url = "{$this->QINIU_UP_HOST}"; - $mimeBoundary = md5(microtime()); - $header = array('Content-Type'=>'multipart/form-data;boundary='.$mimeBoundary); - $data = array(); - - $fields = array( - 'token' => $uploadToken, - 'key' => $config['saveName']? : $file['fileName'], - ); - - if(is_array($config['custom_fields']) && $config['custom_fields'] !== array()){ - $fields = array_merge($fields, $config['custom_fields']); - } - - foreach ($fields as $name => $val) { - array_push($data, '--' . $mimeBoundary); - array_push($data, "Content-Disposition: form-data; name=\"$name\""); - array_push($data, ''); - array_push($data, $val); - } - - //文件 - array_push($data, '--' . $mimeBoundary); - $name = $file['name']; - $fileName = $file['fileName']; - $fileBody = $file['fileBody']; - $fileName = self::Qiniu_escapeQuotes($fileName); - array_push($data, "Content-Disposition: form-data; name=\"$name\"; filename=\"$fileName\""); - array_push($data, 'Content-Type: application/octet-stream'); - array_push($data, ''); - array_push($data, $fileBody); - - array_push($data, '--' . $mimeBoundary . '--'); - array_push($data, ''); - - $body = implode("\r\n", $data); - $response = $this->request($url, 'POST', $header, $body); - return $response; - } - - public function dealWithType($key, $type){ - $param = $this->buildUrlParam(); - $url = ''; - - switch($type){ - case 'img': - $url = $this->downLink($key); - if($param['imageInfo']){ - $url .= '?imageInfo'; - }else if($param['exif']){ - $url .= '?exif'; - }else if($param['imageView']){ - $url .= '?imageView/'.$param['mode']; - if($param['w']) - $url .= "/w/{$param['w']}"; - if($param['h']) - $url .= "/h/{$param['h']}"; - if($param['q']) - $url .= "/q/{$param['q']}"; - if($param['format']) - $url .= "/format/{$param['format']}"; - } - break; - case 'video': //TODO 视频处理 - case 'doc': - $url = $this->downLink($key); - $url .= '?md2html'; - if(isset($param['mode'])) - $url .= '/'.(int)$param['mode']; - if($param['cssurl']) - $url .= '/'. self::Qiniu_Encode($param['cssurl']); - break; - - } - return $url; - } - - public function buildUrlParam(){ - return $_REQUEST; - } - - //获取某个路径下的文件列表 - public function getList($query = array(), $path = ''){ - $query = array_merge(array('bucket'=>$this->bucket), $query); - $url = "{$this->QINIU_RSF_HOST}/list?".http_build_query($query); - $accessToken = $this->accessToken($url); - $response = $this->request($url, 'POST', array('Authorization'=>"QBox $accessToken")); - return $response; - } - - //获取某个文件的信息 - public function info($key){ - $key = trim($key); - $url = "{$this->QINIU_RS_HOST}/stat/" . self::Qiniu_Encode("{$this->bucket}:{$key}"); - $accessToken = $this->accessToken($url); - $response = $this->request($url, 'POST', array( - 'Authorization' => "QBox $accessToken", - )); - return $response; - } - - //获取文件下载资源链接 - public function downLink($key){ - $key = urlencode($key); - $key = self::Qiniu_escapeQuotes($key); - $url = "http://{$this->domain}/{$key}"; - return $url; - } - - //重命名单个文件 - public function rename($file, $new_file){ - $key = trim($file); - $url = "{$this->QINIU_RS_HOST}/move/" . self::Qiniu_Encode("{$this->bucket}:{$key}") .'/'. self::Qiniu_Encode("{$this->bucket}:{$new_file}"); - trace($url); - $accessToken = $this->accessToken($url); - $response = $this->request($url, 'POST', array('Authorization'=>"QBox $accessToken")); - return $response; - } - - //删除单个文件 - public function del($file){ - $key = trim($file); - $url = "{$this->QINIU_RS_HOST}/delete/" . self::Qiniu_Encode("{$this->bucket}:{$key}"); - $accessToken = $this->accessToken($url); - $response = $this->request($url, 'POST', array('Authorization'=>"QBox $accessToken")); - return $response; - } - - //批量删除文件 - public function delBatch($files){ - $url = $this->QINIU_RS_HOST . '/batch'; - $ops = array(); - foreach ($files as $file) { - $ops[] = "/delete/". self::Qiniu_Encode("{$this->bucket}:{$file}"); - } - $params = 'op=' . implode('&op=', $ops); - $url .= '?'.$params; - trace($url); - $accessToken = $this->accessToken($url); - $response = $this->request($url, 'POST', array('Authorization'=>"QBox $accessToken")); - return $response; - } - - static function Qiniu_Encode($str) {// URLSafeBase64Encode - $find = array('+', '/'); - $replace = array('-', '_'); - return str_replace($find, $replace, base64_encode($str)); - } - - static function Qiniu_escapeQuotes($str){ - $find = array("\\", "\""); - $replace = array("\\\\", "\\\""); - return str_replace($find, $replace, $str); - } - - /** - * 请求云服务器 - * @param string $path 请求的PATH - * @param string $method 请求方法 - * @param array $headers 请求header - * @param resource $body 上传文件资源 - * @return boolean - */ - private function request($path, $method, $headers = null, $body = null){ - $ch = curl_init($path); - - $_headers = array('Expect:'); - if (!is_null($headers) && is_array($headers)){ - foreach($headers as $k => $v) { - array_push($_headers, "{$k}: {$v}"); - } - } - - $length = 0; - $date = gmdate('D, d M Y H:i:s \G\M\T'); - - if (!is_null($body)) { - if(is_resource($body)){ - fseek($body, 0, SEEK_END); - $length = ftell($body); - fseek($body, 0); - - array_push($_headers, "Content-Length: {$length}"); - curl_setopt($ch, CURLOPT_INFILE, $body); - curl_setopt($ch, CURLOPT_INFILESIZE, $length); - } else { - $length = @strlen($body); - array_push($_headers, "Content-Length: {$length}"); - curl_setopt($ch, CURLOPT_POSTFIELDS, $body); - } - } else { - array_push($_headers, "Content-Length: {$length}"); - } - - // array_push($_headers, 'Authorization: ' . $this->sign($method, $uri, $date, $length)); - array_push($_headers, "Date: {$date}"); - - curl_setopt($ch, CURLOPT_HTTPHEADER, $_headers); - curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout); - curl_setopt($ch, CURLOPT_HEADER, 1); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); - curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0); - curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); - - if ($method == 'PUT' || $method == 'POST') { - curl_setopt($ch, CURLOPT_POST, 1); - } else { - curl_setopt($ch, CURLOPT_POST, 0); - } - - if ($method == 'HEAD') { - curl_setopt($ch, CURLOPT_NOBODY, true); - } - - $response = curl_exec($ch); - $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); - curl_close($ch); - list($header, $body) = explode("\r\n\r\n", $response, 2); - if ($status == 200) { - if ($method == 'GET') { - return $body; - } else { - return $this->response($response); - } - } else { - $this->error($header , $body); - return false; - } - } - - /** - * 获取响应数据 - * @param string $text 响应头字符串 - * @return array 响应数据列表 - */ - private function response($text){ - $headers = explode(PHP_EOL, $text); - $items = array(); - foreach($headers as $header) { - $header = trim($header); - if(strpos($header, '{') !== False){ - $items = json_decode($header, 1); - break; - } - } - return $items; - } - - /** - * 获取请求错误信息 - * @param string $header 请求返回头信息 - */ - private function error($header, $body) { - list($status, $stash) = explode("\r\n", $header, 2); - list($v, $code, $message) = explode(" ", $status, 3); - $message = is_null($message) ? 'File Not Found' : "[{$status}]:{$message}]"; - $this->error = $message; - $this->errorStr = json_decode($body ,1); - $this->errorStr = $this->errorStr['error']; - } - } +namespace Think\Upload\Driver\Qiniu; + +class QiniuStorage +{ + + public $QINIU_RSF_HOST = 'http://rsf.qbox.me'; + public $QINIU_RS_HOST = 'http://rs.qbox.me'; + public $QINIU_UP_HOST = 'http://up.qiniu.com'; + public $timeout = ''; + + public function __construct($config) + { + $this->sk = $config['secretKey']; + $this->ak = $config['accessKey']; + $this->domain = $config['domain']; + $this->bucket = $config['bucket']; + $this->timeout = isset($config['timeout']) ? $config['timeout'] : 3600; + } + + public static function sign($sk, $ak, $data) + { + $sign = hash_hmac('sha1', $data, $sk, true); + return $ak . ':' . self::qiniuEncode($sign); + } + + public static function signWithData($sk, $ak, $data) + { + $data = self::qiniuEncode($data); + return self::sign($sk, $ak, $data) . ':' . $data; + } + + public function accessToken($url, $body = '') + { + $parsed_url = parse_url($url); + $path = $parsed_url['path']; + $access = $path; + if (isset($parsed_url['query'])) { + $access .= "?" . $parsed_url['query']; + } + $access .= "\n"; + + if ($body) { + $access .= $body; + } + return self::sign($this->sk, $this->ak, $access); + } + + public function UploadToken($sk, $ak, $param) + { + $param['deadline'] = 0 == $param['Expires'] ? 3600 : $param['Expires']; + $param['deadline'] += time(); + $data = array('scope' => $this->bucket, 'deadline' => $param['deadline']); + if (!empty($param['CallbackUrl'])) { + $data['callbackUrl'] = $param['CallbackUrl']; + } + if (!empty($param['CallbackBody'])) { + $data['callbackBody'] = $param['CallbackBody']; + } + if (!empty($param['ReturnUrl'])) { + $data['returnUrl'] = $param['ReturnUrl']; + } + if (!empty($param['ReturnBody'])) { + $data['returnBody'] = $param['ReturnBody']; + } + if (!empty($param['AsyncOps'])) { + $data['asyncOps'] = $param['AsyncOps']; + } + if (!empty($param['EndUser'])) { + $data['endUser'] = $param['EndUser']; + } + $data = json_encode($data); + return self::SignWithData($sk, $ak, $data); + } + + public function upload($config, $file) + { + $uploadToken = $this->UploadToken($this->sk, $this->ak, $config); + + $url = "{$this->QINIU_UP_HOST}"; + $mimeBoundary = md5(microtime()); + $header = array('Content-Type' => 'multipart/form-data;boundary=' . $mimeBoundary); + $data = array(); + + $fields = array( + 'token' => $uploadToken, + 'key' => $config['saveName'] ?: $file['fileName'], + ); + + if (is_array($config['custom_fields']) && array() !== $config['custom_fields']) { + $fields = array_merge($fields, $config['custom_fields']); + } + + foreach ($fields as $name => $val) { + array_push($data, '--' . $mimeBoundary); + array_push($data, "Content-Disposition: form-data; name=\"$name\""); + array_push($data, ''); + array_push($data, $val); + } + + //文件 + array_push($data, '--' . $mimeBoundary); + $name = $file['name']; + $fileName = $file['fileName']; + $fileBody = $file['fileBody']; + $fileName = self::qiniuEscapequotes($fileName); + array_push($data, "Content-Disposition: form-data; name=\"$name\"; filename=\"$fileName\""); + array_push($data, 'Content-Type: application/octet-stream'); + array_push($data, ''); + array_push($data, $fileBody); + + array_push($data, '--' . $mimeBoundary . '--'); + array_push($data, ''); + + $body = implode("\r\n", $data); + $response = $this->request($url, 'POST', $header, $body); + return $response; + } + + public function dealWithType($key, $type) + { + $param = $this->buildUrlParam(); + $url = ''; + + switch ($type) { + case 'img': + $url = $this->downLink($key); + if ($param['imageInfo']) { + $url .= '?imageInfo'; + } else if ($param['exif']) { + $url .= '?exif'; + } else if ($param['imageView']) { + $url .= '?imageView/' . $param['mode']; + if ($param['w']) { + $url .= "/w/{$param['w']}"; + } + + if ($param['h']) { + $url .= "/h/{$param['h']}"; + } + + if ($param['q']) { + $url .= "/q/{$param['q']}"; + } + + if ($param['format']) { + $url .= "/format/{$param['format']}"; + } + + } + break; + case 'video': //TODO 视频处理 + case 'doc': + $url = $this->downLink($key); + $url .= '?md2html'; + if (isset($param['mode'])) { + $url .= '/' . (int) $param['mode']; + } + + if ($param['cssurl']) { + $url .= '/' . self::qiniuEncode($param['cssurl']); + } + + break; + + } + return $url; + } + + public function buildUrlParam() + { + return $_REQUEST; + } + + //获取某个路径下的文件列表 + public function getList($query = array(), $path = '') + { + $query = array_merge(array('bucket' => $this->bucket), $query); + $url = "{$this->QINIU_RSF_HOST}/list?" . http_build_query($query); + $accessToken = $this->accessToken($url); + $response = $this->request($url, 'POST', array('Authorization' => "QBox $accessToken")); + return $response; + } + + //获取某个文件的信息 + public function info($key) + { + $key = trim($key); + $url = "{$this->QINIU_RS_HOST}/stat/" . self::qiniuEncode("{$this->bucket}:{$key}"); + $accessToken = $this->accessToken($url); + $response = $this->request($url, 'POST', array( + 'Authorization' => "QBox $accessToken", + )); + return $response; + } + + //获取文件下载资源链接 + public function downLink($key) + { + $key = urlencode($key); + $key = self::qiniuEscapequotes($key); + $url = "http://{$this->domain}/{$key}"; + return $url; + } + + //重命名单个文件 + public function rename($file, $new_file) + { + $key = trim($file); + $url = "{$this->QINIU_RS_HOST}/move/" . self::qiniuEncode("{$this->bucket}:{$key}") . '/' . self::qiniuEncode("{$this->bucket}:{$new_file}"); + trace($url); + $accessToken = $this->accessToken($url); + $response = $this->request($url, 'POST', array('Authorization' => "QBox $accessToken")); + return $response; + } + + //删除单个文件 + public function del($file) + { + $key = trim($file); + $url = "{$this->QINIU_RS_HOST}/delete/" . self::qiniuEncode("{$this->bucket}:{$key}"); + $accessToken = $this->accessToken($url); + $response = $this->request($url, 'POST', array('Authorization' => "QBox $accessToken")); + return $response; + } + + //批量删除文件 + public function delBatch($files) + { + $url = $this->QINIU_RS_HOST . '/batch'; + $ops = array(); + foreach ($files as $file) { + $ops[] = "/delete/" . self::qiniuEncode("{$this->bucket}:{$file}"); + } + $params = 'op=' . implode('&op=', $ops); + $url .= '?' . $params; + trace($url); + $accessToken = $this->accessToken($url); + $response = $this->request($url, 'POST', array('Authorization' => "QBox $accessToken")); + return $response; + } + + public static function qiniuEncode($str) + { +// URLSafeBase64Encode + $find = array('+', '/'); + $replace = array('-', '_'); + return str_replace($find, $replace, base64_encode($str)); + } + + public static function qiniuEscapequotes($str) + { + $find = array("\\", "\""); + $replace = array("\\\\", "\\\""); + return str_replace($find, $replace, $str); + } + + /** + * 请求云服务器 + * @param string $path 请求的PATH + * @param string $method 请求方法 + * @param array $headers 请求header + * @param resource $body 上传文件资源 + * @return boolean + */ + private function request($path, $method, $headers = null, $body = null) + { + $ch = curl_init($path); + + $_headers = array('Expect:'); + if (!is_null($headers) && is_array($headers)) { + foreach ($headers as $k => $v) { + array_push($_headers, "{$k}: {$v}"); + } + } + + $length = 0; + $date = gmdate('D, d M Y H:i:s \G\M\T'); + + if (!is_null($body)) { + if (is_resource($body)) { + fseek($body, 0, SEEK_END); + $length = ftell($body); + fseek($body, 0); + + array_push($_headers, "Content-Length: {$length}"); + curl_setopt($ch, CURLOPT_INFILE, $body); + curl_setopt($ch, CURLOPT_INFILESIZE, $length); + } else { + $length = @strlen($body); + array_push($_headers, "Content-Length: {$length}"); + curl_setopt($ch, CURLOPT_POSTFIELDS, $body); + } + } else { + array_push($_headers, "Content-Length: {$length}"); + } + + // array_push($_headers, 'Authorization: ' . $this->sign($method, $uri, $date, $length)); + array_push($_headers, "Date: {$date}"); + + curl_setopt($ch, CURLOPT_HTTPHEADER, $_headers); + curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout); + curl_setopt($ch, CURLOPT_HEADER, 1); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0); + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); + + if ('PUT' == $method || 'POST' == $method) { + curl_setopt($ch, CURLOPT_POST, 1); + } else { + curl_setopt($ch, CURLOPT_POST, 0); + } + + if ('HEAD' == $method) { + curl_setopt($ch, CURLOPT_NOBODY, true); + } + + $response = curl_exec($ch); + $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); + curl_close($ch); + list($header, $body) = explode("\r\n\r\n", $response, 2); + if (200 == $status) { + if ('GET' == $method) { + return $body; + } else { + return $this->response($response); + } + } else { + $this->error($header, $body); + return false; + } + } + + /** + * 获取响应数据 + * @param string $text 响应头字符串 + * @return array 响应数据列表 + */ + private function response($text) + { + $headers = explode(PHP_EOL, $text); + $items = array(); + foreach ($headers as $header) { + $header = trim($header); + if (strpos($header, '{') !== false) { + $items = json_decode($header, 1); + break; + } + } + return $items; + } + + /** + * 获取请求错误信息 + * @param string $header 请求返回头信息 + */ + private function error($header, $body) + { + list($status, $stash) = explode("\r\n", $header, 2); + list($v, $code, $message) = explode(" ", $status, 3); + $message = is_null($message) ? 'File Not Found' : "[{$status}]:{$message}]"; + $this->error = $message; + $this->errorStr = json_decode($body, 1); + $this->errorStr = $this->errorStr['error']; + } +} diff --git a/ThinkPHP/Library/Think/Upload/Driver/Sae.class.php b/ThinkPHP/Library/Think/Upload/Driver/Sae.class.php index 82c77d699..efa4df03a 100644 --- a/ThinkPHP/Library/Think/Upload/Driver/Sae.class.php +++ b/ThinkPHP/Library/Think/Upload/Driver/Sae.class.php @@ -10,28 +10,31 @@ // +---------------------------------------------------------------------- namespace Think\Upload\Driver; -class Sae{ + +class Sae +{ /** * Storage的Domain * @var string */ - private $domain = ''; + private $domain = ''; - private $rootPath = ''; + private $rootPath = ''; /** * 本地上传错误信息 * @var string */ - private $error = ''; + private $error = ''; /** - * 构造函数,设置storage的domain, 如果有传配置,则domain为配置项,如果没有传domain为第一个路径的目录名称。 - * @param mixed $config 上传配置 + * 构造函数,设置storage的domain, 如果有传配置,则domain为配置项,如果没有传domain为第一个路径的目录名称。 + * @param mixed $config 上传配置 */ - public function __construct($config = null){ - if(is_array($config) && !empty($config['domain'])){ - $this->domain = strtolower($config['domain']); + public function __construct($config = null) + { + if (is_array($config) && !empty($config['domain'])) { + $this->domain = strtolower($config['domain']); } } @@ -40,19 +43,20 @@ public function __construct($config = null){ * @param string $rootpath 根目录 * @return boolean true-检测通过,false-检测失败 */ - public function checkRootPath($rootpath){ - $rootpath = trim($rootpath,'./'); - if(!$this->domain){ - $rootpath = explode('/', $rootpath); + public function checkRootPath($rootpath) + { + $rootpath = trim($rootpath, './'); + if (!$this->domain) { + $rootpath = explode('/', $rootpath); $this->domain = strtolower(array_shift($rootpath)); - $rootpath = implode('/', $rootpath); + $rootpath = implode('/', $rootpath); } - $this->rootPath = $rootpath; - $st = new \SaeStorage(); - if(false===$st->getDomainCapacity($this->domain)){ - $this->error = '您好像没有建立Storage的domain['.$this->domain.']'; - return false; + $this->rootPath = $rootpath; + $st = new \SaeStorage(); + if (false === $st->getDomainCapacity($this->domain)) { + $this->error = '您好像没有建立Storage的domain[' . $this->domain . ']'; + return false; } return true; } @@ -62,7 +66,8 @@ public function checkRootPath($rootpath){ * @param string $savepath 上传目录 * @return boolean 检测结果,true-通过,false-失败 */ - public function checkSavePath($savepath){ + public function checkSavePath($savepath) + { return true; } @@ -72,26 +77,28 @@ public function checkSavePath($savepath){ * @param boolean $replace 同名文件是否覆盖 * @return boolean 保存状态,true-成功,false-失败 */ - public function save(&$file, $replace=true) { - $filename = ltrim($this->rootPath .'/'. $file['savepath'] . $file['savename'],'/'); - $st = new \SaeStorage(); - /* 不覆盖同名文件 */ - if (!$replace && $st->fileExists($this->domain,$filename)) { + public function save(&$file, $replace = true) + { + $filename = ltrim($this->rootPath . '/' . $file['savepath'] . $file['savename'], '/'); + $st = new \SaeStorage(); + /* 不覆盖同名文件 */ + if (!$replace && $st->fileExists($this->domain, $filename)) { $this->error = '存在同名文件' . $file['savename']; return false; } /* 移动文件 */ - if (!$st->upload($this->domain,$filename,$file['tmp_name'])) { - $this->error = '文件上传保存错误!['.$st->errno().']:'.$st->errmsg(); + if (!$st->upload($this->domain, $filename, $file['tmp_name'])) { + $this->error = '文件上传保存错误![' . $st->errno() . ']:' . $st->errmsg(); return false; - }else{ + } else { $file['url'] = $st->getUrl($this->domain, $filename); } return true; } - public function mkdir(){ + public function mkdir() + { return true; } @@ -99,7 +106,8 @@ public function mkdir(){ * 获取最后一次上传错误信息 * @return string 错误信息 */ - public function getError(){ + public function getError() + { return $this->error; } diff --git a/ThinkPHP/Library/Think/Upload/Driver/Upyun.class.php b/ThinkPHP/Library/Think/Upload/Driver/Upyun.class.php index c15952633..96645985b 100644 --- a/ThinkPHP/Library/Think/Upload/Driver/Upyun.class.php +++ b/ThinkPHP/Library/Think/Upload/Driver/Upyun.class.php @@ -10,7 +10,9 @@ // +---------------------------------------------------------------------- namespace Think\Upload\Driver; -class Upyun{ + +class Upyun +{ /** * 上传文件根目录 * @var string @@ -35,9 +37,10 @@ class Upyun{ * 构造函数,用于设置上传根路径 * @param array $config FTP配置 */ - public function __construct($config){ + public function __construct($config) + { /* 默认FTP配置 */ - $this->config = array_merge($this->config, $config); + $this->config = array_merge($this->config, $config); $this->config['password'] = md5($this->config['password']); } @@ -46,7 +49,8 @@ public function __construct($config){ * @param string $rootpath 根目录 * @return boolean true-检测通过,false-检测失败 */ - public function checkRootPath($rootpath){ + public function checkRootPath($rootpath) + { /* 设置根目录 */ $this->rootPath = trim($rootpath, './') . '/'; return true; @@ -57,7 +61,8 @@ public function checkRootPath($rootpath){ * @param string $savepath 上传目录 * @return boolean 检测结果,true-通过,false-失败 */ - public function checkSavePath($savepath){ + public function checkSavePath($savepath) + { return true; } @@ -66,7 +71,8 @@ public function checkSavePath($savepath){ * @param string $savepath 目录名称 * @return boolean true-创建成功,false-创建失败 */ - public function mkdir($savepath){ + public function mkdir($savepath) + { return true; } @@ -76,11 +82,12 @@ public function mkdir($savepath){ * @param boolean $replace 同名文件是否覆盖 * @return boolean 保存状态,true-成功,false-失败 */ - public function save($file, $replace = true) { + public function save($file, $replace = true) + { $header['Content-Type'] = $file['type']; - $header['Content-MD5'] = $file['md5']; - $header['Mkdir'] = 'true'; - $resource = fopen($file['tmp_name'], 'r'); + $header['Content-MD5'] = $file['md5']; + $header['Mkdir'] = 'true'; + $resource = fopen($file['tmp_name'], 'r'); $save = $this->rootPath . $file['savepath'] . $file['savename']; $data = $this->request($save, 'PUT', $header, $resource); @@ -91,7 +98,8 @@ public function save($file, $replace = true) { * 获取最后一次上传错误信息 * @return string 错误信息 */ - public function getError(){ + public function getError() + { return $this->error; } @@ -103,13 +111,14 @@ public function getError(){ * @param resource $body 上传文件资源 * @return boolean */ - private function request($path, $method, $headers = null, $body = null){ + private function request($path, $method, $headers = null, $body = null) + { $uri = "/{$this->config['bucket']}/{$path}"; $ch = curl_init($this->config['host'] . $uri); $_headers = array('Expect:'); - if (!is_null($headers) && is_array($headers)){ - foreach($headers as $k => $v) { + if (!is_null($headers) && is_array($headers)) { + foreach ($headers as $k => $v) { array_push($_headers, "{$k}: {$v}"); } } @@ -118,7 +127,7 @@ private function request($path, $method, $headers = null, $body = null){ $date = gmdate('D, d M Y H:i:s \G\M\T'); if (!is_null($body)) { - if(is_resource($body)){ + if (is_resource($body)) { fseek($body, 0, SEEK_END); $length = ftell($body); fseek($body, 0); @@ -145,13 +154,13 @@ private function request($path, $method, $headers = null, $body = null){ curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); - if ($method == 'PUT' || $method == 'POST') { + if ('PUT' == $method || 'POST' == $method) { curl_setopt($ch, CURLOPT_POST, 1); } else { curl_setopt($ch, CURLOPT_POST, 0); } - if ($method == 'HEAD') { + if ('HEAD' == $method) { curl_setopt($ch, CURLOPT_NOBODY, true); } @@ -160,8 +169,8 @@ private function request($path, $method, $headers = null, $body = null){ curl_close($ch); list($header, $body) = explode("\r\n\r\n", $response, 2); - if ($status == 200) { - if ($method == 'GET') { + if (200 == $status) { + if ('GET' == $method) { return $body; } else { $data = $this->response($header); @@ -178,14 +187,15 @@ private function request($path, $method, $headers = null, $body = null){ * @param string $text 响应头字符串 * @return array 响应数据列表 */ - private function response($text){ + private function response($text) + { $headers = explode("\r\n", $text); - $items = array(); - foreach($headers as $header) { + $items = array(); + foreach ($headers as $header) { $header = trim($header); - if(strpos($header, 'x-upyun') !== False){ - list($k, $v) = explode(':', $header); - $items[trim($k)] = in_array(substr($k,8,5), array('width','heigh','frame')) ? intval($v) : trim($v); + if (strpos($header, 'x-upyun') !== false) { + list($k, $v) = explode(':', $header); + $items[trim($k)] = in_array(substr($k, 8, 5), array('width', 'heigh', 'frame')) ? intval($v) : trim($v); } } return $items; @@ -199,7 +209,8 @@ private function response($text){ * @param integer $length 请求内容大小 * @return string 请求签名 */ - private function sign($method, $uri, $date, $length){ + private function sign($method, $uri, $date, $length) + { $sign = "{$method}&{$uri}&{$date}&{$length}&{$this->config['password']}"; return 'UpYun ' . $this->config['username'] . ':' . md5($sign); } @@ -208,11 +219,12 @@ private function sign($method, $uri, $date, $length){ * 获取请求错误信息 * @param string $header 请求返回头信息 */ - private function error($header) { - list($status, $stash) = explode("\r\n", $header, 2); + private function error($header) + { + list($status, $stash) = explode("\r\n", $header, 2); list($v, $code, $message) = explode(" ", $status, 3); - $message = is_null($message) ? 'File Not Found' : "[{$status}]:{$message}"; - $this->error = $message; + $message = is_null($message) ? 'File Not Found' : "[{$status}]:{$message}"; + $this->error = $message; } } diff --git a/ThinkPHP/Library/Think/Verify.class.php b/ThinkPHP/Library/Think/Verify.class.php index 6e5e38ae8..036457bc4 100644 --- a/ThinkPHP/Library/Think/Verify.class.php +++ b/ThinkPHP/Library/Think/Verify.class.php @@ -11,67 +11,72 @@ namespace Think; -class Verify { - protected $config = array( - 'seKey' => 'ThinkPHP.CN', // 验证码加密密钥 - 'codeSet' => '2345678abcdefhijkmnpqrstuvwxyzABCDEFGHJKLMNPQRTUVWXY', // 验证码字符集合 - 'expire' => 1800, // 验证码过期时间(s) - 'useZh' => false, // 使用中文验证码 - 'zhSet' => '们以我到他会作时要动国产的一是工就年阶义发成部民可出能方进在了不和有大这主中人上为来分生对于学下级地个用同行面说种过命度革而多子后自社加小机也经力线本电高量长党得实家定深法表着水理化争现所二起政三好十战无农使性前等反体合斗路图把结第里正新开论之物从当两些还天资事队批点育重其思与间内去因件日利相由压员气业代全组数果期导平各基或月毛然如应形想制心样干都向变关问比展那它最及外没看治提五解系林者米群头意只明四道马认次文通但条较克又公孔领军流入接席位情运器并飞原油放立题质指建区验活众很教决特此常石强极土少已根共直团统式转别造切九你取西持总料连任志观调七么山程百报更见必真保热委手改管处己将修支识病象几先老光专什六型具示复安带每东增则完风回南广劳轮科北打积车计给节做务被整联步类集号列温装即毫知轴研单色坚据速防史拉世设达尔场织历花受求传口断况采精金界品判参层止边清至万确究书术状厂须离再目海交权且儿青才证低越际八试规斯近注办布门铁需走议县兵固除般引齿千胜细影济白格效置推空配刀叶率述今选养德话查差半敌始片施响收华觉备名红续均药标记难存测士身紧液派准斤角降维板许破述技消底床田势端感往神便贺村构照容非搞亚磨族火段算适讲按值美态黄易彪服早班麦削信排台声该击素张密害侯草何树肥继右属市严径螺检左页抗苏显苦英快称坏移约巴材省黑武培著河帝仅针怎植京助升王眼她抓含苗副杂普谈围食射源例致酸旧却充足短划剂宣环落首尺波承粉践府鱼随考刻靠够满夫失包住促枝局菌杆周护岩师举曲春元超负砂封换太模贫减阳扬江析亩木言球朝医校古呢稻宋听唯输滑站另卫字鼓刚写刘微略范供阿块某功套友限项余倒卷创律雨让骨远帮初皮播优占死毒圈伟季训控激找叫云互跟裂粮粒母练塞钢顶策双留误础吸阻故寸盾晚丝女散焊功株亲院冷彻弹错散商视艺灭版烈零室轻血倍缺厘泵察绝富城冲喷壤简否柱李望盘磁雄似困巩益洲脱投送奴侧润盖挥距触星松送获兴独官混纪依未突架宽冬章湿偏纹吃执阀矿寨责熟稳夺硬价努翻奇甲预职评读背协损棉侵灰虽矛厚罗泥辟告卵箱掌氧恩爱停曾溶营终纲孟钱待尽俄缩沙退陈讨奋械载胞幼哪剥迫旋征槽倒握担仍呀鲜吧卡粗介钻逐弱脚怕盐末阴丰雾冠丙街莱贝辐肠付吉渗瑞惊顿挤秒悬姆烂森糖圣凹陶词迟蚕亿矩康遵牧遭幅园腔订香肉弟屋敏恢忘编印蜂急拿扩伤飞露核缘游振操央伍域甚迅辉异序免纸夜乡久隶缸夹念兰映沟乙吗儒杀汽磷艰晶插埃燃欢铁补咱芽永瓦倾阵碳演威附牙芽永瓦斜灌欧献顺猪洋腐请透司危括脉宜笑若尾束壮暴企菜穗楚汉愈绿拖牛份染既秋遍锻玉夏疗尖殖井费州访吹荣铜沿替滚客召旱悟刺脑措贯藏敢令隙炉壳硫煤迎铸粘探临薄旬善福纵择礼愿伏残雷延烟句纯渐耕跑泽慢栽鲁赤繁境潮横掉锥希池败船假亮谓托伙哲怀割摆贡呈劲财仪沉炼麻罪祖息车穿货销齐鼠抽画饲龙库守筑房歌寒喜哥洗蚀废纳腹乎录镜妇恶脂庄擦险赞钟摇典柄辩竹谷卖乱虚桥奥伯赶垂途额壁网截野遗静谋弄挂课镇妄盛耐援扎虑键归符庆聚绕摩忙舞遇索顾胶羊湖钉仁音迹碎伸灯避泛亡答勇频皇柳哈揭甘诺概宪浓岛袭谁洪谢炮浇斑讯懂灵蛋闭孩释乳巨徒私银伊景坦累匀霉杜乐勒隔弯绩招绍胡呼痛峰零柴簧午跳居尚丁秦稍追梁折耗碱殊岗挖氏刃剧堆赫荷胸衡勤膜篇登驻案刊秧缓凸役剪川雪链渔啦脸户洛孢勃盟买杨宗焦赛旗滤硅炭股坐蒸凝竟陷枪黎救冒暗洞犯筒您宋弧爆谬涂味津臂障褐陆啊健尊豆拔莫抵桑坡缝警挑污冰柬嘴啥饭塑寄赵喊垫丹渡耳刨虎笔稀昆浪萨茶滴浅拥穴覆伦娘吨浸袖珠雌妈紫戏塔锤震岁貌洁剖牢锋疑霸闪埔猛诉刷狠忽灾闹乔唐漏闻沈熔氯荒茎男凡抢像浆旁玻亦忠唱蒙予纷捕锁尤乘乌智淡允叛畜俘摸锈扫毕璃宝芯爷鉴秘净蒋钙肩腾枯抛轨堂拌爸循诱祝励肯酒绳穷塘燥泡袋朗喂铝软渠颗惯贸粪综墙趋彼届墨碍启逆卸航衣孙龄岭骗休借', // 中文验证码字符串 - 'useImgBg' => false, // 使用背景图片 - 'fontSize' => 25, // 验证码字体大小(px) - 'useCurve' => true, // 是否画混淆曲线 - 'useNoise' => true, // 是否添加杂点 - 'imageH' => 0, // 验证码图片高度 - 'imageW' => 0, // 验证码图片宽度 - 'length' => 5, // 验证码位数 - 'fontttf' => '', // 验证码字体,不设置随机获取 - 'bg' => array(243, 251, 254), // 背景颜色 - 'reset' => true, // 验证成功后是否重置 - ); - - private $_image = NULL; // 验证码图片实例 - private $_color = NULL; // 验证码字体颜色 +class Verify +{ + protected $config = array( + 'seKey' => 'ThinkPHP.CN', // 验证码加密密钥 + 'codeSet' => '2345678abcdefhijkmnpqrstuvwxyzABCDEFGHJKLMNPQRTUVWXY', // 验证码字符集合 + 'expire' => 1800, // 验证码过期时间(s) + 'useZh' => false, // 使用中文验证码 + 'zhSet' => '们以我到他会作时要动国产的一是工就年阶义发成部民可出能方进在了不和有大这主中人上为来分生对于学下级地个用同行面说种过命度革而多子后自社加小机也经力线本电高量长党得实家定深法表着水理化争现所二起政三好十战无农使性前等反体合斗路图把结第里正新开论之物从当两些还天资事队批点育重其思与间内去因件日利相由压员气业代全组数果期导平各基或月毛然如应形想制心样干都向变关问比展那它最及外没看治提五解系林者米群头意只明四道马认次文通但条较克又公孔领军流入接席位情运器并飞原油放立题质指建区验活众很教决特此常石强极土少已根共直团统式转别造切九你取西持总料连任志观调七么山程百报更见必真保热委手改管处己将修支识病象几先老光专什六型具示复安带每东增则完风回南广劳轮科北打积车计给节做务被整联步类集号列温装即毫知轴研单色坚据速防史拉世设达尔场织历花受求传口断况采精金界品判参层止边清至万确究书术状厂须离再目海交权且儿青才证低越际八试规斯近注办布门铁需走议县兵固除般引齿千胜细影济白格效置推空配刀叶率述今选养德话查差半敌始片施响收华觉备名红续均药标记难存测士身紧液派准斤角降维板许破述技消底床田势端感往神便贺村构照容非搞亚磨族火段算适讲按值美态黄易彪服早班麦削信排台声该击素张密害侯草何树肥继右属市严径螺检左页抗苏显苦英快称坏移约巴材省黑武培著河帝仅针怎植京助升王眼她抓含苗副杂普谈围食射源例致酸旧却充足短划剂宣环落首尺波承粉践府鱼随考刻靠够满夫失包住促枝局菌杆周护岩师举曲春元超负砂封换太模贫减阳扬江析亩木言球朝医校古呢稻宋听唯输滑站另卫字鼓刚写刘微略范供阿块某功套友限项余倒卷创律雨让骨远帮初皮播优占死毒圈伟季训控激找叫云互跟裂粮粒母练塞钢顶策双留误础吸阻故寸盾晚丝女散焊功株亲院冷彻弹错散商视艺灭版烈零室轻血倍缺厘泵察绝富城冲喷壤简否柱李望盘磁雄似困巩益洲脱投送奴侧润盖挥距触星松送获兴独官混纪依未突架宽冬章湿偏纹吃执阀矿寨责熟稳夺硬价努翻奇甲预职评读背协损棉侵灰虽矛厚罗泥辟告卵箱掌氧恩爱停曾溶营终纲孟钱待尽俄缩沙退陈讨奋械载胞幼哪剥迫旋征槽倒握担仍呀鲜吧卡粗介钻逐弱脚怕盐末阴丰雾冠丙街莱贝辐肠付吉渗瑞惊顿挤秒悬姆烂森糖圣凹陶词迟蚕亿矩康遵牧遭幅园腔订香肉弟屋敏恢忘编印蜂急拿扩伤飞露核缘游振操央伍域甚迅辉异序免纸夜乡久隶缸夹念兰映沟乙吗儒杀汽磷艰晶插埃燃欢铁补咱芽永瓦倾阵碳演威附牙芽永瓦斜灌欧献顺猪洋腐请透司危括脉宜笑若尾束壮暴企菜穗楚汉愈绿拖牛份染既秋遍锻玉夏疗尖殖井费州访吹荣铜沿替滚客召旱悟刺脑措贯藏敢令隙炉壳硫煤迎铸粘探临薄旬善福纵择礼愿伏残雷延烟句纯渐耕跑泽慢栽鲁赤繁境潮横掉锥希池败船假亮谓托伙哲怀割摆贡呈劲财仪沉炼麻罪祖息车穿货销齐鼠抽画饲龙库守筑房歌寒喜哥洗蚀废纳腹乎录镜妇恶脂庄擦险赞钟摇典柄辩竹谷卖乱虚桥奥伯赶垂途额壁网截野遗静谋弄挂课镇妄盛耐援扎虑键归符庆聚绕摩忙舞遇索顾胶羊湖钉仁音迹碎伸灯避泛亡答勇频皇柳哈揭甘诺概宪浓岛袭谁洪谢炮浇斑讯懂灵蛋闭孩释乳巨徒私银伊景坦累匀霉杜乐勒隔弯绩招绍胡呼痛峰零柴簧午跳居尚丁秦稍追梁折耗碱殊岗挖氏刃剧堆赫荷胸衡勤膜篇登驻案刊秧缓凸役剪川雪链渔啦脸户洛孢勃盟买杨宗焦赛旗滤硅炭股坐蒸凝竟陷枪黎救冒暗洞犯筒您宋弧爆谬涂味津臂障褐陆啊健尊豆拔莫抵桑坡缝警挑污冰柬嘴啥饭塑寄赵喊垫丹渡耳刨虎笔稀昆浪萨茶滴浅拥穴覆伦娘吨浸袖珠雌妈紫戏塔锤震岁貌洁剖牢锋疑霸闪埔猛诉刷狠忽灾闹乔唐漏闻沈熔氯荒茎男凡抢像浆旁玻亦忠唱蒙予纷捕锁尤乘乌智淡允叛畜俘摸锈扫毕璃宝芯爷鉴秘净蒋钙肩腾枯抛轨堂拌爸循诱祝励肯酒绳穷塘燥泡袋朗喂铝软渠颗惯贸粪综墙趋彼届墨碍启逆卸航衣孙龄岭骗休借', // 中文验证码字符串 + 'useImgBg' => false, // 使用背景图片 + 'fontSize' => 25, // 验证码字体大小(px) + 'useCurve' => true, // 是否画混淆曲线 + 'useNoise' => true, // 是否添加杂点 + 'imageH' => 0, // 验证码图片高度 + 'imageW' => 0, // 验证码图片宽度 + 'length' => 5, // 验证码位数 + 'fontttf' => '', // 验证码字体,不设置随机获取 + 'bg' => array(243, 251, 254), // 背景颜色 + 'reset' => true, // 验证成功后是否重置 + ); + + private $_image = null; // 验证码图片实例 + private $_color = null; // 验证码字体颜色 /** * 架构方法 设置参数 - * @access public + * @access public * @param array $config 配置参数 - */ - public function __construct($config=array()){ - $this->config = array_merge($this->config, $config); + */ + public function __construct($config = array()) + { + $this->config = array_merge($this->config, $config); } /** * 使用 $this->name 获取配置 - * @access public + * @access public * @param string $name 配置名称 * @return multitype 配置值 */ - public function __get($name) { + public function __get($name) + { return $this->config[$name]; } /** * 设置验证码配置 - * @access public + * @access public * @param string $name 配置名称 - * @param string $value 配置值 + * @param string $value 配置值 * @return void */ - public function __set($name,$value){ - if(isset($this->config[$name])) { - $this->config[$name] = $value; + public function __set($name, $value) + { + if (isset($this->config[$name])) { + $this->config[$name] = $value; } } /** * 检查配置 - * @access public + * @access public * @param string $name 配置名称 * @return bool */ - public function __isset($name){ + public function __isset($name) + { return isset($this->config[$name]); } @@ -79,23 +84,24 @@ public function __isset($name){ * 验证验证码是否正确 * @access public * @param string $code 用户验证码 - * @param string $id 验证码标识 + * @param string $id 验证码标识 * @return bool 用户验证码是否正确 */ - public function check($code, $id = '') { - $key = $this->authcode($this->seKey).$id; + public function check($code, $id = '') + { + $key = $this->authcode($this->seKey) . $id; // 验证码不能为空 $secode = session($key); - if(empty($code) || empty($secode)) { + if (empty($code) || empty($secode)) { return false; } // session 过期 - if(NOW_TIME - $secode['verify_time'] > $this->expire) { + if (NOW_TIME - $secode['verify_time'] > $this->expire) { session($key, null); return false; } - if($this->authcode(strtoupper($code)) == $secode['verify_code']) { + if ($this->authcode(strtoupper($code)) == $secode['verify_code']) { $this->reset && session($key, null); return true; } @@ -106,77 +112,79 @@ public function check($code, $id = '') { /** * 输出验证码并把验证码的值保存的session中 * 验证码保存到session的格式为: array('verify_code' => '验证码值', 'verify_time' => '验证码创建时间'); - * @access public - * @param string $id 要生成验证码的标识 + * @access public + * @param string $id 要生成验证码的标识 * @return void */ - public function entry($id = '') { + public function entry($id = '') + { // 图片宽(px) - $this->imageW || $this->imageW = $this->length*$this->fontSize*1.5 + $this->length*$this->fontSize/2; + $this->imageW || $this->imageW = $this->length * $this->fontSize * 1.5 + $this->length * $this->fontSize / 2; // 图片高(px) $this->imageH || $this->imageH = $this->fontSize * 2.5; // 建立一幅 $this->imageW x $this->imageH 的图像 - $this->_image = imagecreate($this->imageW, $this->imageH); - // 设置背景 - imagecolorallocate($this->_image, $this->bg[0], $this->bg[1], $this->bg[2]); + $this->_image = imagecreate($this->imageW, $this->imageH); + // 设置背景 + imagecolorallocate($this->_image, $this->bg[0], $this->bg[1], $this->bg[2]); // 验证码字体随机颜色 - $this->_color = imagecolorallocate($this->_image, mt_rand(1,150), mt_rand(1,150), mt_rand(1,150)); + $this->_color = imagecolorallocate($this->_image, mt_rand(1, 150), mt_rand(1, 150), mt_rand(1, 150)); // 验证码使用随机字体 $ttfPath = dirname(__FILE__) . '/Verify/' . ($this->useZh ? 'zhttfs' : 'ttfs') . '/'; - if(empty($this->fontttf)){ - $dir = dir($ttfPath); - $ttfs = array(); + if (empty($this->fontttf)) { + $dir = dir($ttfPath); + $ttfs = array(); while (false !== ($file = $dir->read())) { - if($file[0] != '.' && substr($file, -4) == '.ttf') { + if ('.' != $file[0] && substr($file, -4) == '.ttf') { $ttfs[] = $file; } } $dir->close(); $this->fontttf = $ttfs[array_rand($ttfs)]; - } + } $this->fontttf = $ttfPath . $this->fontttf; - - if($this->useImgBg) { + + if ($this->useImgBg) { $this->_background(); } - + if ($this->useNoise) { // 绘杂点 $this->_writeNoise(); - } + } if ($this->useCurve) { // 绘干扰线 $this->_writeCurve(); } - + // 绘验证码 - $code = array(); // 验证码 + $code = array(); // 验证码 $codeNX = 0; // 验证码第N个字符的左边距 - if($this->useZh){ // 中文验证码 - for ($i = 0; $i<$this->length; $i++) { - $code[$i] = iconv_substr($this->zhSet,floor(mt_rand(0,mb_strlen($this->zhSet,'utf-8')-1)),1,'utf-8'); - imagettftext($this->_image, $this->fontSize, mt_rand(-40, 40), $this->fontSize*($i+1)*1.5, $this->fontSize + mt_rand(10, 20), $this->_color, $this->fontttf, $code[$i]); + if ($this->useZh) { + // 中文验证码 + for ($i = 0; $i < $this->length; $i++) { + $code[$i] = iconv_substr($this->zhSet, floor(mt_rand(0, mb_strlen($this->zhSet, 'utf-8') - 1)), 1, 'utf-8'); + imagettftext($this->_image, $this->fontSize, mt_rand(-40, 40), $this->fontSize * ($i + 1) * 1.5, $this->fontSize + mt_rand(10, 20), $this->_color, $this->fontttf, $code[$i]); } - }else{ - for ($i = 0; $i<$this->length; $i++) { - $code[$i] = $this->codeSet[mt_rand(0, strlen($this->codeSet)-1)]; - $codeNX += mt_rand($this->fontSize*1.2, $this->fontSize*1.6); - imagettftext($this->_image, $this->fontSize, mt_rand(-40, 40), $codeNX, $this->fontSize*1.6, $this->_color, $this->fontttf, $code[$i]); + } else { + for ($i = 0; $i < $this->length; $i++) { + $code[$i] = $this->codeSet[mt_rand(0, strlen($this->codeSet) - 1)]; + $codeNX += mt_rand($this->fontSize * 1.2, $this->fontSize * 1.6); + imagettftext($this->_image, $this->fontSize, mt_rand(-40, 40), $codeNX, $this->fontSize * 1.6, $this->_color, $this->fontttf, $code[$i]); } } - + // 保存验证码 - $key = $this->authcode($this->seKey); - $code = $this->authcode(strtoupper(implode('', $code))); - $secode = array(); + $key = $this->authcode($this->seKey); + $code = $this->authcode(strtoupper(implode('', $code))); + $secode = array(); $secode['verify_code'] = $code; // 把校验码保存到session - $secode['verify_time'] = NOW_TIME; // 验证码创建时间 - session($key.$id, $secode); - + $secode['verify_time'] = NOW_TIME; // 验证码创建时间 + session($key . $id, $secode); + header('Cache-Control: private, max-age=0, no-store, no-cache, must-revalidate'); - header('Cache-Control: post-check=0, pre-check=0', false); + header('Cache-Control: post-check=0, pre-check=0', false); header('Pragma: no-cache'); header("content-type: image/png"); @@ -185,11 +193,11 @@ public function entry($id = '') { imagedestroy($this->_image); } - /** - * 画一条由两条连在一起构成的随机正弦函数曲线作干扰线(你可以改成更帅的曲线函数) - * + /** + * 画一条由两条连在一起构成的随机正弦函数曲线作干扰线(你可以改成更帅的曲线函数) + * * 高中的数学公式咋都忘了涅,写出来 - * 正弦型函数解析式:y=Asin(ωx+φ)+b + * 正弦型函数解析式:y=Asin(ωx+φ)+b * 各常数值对函数图像的影响: * A:决定峰值(即纵向拉伸压缩的倍数) * b:表示波形在Y轴的位置关系或纵向移动距离(上加下减) @@ -197,45 +205,46 @@ public function entry($id = '') { * ω:决定周期(最小正周期T=2π/∣ω∣) * */ - private function _writeCurve() { + private function _writeCurve() + { $px = $py = 0; - + // 曲线前部分 - $A = mt_rand(1, $this->imageH/2); // 振幅 - $b = mt_rand(-$this->imageH/4, $this->imageH/4); // Y轴方向偏移量 - $f = mt_rand(-$this->imageH/4, $this->imageH/4); // X轴方向偏移量 - $T = mt_rand($this->imageH, $this->imageW*2); // 周期 - $w = (2* M_PI)/$T; - - $px1 = 0; // 曲线横坐标起始位置 - $px2 = mt_rand($this->imageW/2, $this->imageW * 0.8); // 曲线横坐标结束位置 - - for ($px=$px1; $px<=$px2; $px = $px + 1) { - if ($w!=0) { - $py = $A * sin($w*$px + $f)+ $b + $this->imageH/2; // y = Asin(ωx+φ) + b - $i = (int) ($this->fontSize/5); - while ($i > 0) { - imagesetpixel($this->_image, $px + $i , $py + $i, $this->_color); // 这里(while)循环画像素点比imagettftext和imagestring用字体大小一次画出(不用这while循环)性能要好很多 + $A = mt_rand(1, $this->imageH / 2); // 振幅 + $b = mt_rand(-$this->imageH / 4, $this->imageH / 4); // Y轴方向偏移量 + $f = mt_rand(-$this->imageH / 4, $this->imageH / 4); // X轴方向偏移量 + $T = mt_rand($this->imageH, $this->imageW * 2); // 周期 + $w = (2 * M_PI) / $T; + + $px1 = 0; // 曲线横坐标起始位置 + $px2 = mt_rand($this->imageW / 2, $this->imageW * 0.8); // 曲线横坐标结束位置 + + for ($px = $px1; $px <= $px2; $px = $px + 1) { + if (0 != $w) { + $py = $A * sin($w * $px + $f) + $b + $this->imageH / 2; // y = Asin(ωx+φ) + b + $i = (int) ($this->fontSize / 5); + while ($i > 0) { + imagesetpixel($this->_image, $px + $i, $py + $i, $this->_color); // 这里(while)循环画像素点比imagettftext和imagestring用字体大小一次画出(不用这while循环)性能要好很多 $i--; } } } - + // 曲线后部分 - $A = mt_rand(1, $this->imageH/2); // 振幅 - $f = mt_rand(-$this->imageH/4, $this->imageH/4); // X轴方向偏移量 - $T = mt_rand($this->imageH, $this->imageW*2); // 周期 - $w = (2* M_PI)/$T; - $b = $py - $A * sin($w*$px + $f) - $this->imageH/2; + $A = mt_rand(1, $this->imageH / 2); // 振幅 + $f = mt_rand(-$this->imageH / 4, $this->imageH / 4); // X轴方向偏移量 + $T = mt_rand($this->imageH, $this->imageW * 2); // 周期 + $w = (2 * M_PI) / $T; + $b = $py - $A * sin($w * $px + $f) - $this->imageH / 2; $px1 = $px2; $px2 = $this->imageW; - for ($px=$px1; $px<=$px2; $px=$px+ 1) { - if ($w!=0) { - $py = $A * sin($w*$px + $f)+ $b + $this->imageH/2; // y = Asin(ωx+φ) + b - $i = (int) ($this->fontSize/5); - while ($i > 0) { - imagesetpixel($this->_image, $px + $i, $py + $i, $this->_color); + for ($px = $px1; $px <= $px2; $px = $px + 1) { + if (0 != $w) { + $py = $A * sin($w * $px + $f) + $b + $this->imageH / 2; // y = Asin(ωx+φ) + b + $i = (int) ($this->fontSize / 5); + while ($i > 0) { + imagesetpixel($this->_image, $px + $i, $py + $i, $this->_color); $i--; } } @@ -246,14 +255,15 @@ private function _writeCurve() { * 画杂点 * 往图片上写不同颜色的字母或数字 */ - private function _writeNoise() { + private function _writeNoise() + { $codeSet = '2345678abcdefhijkmnpqrstuvwxyz'; - for($i = 0; $i < 10; $i++){ + for ($i = 0; $i < 10; $i++) { //杂点颜色 - $noiseColor = imagecolorallocate($this->_image, mt_rand(150,225), mt_rand(150,225), mt_rand(150,225)); - for($j = 0; $j < 5; $j++) { + $noiseColor = imagecolorallocate($this->_image, mt_rand(150, 225), mt_rand(150, 225), mt_rand(150, 225)); + for ($j = 0; $j < 5; $j++) { // 绘杂点 - imagestring($this->_image, 5, mt_rand(-10, $this->imageW), mt_rand(-10, $this->imageH), $codeSet[mt_rand(0, 29)], $noiseColor); + imagestring($this->_image, 5, mt_rand(-10, $this->imageW), mt_rand(-10, $this->imageH), $codeSet[mt_rand(0, 29)], $noiseColor); } } } @@ -262,13 +272,14 @@ private function _writeNoise() { * 绘制背景图片 * 注:如果验证码输出图片比较大,将占用比较多的系统资源 */ - private function _background() { - $path = dirname(__FILE__).'/Verify/bgs/'; - $dir = dir($path); + private function _background() + { + $path = dirname(__FILE__) . '/Verify/bgs/'; + $dir = dir($path); - $bgs = array(); + $bgs = array(); while (false !== ($file = $dir->read())) { - if($file[0] != '.' && substr($file, -4) == '.jpg') { + if ('.' != $file[0] && substr($file, -4) == '.jpg') { $bgs[] = $path . $file; } } @@ -284,7 +295,8 @@ private function _background() { } /* 加密验证码 */ - private function authcode($str){ + private function authcode($str) + { $key = substr(md5($this->seKey), 5, 8); $str = substr(md5($str), 8, 10); return md5($key . $str); diff --git a/ThinkPHP/Library/Think/View.class.php b/ThinkPHP/Library/Think/View.class.php index cbd6aaf39..b5731bbc3 100644 --- a/ThinkPHP/Library/Think/View.class.php +++ b/ThinkPHP/Library/Think/View.class.php @@ -9,23 +9,25 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think; + /** * ThinkPHP 视图类 */ -class View { +class View +{ /** * 模板输出变量 * @var tVar * @access protected - */ - protected $tVar = array(); + */ + protected $tVar = array(); /** * 模板主题 * @var theme * @access protected - */ - protected $theme = ''; + */ + protected $theme = ''; /** * 模板变量赋值 @@ -33,10 +35,11 @@ class View { * @param mixed $name * @param mixed $value */ - public function assign($name,$value=''){ - if(is_array($name)) { - $this->tVar = array_merge($this->tVar,$name); - }else { + public function assign($name, $value = '') + { + if (is_array($name)) { + $this->tVar = array_merge($this->tVar, $name); + } else { $this->tVar[$name] = $value; } } @@ -47,11 +50,12 @@ public function assign($name,$value=''){ * @param string $name * @return mixed */ - public function get($name=''){ - if('' === $name) { + public function get($name = '') + { + if ('' === $name) { return $this->tVar; } - return isset($this->tVar[$name])?$this->tVar[$name]:false; + return isset($this->tVar[$name]) ? $this->tVar[$name] : false; } /** @@ -64,14 +68,15 @@ public function get($name=''){ * @param string $prefix 模板缓存前缀 * @return mixed */ - public function display($templateFile='',$charset='',$contentType='',$content='',$prefix='') { + public function display($templateFile = '', $charset = '', $contentType = '', $content = '', $prefix = '') + { G('viewStartTime'); // 视图开始标签 - Hook::listen('view_begin',$templateFile); + Hook::listen('view_begin', $templateFile); // 解析并获取模板内容 - $content = $this->fetch($templateFile,$content,$prefix); + $content = $this->fetch($templateFile, $content, $prefix); // 输出模板内容 - $this->render($content,$charset,$contentType); + $this->render($content, $charset, $contentType); // 视图结束标签 Hook::listen('view_end'); } @@ -84,12 +89,19 @@ public function display($templateFile='',$charset='',$contentType='',$content='' * @param string $contentType 输出类型 * @return mixed */ - private function render($content,$charset='',$contentType=''){ - if(empty($charset)) $charset = C('DEFAULT_CHARSET'); - if(empty($contentType)) $contentType = C('TMPL_CONTENT_TYPE'); + private function render($content, $charset = '', $contentType = '') + { + if (empty($charset)) { + $charset = C('DEFAULT_CHARSET'); + } + + if (empty($contentType)) { + $contentType = C('TMPL_CONTENT_TYPE'); + } + // 网页字符编码 - header('Content-Type:'.$contentType.'; charset='.$charset); - header('Cache-control: '.C('HTTP_CACHE_CONTROL')); // 页面缓存控制 + header('Content-Type:' . $contentType . '; charset=' . $charset); + header('Cache-control: ' . C('HTTP_CACHE_CONTROL')); // 页面缓存控制 header('X-Powered-By:ThinkPHP'); // 输出模板文件 echo $content; @@ -103,32 +115,37 @@ private function render($content,$charset='',$contentType=''){ * @param string $prefix 模板缓存前缀 * @return string */ - public function fetch($templateFile='',$content='',$prefix='') { - if(empty($content)) { - $templateFile = $this->parseTemplate($templateFile); + public function fetch($templateFile = '', $content = '', $prefix = '') + { + if (empty($content)) { + $templateFile = $this->parseTemplate($templateFile); // 模板文件不存在直接返回 - if(!is_file($templateFile)) E(L('_TEMPLATE_NOT_EXIST_').':'.$templateFile); - }else{ - defined('THEME_PATH') or define('THEME_PATH', $this->getThemePath()); + if (!is_file($templateFile)) { + E(L('_TEMPLATE_NOT_EXIST_') . ':' . $templateFile); + } + + } else { + defined('THEME_PATH') or define('THEME_PATH', $this->getThemePath()); } // 页面缓存 ob_start(); ob_implicit_flush(0); - if('php' == strtolower(C('TMPL_ENGINE_TYPE'))) { // 使用PHP原生模板 - $_content = $content; + if ('php' == strtolower(C('TMPL_ENGINE_TYPE'))) { + // 使用PHP原生模板 + $_content = $content; // 模板阵列变量分解成为独立变量 extract($this->tVar, EXTR_OVERWRITE); // 直接载入PHP模板 - empty($_content)?include $templateFile:eval('?>'.$_content); - }else{ + empty($_content) ? include $templateFile : eval('?>' . $_content); + } else { // 视图解析标签 - $params = array('var'=>$this->tVar,'file'=>$templateFile,'content'=>$content,'prefix'=>$prefix); - Hook::listen('view_parse',$params); + $params = array('var' => $this->tVar, 'file' => $templateFile, 'content' => $content, 'prefix' => $prefix); + Hook::listen('view_parse', $params); } // 获取并清空缓存 $content = ob_get_clean(); // 内容过滤标签 - Hook::listen('view_filter',$content); + Hook::listen('view_filter', $content); // 输出模板文件 return $content; } @@ -139,32 +156,34 @@ public function fetch($templateFile='',$content='',$prefix='') { * @param string $template 模板文件规则 * @return string */ - public function parseTemplate($template='') { - if(is_file($template)) { + public function parseTemplate($template = '') + { + if (is_file($template)) { return $template; } - $depr = C('TMPL_FILE_DEPR'); - $template = str_replace(':', $depr, $template); + $depr = C('TMPL_FILE_DEPR'); + $template = str_replace(':', $depr, $template); // 获取当前模块 - $module = MODULE_NAME; - if(strpos($template,'@')){ // 跨模块调用模版文件 - list($module,$template) = explode('@',$template); + $module = MODULE_NAME; + if (strpos($template, '@')) { + // 跨模块调用模版文件 + list($module, $template) = explode('@', $template); } // 获取当前主题的模版路径 - defined('THEME_PATH') or define('THEME_PATH', $this->getThemePath($module)); + defined('THEME_PATH') or define('THEME_PATH', $this->getThemePath($module)); // 分析模板文件规则 - if('' == $template) { + if ('' == $template) { // 如果模板文件名为空 按照默认规则定位 $template = CONTROLLER_NAME . $depr . ACTION_NAME; - }elseif(false === strpos($template, $depr)){ + } elseif (false === strpos($template, $depr)) { $template = CONTROLLER_NAME . $depr . $template; } - $file = THEME_PATH.$template.C('TMPL_TEMPLATE_SUFFIX'); - if(C('TMPL_LOAD_DEFAULTTHEME') && THEME_NAME != C('DEFAULT_THEME') && !is_file($file)){ + $file = THEME_PATH . $template . C('TMPL_TEMPLATE_SUFFIX'); + if (C('TMPL_LOAD_DEFAULTTHEME') && THEME_NAME != C('DEFAULT_THEME') && !is_file($file)) { // 找不到当前主题模板的时候定位默认主题中的模板 - $file = dirname(THEME_PATH).'/'.C('DEFAULT_THEME').'/'.$template.C('TMPL_TEMPLATE_SUFFIX'); + $file = dirname(THEME_PATH) . '/' . C('DEFAULT_THEME') . '/' . $template . C('TMPL_TEMPLATE_SUFFIX'); } return $file; } @@ -175,16 +194,17 @@ public function parseTemplate($template='') { * @param string $module 模块名 * @return string */ - protected function getThemePath($module=MODULE_NAME){ + protected function getThemePath($module = MODULE_NAME) + { // 获取当前主题名称 $theme = $this->getTemplateTheme(); // 获取当前主题的模版路径 - $tmplPath = C('VIEW_PATH'); // 模块设置独立的视图目录 - if(!$tmplPath){ + $tmplPath = C('VIEW_PATH'); // 模块设置独立的视图目录 + if (!$tmplPath) { // 定义TMPL_PATH 则改变全局的视图目录到模块之外 - $tmplPath = defined('TMPL_PATH')? TMPL_PATH.$module.'/' : APP_PATH.$module.'/'.C('DEFAULT_V_LAYER').'/'; + $tmplPath = defined('TMPL_PATH') ? TMPL_PATH . $module . '/' : APP_PATH . $module . '/' . C('DEFAULT_V_LAYER') . '/'; } - return $tmplPath.$theme; + return $tmplPath . $theme; } /** @@ -193,7 +213,8 @@ protected function getThemePath($module=MODULE_NAME){ * @param mixed $theme 主题名称 * @return View */ - public function theme($theme){ + public function theme($theme) + { $this->theme = $theme; return $this; } @@ -203,27 +224,30 @@ public function theme($theme){ * @access private * @return string */ - private function getTemplateTheme() { - if($this->theme) { // 指定模板主题 + private function getTemplateTheme() + { + if ($this->theme) { + // 指定模板主题 $theme = $this->theme; - }else{ + } else { /* 获取模板主题名称 */ - $theme = C('DEFAULT_THEME'); - if(C('TMPL_DETECT_THEME')) {// 自动侦测模板主题 + $theme = C('DEFAULT_THEME'); + if (C('TMPL_DETECT_THEME')) { +// 自动侦测模板主题 $t = C('VAR_TEMPLATE'); - if (isset($_GET[$t])){ + if (isset($_GET[$t])) { $theme = $_GET[$t]; - }elseif(cookie('think_template')){ + } elseif (cookie('think_template')) { $theme = cookie('think_template'); } - if(!in_array($theme,explode(',',C('THEME_LIST')))){ - $theme = C('DEFAULT_THEME'); + if (!in_array($theme, explode(',', C('THEME_LIST')))) { + $theme = C('DEFAULT_THEME'); } - cookie('think_template',$theme,864000); + cookie('think_template', $theme, 864000); } } - defined('THEME_NAME') || define('THEME_NAME', $theme); // 当前模板主题名称 - return $theme?$theme . '/':''; + defined('THEME_NAME') || define('THEME_NAME', $theme); // 当前模板主题名称 + return $theme ? $theme . '/' : ''; } -} \ No newline at end of file +} diff --git a/ThinkPHP/Mode/Api/App.class.php b/ThinkPHP/Mode/Api/App.class.php index 92fd3ec3a..ccc168b34 100644 --- a/ThinkPHP/Mode/Api/App.class.php +++ b/ThinkPHP/Mode/Api/App.class.php @@ -9,41 +9,45 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think; + /** * ThinkPHP API模式 应用程序类 */ -class App { + +class App +{ /** * 应用程序初始化 * @access public * @return void */ - static public function init() { + public static function init() + { // 定义当前请求的系统常量 - define('NOW_TIME', $_SERVER['REQUEST_TIME']); - define('REQUEST_METHOD',$_SERVER['REQUEST_METHOD']); - define('IS_GET', REQUEST_METHOD =='GET' ? true : false); - define('IS_POST', REQUEST_METHOD =='POST' ? true : false); - define('IS_PUT', REQUEST_METHOD =='PUT' ? true : false); - define('IS_DELETE', REQUEST_METHOD =='DELETE' ? true : false); - define('IS_AJAX', ((isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') || !empty($_POST[C('VAR_AJAX_SUBMIT')]) || !empty($_GET[C('VAR_AJAX_SUBMIT')])) ? true : false); + define('NOW_TIME', $_SERVER['REQUEST_TIME']); + define('REQUEST_METHOD', $_SERVER['REQUEST_METHOD']); + define('IS_GET', REQUEST_METHOD == 'GET' ? true : false); + define('IS_POST', REQUEST_METHOD == 'POST' ? true : false); + define('IS_PUT', REQUEST_METHOD == 'PUT' ? true : false); + define('IS_DELETE', REQUEST_METHOD == 'DELETE' ? true : false); + define('IS_AJAX', ((isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') || !empty($_POST[C('VAR_AJAX_SUBMIT')]) || !empty($_GET[C('VAR_AJAX_SUBMIT')])) ? true : false); // URL调度 Dispatcher::dispatch(); - if(C('REQUEST_VARS_FILTER')){ - // 全局安全过滤 - array_walk_recursive($_GET, 'think_filter'); - array_walk_recursive($_POST, 'think_filter'); - array_walk_recursive($_REQUEST, 'think_filter'); - } + if (C('REQUEST_VARS_FILTER')) { + // 全局安全过滤 + array_walk_recursive($_GET, 'think_filter'); + array_walk_recursive($_POST, 'think_filter'); + array_walk_recursive($_REQUEST, 'think_filter'); + } // 日志目录转换为绝对路径 - C('LOG_PATH',realpath(LOG_PATH).'/'); + C('LOG_PATH', realpath(LOG_PATH) . '/'); // TMPL_EXCEPTION_FILE 改为绝对地址 - C('TMPL_EXCEPTION_FILE',realpath(C('TMPL_EXCEPTION_FILE'))); - return ; + C('TMPL_EXCEPTION_FILE', realpath(C('TMPL_EXCEPTION_FILE'))); + return; } /** @@ -51,76 +55,78 @@ static public function init() { * @access public * @return void */ - static public function exec() { - - if(!preg_match('/^[A-Za-z](\/|\w)*$/',CONTROLLER_NAME)){ // 安全检测 - $module = false; - }else{ + public static function exec() + { + + if (!preg_match('/^[A-Za-z](\/|\w)*$/', CONTROLLER_NAME)) { + // 安全检测 + $module = false; + } else { //创建控制器实例 - $module = A(CONTROLLER_NAME); + $module = A(CONTROLLER_NAME); } - if(!$module) { + if (!$module) { // 是否定义Empty控制器 $module = A('Empty'); - if(!$module){ - E(L('_CONTROLLER_NOT_EXIST_').':'.CONTROLLER_NAME); + if (!$module) { + E(L('_CONTROLLER_NOT_EXIST_') . ':' . CONTROLLER_NAME); } } // 获取当前操作名 支持动态路由 - $action = ACTION_NAME; + $action = ACTION_NAME; - try{ - if(!preg_match('/^[A-Za-z](\w)*$/',$action)){ + try { + if (!preg_match('/^[A-Za-z](\w)*$/', $action)) { // 非法操作 throw new \ReflectionException(); } //执行当前操作 - $method = new \ReflectionMethod($module, $action); - if($method->isPublic() && !$method->isStatic()) { - $class = new \ReflectionClass($module); + $method = new \ReflectionMethod($module, $action); + if ($method->isPublic() && !$method->isStatic()) { + $class = new \ReflectionClass($module); // URL参数绑定检测 - if(C('URL_PARAMS_BIND') && $method->getNumberOfParameters()>0){ - switch($_SERVER['REQUEST_METHOD']) { + if (C('URL_PARAMS_BIND') && $method->getNumberOfParameters() > 0) { + switch ($_SERVER['REQUEST_METHOD']) { case 'POST': - $vars = array_merge($_GET,$_POST); + $vars = array_merge($_GET, $_POST); break; case 'PUT': parse_str(file_get_contents('php://input'), $vars); break; default: - $vars = $_GET; + $vars = $_GET; } - $params = $method->getParameters(); - $paramsBindType = C('URL_PARAMS_BIND_TYPE'); - foreach ($params as $param){ + $params = $method->getParameters(); + $paramsBindType = C('URL_PARAMS_BIND_TYPE'); + foreach ($params as $param) { $name = $param->getName(); - if( 1 == $paramsBindType && !empty($vars) ){ - $args[] = array_shift($vars); - }elseif( 0 == $paramsBindType && isset($vars[$name])){ - $args[] = $vars[$name]; - }elseif($param->isDefaultValueAvailable()){ - $args[] = $param->getDefaultValue(); - }else{ - E(L('_PARAM_ERROR_').':'.$name); - } + if (1 == $paramsBindType && !empty($vars)) { + $args[] = array_shift($vars); + } elseif (0 == $paramsBindType && isset($vars[$name])) { + $args[] = $vars[$name]; + } elseif ($param->isDefaultValueAvailable()) { + $args[] = $param->getDefaultValue(); + } else { + E(L('_PARAM_ERROR_') . ':' . $name); + } } - array_walk_recursive($args,'think_filter'); - $method->invokeArgs($module,$args); - }else{ + array_walk_recursive($args, 'think_filter'); + $method->invokeArgs($module, $args); + } else { $method->invoke($module); } - }else{ + } else { // 操作方法不是Public 抛出异常 throw new \ReflectionException(); } - } catch (\ReflectionException $e) { + } catch (\ReflectionException $e) { // 方法调用发生异常后 引导到__call方法处理 - $method = new \ReflectionMethod($module,'__call'); - $method->invokeArgs($module,array($action,'')); + $method = new \ReflectionMethod($module, '__call'); + $method->invokeArgs($module, array($action, '')); } - return ; + return; } /** @@ -128,16 +134,17 @@ static public function exec() { * @access public * @return void */ - static public function run() { + public static function run() + { App::init(); // Session初始化 - if(!IS_CLI){ + if (!IS_CLI) { session(C('SESSION_OPTIONS')); } // 记录应用初始化时间 G('initTime'); App::exec(); - return ; + return; } -} \ No newline at end of file +} diff --git a/ThinkPHP/Mode/Api/Controller.class.php b/ThinkPHP/Mode/Api/Controller.class.php index 578e2b7dc..e266f54a3 100644 --- a/ThinkPHP/Mode/Api/Controller.class.php +++ b/ThinkPHP/Mode/Api/Controller.class.php @@ -9,19 +9,24 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think; + /** * ThinkPHP API模式控制器基类 */ -abstract class Controller { +abstract class Controller +{ - /** + /** * 架构函数 * @access public */ - public function __construct() { + public function __construct() + { //控制器初始化 - if(method_exists($this,'_initialize')) + if (method_exists($this, '_initialize')) { $this->_initialize(); + } + } /** @@ -31,16 +36,17 @@ public function __construct() { * @param array $args 参数 * @return mixed */ - public function __call($method,$args) { - if( 0 === strcasecmp($method,ACTION_NAME.C('ACTION_SUFFIX'))) { - if(method_exists($this,'_empty')) { + public function __call($method, $args) + { + if (0 === strcasecmp($method, ACTION_NAME . C('ACTION_SUFFIX'))) { + if (method_exists($this, '_empty')) { // 如果定义了_empty操作 则调用 - $this->_empty($method,$args); - }else{ - E(L('_ERROR_ACTION_').':'.ACTION_NAME); + $this->_empty($method, $args); + } else { + E(L('_ERROR_ACTION_') . ':' . ACTION_NAME); } - }else{ - E(__CLASS__.':'.$method.L('_METHOD_NOT_EXIST_')); + } else { + E(__CLASS__ . ':' . $method . L('_METHOD_NOT_EXIST_')); return; } } @@ -52,26 +58,30 @@ public function __call($method,$args) { * @param String $type AJAX返回数据格式 * @return void */ - protected function ajaxReturn($data,$type='') { - if(empty($type)) $type = C('DEFAULT_AJAX_RETURN'); - switch (strtoupper($type)){ - case 'JSON' : + protected function ajaxReturn($data, $type = '') + { + 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)); - case 'XML' : + 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).');'); - case 'EVAL' : + $handler = isset($_GET[C('VAR_JSONP_HANDLER')]) ? $_GET[C('VAR_JSONP_HANDLER')] : C('DEFAULT_JSONP_HANDLER'); + exit($handler . '(' . json_encode($data) . ');'); + case 'EVAL': // 返回可执行的js脚本 header('Content-Type:text/html; charset=utf-8'); - exit($data); + exit($data); } } @@ -84,9 +94,10 @@ protected function ajaxReturn($data,$type='') { * @param string $msg 跳转提示信息 * @return void */ - protected function redirect($url,$params=array(),$delay=0,$msg='') { - $url = U($url,$params); - redirect($url,$delay,$msg); + protected function redirect($url, $params = array(), $delay = 0, $msg = '') + { + $url = U($url, $params); + redirect($url, $delay, $msg); } -} \ No newline at end of file +} diff --git a/ThinkPHP/Mode/Api/Dispatcher.class.php b/ThinkPHP/Mode/Api/Dispatcher.class.php index 99ee2360f..a946b4956 100644 --- a/ThinkPHP/Mode/Api/Dispatcher.class.php +++ b/ThinkPHP/Mode/Api/Dispatcher.class.php @@ -9,191 +9,214 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think; + /** * ThinkPHP API模式的Dispatcher类 * 完成URL解析、路由和调度 */ -class Dispatcher { + +class Dispatcher +{ /** * URL映射到控制器 * @access public * @return void */ - static public function dispatch() { - $varPath = C('VAR_PATHINFO'); - $varModule = C('VAR_MODULE'); - $varController = C('VAR_CONTROLLER'); - $varAction = C('VAR_ACTION'); - $urlCase = C('URL_CASE_INSENSITIVE'); - if(isset($_GET[$varPath])) { // 判断URL里面是否有兼容模式参数 + public static function dispatch() + { + $varPath = C('VAR_PATHINFO'); + $varModule = C('VAR_MODULE'); + $varController = C('VAR_CONTROLLER'); + $varAction = C('VAR_ACTION'); + $urlCase = C('URL_CASE_INSENSITIVE'); + if (isset($_GET[$varPath])) { + // 判断URL里面是否有兼容模式参数 $_SERVER['PATH_INFO'] = $_GET[$varPath]; unset($_GET[$varPath]); - }elseif(IS_CLI){ // CLI模式下 index.php module/controller/action/params/... + } elseif (IS_CLI) { + // CLI模式下 index.php module/controller/action/params/... $_SERVER['PATH_INFO'] = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : ''; } // 开启子域名部署 - if(C('APP_SUB_DOMAIN_DEPLOY')) { - $rules = C('APP_SUB_DOMAIN_RULES'); - if(isset($rules[$_SERVER['HTTP_HOST']])) { // 完整域名或者IP配置 - define('APP_DOMAIN',$_SERVER['HTTP_HOST']); // 当前完整域名 + if (C('APP_SUB_DOMAIN_DEPLOY')) { + $rules = C('APP_SUB_DOMAIN_RULES'); + if (isset($rules[$_SERVER['HTTP_HOST']])) { + // 完整域名或者IP配置 + define('APP_DOMAIN', $_SERVER['HTTP_HOST']); // 当前完整域名 $rule = $rules[APP_DOMAIN]; - }else{ - if(strpos(C('APP_DOMAIN_SUFFIX'),'.')){ // com.cn net.cn + } else { + if (strpos(C('APP_DOMAIN_SUFFIX'), '.')) { + // com.cn net.cn $domain = array_slice(explode('.', $_SERVER['HTTP_HOST']), 0, -3); - }else{ - $domain = array_slice(explode('.', $_SERVER['HTTP_HOST']), 0, -2); + } else { + $domain = array_slice(explode('.', $_SERVER['HTTP_HOST']), 0, -2); } - if(!empty($domain)) { + if (!empty($domain)) { $subDomain = implode('.', $domain); - define('SUB_DOMAIN',$subDomain); // 当前完整子域名 - $domain2 = array_pop($domain); // 二级域名 - if($domain) { // 存在三级域名 + define('SUB_DOMAIN', $subDomain); // 当前完整子域名 + $domain2 = array_pop($domain); // 二级域名 + if ($domain) { + // 存在三级域名 $domain3 = array_pop($domain); } - if(isset($rules[$subDomain])) { // 子域名 + if (isset($rules[$subDomain])) { + // 子域名 $rule = $rules[$subDomain]; - }elseif(isset($rules['*.' . $domain2]) && !empty($domain3)){ // 泛三级域名 - $rule = $rules['*.' . $domain2]; + } elseif (isset($rules['*.' . $domain2]) && !empty($domain3)) { + // 泛三级域名 + $rule = $rules['*.' . $domain2]; $panDomain = $domain3; - }elseif(isset($rules['*']) && !empty($domain2) && 'www' != $domain2 ){ // 泛二级域名 + } elseif (isset($rules['*']) && !empty($domain2) && 'www' != $domain2) { + // 泛二级域名 $rule = $rules['*']; $panDomain = $domain2; } - } + } } - if(!empty($rule)) { + if (!empty($rule)) { // 子域名部署规则 '子域名'=>array('模块名[/控制器名]','var1=a&var2=b'); - if(is_array($rule)){ - list($rule,$vars) = $rule; + if (is_array($rule)) { + list($rule, $vars) = $rule; } - $array = explode('/',$rule); + $array = explode('/', $rule); // 模块绑定 - define('BIND_MODULE',array_shift($array)); - // 控制器绑定 - if(!empty($array)) { - $controller = array_shift($array); - if($controller){ - define('BIND_CONTROLLER',$controller); + define('BIND_MODULE', array_shift($array)); + // 控制器绑定 + if (!empty($array)) { + $controller = array_shift($array); + if ($controller) { + define('BIND_CONTROLLER', $controller); } } - if(isset($vars)) { // 传入参数 - parse_str($vars,$parms); - if(isset($panDomain)){ + if (isset($vars)) { + // 传入参数 + parse_str($vars, $parms); + if (isset($panDomain)) { $pos = array_search('*', $parms); - if(false !== $pos) { + if (false !== $pos) { // 泛域名作为参数 $parms[$pos] = $panDomain; - } - } - $_GET = array_merge($_GET,$parms); + } + } + $_GET = array_merge($_GET, $parms); } } } // 分析PATHINFO信息 - if(!isset($_SERVER['PATH_INFO'])) { - $types = explode(',',C('URL_PATHINFO_FETCH')); - foreach ($types as $type){ - if(!empty($_SERVER[$type])) { - $_SERVER['PATH_INFO'] = (0 === strpos($_SERVER[$type],$_SERVER['SCRIPT_NAME']))? - substr($_SERVER[$type], strlen($_SERVER['SCRIPT_NAME'])) : $_SERVER[$type]; + if (!isset($_SERVER['PATH_INFO'])) { + $types = explode(',', C('URL_PATHINFO_FETCH')); + foreach ($types as $type) { + if (!empty($_SERVER[$type])) { + $_SERVER['PATH_INFO'] = (0 === strpos($_SERVER[$type], $_SERVER['SCRIPT_NAME'])) ? + substr($_SERVER[$type], strlen($_SERVER['SCRIPT_NAME'])) : $_SERVER[$type]; break; } } } - if(empty($_SERVER['PATH_INFO'])) { + if (empty($_SERVER['PATH_INFO'])) { $_SERVER['PATH_INFO'] = ''; } $depr = C('URL_PATHINFO_DEPR'); - define('MODULE_PATHINFO_DEPR', $depr); - define('__INFO__',trim($_SERVER['PATH_INFO'],'/')); + define('MODULE_PATHINFO_DEPR', $depr); + define('__INFO__', trim($_SERVER['PATH_INFO'], '/')); // URL后缀 - define('__EXT__', strtolower(pathinfo($_SERVER['PATH_INFO'],PATHINFO_EXTENSION))); + define('__EXT__', strtolower(pathinfo($_SERVER['PATH_INFO'], PATHINFO_EXTENSION))); $_SERVER['PATH_INFO'] = __INFO__; - if (__INFO__ && C('MULTI_MODULE') && !defined('BIND_MODULE')){ // 获取模块名 - $paths = explode($depr,__INFO__,2); - $allowList = C('MODULE_ALLOW_LIST'); // 允许的模块列表 - $module = preg_replace('/\.' . __EXT__ . '$/i', '',$paths[0]); - if( empty($allowList) || (is_array($allowList) && in_array_case($module, $allowList))){ - $_GET[$varModule] = $module; - $_SERVER['PATH_INFO'] = isset($paths[1])?$paths[1]:''; + if (__INFO__ && C('MULTI_MODULE') && !defined('BIND_MODULE')) { + // 获取模块名 + $paths = explode($depr, __INFO__, 2); + $allowList = C('MODULE_ALLOW_LIST'); // 允许的模块列表 + $module = preg_replace('/\.' . __EXT__ . '$/i', '', $paths[0]); + if (empty($allowList) || (is_array($allowList) && in_array_case($module, $allowList))) { + $_GET[$varModule] = $module; + $_SERVER['PATH_INFO'] = isset($paths[1]) ? $paths[1] : ''; } } // 获取模块名称 - define('MODULE_NAME', defined('BIND_MODULE')? BIND_MODULE : self::getModule($varModule)); - + define('MODULE_NAME', defined('BIND_MODULE') ? BIND_MODULE : self::getModule($varModule)); + // 检测模块是否存在 - if( MODULE_NAME && (defined('BIND_MODULE') || !in_array_case(MODULE_NAME,C('MODULE_DENY_LIST')) ) && is_dir(APP_PATH.MODULE_NAME)){ + if (MODULE_NAME && (defined('BIND_MODULE') || !in_array_case(MODULE_NAME, C('MODULE_DENY_LIST'))) && is_dir(APP_PATH . MODULE_NAME)) { // 定义当前模块路径 - define('MODULE_PATH', APP_PATH.MODULE_NAME.'/'); + define('MODULE_PATH', APP_PATH . MODULE_NAME . '/'); // 定义当前模块的模版缓存路径 - C('CACHE_PATH',CACHE_PATH.MODULE_NAME.'/'); + C('CACHE_PATH', CACHE_PATH . MODULE_NAME . '/'); // 加载模块配置文件 - if(is_file(MODULE_PATH.'Conf/config.php')) - C(include MODULE_PATH.'Conf/config.php'); + if (is_file(MODULE_PATH . 'Conf/config.php')) { + C(include MODULE_PATH . 'Conf/config.php'); + } + // 加载模块别名定义 - if(is_file(MODULE_PATH.'Conf/alias.php')) - Think::addMap(include MODULE_PATH.'Conf/alias.php'); + if (is_file(MODULE_PATH . 'Conf/alias.php')) { + Think::addMap(include MODULE_PATH . 'Conf/alias.php'); + } + // 加载模块函数文件 - if(is_file(MODULE_PATH.'Common/function.php')) - include MODULE_PATH.'Common/function.php'; - }else{ - E(L('_MODULE_NOT_EXIST_').':'.MODULE_NAME); + if (is_file(MODULE_PATH . 'Common/function.php')) { + include MODULE_PATH . 'Common/function.php'; + } + + } else { + E(L('_MODULE_NOT_EXIST_') . ':' . MODULE_NAME); } - if('' != $_SERVER['PATH_INFO'] && (!C('URL_ROUTER_ON') || !Route::check()) ){ // 检测路由规则 如果没有则按默认规则调度URL + if ('' != $_SERVER['PATH_INFO'] && (!C('URL_ROUTER_ON') || !Route::check())) { + // 检测路由规则 如果没有则按默认规则调度URL // 检查禁止访问的URL后缀 - if(C('URL_DENY_SUFFIX') && preg_match('/\.('.trim(C('URL_DENY_SUFFIX'),'.').')$/i', $_SERVER['PATH_INFO'])){ + if (C('URL_DENY_SUFFIX') && preg_match('/\.(' . trim(C('URL_DENY_SUFFIX'), '.') . ')$/i', $_SERVER['PATH_INFO'])) { send_http_status(404); exit; } - + // 去除URL后缀 - $_SERVER['PATH_INFO'] = preg_replace(C('URL_HTML_SUFFIX')? '/\.('.trim(C('URL_HTML_SUFFIX'),'.').')$/i' : '/\.'.__EXT__.'$/i', '', $_SERVER['PATH_INFO']); + $_SERVER['PATH_INFO'] = preg_replace(C('URL_HTML_SUFFIX') ? '/\.(' . trim(C('URL_HTML_SUFFIX'), '.') . ')$/i' : '/\.' . __EXT__ . '$/i', '', $_SERVER['PATH_INFO']); - $depr = C('URL_PATHINFO_DEPR'); - $paths = explode($depr,trim($_SERVER['PATH_INFO'],$depr)); + $depr = C('URL_PATHINFO_DEPR'); + $paths = explode($depr, trim($_SERVER['PATH_INFO'], $depr)); - if(!defined('BIND_CONTROLLER')) {// 获取控制器 - $_GET[$varController] = array_shift($paths); + if (!defined('BIND_CONTROLLER')) { +// 获取控制器 + $_GET[$varController] = array_shift($paths); } // 获取操作 - if(!defined('BIND_ACTION')){ - $_GET[$varAction] = array_shift($paths); + if (!defined('BIND_ACTION')) { + $_GET[$varAction] = array_shift($paths); } // 解析剩余的URL参数 - $var = array(); - if(C('URL_PARAMS_BIND') && 1 == C('URL_PARAMS_BIND_TYPE')){ + $var = array(); + if (C('URL_PARAMS_BIND') && 1 == C('URL_PARAMS_BIND_TYPE')) { // URL参数按顺序绑定变量 - $var = $paths; - }else{ - preg_replace_callback('/(\w+)\/([^\/]+)/', function($match) use(&$var){$var[$match[1]]=strip_tags($match[2]);}, implode('/',$paths)); + $var = $paths; + } else { + preg_replace_callback('/(\w+)\/([^\/]+)/', function ($match) use (&$var) {$var[$match[1]] = strip_tags($match[2]);}, implode('/', $paths)); } - $_GET = array_merge($var,$_GET); + $_GET = array_merge($var, $_GET); } // 获取控制器和操作名 - define('CONTROLLER_NAME', defined('BIND_CONTROLLER')? BIND_CONTROLLER : self::getController($varController,$urlCase)); - define('ACTION_NAME', defined('BIND_ACTION')? BIND_ACTION : self::getAction($varAction,$urlCase)); + define('CONTROLLER_NAME', defined('BIND_CONTROLLER') ? BIND_CONTROLLER : self::getController($varController, $urlCase)); + define('ACTION_NAME', defined('BIND_ACTION') ? BIND_ACTION : self::getAction($varAction, $urlCase)); //保证$_REQUEST正常取值 - $_REQUEST = array_merge($_POST,$_GET); + $_REQUEST = array_merge($_POST, $_GET); } /** * 获得实际的控制器名称 */ - static private function getController($var,$urlCase) { - $controller = (!empty($_GET[$var])? $_GET[$var]:C('DEFAULT_CONTROLLER')); + private static function getController($var, $urlCase) + { + $controller = (!empty($_GET[$var]) ? $_GET[$var] : C('DEFAULT_CONTROLLER')); unset($_GET[$var]); - if($urlCase) { + if ($urlCase) { // URL地址不区分大小写 // 智能识别方式 user_type 识别到 UserTypeController 控制器 - $controller = parse_name($controller,1); + $controller = parse_name($controller, 1); } return strip_tags(ucfirst($controller)); } @@ -201,29 +224,31 @@ static private function getController($var,$urlCase) { /** * 获得实际的操作名称 */ - static private function getAction($var,$urlCase) { - $action = !empty($_POST[$var]) ? - $_POST[$var] : - (!empty($_GET[$var])?$_GET[$var]:C('DEFAULT_ACTION')); - unset($_POST[$var],$_GET[$var]); - return strip_tags($urlCase?strtolower($action):$action); + private static function getAction($var, $urlCase) + { + $action = !empty($_POST[$var]) ? + $_POST[$var] : + (!empty($_GET[$var]) ? $_GET[$var] : C('DEFAULT_ACTION')); + unset($_POST[$var], $_GET[$var]); + return strip_tags($urlCase ? strtolower($action) : $action); } /** * 获得实际的模块名称 */ - static private function getModule($var) { - $module = (!empty($_GET[$var])?$_GET[$var]:C('DEFAULT_MODULE')); + private static function getModule($var) + { + $module = (!empty($_GET[$var]) ? $_GET[$var] : C('DEFAULT_MODULE')); unset($_GET[$var]); - if($maps = C('URL_MODULE_MAP')) { - if(isset($maps[strtolower($module)])) { + if ($maps = C('URL_MODULE_MAP')) { + if (isset($maps[strtolower($module)])) { // 记录当前别名 - define('MODULE_ALIAS',strtolower($module)); + define('MODULE_ALIAS', strtolower($module)); // 获取实际的模块名 - return ucfirst($maps[MODULE_ALIAS]); - }elseif(array_search(strtolower($module),$maps)){ + return ucfirst($maps[MODULE_ALIAS]); + } elseif (array_search(strtolower($module), $maps)) { // 禁止访问原始模块 - return ''; + return ''; } } return strip_tags(ucfirst(strtolower($module))); diff --git a/ThinkPHP/Mode/Api/functions.php b/ThinkPHP/Mode/Api/functions.php index 04a8e6978..3931ae7f9 100644 --- a/ThinkPHP/Mode/Api/functions.php +++ b/ThinkPHP/Mode/Api/functions.php @@ -20,7 +20,8 @@ * @param mixed $default 默认值 * @return mixed */ -function C($name=null, $value=null,$default=null) { +function C($name = null, $value = null, $default = null) +{ static $_config = array(); // 无参数时获取所有 if (empty($name)) { @@ -30,21 +31,25 @@ function C($name=null, $value=null,$default=null) { if (is_string($name)) { if (!strpos($name, '.')) { $name = strtolower($name); - if (is_null($value)) + if (is_null($value)) { return isset($_config[$name]) ? $_config[$name] : $default; + } + $_config[$name] = $value; return; } // 二维数组设置和获取支持 - $name = explode('.', $name); - $name[0] = strtolower($name[0]); - if (is_null($value)) + $name = explode('.', $name); + $name[0] = strtolower($name[0]); + if (is_null($value)) { return isset($_config[$name[0]][$name[1]]) ? $_config[$name[0]][$name[1]] : $default; + } + $_config[$name[0]][$name[1]] = $value; return; } // 批量设置 - if (is_array($name)){ + if (is_array($name)) { $_config = array_merge($_config, array_change_key_case($name)); return; } @@ -57,24 +62,25 @@ function C($name=null, $value=null,$default=null) { * @param string $parse 配置解析方法 有些格式需要用户自己解析 * @return void */ -function load_config($file,$parse=CONF_PARSE){ - $ext = pathinfo($file,PATHINFO_EXTENSION); - switch($ext){ +function loadConfig($file, $parse = CONF_PARSE) +{ + $ext = pathinfo($file, PATHINFO_EXTENSION); + switch ($ext) { case 'php': return include $file; case 'ini': return parse_ini_file($file); case 'yaml': return yaml_parse_file($file); - case 'xml': - return (array)simplexml_load_file($file); + case 'xml': + return (array) simplexml_load_file($file); case 'json': return json_decode(file_get_contents($file), true); default: - if(function_exists($parse)){ + if (function_exists($parse)) { return $parse($file); - }else{ - E(L('_NOT_SUPPORT_').':'.$ext); + } else { + E(L('_NOT_SUPPORT_') . ':' . $ext); } } } @@ -85,7 +91,8 @@ function load_config($file,$parse=CONF_PARSE){ * @param integer $code 异常代码 默认为0 * @return void */ -function E($msg, $code=0) { +function E($msg, $code = 0) +{ throw new Think\Exception($msg, $code); } @@ -106,23 +113,36 @@ function E($msg, $code=0) { * @param integer|string $dec 小数位或者m * @return mixed */ -function G($start,$end='',$dec=4) { - static $_info = array(); - static $_mem = array(); - if(is_float($end)) { // 记录时间 - $_info[$start] = $end; - }elseif(!empty($end)){ // 统计时间和内存使用 - if(!isset($_info[$end])) $_info[$end] = microtime(TRUE); - if(MEMORY_LIMIT_ON && $dec=='m'){ - if(!isset($_mem[$end])) $_mem[$end] = memory_get_usage(); - return number_format(($_mem[$end]-$_mem[$start])/1024); - }else{ - return number_format(($_info[$end]-$_info[$start]),$dec); +function G($start, $end = '', $dec = 4) +{ + static $_info = array(); + static $_mem = array(); + if (is_float($end)) { + // 记录时间 + $_info[$start] = $end; + } elseif (!empty($end)) { + // 统计时间和内存使用 + if (!isset($_info[$end])) { + $_info[$end] = microtime(true); + } + + if (MEMORY_LIMIT_ON && 'm' == $dec) { + if (!isset($_mem[$end])) { + $_mem[$end] = memory_get_usage(); + } + + return number_format(($_mem[$end] - $_mem[$start]) / 1024); + } else { + return number_format(($_info[$end] - $_info[$start]), $dec); + } + + } else { + // 记录时间和内存使用 + $_info[$start] = microtime(true); + if (MEMORY_LIMIT_ON) { + $_mem[$start] = memory_get_usage(); } - }else{ // 记录时间和内存使用 - $_info[$start] = microtime(TRUE); - if(MEMORY_LIMIT_ON) $_mem[$start] = memory_get_usage(); } } @@ -132,23 +152,30 @@ function G($start,$end='',$dec=4) { * @param string $value 语言值 * @return mixed */ -function L($name=null, $value=null) { +function L($name = null, $value = null) +{ static $_lang = array(); // 空参数返回所有定义 - if (empty($name)) + if (empty($name)) { return $_lang; + } + // 判断语言获取(或设置) // 若不存在,直接返回全大写$name if (is_string($name)) { $name = strtoupper($name); - if (is_null($value)) + if (is_null($value)) { return isset($_lang[$name]) ? $_lang[$name] : $name; + } + $_lang[$name] = $value; // 语言定义 return; } // 批量定义 - if (is_array($name)) + if (is_array($name)) { $_lang = array_merge($_lang, array_change_key_case($name, CASE_UPPER)); + } + return; } @@ -160,8 +187,9 @@ function L($name=null, $value=null) { * @param boolean $record 是否记录日志 * @return void */ -function trace($value='[think]',$label='',$level='DEBUG',$record=false) { - return Think\Think::trace($value,$label,$level,$record); +function trace($value = '[think]', $label = '', $level = 'DEBUG', $record = false) +{ + return Think\Think::trace($value, $label, $level, $record); } /** @@ -169,19 +197,22 @@ function trace($value='[think]',$label='',$level='DEBUG',$record=false) { * @param string $filename 文件名 * @return string */ -function compile($filename) { - $content = php_strip_whitespace($filename); - $content = trim(substr($content, 5)); +function compile($filename) +{ + $content = php_strip_whitespace($filename); + $content = trim(substr($content, 5)); // 替换预编译指令 - $content = preg_replace('/\/\/\[RUNTIME\](.*?)\/\/\[\/RUNTIME\]/s', '', $content); - if(0===strpos($content,'namespace')){ - $content = preg_replace('/namespace\s(.*?);/','namespace \\1{',$content,1); - }else{ - $content = 'namespace {'.$content; - } - if ('?>' == substr($content, -2)) - $content = substr($content, 0, -2); - return $content.'}'; + $content = preg_replace('/\/\/\[RUNTIME\](.*?)\/\/\[\/RUNTIME\]/s', '', $content); + if (0 === strpos($content, 'namespace')) { + $content = preg_replace('/namespace\s(.*?);/', 'namespace \\1{', $content, 1); + } else { + $content = 'namespace {' . $content; + } + if ('?>' == substr($content, -2)) { + $content = substr($content, 0, -2); + } + + return $content . '}'; } /** @@ -198,119 +229,136 @@ function compile($filename) { * @param mixed $datas 要获取的额外数据源 * @return mixed */ -function I($name,$default='',$filter=null,$datas=null) { - if(strpos($name,'/')){ // 指定修饰符 - list($name,$type) = explode('/',$name,2); - } - if(strpos($name,'.')) { // 指定参数来源 - list($method,$name) = explode('.',$name,2); - }else{ // 默认为自动判断 - $method = 'param'; - } - switch(strtolower($method)) { - case 'get' : $input =& $_GET;break; - case 'post' : $input =& $_POST;break; - case 'put' : parse_str(file_get_contents('php://input'), $input);break; - case 'param' : - switch($_SERVER['REQUEST_METHOD']) { +function I($name, $default = '', $filter = null, $datas = null) +{ + if (strpos($name, '/')) { + // 指定修饰符 + list($name, $type) = explode('/', $name, 2); + } + if (strpos($name, '.')) { + // 指定参数来源 + list($method, $name) = explode('.', $name, 2); + } else { + // 默认为自动判断 + $method = 'param'; + } + switch (strtolower($method)) { + case 'get':$input = &$_GET; + break; + case 'post':$input = &$_POST; + break; + case 'put':parse_str(file_get_contents('php://input'), $input); + break; + case 'param': + switch ($_SERVER['REQUEST_METHOD']) { case 'POST': - $input = $_POST; + $input = $_POST; break; case 'PUT': parse_str(file_get_contents('php://input'), $input); break; default: - $input = $_GET; + $input = $_GET; } break; - case 'path' : - $input = array(); - if(!empty($_SERVER['PATH_INFO'])){ - $depr = C('URL_PATHINFO_DEPR'); - $input = explode($depr,trim($_SERVER['PATH_INFO'],$depr)); + case 'path': + $input = array(); + if (!empty($_SERVER['PATH_INFO'])) { + $depr = C('URL_PATHINFO_DEPR'); + $input = explode($depr, trim($_SERVER['PATH_INFO'], $depr)); } break; - case 'request' : $input =& $_REQUEST; break; - case 'session' : $input =& $_SESSION; break; - case 'cookie' : $input =& $_COOKIE; break; - case 'server' : $input =& $_SERVER; break; - case 'globals' : $input =& $GLOBALS; break; - case 'data' : $input =& $datas; break; + case 'request':$input = &$_REQUEST; + break; + case 'session':$input = &$_SESSION; + break; + case 'cookie':$input = &$_COOKIE; + break; + case 'server':$input = &$_SERVER; + break; + case 'globals':$input = &$GLOBALS; + break; + case 'data':$input = &$datas; + break; default: - return NULL; - } - if(''==$name) { // 获取全部变量 - $data = $input; - $filters = isset($filter)?$filter:C('DEFAULT_FILTER'); - if($filters) { - if(is_string($filters)){ - $filters = explode(',',$filters); + return null; + } + if ('' == $name) { + // 获取全部变量 + $data = $input; + $filters = isset($filter) ? $filter : C('DEFAULT_FILTER'); + if ($filters) { + if (is_string($filters)) { + $filters = explode(',', $filters); } - foreach($filters as $filter){ - $data = array_map_recursive($filter,$data); // 参数过滤 + foreach ($filters as $filter) { + $data = arrayMapRecursive($filter, $data); // 参数过滤 } } - }elseif(isset($input[$name])) { // 取值操作 - $data = $input[$name]; - $filters = isset($filter)?$filter:C('DEFAULT_FILTER'); - if($filters) { - if(is_string($filters)){ - $filters = explode(',',$filters); - }elseif(is_int($filters)){ - $filters = array($filters); + } elseif (isset($input[$name])) { + // 取值操作 + $data = $input[$name]; + $filters = isset($filter) ? $filter : C('DEFAULT_FILTER'); + if ($filters) { + if (is_string($filters)) { + $filters = explode(',', $filters); + } elseif (is_int($filters)) { + $filters = array($filters); } - - foreach($filters as $filter){ - if(function_exists($filter)) { - $data = is_array($data) ? array_map_recursive($filter,$data) : $filter($data); // 参数过滤 - }elseif(0===strpos($filter,'/')){ - // 支持正则验证 - if(1 !== preg_match($filter,(string)$data)){ - return isset($default) ? $default : NULL; - } - }else{ - $data = filter_var($data,is_int($filter) ? $filter : filter_id($filter)); - if(false === $data) { - return isset($default) ? $default : NULL; + + foreach ($filters as $filter) { + if (function_exists($filter)) { + $data = is_array($data) ? arrayMapRecursive($filter, $data) : $filter($data); // 参数过滤 + } elseif (0 === strpos($filter, '/')) { + // 支持正则验证 + if (1 !== preg_match($filter, (string) $data)) { + return isset($default) ? $default : null; + } + } else { + $data = filter_var($data, is_int($filter) ? $filter : filter_id($filter)); + if (false === $data) { + return isset($default) ? $default : null; } } } } - if(!empty($type)){ - switch(strtolower($type)){ - case 's': // 字符串 - $data = (string)$data; - break; - case 'a': // 数组 - $data = (array)$data; - break; - case 'd': // 数字 - $data = (int)$data; - break; - case 'f': // 浮点 - $data = (float)$data; - break; - case 'b': // 布尔 - $data = (boolean)$data; - break; - } + if (!empty($type)) { + switch (strtolower($type)) { + case 's': // 字符串 + $data = (string) $data; + break; + case 'a': // 数组 + $data = (array) $data; + break; + case 'd': // 数字 + $data = (int) $data; + break; + case 'f': // 浮点 + $data = (float) $data; + break; + case 'b': // 布尔 + $data = (boolean) $data; + break; + } } - }else{ // 变量默认值 - $data = isset($default)?$default:NULL; + } else { + // 变量默认值 + $data = isset($default) ? $default : null; } - is_array($data) && array_walk_recursive($data,'think_filter'); + is_array($data) && array_walk_recursive($data, 'think_filter'); return $data; } -function array_map_recursive($filter, $data) { - $result = array(); - foreach ($data as $key => $val) { - $result[$key] = is_array($val) - ? array_map_recursive($filter, $val) - : call_user_func($filter, $val); - } - return $result; - } +function arrayMapRecursive($filter, $data) +{ + $result = array(); + foreach ($data as $key => $val) { + $result[$key] = is_array($val) + ? arrayMapRecursive($filter, $val) + : call_user_func($filter, $val); + } + return $result; +} /** * 设置和获取统计数据 @@ -325,17 +373,21 @@ function array_map_recursive($filter, $data) { * @param integer $step 步进值 * @return mixed */ -function N($key, $step=0,$save=false) { - static $_num = array(); +function N($key, $step = 0, $save = false) +{ + static $_num = array(); if (!isset($_num[$key])) { - $_num[$key] = (false !== $save)? S('N_'.$key) : 0; + $_num[$key] = (false !== $save) ? S('N_' . $key) : 0; } - if (empty($step)) + if (empty($step)) { return $_num[$key]; - else + } else { $_num[$key] = $_num[$key] + (int) $step; - if(false !== $save){ // 保存结果 - S('N_'.$key,$_num[$key],$save); + } + + if (false !== $save) { + // 保存结果 + S('N_' . $key, $_num[$key], $save); } } @@ -346,9 +398,10 @@ function N($key, $step=0,$save=false) { * @param integer $type 转换类型 * @return string */ -function parse_name($name, $type=0) { +function parseName($name, $type = 0) +{ if ($type) { - return ucfirst(preg_replace_callback('/_([a-zA-Z])/', function($match){return strtoupper($match[1]);}, $name)); + return ucfirst(preg_replace_callback('/_([a-zA-Z])/', function ($match) {return strtoupper($match[1]);}, $name)); } else { return strtolower(trim(preg_replace("/[A-Z]/", "_\\0", $name), "_")); } @@ -359,10 +412,11 @@ function parse_name($name, $type=0) { * @param string $filename 文件地址 * @return boolean */ -function require_cache($filename) { +function requireCache($filename) +{ static $_importFiles = array(); if (!isset($_importFiles[$filename])) { - if (file_exists_case($filename)) { + if (fileExistsCase($filename)) { require $filename; $_importFiles[$filename] = true; } else { @@ -377,11 +431,14 @@ function require_cache($filename) { * @param string $filename 文件地址 * @return boolean */ -function file_exists_case($filename) { +function fileExistsCase($filename) +{ if (is_file($filename)) { if (IS_WIN && APP_DEBUG) { - if (basename(realpath($filename)) != basename($filename)) + if (basename(realpath($filename)) != basename($filename)) { return false; + } + } return true; } @@ -395,32 +452,38 @@ function file_exists_case($filename) { * @param string $ext 导入的文件扩展名 * @return boolean */ -function import($class, $baseUrl = '', $ext=EXT) { +function import($class, $baseUrl = '', $ext = EXT) +{ static $_file = array(); - $class = str_replace(array('.', '#'), array('/', '.'), $class); - if (isset($_file[$class . $baseUrl])) + $class = str_replace(array('.', '#'), array('/', '.'), $class); + if (isset($_file[$class . $baseUrl])) { return true; - else + } else { $_file[$class . $baseUrl] = true; - $class_strut = explode('/', $class); + } + + $class_strut = explode('/', $class); if (empty($baseUrl)) { if ('@' == $class_strut[0] || MODULE_NAME == $class_strut[0]) { //加载当前模块的类库 $baseUrl = MODULE_PATH; $class = substr_replace($class, '', 0, strlen($class_strut[0]) + 1); - }elseif (in_array($class_strut[0],array('Think','Org','Behavior','Com','Vendor')) || is_dir(LIB_PATH.$class_strut[0])) { + } elseif (in_array($class_strut[0], array('Think', 'Org', 'Behavior', 'Com', 'Vendor')) || is_dir(LIB_PATH . $class_strut[0])) { // 系统类库包和第三方类库包 $baseUrl = LIB_PATH; - }else { // 加载其他模块的类库 + } else { + // 加载其他模块的类库 $baseUrl = APP_PATH; } } - if (substr($baseUrl, -1) != '/') - $baseUrl .= '/'; - $classfile = $baseUrl . $class . $ext; - if (!class_exists(basename($class),false)) { + if (substr($baseUrl, -1) != '/') { + $baseUrl .= '/'; + } + + $classfile = $baseUrl . $class . $ext; + if (!class_exists(basename($class), false)) { // 如果类不存在 则导入类库文件 - return require_cache($classfile); + return requireCache($classfile); } } @@ -432,21 +495,26 @@ function import($class, $baseUrl = '', $ext=EXT) { * @param string $ext 导入的文件扩展名 * @return void */ -function load($name, $baseUrl='', $ext='.php') { +function load($name, $baseUrl = '', $ext = '.php') +{ $name = str_replace(array('.', '#'), array('/', '.'), $name); if (empty($baseUrl)) { - if (0 === strpos($name, '@/')) {//加载当前模块函数库 - $baseUrl = MODULE_PATH.'Common/'; - $name = substr($name, 2); - } else { //加载其他模块函数库 - $array = explode('/', $name); - $baseUrl = APP_PATH . array_shift($array).'/Common/'; - $name = implode('/',$array); + if (0 === strpos($name, '@/')) { +//加载当前模块函数库 + $baseUrl = MODULE_PATH . 'Common/'; + $name = substr($name, 2); + } else { + //加载其他模块函数库 + $array = explode('/', $name); + $baseUrl = APP_PATH . array_shift($array) . '/Common/'; + $name = implode('/', $array); } } - if (substr($baseUrl, -1) != '/') - $baseUrl .= '/'; - require_cache($baseUrl . $name . $ext); + if (substr($baseUrl, -1) != '/') { + $baseUrl .= '/'; + } + + requireCache($baseUrl . $name . $ext); } /** @@ -456,9 +524,12 @@ function load($name, $baseUrl='', $ext='.php') { * @param string $ext 类库后缀 * @return boolean */ -function vendor($class, $baseUrl = '', $ext='.php') { - if (empty($baseUrl)) +function vendor($class, $baseUrl = '', $ext = '.php') +{ + if (empty($baseUrl)) { $baseUrl = VENDOR_PATH; + } + return import($class, $baseUrl, $ext); } @@ -468,24 +539,30 @@ function vendor($class, $baseUrl = '', $ext='.php') { * @param string $layer 模型层名称 * @return Model */ -function D($name='',$layer='') { - if(empty($name)) return new Think\Model; - static $_model = array(); - $layer = $layer? : C('DEFAULT_M_LAYER'); - if(isset($_model[$name.$layer])) - return $_model[$name.$layer]; - $class = parse_res_name($name,$layer); - if(class_exists($class)) { - $model = new $class(basename($name)); - }elseif(false === strpos($name,'/')){ +function D($name = '', $layer = '') +{ + if (empty($name)) { + return new Think\Model; + } + + static $_model = array(); + $layer = $layer ?: C('DEFAULT_M_LAYER'); + if (isset($_model[$name . $layer])) { + return $_model[$name . $layer]; + } + + $class = parseResName($name, $layer); + if (class_exists($class)) { + $model = new $class(basename($name)); + } elseif (false === strpos($name, '/')) { // 自动加载公共模块下面的模型 - $class = '\\Common\\'.$layer.'\\'.$name.$layer; - $model = class_exists($class)? new $class($name) : new Think\Model($name); - }else { - Think\Log::record('D方法实例化没找到模型类'.$class,Think\Log::NOTICE); - $model = new Think\Model(basename($name)); + $class = '\\Common\\' . $layer . '\\' . $name . $layer; + $model = class_exists($class) ? new $class($name) : new Think\Model($name); + } else { + Think\Log::record('D方法实例化没找到模型类' . $class, Think\Log::NOTICE); + $model = new Think\Model(basename($name)); } - $_model[$name.$layer] = $model; + $_model[$name . $layer] = $model; return $model; } @@ -496,16 +573,19 @@ function D($name='',$layer='') { * @param mixed $connection 数据库连接信息 * @return Model */ -function M($name='', $tablePrefix='',$connection='') { - static $_model = array(); - if(strpos($name,':')) { - list($class,$name) = explode(':',$name); - }else{ - $class = 'Think\\Model'; - } - $guid = (is_array($connection)?implode('',$connection):$connection).$tablePrefix . $name . '_' . $class; - if (!isset($_model[$guid])) - $_model[$guid] = new $class($name,$tablePrefix,$connection); +function M($name = '', $tablePrefix = '', $connection = '') +{ + static $_model = array(); + if (strpos($name, ':')) { + list($class, $name) = explode(':', $name); + } else { + $class = 'Think\\Model'; + } + $guid = (is_array($connection) ? implode('', $connection) : $connection) . $tablePrefix . $name . '_' . $class; + if (!isset($_model[$guid])) { + $_model[$guid] = new $class($name, $tablePrefix, $connection); + } + return $_model[$guid]; } @@ -516,27 +596,31 @@ function M($name='', $tablePrefix='',$connection='') { * @param string $layer 分层名称 * @return string */ -function parse_res_name($name,$layer,$level=1){ - if(strpos($name,'://')) {// 指定扩展资源 - list($extend,$name) = explode('://',$name); - }else{ - $extend = ''; - } - if(strpos($name,'/') && substr_count($name, '/')>=$level){ // 指定模块 - list($module,$name) = explode('/',$name,2); - }else{ - $module = MODULE_NAME; - } - $array = explode('/',$name); - $class = $module.'\\'.$layer; - foreach($array as $name){ - $class .= '\\'.parse_name($name, 1); +function parseResName($name, $layer, $level = 1) +{ + if (strpos($name, '://')) { +// 指定扩展资源 + list($extend, $name) = explode('://', $name); + } else { + $extend = ''; + } + if (strpos($name, '/') && substr_count($name, '/') >= $level) { + // 指定模块 + list($module, $name) = explode('/', $name, 2); + } else { + $module = MODULE_NAME; + } + $array = explode('/', $name); + $class = $module . '\\' . $layer; + foreach ($array as $name) { + $class .= '\\' . parseName($name, 1); } // 导入资源类库 - if($extend){ // 扩展资源 - $class = $extend.'\\'.$class; + if ($extend) { + // 扩展资源 + $class = $extend . '\\' . $class; } - return $class.$layer; + return $class . $layer; } /** @@ -546,18 +630,21 @@ function parse_res_name($name,$layer,$level=1){ * @param integer $level 控制器层次 * @return Controller|false */ -function A($name,$layer='',$level='') { +function A($name, $layer = '', $level = '') +{ static $_action = array(); - $layer = $layer? : C('DEFAULT_C_LAYER'); - $level = $level? : ($layer == C('DEFAULT_C_LAYER')?C('CONTROLLER_LEVEL'):1); - if(isset($_action[$name.$layer])) - return $_action[$name.$layer]; - $class = parse_res_name($name,$layer,$level); - if(class_exists($class)) { - $action = new $class(); - $_action[$name.$layer] = $action; + $layer = $layer ?: C('DEFAULT_C_LAYER'); + $level = $level ?: (C('DEFAULT_C_LAYER') == $layer ? C('CONTROLLER_LEVEL') : 1); + if (isset($_action[$name . $layer])) { + return $_action[$name . $layer]; + } + + $class = parseResName($name, $layer, $level); + if (class_exists($class)) { + $action = new $class(); + $_action[$name . $layer] = $action; return $action; - }else { + } else { return false; } } @@ -569,17 +656,18 @@ function A($name,$layer='',$level='') { * @param string $layer 要调用的控制层名称 * @return mixed */ -function R($url,$vars=array(),$layer='') { - $info = pathinfo($url); - $action = $info['basename']; - $module = $info['dirname']; - $class = A($module,$layer); - if($class){ - if(is_string($vars)) { - parse_str($vars,$vars); +function R($url, $vars = array(), $layer = '') +{ + $info = pathinfo($url); + $action = $info['basename']; + $module = $info['dirname']; + $class = A($module, $layer); + if ($class) { + if (is_string($vars)) { + parse_str($vars, $vars); } - return call_user_func_array(array(&$class,$action.C('ACTION_SUFFIX')),$vars); - }else{ + return call_user_func_array(array(&$class, $action . C('ACTION_SUFFIX')), $vars); + } else { return false; } } @@ -590,13 +678,14 @@ function R($url,$vars=array(),$layer='') { * @param Mixed $params 传入的参数 * @return void */ -function B($name, &$params=NULL) { - if(strpos($name,'/')){ - list($name,$tag) = explode('/',$name); - }else{ - $tag = 'run'; +function B($name, &$params = null) +{ + if (strpos($name, '/')) { + list($name, $tag) = explode('/', $name); + } else { + $tag = 'run'; } - return \Think\Hook::exec($name,$tag,$params); + return \Think\Hook::exec($name, $tag, $params); } /** @@ -604,15 +693,16 @@ function B($name, &$params=NULL) { * @param string $content 代码内容 * @return string */ -function strip_whitespace($content) { - $stripStr = ''; +function stripWhitespace($content) +{ + $stripStr = ''; //分析php源码 $tokens = token_get_all($content); $last_space = false; for ($i = 0, $j = count($tokens); $i < $j; $i++) { if (is_string($tokens[$i])) { $last_space = false; - $stripStr .= $tokens[$i]; + $stripStr .= $tokens[$i]; } else { switch ($tokens[$i][0]) { //过滤各种PHP注释 @@ -622,7 +712,7 @@ function strip_whitespace($content) { //过滤空格 case T_WHITESPACE: if (!$last_space) { - $stripStr .= ' '; + $stripStr .= ' '; $last_space = true; } break; @@ -631,18 +721,18 @@ function strip_whitespace($content) { break; case T_END_HEREDOC: $stripStr .= "THINK;\n"; - for($k = $i+1; $k < $j; $k++) { - if(is_string($tokens[$k]) && $tokens[$k] == ';') { + for ($k = $i + 1; $k < $j; $k++) { + if (is_string($tokens[$k]) && ';' == $tokens[$k]) { $i = $k; break; - } else if($tokens[$k][0] == T_CLOSE_TAG) { + } else if (T_CLOSE_TAG == $tokens[$k][0]) { break; } } break; default: $last_space = false; - $stripStr .= $tokens[$i][1]; + $stripStr .= $tokens[$i][1]; } } } @@ -657,8 +747,9 @@ function strip_whitespace($content) { * @param boolean $strict 是否严谨 默认为true * @return void|string */ -function dump($var, $echo=true, $label=null, $strict=true) { - $label = ($label === null) ? '' : rtrim($label) . ' '; +function dump($var, $echo = true, $label = null, $strict = true) +{ + $label = (null === $label) ? '' : rtrim($label) . ' '; if (!$strict) { if (ini_get('html_errors')) { $output = print_r($var, true); @@ -676,10 +767,12 @@ function dump($var, $echo=true, $label=null, $strict=true) { } } if ($echo) { - echo($output); + echo ($output); return null; - }else + } else { return $output; + } + } /** @@ -689,24 +782,29 @@ function dump($var, $echo=true, $label=null, $strict=true) { * @param string $msg 重定向前的提示信息 * @return void */ -function redirect($url, $time=0, $msg='') { +function redirect($url, $time = 0, $msg = '') +{ //多行URL地址支持 - $url = str_replace(array("\n", "\r"), '', $url); - if (empty($msg)) - $msg = "系统将在{$time}秒之后自动跳转到{$url}!"; + $url = str_replace(array("\n", "\r"), '', $url); + if (empty($msg)) { + $msg = "系统将在{$time}秒之后自动跳转到{$url}!"; + } + if (!headers_sent()) { // redirect if (0 === $time) { header('Location: ' . $url); } else { header("refresh:{$time};url={$url}"); - echo($msg); + echo ($msg); } exit(); } else { - $str = ""; - if ($time != 0) + $str = ""; + if (0 != $time) { $str .= $msg; + } + exit($str); } } @@ -718,28 +816,34 @@ function redirect($url, $time=0, $msg='') { * @param mixed $options 缓存参数 * @return mixed */ -function S($name,$value='',$options=null) { - static $cache = ''; - if(is_array($options) && empty($cache)){ +function S($name, $value = '', $options = null) +{ + static $cache = ''; + if (is_array($options) && empty($cache)) { // 缓存操作的同时初始化 - $type = isset($options['type'])?$options['type']:''; - $cache = Think\Cache::getInstance($type,$options); - }elseif(is_array($name)) { // 缓存初始化 - $type = isset($name['type'])?$name['type']:''; - $cache = Think\Cache::getInstance($type,$name); + $type = isset($options['type']) ? $options['type'] : ''; + $cache = Think\Cache::getInstance($type, $options); + } elseif (is_array($name)) { + // 缓存初始化 + $type = isset($name['type']) ? $name['type'] : ''; + $cache = Think\Cache::getInstance($type, $name); return $cache; - }elseif(empty($cache)) { // 自动初始化 - $cache = Think\Cache::getInstance(); + } elseif (empty($cache)) { + // 自动初始化 + $cache = Think\Cache::getInstance(); } - if(''=== $value){ // 获取缓存 + if ('' === $value) { + // 获取缓存 return $cache->get($name); - }elseif(is_null($value)) { // 删除缓存 + } elseif (is_null($value)) { + // 删除缓存 return $cache->rm($name); - }else { // 缓存数据 - if(is_array($options)) { - $expire = isset($options['expire'])?$options['expire']:NULL; - }else{ - $expire = is_numeric($options)?$options:NULL; + } else { + // 缓存数据 + if (is_array($options)) { + $expire = isset($options['expire']) ? $options['expire'] : null; + } else { + $expire = is_numeric($options) ? $options : null; } return $cache->set($name, $value, $expire); } @@ -752,33 +856,36 @@ function S($name,$value='',$options=null) { * @param string $path 缓存路径 * @return mixed */ -function F($name, $value='', $path=DATA_PATH) { - static $_cache = array(); - $filename = $path . $name . '.php'; +function F($name, $value = '', $path = DATA_PATH) +{ + static $_cache = array(); + $filename = $path . $name . '.php'; if ('' !== $value) { if (is_null($value)) { // 删除缓存 - if(false !== strpos($name,'*')){ - return false; // TODO - }else{ + if (false !== strpos($name, '*')) { + return false; // TODO + } else { unset($_cache[$name]); - return Think\Storage::unlink($filename,'F'); + return Think\Storage::unlink($filename, 'F'); } } else { - Think\Storage::put($filename,serialize($value),'F'); + Think\Storage::put($filename, serialize($value), 'F'); // 缓存数据 - $_cache[$name] = $value; - return ; + $_cache[$name] = $value; + return; } } // 获取缓存数据 - if (isset($_cache[$name])) + if (isset($_cache[$name])) { return $_cache[$name]; - if (Think\Storage::has($filename,'F')){ - $value = unserialize(Think\Storage::read($filename,'F')); - $_cache[$name] = $value; + } + + if (Think\Storage::has($filename, 'F')) { + $value = unserialize(Think\Storage::read($filename, 'F')); + $_cache[$name] = $value; } else { - $value = false; + $value = false; } return $value; } @@ -788,7 +895,8 @@ function F($name, $value='', $path=DATA_PATH) { * @param mixed $mix 变量 * @return string */ -function to_guid_string($mix) { +function toGuidString($mix) +{ if (is_object($mix)) { return spl_object_hash($mix); } elseif (is_resource($mix)) { @@ -809,20 +917,21 @@ function to_guid_string($mix) { * @param string $encoding 数据编码 * @return string */ -function xml_encode($data, $root='think', $item='item', $attr='', $id='id', $encoding='utf-8') { - if(is_array($attr)){ +function xmlEncode($data, $root = 'think', $item = 'item', $attr = '', $id = 'id', $encoding = 'utf-8') +{ + if (is_array($attr)) { $_attr = array(); foreach ($attr as $key => $value) { $_attr[] = "{$key}=\"{$value}\""; } $attr = implode(' ', $_attr); } - $attr = trim($attr); - $attr = empty($attr) ? '' : " {$attr}"; - $xml = ""; - $xml .= "<{$root}{$attr}>"; - $xml .= data_to_xml($data, $item, $id); - $xml .= ""; + $attr = trim($attr); + $attr = empty($attr) ? '' : " {$attr}"; + $xml = ""; + $xml .= "<{$root}{$attr}>"; + $xml .= dataToXml($data, $item, $id); + $xml .= ""; return $xml; } @@ -833,16 +942,17 @@ function xml_encode($data, $root='think', $item='item', $attr='', $id='id', $enc * @param string $id 数字索引key转换为的属性名 * @return string */ -function data_to_xml($data, $item='item', $id='id') { +function dataToXml($data, $item = 'item', $id = 'id') +{ $xml = $attr = ''; foreach ($data as $key => $val) { - if(is_numeric($key)){ + if (is_numeric($key)) { $id && $attr = " {$id}=\"{$key}\""; - $key = $item; + $key = $item; } - $xml .= "<{$key}{$attr}>"; - $xml .= (is_array($val) || is_object($val)) ? data_to_xml($val, $item, $id) : $val; - $xml .= ""; + $xml .= "<{$key}{$attr}>"; + $xml .= (is_array($val) || is_object($val)) ? dataToXml($val, $item, $id) : $val; + $xml .= ""; } return $xml; } @@ -853,97 +963,144 @@ function data_to_xml($data, $item='item', $id='id') { * @param mixed $value session值 * @return mixed */ -function session($name,$value='') { - $prefix = C('SESSION_PREFIX'); - if(is_array($name)) { // session初始化 在session_start 之前调用 - if(isset($name['prefix'])) C('SESSION_PREFIX',$name['prefix']); - if(C('VAR_SESSION_ID') && isset($_REQUEST[C('VAR_SESSION_ID')])){ +function session($name, $value = '') +{ + $prefix = C('SESSION_PREFIX'); + if (is_array($name)) { + // session初始化 在session_start 之前调用 + if (isset($name['prefix'])) { + C('SESSION_PREFIX', $name['prefix']); + } + + if (C('VAR_SESSION_ID') && isset($_REQUEST[C('VAR_SESSION_ID')])) { session_id($_REQUEST[C('VAR_SESSION_ID')]); - }elseif(isset($name['id'])) { + } elseif (isset($name['id'])) { session_id($name['id']); } - if('common' != APP_MODE){ // 其它模式可能不支持 + if ('common' != APP_MODE) { + // 其它模式可能不支持 ini_set('session.auto_start', 0); } - if(isset($name['name'])) session_name($name['name']); - if(isset($name['path'])) session_save_path($name['path']); - if(isset($name['domain'])) ini_set('session.cookie_domain', $name['domain']); - if(isset($name['expire'])) ini_set('session.gc_maxlifetime', $name['expire']); - if(isset($name['use_trans_sid'])) ini_set('session.use_trans_sid', $name['use_trans_sid']?1:0); - if(isset($name['use_cookies'])) ini_set('session.use_cookies', $name['use_cookies']?1:0); - if(isset($name['cache_limiter'])) session_cache_limiter($name['cache_limiter']); - if(isset($name['cache_expire'])) session_cache_expire($name['cache_expire']); - if(isset($name['type'])) C('SESSION_TYPE',$name['type']); - if(C('SESSION_TYPE')) { // 读取session驱动 - $type = C('SESSION_TYPE'); - $class = strpos($type,'\\')? $type : 'Think\\Session\\Driver\\'. ucwords(strtolower($type)); - $hander = new $class(); + if (isset($name['name'])) { + session_name($name['name']); + } + + if (isset($name['path'])) { + session_save_path($name['path']); + } + + if (isset($name['domain'])) { + ini_set('session.cookie_domain', $name['domain']); + } + + if (isset($name['expire'])) { + ini_set('session.gc_maxlifetime', $name['expire']); + } + + if (isset($name['use_trans_sid'])) { + ini_set('session.use_trans_sid', $name['use_trans_sid'] ? 1 : 0); + } + + if (isset($name['use_cookies'])) { + ini_set('session.use_cookies', $name['use_cookies'] ? 1 : 0); + } + + if (isset($name['cache_limiter'])) { + session_cache_limiter($name['cache_limiter']); + } + + if (isset($name['cache_expire'])) { + session_cache_expire($name['cache_expire']); + } + + if (isset($name['type'])) { + C('SESSION_TYPE', $name['type']); + } + + if (C('SESSION_TYPE')) { + // 读取session驱动 + $type = C('SESSION_TYPE'); + $class = strpos($type, '\\') ? $type : 'Think\\Session\\Driver\\' . ucwords(strtolower($type)); + $hander = new $class(); session_set_save_handler( - array(&$hander,"open"), - array(&$hander,"close"), - array(&$hander,"read"), - array(&$hander,"write"), - array(&$hander,"destroy"), - array(&$hander,"gc")); + array(&$hander, "open"), + array(&$hander, "close"), + array(&$hander, "read"), + array(&$hander, "write"), + array(&$hander, "destroy"), + array(&$hander, "gc")); } // 启动session - if(C('SESSION_AUTO_START')) session_start(); - }elseif('' === $value){ - if(0===strpos($name,'[')) { // session 操作 - if('[pause]'==$name){ // 暂停session + if (C('SESSION_AUTO_START')) { + session_start(); + } + + } elseif ('' === $value) { + if (0 === strpos($name, '[')) { + // session 操作 + if ('[pause]' == $name) { // 暂停session session_write_close(); - }elseif('[start]'==$name){ // 启动session + } elseif ('[start]' == $name) { + // 启动session session_start(); - }elseif('[destroy]'==$name){ // 销毁session - $_SESSION = array(); + } elseif ('[destroy]' == $name) { + // 销毁session + $_SESSION = array(); session_unset(); session_destroy(); - }elseif('[regenerate]'==$name){ // 重新生成id + } elseif ('[regenerate]' == $name) { + // 重新生成id session_regenerate_id(); } - }elseif(0===strpos($name,'?')){ // 检查session - $name = substr($name,1); - if(strpos($name,'.')){ // 支持数组 - list($name1,$name2) = explode('.',$name); - return $prefix?isset($_SESSION[$prefix][$name1][$name2]):isset($_SESSION[$name1][$name2]); - }else{ - return $prefix?isset($_SESSION[$prefix][$name]):isset($_SESSION[$name]); + } elseif (0 === strpos($name, '?')) { + // 检查session + $name = substr($name, 1); + if (strpos($name, '.')) { + // 支持数组 + list($name1, $name2) = explode('.', $name); + return $prefix ? isset($_SESSION[$prefix][$name1][$name2]) : isset($_SESSION[$name1][$name2]); + } else { + return $prefix ? isset($_SESSION[$prefix][$name]) : isset($_SESSION[$name]); } - }elseif(is_null($name)){ // 清空session - if($prefix) { + } elseif (is_null($name)) { + // 清空session + if ($prefix) { unset($_SESSION[$prefix]); - }else{ + } else { $_SESSION = array(); } - }elseif($prefix){ // 获取session - if(strpos($name,'.')){ - list($name1,$name2) = explode('.',$name); - return isset($_SESSION[$prefix][$name1][$name2])?$_SESSION[$prefix][$name1][$name2]:null; - }else{ - return isset($_SESSION[$prefix][$name])?$_SESSION[$prefix][$name]:null; - } - }else{ - if(strpos($name,'.')){ - list($name1,$name2) = explode('.',$name); - return isset($_SESSION[$name1][$name2])?$_SESSION[$name1][$name2]:null; - }else{ - return isset($_SESSION[$name])?$_SESSION[$name]:null; - } + } elseif ($prefix) { + // 获取session + if (strpos($name, '.')) { + list($name1, $name2) = explode('.', $name); + return isset($_SESSION[$prefix][$name1][$name2]) ? $_SESSION[$prefix][$name1][$name2] : null; + } else { + return isset($_SESSION[$prefix][$name]) ? $_SESSION[$prefix][$name] : null; + } + } else { + if (strpos($name, '.')) { + list($name1, $name2) = explode('.', $name); + return isset($_SESSION[$name1][$name2]) ? $_SESSION[$name1][$name2] : null; + } else { + return isset($_SESSION[$name]) ? $_SESSION[$name] : null; + } } - }elseif(is_null($value)){ // 删除session - if($prefix){ + } elseif (is_null($value)) { + // 删除session + if ($prefix) { unset($_SESSION[$prefix][$name]); - }else{ + } else { unset($_SESSION[$name]); } - }else{ // 设置session - if($prefix){ + } else { + // 设置session + if ($prefix) { if (!is_array($_SESSION[$prefix])) { $_SESSION[$prefix] = array(); } - $_SESSION[$prefix][$name] = $value; - }else{ - $_SESSION[$name] = $value; + $_SESSION[$prefix][$name] = $value; + } else { + $_SESSION[$name] = $value; } } } @@ -955,29 +1112,35 @@ function session($name,$value='') { * @param mixed $options cookie参数 * @return mixed */ -function cookie($name, $value='', $option=null) { +function cookie($name, $value = '', $option = null) +{ // 默认设置 $config = array( - 'prefix' => C('COOKIE_PREFIX'), // cookie 名称前缀 - 'expire' => C('COOKIE_EXPIRE'), // cookie 保存时间 - 'path' => C('COOKIE_PATH'), // cookie 保存路径 - 'domain' => C('COOKIE_DOMAIN'), // cookie 有效域名 + 'prefix' => C('COOKIE_PREFIX'), // cookie 名称前缀 + 'expire' => C('COOKIE_EXPIRE'), // cookie 保存时间 + 'path' => C('COOKIE_PATH'), // cookie 保存路径 + 'domain' => C('COOKIE_DOMAIN'), // cookie 有效域名 ); // 参数设置(会覆盖黙认设置) if (!is_null($option)) { - if (is_numeric($option)) + if (is_numeric($option)) { $option = array('expire' => $option); - elseif (is_string($option)) + } elseif (is_string($option)) { parse_str($option, $option); - $config = array_merge($config, array_change_key_case($option)); + } + + $config = array_merge($config, array_change_key_case($option)); } // 清除指定前缀的所有cookie if (is_null($name)) { - if (empty($_COOKIE)) + if (empty($_COOKIE)) { return; + } + // 要删除的cookie前缀,不指定则删除config设置的指定前缀 $prefix = empty($value) ? $config['prefix'] : $value; - if (!empty($prefix)) {// 如果前缀为空字符串将不作处理直接返回 + if (!empty($prefix)) { +// 如果前缀为空字符串将不作处理直接返回 foreach ($_COOKIE as $key => $val) { if (0 === stripos($key, $prefix)) { setcookie($key, '', time() - 3600, $config['path'], $config['domain']); @@ -989,15 +1152,15 @@ function cookie($name, $value='', $option=null) { } $name = $config['prefix'] . $name; if ('' === $value) { - if(isset($_COOKIE[$name])){ - $value = $_COOKIE[$name]; - if(0===strpos($value,'think:')){ - $value = substr($value,6); - return array_map('urldecode',json_decode(MAGIC_QUOTES_GPC?stripslashes($value):$value,true)); - }else{ + if (isset($_COOKIE[$name])) { + $value = $_COOKIE[$name]; + if (0 === strpos($value, 'think:')) { + $value = substr($value, 6); + return array_map('urldecode', json_decode(MAGIC_QUOTES_GPC ? stripslashes($value) : $value, true)); + } else { return $value; } - }else{ + } else { return null; } } else { @@ -1006,8 +1169,8 @@ function cookie($name, $value='', $option=null) { unset($_COOKIE[$name]); // 删除指定cookie } else { // 设置cookie - if(is_array($value)){ - $value = 'think:'.json_encode(array_map('urlencode',$value)); + if (is_array($value)) { + $value = 'think:' . json_encode(array_map('urlencode', $value)); } $expire = !empty($config['expire']) ? time() + intval($config['expire']) : 0; setcookie($name, $value, $expire, $config['path'], $config['domain']); @@ -1020,23 +1183,30 @@ function cookie($name, $value='', $option=null) { * 加载动态扩展文件 * @return void */ -function load_ext_file($path) { +function loadExtFile($path) +{ // 加载自定义外部文件 - if(C('LOAD_EXT_FILE')) { - $files = explode(',',C('LOAD_EXT_FILE')); - foreach ($files as $file){ - $file = $path.'Common/'.$file.'.php'; - if(is_file($file)) include $file; + if (C('LOAD_EXT_FILE')) { + $files = explode(',', C('LOAD_EXT_FILE')); + foreach ($files as $file) { + $file = $path . 'Common/' . $file . '.php'; + if (is_file($file)) { + include $file; + } + } } // 加载自定义的动态配置文件 - if(C('LOAD_EXT_CONFIG')) { - $configs = C('LOAD_EXT_CONFIG'); - if(is_string($configs)) $configs = explode(',',$configs); - foreach ($configs as $key=>$config){ - $file = $path.'Conf/'.$config.'.php'; - if(is_file($file)) { - is_numeric($key)?C(include $file):C($key,include $file); + if (C('LOAD_EXT_CONFIG')) { + $configs = C('LOAD_EXT_CONFIG'); + if (is_string($configs)) { + $configs = explode(',', $configs); + } + + foreach ($configs as $key => $config) { + $file = $path . 'Conf/' . $config . '.php'; + if (is_file($file)) { + is_numeric($key) ? C(include $file) : C($key, include $file); } } } @@ -1047,22 +1217,29 @@ function load_ext_file($path) { * @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字 * @return mixed */ -function get_client_ip($type = 0) { - $type = $type ? 1 : 0; - static $ip = NULL; - if ($ip !== NULL) return $ip[$type]; +function getClientIp($type = 0) +{ + $type = $type ? 1 : 0; + static $ip = null; + if (null !== $ip) { + return $ip[$type]; + } + if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { - $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); - $pos = array_search('unknown',$arr); - if(false !== $pos) unset($arr[$pos]); - $ip = trim($arr[0]); - }elseif (isset($_SERVER['HTTP_CLIENT_IP'])) { - $ip = $_SERVER['HTTP_CLIENT_IP']; - }elseif (isset($_SERVER['REMOTE_ADDR'])) { - $ip = $_SERVER['REMOTE_ADDR']; + $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); + $pos = array_search('unknown', $arr); + if (false !== $pos) { + unset($arr[$pos]); + } + + $ip = trim($arr[0]); + } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) { + $ip = $_SERVER['HTTP_CLIENT_IP']; + } elseif (isset($_SERVER['REMOTE_ADDR'])) { + $ip = $_SERVER['REMOTE_ADDR']; } // IP地址合法验证 - $long = sprintf("%u",ip2long($ip)); + $long = sprintf("%u", ip2long($ip)); $ip = $long ? array($ip, $long) : array('0.0.0.0', 0); return $ip[$type]; } @@ -1072,13 +1249,14 @@ function get_client_ip($type = 0) { * @param integer $code 状态码 * @return void */ -function send_http_status($code) { +function sendHttpStatus($code) +{ static $_status = array( // Success 2xx 200 => 'OK', // Redirection 3xx 301 => 'Moved Permanently', - 302 => 'Moved Temporarily ', // 1.1 + 302 => 'Moved Temporarily ', // 1.1 // Client Error 4xx 400 => 'Bad Request', 403 => 'Forbidden', @@ -1087,23 +1265,25 @@ function send_http_status($code) { 500 => 'Internal Server Error', 503 => 'Service Unavailable', ); - if(isset($_status[$code])) { - header('HTTP/1.1 '.$code.' '.$_status[$code]); + if (isset($_status[$code])) { + header('HTTP/1.1 ' . $code . ' ' . $_status[$code]); // 确保FastCGI模式下正常 - header('Status:'.$code.' '.$_status[$code]); + header('Status:' . $code . ' ' . $_status[$code]); } } // 不区分大小写的in_array实现 -function in_array_case($value,$array){ - return in_array(strtolower($value),array_map('strtolower',$array)); +function inArrayCase($value, $array) +{ + return in_array(strtolower($value), array_map('strtolower', $array)); } -function think_filter(&$value){ - // TODO 其他安全过滤 +function thinkFilter(&$value) +{ + // TODO 其他安全过滤 - // 过滤查询特殊字符 - if(preg_match('/^(EXP|NEQ|GT|EGT|LT|ELT|OR|XOR|LIKE|NOTLIKE|NOT BETWEEN|NOTBETWEEN|BETWEEN|NOTIN|NOT IN|IN)$/i',$value)){ + // 过滤查询特殊字符 + if (preg_match('/^(EXP|NEQ|GT|EGT|LT|ELT|OR|XOR|LIKE|NOTLIKE|NOT BETWEEN|NOTBETWEEN|BETWEEN|NOTIN|NOT IN|IN)$/i', $value)) { $value .= ' '; } -} \ No newline at end of file +} diff --git a/ThinkPHP/Mode/Lite/App.class.php b/ThinkPHP/Mode/Lite/App.class.php index 78e5a14c9..8915d4e42 100644 --- a/ThinkPHP/Mode/Lite/App.class.php +++ b/ThinkPHP/Mode/Lite/App.class.php @@ -9,44 +9,48 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think; + /** * ThinkPHP 应用程序类 执行应用过程管理 */ -class App { + +class App +{ /** * 应用程序初始化 * @access public * @return void */ - static public function init() { + public static function init() + { // 日志目录转换为绝对路径 默认情况下存储到公共模块下面 - C('LOG_PATH', realpath(LOG_PATH).'/Common/'); + C('LOG_PATH', realpath(LOG_PATH) . '/Common/'); // 定义当前请求的系统常量 - define('NOW_TIME', $_SERVER['REQUEST_TIME']); - define('REQUEST_METHOD',$_SERVER['REQUEST_METHOD']); - define('IS_GET', REQUEST_METHOD =='GET' ? true : false); - define('IS_POST', REQUEST_METHOD =='POST' ? true : false); - define('IS_PUT', REQUEST_METHOD =='PUT' ? true : false); - define('IS_DELETE', REQUEST_METHOD =='DELETE' ? true : false); + define('NOW_TIME', $_SERVER['REQUEST_TIME']); + define('REQUEST_METHOD', $_SERVER['REQUEST_METHOD']); + define('IS_GET', REQUEST_METHOD == 'GET' ? true : false); + define('IS_POST', REQUEST_METHOD == 'POST' ? true : false); + define('IS_PUT', REQUEST_METHOD == 'PUT' ? true : false); + define('IS_DELETE', REQUEST_METHOD == 'DELETE' ? true : false); // URL调度 Dispatcher::dispatch(); - if(C('REQUEST_VARS_FILTER')){ - // 全局安全过滤 - array_walk_recursive($_GET, 'think_filter'); - array_walk_recursive($_POST, 'think_filter'); - array_walk_recursive($_REQUEST, 'think_filter'); - } + if (C('REQUEST_VARS_FILTER')) { + // 全局安全过滤 + array_walk_recursive($_GET, 'think_filter'); + array_walk_recursive($_POST, 'think_filter'); + array_walk_recursive($_REQUEST, 'think_filter'); + } - define('IS_AJAX', ((isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') || !empty($_POST[C('VAR_AJAX_SUBMIT')]) || !empty($_GET[C('VAR_AJAX_SUBMIT')])) ? true : false); + define('IS_AJAX', ((isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') || !empty($_POST[C('VAR_AJAX_SUBMIT')]) || !empty($_GET[C('VAR_AJAX_SUBMIT')])) ? true : false); // TMPL_EXCEPTION_FILE 改为绝对地址 - C('TMPL_EXCEPTION_FILE',realpath(C('TMPL_EXCEPTION_FILE'))); - return ; + C('TMPL_EXCEPTION_FILE', realpath(C('TMPL_EXCEPTION_FILE'))); + return; } /** @@ -54,86 +58,88 @@ static public function init() { * @access public * @return void */ - static public function exec() { - - if(!preg_match('/^[A-Za-z](\/|\w)*$/',CONTROLLER_NAME)){ // 安全检测 - $module = false; - }else{ + public static function exec() + { + + if (!preg_match('/^[A-Za-z](\/|\w)*$/', CONTROLLER_NAME)) { + // 安全检测 + $module = false; + } else { //创建控制器实例 - $module = controller(CONTROLLER_NAME); + $module = controller(CONTROLLER_NAME); } - if(!$module) { + if (!$module) { // 是否定义Empty控制器 $module = A('Empty'); - if(!$module){ - E(L('_CONTROLLER_NOT_EXIST_').':'.CONTROLLER_NAME); + if (!$module) { + E(L('_CONTROLLER_NOT_EXIST_') . ':' . CONTROLLER_NAME); } } // 获取当前操作名 支持动态路由 - $action = ACTION_NAME.C('ACTION_SUFFIX'); + $action = ACTION_NAME . C('ACTION_SUFFIX'); - try{ - if(!preg_match('/^[A-Za-z](\w)*$/',$action)){ + try { + if (!preg_match('/^[A-Za-z](\w)*$/', $action)) { // 非法操作 throw new \ReflectionException(); } //执行当前操作 - $method = new \ReflectionMethod($module, $action); - if($method->isPublic() && !$method->isStatic()) { - $class = new \ReflectionClass($module); + $method = new \ReflectionMethod($module, $action); + if ($method->isPublic() && !$method->isStatic()) { + $class = new \ReflectionClass($module); // URL参数绑定检测 - if($method->getNumberOfParameters()>0 && C('URL_PARAMS_BIND')){ - switch($_SERVER['REQUEST_METHOD']) { + if ($method->getNumberOfParameters() > 0 && C('URL_PARAMS_BIND')) { + switch ($_SERVER['REQUEST_METHOD']) { case 'POST': - $vars = array_merge($_GET,$_POST); + $vars = array_merge($_GET, $_POST); break; case 'PUT': parse_str(file_get_contents('php://input'), $vars); break; default: - $vars = $_GET; + $vars = $_GET; } - $params = $method->getParameters(); - $paramsBindType = C('URL_PARAMS_BIND_TYPE'); - foreach ($params as $param){ + $params = $method->getParameters(); + $paramsBindType = C('URL_PARAMS_BIND_TYPE'); + foreach ($params as $param) { $name = $param->getName(); - if( 1 == $paramsBindType && !empty($vars) ){ - $args[] = array_shift($vars); - }elseif( 0 == $paramsBindType && isset($vars[$name])){ - $args[] = $vars[$name]; - }elseif($param->isDefaultValueAvailable()){ - $args[] = $param->getDefaultValue(); - }else{ - E(L('_PARAM_ERROR_').':'.$name); - } + if (1 == $paramsBindType && !empty($vars)) { + $args[] = array_shift($vars); + } elseif (0 == $paramsBindType && isset($vars[$name])) { + $args[] = $vars[$name]; + } elseif ($param->isDefaultValueAvailable()) { + $args[] = $param->getDefaultValue(); + } else { + E(L('_PARAM_ERROR_') . ':' . $name); + } } // 开启绑定参数过滤机制 - if(C('URL_PARAMS_SAFE')){ - $filters = C('URL_PARAMS_FILTER')?:C('DEFAULT_FILTER'); - if($filters) { - $filters = explode(',',$filters); - foreach($filters as $filter){ - $args = array_map_recursive($filter,$args); // 参数过滤 + if (C('URL_PARAMS_SAFE')) { + $filters = C('URL_PARAMS_FILTER') ?: C('DEFAULT_FILTER'); + if ($filters) { + $filters = explode(',', $filters); + foreach ($filters as $filter) { + $args = array_map_recursive($filter, $args); // 参数过滤 } - } + } } - array_walk_recursive($args,'think_filter'); - $method->invokeArgs($module,$args); - }else{ + array_walk_recursive($args, 'think_filter'); + $method->invokeArgs($module, $args); + } else { $method->invoke($module); } - }else{ + } else { // 操作方法不是Public 抛出异常 throw new \ReflectionException(); } - } catch (\ReflectionException $e) { + } catch (\ReflectionException $e) { // 方法调用发生异常后 引导到__call方法处理 - $method = new \ReflectionMethod($module,'__call'); - $method->invokeArgs($module,array($action,'')); + $method = new \ReflectionMethod($module, '__call'); + $method->invokeArgs($module, array($action, '')); } - return ; + return; } /** @@ -141,16 +147,17 @@ static public function exec() { * @access public * @return void */ - static public function run() { + public static function run() + { App::init(); // Session初始化 - if(!IS_CLI){ + if (!IS_CLI) { session(C('SESSION_OPTIONS')); } // 记录应用初始化时间 G('initTime'); App::exec(); - return ; + return; } -} \ No newline at end of file +} diff --git a/ThinkPHP/Mode/Lite/Controller.class.php b/ThinkPHP/Mode/Lite/Controller.class.php index 9d25a7a34..3e021ec92 100644 --- a/ThinkPHP/Mode/Lite/Controller.class.php +++ b/ThinkPHP/Mode/Lite/Controller.class.php @@ -9,35 +9,40 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think; + /** * ThinkPHP 控制器基类 抽象类 */ -abstract class Controller { +abstract class Controller +{ /** * 视图实例对象 * @var view * @access protected - */ - protected $view = null; + */ + protected $view = null; /** * 控制器参数 * @var config * @access protected - */ - protected $config = array(); + */ + protected $config = array(); - /** + /** * 架构函数 取得模板对象实例 * @access public */ - public function __construct() { + public function __construct() + { //实例化视图类 - $this->view = Think::instance('Think\View'); + $this->view = Think::instance('Think\View'); //控制器初始化 - if(method_exists($this,'_initialize')) + if (method_exists($this, '_initialize')) { $this->_initialize(); + } + } /** @@ -51,8 +56,9 @@ public function __construct() { * @param string $prefix 模板缓存前缀 * @return void */ - protected function display($templateFile='',$charset='',$contentType='',$content='',$prefix='') { - $this->view->display($templateFile,$charset,$contentType,$content,$prefix); + protected function display($templateFile = '', $charset = '', $contentType = '', $content = '', $prefix = '') + { + $this->view->display($templateFile, $charset, $contentType, $content, $prefix); } /** @@ -64,8 +70,9 @@ protected function display($templateFile='',$charset='',$contentType='',$content * @param string $prefix 模板缓存前缀 * @return mixed */ - protected function show($content,$charset='',$contentType='',$prefix='') { - $this->view->display('',$charset,$contentType,$content,$prefix); + protected function show($content, $charset = '', $contentType = '', $prefix = '') + { + $this->view->display('', $charset, $contentType, $content, $prefix); } /** @@ -75,11 +82,12 @@ protected function show($content,$charset='',$contentType='',$prefix='') { * @param string $templateFile 指定要调用的模板文件 * 默认为空 由系统自动定位模板文件 * @param string $content 模板输出内容 - * @param string $prefix 模板缓存前缀* + * @param string $prefix 模板缓存前缀* * @return string */ - protected function fetch($templateFile='',$content='',$prefix='') { - return $this->view->fetch($templateFile,$content,$prefix); + protected function fetch($templateFile = '', $content = '', $prefix = '') + { + return $this->view->fetch($templateFile, $content, $prefix); } /** @@ -88,7 +96,8 @@ protected function fetch($templateFile='',$content='',$prefix='') { * @param string $theme 模版主题 * @return Action */ - protected function theme($theme){ + protected function theme($theme) + { $this->view->theme($theme); return $this; } @@ -100,13 +109,15 @@ protected function theme($theme){ * @param mixed $value 变量的值 * @return Action */ - protected function assign($name,$value='') { - $this->view->assign($name,$value); + protected function assign($name, $value = '') + { + $this->view->assign($name, $value); return $this; } - public function __set($name,$value) { - $this->assign($name,$value); + public function __set($name, $value) + { + $this->assign($name, $value); } /** @@ -115,11 +126,13 @@ public function __set($name,$value) { * @param string $name 模板显示变量 * @return mixed */ - public function get($name='') { - return $this->view->get($name); + public function get($name = '') + { + return $this->view->get($name); } - public function __get($name) { + public function __get($name) + { return $this->get($name); } @@ -129,7 +142,8 @@ public function __get($name) { * @param string $name 名称 * @return boolean */ - public function __isset($name) { + public function __isset($name) + { return $this->get($name); } @@ -140,19 +154,20 @@ public function __isset($name) { * @param array $args 参数 * @return mixed */ - public function __call($method,$args) { - if( 0 === strcasecmp($method,ACTION_NAME.C('ACTION_SUFFIX'))) { - if(method_exists($this,'_empty')) { + 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->_empty($method, $args); + } elseif (file_exists_case($this->view->parseTemplate())) { // 检查是否存在默认模版 如果有直接输出模版 $this->display(); - }else{ - E(L('_ERROR_ACTION_').':'.ACTION_NAME); + } else { + E(L('_ERROR_ACTION_') . ':' . ACTION_NAME); } - }else{ - E(__CLASS__.':'.$method.L('_METHOD_NOT_EXIST_')); + } else { + E(__CLASS__ . ':' . $method . L('_METHOD_NOT_EXIST_')); return; } } @@ -165,8 +180,9 @@ public function __call($method,$args) { * @param mixed $ajax 是否为Ajax方式 当数字时指定跳转时间 * @return void */ - protected function error($message='',$jumpUrl='',$ajax=false) { - $this->dispatchJump($message,0,$jumpUrl,$ajax); + protected function error($message = '', $jumpUrl = '', $ajax = false) + { + $this->dispatchJump($message, 0, $jumpUrl, $ajax); } /** @@ -177,8 +193,9 @@ protected function error($message='',$jumpUrl='',$ajax=false) { * @param mixed $ajax 是否为Ajax方式 当数字时指定跳转时间 * @return void */ - protected function success($message='',$jumpUrl='',$ajax=false) { - $this->dispatchJump($message,1,$jumpUrl,$ajax); + protected function success($message = '', $jumpUrl = '', $ajax = false) + { + $this->dispatchJump($message, 1, $jumpUrl, $ajax); } /** @@ -189,24 +206,28 @@ protected function success($message='',$jumpUrl='',$ajax=false) { * @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' : + 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'); - $data = json_encode($data,$json_option); + $data = json_encode($data, $json_option); break; 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'); - $data = $handler.'('.json_encode($data,$json_option).');'; + $handler = isset($_GET[C('VAR_JSONP_HANDLER')]) ? $_GET[C('VAR_JSONP_HANDLER')] : C('DEFAULT_JSONP_HANDLER'); + $data = $handler . '(' . json_encode($data, $json_option) . ');'; break; - case 'EVAL' : + case 'EVAL': // 返回可执行的js脚本 header('Content-Type:text/html; charset=utf-8'); - break; + break; } exit($data); } @@ -220,9 +241,10 @@ protected function ajaxReturn($data,$type='',$json_option=0) { * @param string $msg 跳转提示信息 * @return void */ - protected function redirect($url,$params=array(),$delay=0,$msg='') { - $url = U($url,$params); - redirect($url,$delay,$msg); + protected function redirect($url, $params = array(), $delay = 0, $msg = '') + { + $url = U($url, $params); + redirect($url, $delay, $msg); } /** @@ -236,39 +258,63 @@ protected function redirect($url,$params=array(),$delay=0,$msg='') { * @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; + 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); + 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_')); + $this->assign('msgTitle', $status ? L('_OPERATION_SUCCESS_') : L('_OPERATION_FAIL_')); //如果设置了关闭窗口,则提示完毕后自动关闭窗口 - if($this->get('closeWin')) $this->assign('jumpUrl','javascript:window.close();'); - $this->assign('status',$status); // 状态 + 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);// 提示信息 + C('HTML_CACHE_ON', false); + if ($status) { + //发送成功信息 + $this->assign('message', $message); // 提示信息 // 成功操作后默认停留1秒 - if(!isset($this->waitSecond)) $this->assign('waitSecond','1'); + if (!isset($this->waitSecond)) { + $this->assign('waitSecond', '1'); + } + // 默认操作成功自动返回操作前页面 - if(!isset($this->jumpUrl)) $this->assign("jumpUrl",$_SERVER["HTTP_REFERER"]); + if (!isset($this->jumpUrl)) { + $this->assign("jumpUrl", $_SERVER["HTTP_REFERER"]); + } + $this->display(C('TMPL_ACTION_SUCCESS')); - }else{ - $this->assign('error',$message);// 提示信息 + } else { + $this->assign('error', $message); // 提示信息 //发生错误时候默认停留3秒 - if(!isset($this->waitSecond)) $this->assign('waitSecond','3'); + if (!isset($this->waitSecond)) { + $this->assign('waitSecond', '3'); + } + // 默认发生错误的话自动返回上页 - if(!isset($this->jumpUrl)) $this->assign('jumpUrl',"javascript:history.back(-1);"); + if (!isset($this->jumpUrl)) { + $this->assign('jumpUrl', "javascript:history.back(-1);"); + } + $this->display(C('TMPL_ACTION_ERROR')); // 中止执行 避免出错后继续执行 - exit ; + exit; } } diff --git a/ThinkPHP/Mode/Lite/Dispatcher.class.php b/ThinkPHP/Mode/Lite/Dispatcher.class.php index ff5c5dc28..6e471ca45 100644 --- a/ThinkPHP/Mode/Lite/Dispatcher.class.php +++ b/ThinkPHP/Mode/Lite/Dispatcher.class.php @@ -9,223 +9,247 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think; + /** * ThinkPHP内置的Dispatcher类 * 完成URL解析、路由和调度 */ -class Dispatcher { + +class Dispatcher +{ /** * URL映射到控制器 * @access public * @return void */ - static public function dispatch() { - $varPath = C('VAR_PATHINFO'); - $varModule = C('VAR_MODULE'); - $varController = C('VAR_CONTROLLER'); - $varAction = C('VAR_ACTION'); - $urlCase = C('URL_CASE_INSENSITIVE'); - if(isset($_GET[$varPath])) { // 判断URL里面是否有兼容模式参数 + public static function dispatch() + { + $varPath = C('VAR_PATHINFO'); + $varModule = C('VAR_MODULE'); + $varController = C('VAR_CONTROLLER'); + $varAction = C('VAR_ACTION'); + $urlCase = C('URL_CASE_INSENSITIVE'); + if (isset($_GET[$varPath])) { + // 判断URL里面是否有兼容模式参数 $_SERVER['PATH_INFO'] = $_GET[$varPath]; unset($_GET[$varPath]); - }elseif(IS_CLI){ // CLI模式下 index.php module/controller/action/params/... + } elseif (IS_CLI) { + // CLI模式下 index.php module/controller/action/params/... $_SERVER['PATH_INFO'] = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : ''; } // 开启子域名部署 - if(C('APP_SUB_DOMAIN_DEPLOY')) { - $rules = C('APP_SUB_DOMAIN_RULES'); - if(isset($rules[$_SERVER['HTTP_HOST']])) { // 完整域名或者IP配置 - define('APP_DOMAIN',$_SERVER['HTTP_HOST']); // 当前完整域名 + if (C('APP_SUB_DOMAIN_DEPLOY')) { + $rules = C('APP_SUB_DOMAIN_RULES'); + if (isset($rules[$_SERVER['HTTP_HOST']])) { + // 完整域名或者IP配置 + define('APP_DOMAIN', $_SERVER['HTTP_HOST']); // 当前完整域名 $rule = $rules[APP_DOMAIN]; - }else{ - if(strpos(C('APP_DOMAIN_SUFFIX'),'.')){ // com.cn net.cn + } else { + if (strpos(C('APP_DOMAIN_SUFFIX'), '.')) { + // com.cn net.cn $domain = array_slice(explode('.', $_SERVER['HTTP_HOST']), 0, -3); - }else{ - $domain = array_slice(explode('.', $_SERVER['HTTP_HOST']), 0, -2); + } else { + $domain = array_slice(explode('.', $_SERVER['HTTP_HOST']), 0, -2); } - if(!empty($domain)) { + if (!empty($domain)) { $subDomain = implode('.', $domain); - define('SUB_DOMAIN',$subDomain); // 当前完整子域名 - $domain2 = array_pop($domain); // 二级域名 - if($domain) { // 存在三级域名 + define('SUB_DOMAIN', $subDomain); // 当前完整子域名 + $domain2 = array_pop($domain); // 二级域名 + if ($domain) { + // 存在三级域名 $domain3 = array_pop($domain); } - if(isset($rules[$subDomain])) { // 子域名 + if (isset($rules[$subDomain])) { + // 子域名 $rule = $rules[$subDomain]; - }elseif(isset($rules['*.' . $domain2]) && !empty($domain3)){ // 泛三级域名 - $rule = $rules['*.' . $domain2]; + } elseif (isset($rules['*.' . $domain2]) && !empty($domain3)) { + // 泛三级域名 + $rule = $rules['*.' . $domain2]; $panDomain = $domain3; - }elseif(isset($rules['*']) && !empty($domain2) && 'www' != $domain2 ){ // 泛二级域名 + } elseif (isset($rules['*']) && !empty($domain2) && 'www' != $domain2) { + // 泛二级域名 $rule = $rules['*']; $panDomain = $domain2; } - } + } } - if(!empty($rule)) { + if (!empty($rule)) { // 子域名部署规则 '子域名'=>array('模块名','var1=a&var2=b'); - if(is_array($rule)){ - list($rule,$vars) = $rule; + if (is_array($rule)) { + list($rule, $vars) = $rule; } - $array = explode('/',$rule); + $array = explode('/', $rule); // 模块绑定 - define('BIND_MODULE',array_shift($array)); + define('BIND_MODULE', array_shift($array)); - if(isset($vars)) { // 传入参数 - parse_str($vars,$parms); - if(isset($panDomain)){ + if (isset($vars)) { + // 传入参数 + parse_str($vars, $parms); + if (isset($panDomain)) { $pos = array_search('*', $parms); - if(false !== $pos) { + if (false !== $pos) { // 泛域名作为参数 $parms[$pos] = $panDomain; - } - } - $_GET = array_merge($_GET,$parms); + } + } + $_GET = array_merge($_GET, $parms); } } } // 分析PATHINFO信息 - if(!isset($_SERVER['PATH_INFO'])) { - $types = explode(',',C('URL_PATHINFO_FETCH')); - foreach ($types as $type){ - if(0===strpos($type,':')) {// 支持函数判断 - $_SERVER['PATH_INFO'] = call_user_func(substr($type,1)); + if (!isset($_SERVER['PATH_INFO'])) { + $types = explode(',', C('URL_PATHINFO_FETCH')); + foreach ($types as $type) { + if (0 === strpos($type, ':')) { +// 支持函数判断 + $_SERVER['PATH_INFO'] = call_user_func(substr($type, 1)); break; - }elseif(!empty($_SERVER[$type])) { - $_SERVER['PATH_INFO'] = (0 === strpos($_SERVER[$type],$_SERVER['SCRIPT_NAME']))? - substr($_SERVER[$type], strlen($_SERVER['SCRIPT_NAME'])) : $_SERVER[$type]; + } elseif (!empty($_SERVER[$type])) { + $_SERVER['PATH_INFO'] = (0 === strpos($_SERVER[$type], $_SERVER['SCRIPT_NAME'])) ? + substr($_SERVER[$type], strlen($_SERVER['SCRIPT_NAME'])) : $_SERVER[$type]; break; } } } $depr = C('URL_PATHINFO_DEPR'); - define('MODULE_PATHINFO_DEPR', $depr); + define('MODULE_PATHINFO_DEPR', $depr); - if(empty($_SERVER['PATH_INFO'])) { + if (empty($_SERVER['PATH_INFO'])) { $_SERVER['PATH_INFO'] = ''; - define('__INFO__',''); - define('__EXT__',''); - }else{ - define('__INFO__',trim($_SERVER['PATH_INFO'],'/')); + define('__INFO__', ''); + define('__EXT__', ''); + } else { + define('__INFO__', trim($_SERVER['PATH_INFO'], '/')); // URL后缀 - define('__EXT__', strtolower(pathinfo($_SERVER['PATH_INFO'],PATHINFO_EXTENSION))); - $_SERVER['PATH_INFO'] = __INFO__; - if(!defined('BIND_MODULE') && (!C('URL_ROUTER_ON') || !Route::check())){ - if (__INFO__ ){ // 获取模块名 - $paths = explode($depr,__INFO__,2); - $allowList = C('MODULE_ALLOW_LIST'); // 允许的模块列表 - $module = preg_replace('/\.' . __EXT__ . '$/i', '',$paths[0]); - if( empty($allowList) || (is_array($allowList) && in_array_case($module, $allowList))){ - $_GET[$varModule] = $module; - $_SERVER['PATH_INFO'] = isset($paths[1])?$paths[1]:''; + define('__EXT__', strtolower(pathinfo($_SERVER['PATH_INFO'], PATHINFO_EXTENSION))); + $_SERVER['PATH_INFO'] = __INFO__; + if (!defined('BIND_MODULE') && (!C('URL_ROUTER_ON') || !Route::check())) { + if (__INFO__) { + // 获取模块名 + $paths = explode($depr, __INFO__, 2); + $allowList = C('MODULE_ALLOW_LIST'); // 允许的模块列表 + $module = preg_replace('/\.' . __EXT__ . '$/i', '', $paths[0]); + if (empty($allowList) || (is_array($allowList) && in_array_case($module, $allowList))) { + $_GET[$varModule] = $module; + $_SERVER['PATH_INFO'] = isset($paths[1]) ? $paths[1] : ''; } } - } + } } // URL常量 - define('__SELF__',strip_tags($_SERVER[C('URL_REQUEST_URI')])); + define('__SELF__', strip_tags($_SERVER[C('URL_REQUEST_URI')])); // 获取模块名称 - define('MODULE_NAME', defined('BIND_MODULE')? BIND_MODULE : self::getModule($varModule)); - + define('MODULE_NAME', defined('BIND_MODULE') ? BIND_MODULE : self::getModule($varModule)); + // 检测模块是否存在 - if( MODULE_NAME && (defined('BIND_MODULE') || !in_array_case(MODULE_NAME,C('MODULE_DENY_LIST')) ) && is_dir(APP_PATH.MODULE_NAME)){ + if (MODULE_NAME && (defined('BIND_MODULE') || !in_array_case(MODULE_NAME, C('MODULE_DENY_LIST'))) && is_dir(APP_PATH . MODULE_NAME)) { // 定义当前模块路径 - define('MODULE_PATH', APP_PATH.MODULE_NAME.'/'); + define('MODULE_PATH', APP_PATH . MODULE_NAME . '/'); // 定义当前模块的模版缓存路径 - C('CACHE_PATH',CACHE_PATH.MODULE_NAME.'/'); + C('CACHE_PATH', CACHE_PATH . MODULE_NAME . '/'); // 定义当前模块的日志目录 - C('LOG_PATH', realpath(LOG_PATH).'/'.MODULE_NAME.'/'); + C('LOG_PATH', realpath(LOG_PATH) . '/' . MODULE_NAME . '/'); // 加载模块配置文件 - if(is_file(MODULE_PATH.'Conf/config'.CONF_EXT)) - C(load_config(MODULE_PATH.'Conf/config'.CONF_EXT)); + if (is_file(MODULE_PATH . 'Conf/config' . CONF_EXT)) { + C(load_config(MODULE_PATH . 'Conf/config' . CONF_EXT)); + } // 加载模块别名定义 - if(is_file(MODULE_PATH.'Conf/alias.php')) - Think::addMap(include MODULE_PATH.'Conf/alias.php'); + if (is_file(MODULE_PATH . 'Conf/alias.php')) { + Think::addMap(include MODULE_PATH . 'Conf/alias.php'); + } // 加载模块函数文件 - if(is_file(MODULE_PATH.'Common/function.php')) - include MODULE_PATH.'Common/function.php'; - }else{ - E(L('_MODULE_NOT_EXIST_').':'.MODULE_NAME); + if (is_file(MODULE_PATH . 'Common/function.php')) { + include MODULE_PATH . 'Common/function.php'; + } + + } else { + E(L('_MODULE_NOT_EXIST_') . ':' . MODULE_NAME); } - if(!defined('__APP__')){ - $urlMode = C('URL_MODEL'); - if($urlMode == URL_COMPAT ){// 兼容模式判断 - define('PHP_FILE',_PHP_FILE_.'?'.$varPath.'='); - }elseif($urlMode == URL_REWRITE ) { - $url = dirname(_PHP_FILE_); - if($url == '/' || $url == '\\') - $url = ''; - define('PHP_FILE',$url); - }else { - define('PHP_FILE',_PHP_FILE_); - } - // 当前应用地址 - define('__APP__',strip_tags(PHP_FILE)); - } + if (!defined('__APP__')) { + $urlMode = C('URL_MODEL'); + if (URL_COMPAT == $urlMode) { +// 兼容模式判断 + define('PHP_FILE', _PHP_FILE_ . '?' . $varPath . '='); + } elseif (URL_REWRITE == $urlMode) { + $url = dirname(_PHP_FILE_); + if ('/' == $url || '\\' == $url) { + $url = ''; + } + + define('PHP_FILE', $url); + } else { + define('PHP_FILE', _PHP_FILE_); + } + // 当前应用地址 + define('__APP__', strip_tags(PHP_FILE)); + } // 模块URL地址 - $moduleName = defined('MODULE_ALIAS')? MODULE_ALIAS : MODULE_NAME; - define('__MODULE__',defined('BIND_MODULE') ? __APP__ : __APP__.'/'.($urlCase ? strtolower($moduleName) : $moduleName)); + $moduleName = defined('MODULE_ALIAS') ? MODULE_ALIAS : MODULE_NAME; + define('__MODULE__', defined('BIND_MODULE') ? __APP__ : __APP__ . '/' . ($urlCase ? strtolower($moduleName) : $moduleName)); - if('' != $_SERVER['PATH_INFO'] && (!C('URL_ROUTER_ON') || !Route::check()) ){ // 检测路由规则 如果没有则按默认规则调度URL + if ('' != $_SERVER['PATH_INFO'] && (!C('URL_ROUTER_ON') || !Route::check())) { + // 检测路由规则 如果没有则按默认规则调度URL // 检查禁止访问的URL后缀 - if(C('URL_DENY_SUFFIX') && preg_match('/\.('.trim(C('URL_DENY_SUFFIX'),'.').')$/i', $_SERVER['PATH_INFO'])){ + if (C('URL_DENY_SUFFIX') && preg_match('/\.(' . trim(C('URL_DENY_SUFFIX'), '.') . ')$/i', $_SERVER['PATH_INFO'])) { send_http_status(404); exit; } - + // 去除URL后缀 - $_SERVER['PATH_INFO'] = preg_replace(C('URL_HTML_SUFFIX')? '/\.('.trim(C('URL_HTML_SUFFIX'),'.').')$/i' : '/\.'.__EXT__.'$/i', '', $_SERVER['PATH_INFO']); + $_SERVER['PATH_INFO'] = preg_replace(C('URL_HTML_SUFFIX') ? '/\.(' . trim(C('URL_HTML_SUFFIX'), '.') . ')$/i' : '/\.' . __EXT__ . '$/i', '', $_SERVER['PATH_INFO']); - $depr = C('URL_PATHINFO_DEPR'); - $paths = explode($depr,trim($_SERVER['PATH_INFO'],$depr)); + $depr = C('URL_PATHINFO_DEPR'); + $paths = explode($depr, trim($_SERVER['PATH_INFO'], $depr)); - $_GET[$varController] = array_shift($paths); + $_GET[$varController] = array_shift($paths); // 获取操作 - $_GET[$varAction] = array_shift($paths); + $_GET[$varAction] = array_shift($paths); // 解析剩余的URL参数 - $var = array(); - if(C('URL_PARAMS_BIND') && 1 == C('URL_PARAMS_BIND_TYPE')){ + $var = array(); + if (C('URL_PARAMS_BIND') && 1 == C('URL_PARAMS_BIND_TYPE')) { // URL参数按顺序绑定变量 - $var = $paths; - }else{ - preg_replace_callback('/(\w+)\/([^\/]+)/', function($match) use(&$var){$var[$match[1]]=strip_tags($match[2]);}, implode('/',$paths)); + $var = $paths; + } else { + preg_replace_callback('/(\w+)\/([^\/]+)/', function ($match) use (&$var) {$var[$match[1]] = strip_tags($match[2]);}, implode('/', $paths)); } - $_GET = array_merge($var,$_GET); + $_GET = array_merge($var, $_GET); } // 获取控制器和操作名 - define('CONTROLLER_NAME', self::getController($varController,$urlCase)); - define('ACTION_NAME', self::getAction($varAction,$urlCase)); + define('CONTROLLER_NAME', self::getController($varController, $urlCase)); + define('ACTION_NAME', self::getAction($varAction, $urlCase)); // 当前控制器的UR地址 - define('__CONTROLLER__',__MODULE__.$depr.( $urlCase ? parse_name(CONTROLLER_NAME) : CONTROLLER_NAME ) ); + define('__CONTROLLER__', __MODULE__ . $depr . ($urlCase ? parse_name(CONTROLLER_NAME) : CONTROLLER_NAME)); // 当前操作的URL地址 - define('__ACTION__',__CONTROLLER__.$depr.ACTION_NAME); + define('__ACTION__', __CONTROLLER__ . $depr . ACTION_NAME); //保证$_REQUEST正常取值 - $_REQUEST = array_merge($_POST,$_GET); + $_REQUEST = array_merge($_POST, $_GET); } /** * 获得实际的控制器名称 */ - static private function getController($var,$urlCase) { - $controller = (!empty($_GET[$var])? $_GET[$var]:C('DEFAULT_CONTROLLER')); + private static function getController($var, $urlCase) + { + $controller = (!empty($_GET[$var]) ? $_GET[$var] : C('DEFAULT_CONTROLLER')); unset($_GET[$var]); - if($urlCase) { + if ($urlCase) { // URL地址不区分大小写 // 智能识别方式 user_type 识别到 UserTypeController 控制器 - $controller = parse_name($controller,1); + $controller = parse_name($controller, 1); } return strip_tags(ucfirst($controller)); } @@ -233,29 +257,31 @@ static private function getController($var,$urlCase) { /** * 获得实际的操作名称 */ - static private function getAction($var,$urlCase) { - $action = !empty($_POST[$var]) ? - $_POST[$var] : - (!empty($_GET[$var])?$_GET[$var]:C('DEFAULT_ACTION')); - unset($_POST[$var],$_GET[$var]); - return strip_tags( $urlCase? strtolower($action) : $action ); + private static function getAction($var, $urlCase) + { + $action = !empty($_POST[$var]) ? + $_POST[$var] : + (!empty($_GET[$var]) ? $_GET[$var] : C('DEFAULT_ACTION')); + unset($_POST[$var], $_GET[$var]); + return strip_tags($urlCase ? strtolower($action) : $action); } /** * 获得实际的模块名称 */ - static private function getModule($var) { - $module = (!empty($_GET[$var])?$_GET[$var]:C('DEFAULT_MODULE')); + private static function getModule($var) + { + $module = (!empty($_GET[$var]) ? $_GET[$var] : C('DEFAULT_MODULE')); unset($_GET[$var]); - if($maps = C('URL_MODULE_MAP')) { - if(isset($maps[strtolower($module)])) { + if ($maps = C('URL_MODULE_MAP')) { + if (isset($maps[strtolower($module)])) { // 记录当前别名 - define('MODULE_ALIAS',strtolower($module)); + define('MODULE_ALIAS', strtolower($module)); // 获取实际的模块名 - return ucfirst($maps[MODULE_ALIAS]); - }elseif(array_search(strtolower($module),$maps)){ + return ucfirst($maps[MODULE_ALIAS]); + } elseif (array_search(strtolower($module), $maps)) { // 禁止访问原始模块 - return ''; + return ''; } } return strip_tags(ucfirst($module)); diff --git a/ThinkPHP/Mode/Lite/Model.class.php b/ThinkPHP/Mode/Lite/Model.class.php index 9135078da..e2269cd6f 100644 --- a/ThinkPHP/Mode/Lite/Model.class.php +++ b/ThinkPHP/Mode/Lite/Model.class.php @@ -9,50 +9,52 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think; + /** * ThinkPHP Model模型类 * 实现了ORM和ActiveRecords模式 */ -class Model { +class Model +{ // 当前数据库操作对象 - protected $db = null; - // 数据库对象池 - private $_db = array(); + protected $db = null; + // 数据库对象池 + private $_db = array(); // 主键名称 - protected $pk = 'id'; + protected $pk = 'id'; // 主键是否自动增长 - protected $autoinc = false; + protected $autoinc = false; // 数据表前缀 - protected $tablePrefix = null; + protected $tablePrefix = null; // 模型名称 - protected $name = ''; + protected $name = ''; // 数据库名称 - protected $dbName = ''; + protected $dbName = ''; //数据库配置 - protected $connection = ''; + protected $connection = ''; // 数据表名(不包含表前缀) - protected $tableName = ''; + protected $tableName = ''; // 实际数据表名(包含表前缀) - protected $trueTableName = ''; + protected $trueTableName = ''; // 最近错误信息 - protected $error = ''; + protected $error = ''; // 字段信息 - protected $fields = array(); + protected $fields = array(); // 数据信息 - protected $data = array(); + protected $data = array(); // 查询表达式参数 - protected $options = array(); - protected $_validate = array(); // 自动验证定义 - protected $_auto = array(); // 自动完成定义 - protected $_map = array(); // 字段映射定义 - protected $_scope = array(); // 命名范围定义 + protected $options = array(); + protected $_validate = array(); // 自动验证定义 + protected $_auto = array(); // 自动完成定义 + protected $_map = array(); // 字段映射定义 + protected $_scope = array(); // 命名范围定义 // 是否自动检测数据表字段信息 - protected $autoCheckFields = true; + protected $autoCheckFields = true; // 是否批处理验证 - protected $patchValidate = false; + protected $patchValidate = false; // 链操作方法列表 - protected $methods = array('strict','order','alias','having','group','lock','distinct','auto','filter','validate','result','token','index','force'); + protected $methods = array('strict', 'order', 'alias', 'having', 'group', 'lock', 'distinct', 'auto', 'filter', 'validate', 'result', 'token', 'index', 'force'); /** * 架构函数 @@ -62,32 +64,35 @@ class Model { * @param string $tablePrefix 表前缀 * @param mixed $connection 数据库连接信息 */ - public function __construct($name='',$tablePrefix='',$connection='') { + public function __construct($name = '', $tablePrefix = '', $connection = '') + { // 模型初始化 $this->_initialize(); // 获取模型名称 - if(!empty($name)) { - if(strpos($name,'.')) { // 支持 数据库名.模型名的 定义 - list($this->dbName,$this->name) = explode('.',$name); - }else{ - $this->name = $name; + if (!empty($name)) { + if (strpos($name, '.')) { + // 支持 数据库名.模型名的 定义 + list($this->dbName, $this->name) = explode('.', $name); + } else { + $this->name = $name; } - }elseif(empty($this->name)){ - $this->name = $this->getModelName(); + } elseif (empty($this->name)) { + $this->name = $this->getModelName(); } // 设置表前缀 - if(is_null($tablePrefix)) {// 前缀为Null表示没有前缀 + if (is_null($tablePrefix)) { +// 前缀为Null表示没有前缀 $this->tablePrefix = ''; - }elseif('' != $tablePrefix) { + } elseif ('' != $tablePrefix) { $this->tablePrefix = $tablePrefix; - }elseif(!isset($this->tablePrefix)){ + } elseif (!isset($this->tablePrefix)) { $this->tablePrefix = C('DB_PREFIX'); } // 数据库初始化操作 // 获取数据库操作对象 // 当前模型有独立的数据库连接信息 - $this->db(0,empty($this->connection)?$connection:$this->connection,true); + $this->db(0, empty($this->connection) ? $connection : $this->connection, true); } /** @@ -95,20 +100,21 @@ public function __construct($name='',$tablePrefix='',$connection='') { * @access protected * @return void */ - protected function _checkTableInfo() { + protected function _checkTableInfo() + { // 如果不是Model类 自动记录数据表信息 // 只在第一次执行记录 - if(empty($this->fields)) { + if (empty($this->fields)) { // 如果数据表字段没有定义则自动获取 - if(C('DB_FIELDS_CACHE')) { - $db = $this->dbName?:C('DB_NAME'); - $fields = F('_fields/'.strtolower($db.'.'.$this->tablePrefix.$this->name)); - if($fields) { - $this->fields = $fields; - if(!empty($fields['_pk'])){ - $this->pk = $fields['_pk']; + if (C('DB_FIELDS_CACHE')) { + $db = $this->dbName ?: C('DB_NAME'); + $fields = F('_fields/' . strtolower($db . '.' . $this->tablePrefix . $this->name)); + if ($fields) { + $this->fields = $fields; + if (!empty($fields['_pk'])) { + $this->pk = $fields['_pk']; } - return ; + return; } } // 每次都会读取数据表信息 @@ -121,42 +127,47 @@ protected function _checkTableInfo() { * @access public * @return void */ - public function flush() { + public function flush() + { // 缓存不存在则查询数据表信息 $this->db->setModel($this->name); - $fields = $this->db->getFields($this->getTableName()); - if(!$fields) { // 无法获取字段信息 + $fields = $this->db->getFields($this->getTableName()); + if (!$fields) { + // 无法获取字段信息 return false; } - $this->fields = array_keys($fields); + $this->fields = array_keys($fields); unset($this->fields['_pk']); - foreach ($fields as $key=>$val){ + foreach ($fields as $key => $val) { // 记录字段类型 - $type[$key] = $val['type']; - if($val['primary']) { - // 增加复合主键支持 - if (isset($this->fields['_pk']) && $this->fields['_pk'] != null) { + $type[$key] = $val['type']; + if ($val['primary']) { + // 增加复合主键支持 + if (isset($this->fields['_pk']) && null != $this->fields['_pk']) { if (is_string($this->fields['_pk'])) { - $this->pk = array($this->fields['_pk']); - $this->fields['_pk'] = $this->pk; + $this->pk = array($this->fields['_pk']); + $this->fields['_pk'] = $this->pk; } - $this->pk[] = $key; - $this->fields['_pk'][] = $key; + $this->pk[] = $key; + $this->fields['_pk'][] = $key; } else { - $this->pk = $key; - $this->fields['_pk'] = $key; + $this->pk = $key; + $this->fields['_pk'] = $key; + } + if ($val['autoinc']) { + $this->autoinc = true; } - if($val['autoinc']) $this->autoinc = true; + } } // 记录字段类型信息 - $this->fields['_type'] = $type; + $this->fields['_type'] = $type; // 2008-3-7 增加缓存开关控制 - if(C('DB_FIELDS_CACHE')){ + if (C('DB_FIELDS_CACHE')) { // 永久缓存数据表信息 - $db = $this->dbName?:C('DB_NAME'); - F('_fields/'.strtolower($db.'.'.$this->tablePrefix.$this->name),$this->fields); + $db = $this->dbName ?: C('DB_NAME'); + F('_fields/' . strtolower($db . '.' . $this->tablePrefix . $this->name), $this->fields); } } @@ -167,9 +178,10 @@ public function flush() { * @param mixed $value 值 * @return void */ - public function __set($name,$value) { + public function __set($name, $value) + { // 设置数据对象属性 - $this->data[$name] = $value; + $this->data[$name] = $value; } /** @@ -178,8 +190,9 @@ public function __set($name,$value) { * @param string $name 名称 * @return mixed */ - public function __get($name) { - return isset($this->data[$name])?$this->data[$name]:null; + public function __get($name) + { + return isset($this->data[$name]) ? $this->data[$name] : null; } /** @@ -188,7 +201,8 @@ public function __get($name) { * @param string $name 名称 * @return boolean */ - public function __isset($name) { + public function __isset($name) + { return isset($this->data[$name]); } @@ -198,7 +212,8 @@ public function __isset($name) { * @param string $name 名称 * @return void */ - public function __unset($name) { + public function __unset($name) + { unset($this->data[$name]); } @@ -209,34 +224,37 @@ public function __unset($name) { * @param array $args 调用参数 * @return mixed */ - public function __call($method,$args) { - if(in_array(strtolower($method),$this->methods,true)) { + public function __call($method, $args) + { + if (in_array(strtolower($method), $this->methods, true)) { // 连贯操作的实现 - $this->options[strtolower($method)] = $args[0]; + $this->options[strtolower($method)] = $args[0]; return $this; - }elseif(in_array(strtolower($method),array('count','sum','min','max','avg'),true)){ + } elseif (in_array(strtolower($method), array('count', 'sum', 'min', 'max', 'avg'), true)) { // 统计查询的实现 - $field = isset($args[0])?$args[0]:'*'; - return $this->getField(strtoupper($method).'('.$field.') AS tp_'.$method); - }elseif(strtolower(substr($method,0,5))=='getby') { + $field = isset($args[0]) ? $args[0] : '*'; + return $this->getField(strtoupper($method) . '(' . $field . ') AS tp_' . $method); + } elseif (strtolower(substr($method, 0, 5)) == 'getby') { // 根据某个字段获取记录 - $field = parse_name(substr($method,5)); - $where[$field] = $args[0]; + $field = parse_name(substr($method, 5)); + $where[$field] = $args[0]; return $this->where($where)->find(); - }elseif(strtolower(substr($method,0,10))=='getfieldby') { + } elseif (strtolower(substr($method, 0, 10)) == 'getfieldby') { // 根据某个字段获取记录的某个值 - $name = parse_name(substr($method,10)); - $where[$name] =$args[0]; + $name = parse_name(substr($method, 10)); + $where[$name] = $args[0]; return $this->where($where)->getField($args[1]); - }elseif(isset($this->_scope[$method])){// 命名范围的单独调用支持 - return $this->scope($method,$args[0]); - }else{ - E(__CLASS__.':'.$method.L('_METHOD_NOT_EXIST_')); + } elseif (isset($this->_scope[$method])) { +// 命名范围的单独调用支持 + return $this->scope($method, $args[0]); + } else { + E(__CLASS__ . ':' . $method . L('_METHOD_NOT_EXIST_')); return; } } // 回调方法 初始化模型 - protected function _initialize() {} + protected function _initialize() + {} /** * 对保存到数据库的数据进行处理 @@ -244,43 +262,45 @@ protected function _initialize() {} * @param mixed $data 要操作的数据 * @return boolean */ - protected function _facade($data) { + protected function _facade($data) + { // 检查数据字段合法性 - if(!empty($this->fields)) { - if(!empty($this->options['field'])) { - $fields = $this->options['field']; + if (!empty($this->fields)) { + if (!empty($this->options['field'])) { + $fields = $this->options['field']; unset($this->options['field']); - if(is_string($fields)) { - $fields = explode(',',$fields); - } - }else{ - $fields = $this->fields; - } - foreach ($data as $key=>$val){ - if(!in_array($key,$fields,true)){ - if(!empty($this->options['strict'])){ - E(L('_DATA_TYPE_INVALID_').':['.$key.'=>'.$val.']'); + if (is_string($fields)) { + $fields = explode(',', $fields); + } + } else { + $fields = $this->fields; + } + foreach ($data as $key => $val) { + if (!in_array($key, $fields, true)) { + if (!empty($this->options['strict'])) { + E(L('_DATA_TYPE_INVALID_') . ':[' . $key . '=>' . $val . ']'); } unset($data[$key]); - }elseif(is_scalar($val)) { + } elseif (is_scalar($val)) { // 字段类型检查 和 强制转换 - $this->_parseType($data,$key); + $this->_parseType($data, $key); } } } - + // 安全过滤 - if(!empty($this->options['filter'])) { - $data = array_map($this->options['filter'],$data); + if (!empty($this->options['filter'])) { + $data = array_map($this->options['filter'], $data); unset($this->options['filter']); } $this->_before_write($data); return $data; - } + } // 写入数据前的回调方法 包括新增和更新 - protected function _before_write(&$data) {} + protected function _before_write(&$data) + {} /** * 新增数据 @@ -290,67 +310,74 @@ protected function _before_write(&$data) {} * @param boolean $replace 是否replace * @return mixed */ - public function add($data='',$options=array(),$replace=false) { - if(empty($data)) { + public function add($data = '', $options = array(), $replace = false) + { + if (empty($data)) { // 没有传递数据,获取当前数据对象的值 - if(!empty($this->data)) { - $data = $this->data; + if (!empty($this->data)) { + $data = $this->data; // 重置数据 - $this->data = array(); - }else{ - $this->error = L('_DATA_TYPE_INVALID_'); + $this->data = array(); + } else { + $this->error = L('_DATA_TYPE_INVALID_'); return false; } } // 数据处理 - $data = $this->_facade($data); + $data = $this->_facade($data); // 分析表达式 - $options = $this->_parseOptions($options); - if(false === $this->_before_insert($data,$options)) { + $options = $this->_parseOptions($options); + if (false === $this->_before_insert($data, $options)) { return false; } // 写入数据到数据库 - $result = $this->db->insert($data,$options,$replace); - if(false !== $result && is_numeric($result)) { - $pk = $this->getPk(); - // 增加复合主键支持 - if (is_array($pk)) return $result; - $insertId = $this->getLastInsID(); - if($insertId) { + $result = $this->db->insert($data, $options, $replace); + if (false !== $result && is_numeric($result)) { + $pk = $this->getPk(); + // 增加复合主键支持 + if (is_array($pk)) { + return $result; + } + + $insertId = $this->getLastInsID(); + if ($insertId) { // 自增主键返回插入ID - $data[$pk] = $insertId; - if(false === $this->_after_insert($data,$options)) { + $data[$pk] = $insertId; + if (false === $this->_after_insert($data, $options)) { return false; } return $insertId; } - if(false === $this->_after_insert($data,$options)) { + if (false === $this->_after_insert($data, $options)) { return false; } } return $result; } // 插入数据前的回调方法 - protected function _before_insert(&$data,$options) {} + protected function _before_insert(&$data, $options) + {} // 插入成功后的回调方法 - protected function _after_insert($data,$options) {} + protected function _after_insert($data, $options) + {} - public function addAll($dataList,$options=array(),$replace=false){ - if(empty($dataList)) { + public function addAll($dataList, $options = array(), $replace = false) + { + if (empty($dataList)) { $this->error = L('_DATA_TYPE_INVALID_'); return false; } // 数据处理 - foreach ($dataList as $key=>$data){ + foreach ($dataList as $key => $data) { $dataList[$key] = $this->_facade($data); } // 分析表达式 - $options = $this->_parseOptions($options); + $options = $this->_parseOptions($options); // 写入数据到数据库 - $result = $this->db->insertAll($dataList,$options,$replace); - if(false !== $result ) { - $insertId = $this->getLastInsID(); - if($insertId) { + $result = $this->db->insertAll($dataList, $options, $replace); + if (false !== $result) { + $insertId = $this->getLastInsID(); + if ($insertId) { return $insertId; } } @@ -364,72 +391,78 @@ public function addAll($dataList,$options=array(),$replace=false){ * @param array $options 表达式 * @return boolean */ - public function save($data='',$options=array()) { - if(empty($data)) { + public function save($data = '', $options = array()) + { + if (empty($data)) { // 没有传递数据,获取当前数据对象的值 - if(!empty($this->data)) { - $data = $this->data; + if (!empty($this->data)) { + $data = $this->data; // 重置数据 - $this->data = array(); - }else{ - $this->error = L('_DATA_TYPE_INVALID_'); + $this->data = array(); + } else { + $this->error = L('_DATA_TYPE_INVALID_'); return false; } } // 数据处理 - $data = $this->_facade($data); - if(empty($data)){ + $data = $this->_facade($data); + if (empty($data)) { // 没有数据则不执行 - $this->error = L('_DATA_TYPE_INVALID_'); + $this->error = L('_DATA_TYPE_INVALID_'); return false; } // 分析表达式 - $options = $this->_parseOptions($options); - $pk = $this->getPk(); - if(!isset($options['where']) ) { + $options = $this->_parseOptions($options); + $pk = $this->getPk(); + if (!isset($options['where'])) { // 如果存在主键数据 则自动作为更新条件 if (is_string($pk) && isset($data[$pk])) { - $where[$pk] = $data[$pk]; + $where[$pk] = $data[$pk]; unset($data[$pk]); } elseif (is_array($pk)) { // 增加复合主键支持 foreach ($pk as $field) { - if(isset($data[$field])) { - $where[$field] = $data[$field]; + if (isset($data[$field])) { + $where[$field] = $data[$field]; } else { - // 如果缺少复合主键数据则不执行 - $this->error = L('_OPERATION_WRONG_'); + // 如果缺少复合主键数据则不执行 + $this->error = L('_OPERATION_WRONG_'); return false; } unset($data[$field]); } } - if(!isset($where)){ + if (!isset($where)) { // 如果没有任何更新条件则不执行 - $this->error = L('_OPERATION_WRONG_'); + $this->error = L('_OPERATION_WRONG_'); return false; - }else{ - $options['where'] = $where; + } else { + $options['where'] = $where; } } - if(is_array($options['where']) && isset($options['where'][$pk])){ - $pkValue = $options['where'][$pk]; + if (is_array($options['where']) && isset($options['where'][$pk])) { + $pkValue = $options['where'][$pk]; } - if(false === $this->_before_update($data,$options)) { + if (false === $this->_before_update($data, $options)) { return false; } - $result = $this->db->update($data,$options); - if(false !== $result && is_numeric($result)) { - if(isset($pkValue)) $data[$pk] = $pkValue; - $this->_after_update($data,$options); + $result = $this->db->update($data, $options); + if (false !== $result && is_numeric($result)) { + if (isset($pkValue)) { + $data[$pk] = $pkValue; + } + + $this->_after_update($data, $options); } return $result; } // 更新数据前的回调方法 - protected function _before_update(&$data,$options) {} + protected function _before_update(&$data, $options) + {} // 更新成功后的回调方法 - protected function _after_update($data,$options) {} + protected function _after_update($data, $options) + {} /** * 删除数据 @@ -437,68 +470,79 @@ protected function _after_update($data,$options) {} * @param mixed $options 表达式 * @return mixed */ - public function delete($options=array()) { - $pk = $this->getPk(); - if(empty($options) && empty($this->options['where'])) { + public function delete($options = array()) + { + $pk = $this->getPk(); + if (empty($options) && empty($this->options['where'])) { // 如果删除条件为空 则删除当前数据对象所对应的记录 - if(!empty($this->data) && isset($this->data[$pk])) + if (!empty($this->data) && isset($this->data[$pk])) { return $this->delete($this->data[$pk]); - else + } else { return false; + } + } - if(is_numeric($options) || is_string($options)) { + if (is_numeric($options) || is_string($options)) { // 根据主键删除记录 - if(strpos($options,',')) { - $where[$pk] = array('IN', $options); - }else{ - $where[$pk] = $options; + if (strpos($options, ',')) { + $where[$pk] = array('IN', $options); + } else { + $where[$pk] = $options; } - $options = array(); - $options['where'] = $where; + $options = array(); + $options['where'] = $where; } // 根据复合主键删除记录 if (is_array($options) && (count($options) > 0) && is_array($pk)) { $count = 0; foreach (array_keys($options) as $key) { - if (is_int($key)) $count++; - } - if ($count == count($pk)) { + if (is_int($key)) { + $count++; + } + + } + if (count($pk) == $count) { $i = 0; foreach ($pk as $field) { $where[$field] = $options[$i]; unset($options[$i++]); } - $options['where'] = $where; + $options['where'] = $where; } else { return false; } } // 分析表达式 - $options = $this->_parseOptions($options); - if(empty($options['where'])){ + $options = $this->_parseOptions($options); + if (empty($options['where'])) { // 如果条件为空 不进行删除操作 除非设置 1=1 return false; - } - if(is_array($options['where']) && isset($options['where'][$pk])){ - $pkValue = $options['where'][$pk]; + } + if (is_array($options['where']) && isset($options['where'][$pk])) { + $pkValue = $options['where'][$pk]; } - if(false === $this->_before_delete($options)) { + if (false === $this->_before_delete($options)) { return false; - } - $result = $this->db->delete($options); - if(false !== $result && is_numeric($result)) { + } + $result = $this->db->delete($options); + if (false !== $result && is_numeric($result)) { $data = array(); - if(isset($pkValue)) $data[$pk] = $pkValue; - $this->_after_delete($data,$options); + if (isset($pkValue)) { + $data[$pk] = $pkValue; + } + + $this->_after_delete($data, $options); } // 返回删除记录个数 return $result; } // 删除数据前的回调方法 - protected function _before_delete($options) {} + protected function _before_delete($options) + {} // 删除成功后的回调方法 - protected function _after_delete($data,$options) {} + protected function _after_delete($data, $options) + {} /** * 查询数据集 @@ -506,83 +550,91 @@ protected function _after_delete($data,$options) {} * @param array $options 表达式参数 * @return mixed */ - public function select($options=array()) { - $pk = $this->getPk(); - if(is_string($options) || is_numeric($options)) { + public function select($options = array()) + { + $pk = $this->getPk(); + if (is_string($options) || is_numeric($options)) { // 根据主键查询 - if(strpos($options,',')) { - $where[$pk] = array('IN',$options); - }else{ - $where[$pk] = $options; + if (strpos($options, ',')) { + $where[$pk] = array('IN', $options); + } else { + $where[$pk] = $options; } - $options = array(); - $options['where'] = $where; - }elseif (is_array($options) && (count($options) > 0) && is_array($pk)) { + $options = array(); + $options['where'] = $where; + } elseif (is_array($options) && (count($options) > 0) && is_array($pk)) { // 根据复合主键查询 $count = 0; foreach (array_keys($options) as $key) { - if (is_int($key)) $count++; - } - if ($count == count($pk)) { + if (is_int($key)) { + $count++; + } + + } + if (count($pk) == $count) { $i = 0; foreach ($pk as $field) { $where[$field] = $options[$i]; unset($options[$i++]); } - $options['where'] = $where; + $options['where'] = $where; } else { return false; } - } elseif(false === $options){ // 用于子查询 不查询只返回SQL - $options = array(); + } elseif (false === $options) { + // 用于子查询 不查询只返回SQL + $options = array(); // 分析表达式 - $options = $this->_parseOptions($options); - return '( '.$this->fetchSql(true)->select($options).' )'; + $options = $this->_parseOptions($options); + return '( ' . $this->fetchSql(true)->select($options) . ' )'; } // 分析表达式 - $options = $this->_parseOptions($options); + $options = $this->_parseOptions($options); // 判断查询缓存 - if(isset($options['cache'])){ - $cache = $options['cache']; - $key = is_string($cache['key'])?$cache['key']:md5(serialize($options)); - $data = S($key,'',$cache); - if(false !== $data){ + if (isset($options['cache'])) { + $cache = $options['cache']; + $key = is_string($cache['key']) ? $cache['key'] : md5(serialize($options)); + $data = S($key, '', $cache); + if (false !== $data) { return $data; } - } - $resultSet = $this->db->select($options); - if(false === $resultSet) { + } + $resultSet = $this->db->select($options); + if (false === $resultSet) { return false; } - if(empty($resultSet)) { // 查询结果为空 + if (empty($resultSet)) { + // 查询结果为空 return null; } - if(is_string($resultSet)){ + if (is_string($resultSet)) { return $resultSet; } - $resultSet = array_map(array($this,'_read_data'),$resultSet); - $this->_after_select($resultSet,$options); - if(isset($options['index'])){ // 对数据集进行索引 - $index = explode(',',$options['index']); - foreach ($resultSet as $result){ - $_key = $result[$index[0]]; - if(isset($index[1]) && isset($result[$index[1]])){ - $cols[$_key] = $result[$index[1]]; - }else{ - $cols[$_key] = $result; + $resultSet = array_map(array($this, '_read_data'), $resultSet); + $this->_after_select($resultSet, $options); + if (isset($options['index'])) { + // 对数据集进行索引 + $index = explode(',', $options['index']); + foreach ($resultSet as $result) { + $_key = $result[$index[0]]; + if (isset($index[1]) && isset($result[$index[1]])) { + $cols[$_key] = $result[$index[1]]; + } else { + $cols[$_key] = $result; } } - $resultSet = $cols; + $resultSet = $cols; } - if(isset($cache)){ - S($key,$resultSet,$cache); + if (isset($cache)) { + S($key, $resultSet, $cache); } return $resultSet; } // 查询成功后的回调方法 - protected function _after_select(&$resultSet,$options) {} + protected function _after_select(&$resultSet, $options) + {} /** * 分析表达式 @@ -590,51 +642,54 @@ protected function _after_select(&$resultSet,$options) {} * @param array $options 表达式参数 * @return array */ - protected function _parseOptions($options=array()) { - if(is_array($options)) - $options = array_merge($this->options,$options); + protected function _parseOptions($options = array()) + { + if (is_array($options)) { + $options = array_merge($this->options, $options); + } - if(!isset($options['table'])){ + if (!isset($options['table'])) { // 自动获取表名 - $options['table'] = $this->getTableName(); - $fields = $this->fields; - }else{ + $options['table'] = $this->getTableName(); + $fields = $this->fields; + } else { // 指定数据表 则重新获取字段列表 但不支持类型检测 - $fields = $this->getDbFields(); + $fields = $this->getDbFields(); } // 数据表别名 - if(!empty($options['alias'])) { - $options['table'] .= ' '.$options['alias']; + if (!empty($options['alias'])) { + $options['table'] .= ' ' . $options['alias']; } // 记录操作的模型名称 - $options['model'] = $this->name; + $options['model'] = $this->name; // 字段类型验证 - if(isset($options['where']) && is_array($options['where']) && !empty($fields) && !isset($options['join'])) { + if (isset($options['where']) && is_array($options['where']) && !empty($fields) && !isset($options['join'])) { // 对数组查询条件进行字段类型检查 - foreach ($options['where'] as $key=>$val){ - $key = trim($key); - if(in_array($key,$fields,true)){ - if(is_scalar($val)) { - $this->_parseType($options['where'],$key); + foreach ($options['where'] as $key => $val) { + $key = trim($key); + if (in_array($key, $fields, true)) { + if (is_scalar($val)) { + $this->_parseType($options['where'], $key); + } + } elseif (!is_numeric($key) && '_' != substr($key, 0, 1) && false === strpos($key, '.') && false === strpos($key, '(') && false === strpos($key, '|') && false === strpos($key, '&')) { + if (!empty($this->options['strict'])) { + E(L('_ERROR_QUERY_EXPRESS_') . ':[' . $key . '=>' . $val . ']'); } - }elseif(!is_numeric($key) && '_' != substr($key,0,1) && false === strpos($key,'.') && false === strpos($key,'(') && false === strpos($key,'|') && false === strpos($key,'&')){ - if(!empty($this->options['strict'])){ - E(L('_ERROR_QUERY_EXPRESS_').':['.$key.'=>'.$val.']'); - } unset($options['where'][$key]); } } } // 查询过后清空sql表达式组装 避免影响下次查询 - $this->options = array(); + $this->options = array(); // 表达式过滤 $this->_options_filter($options); return $options; } // 表达式过滤回调方法 - protected function _options_filter(&$options) {} + protected function _options_filter(&$options) + {} /** * 数据类型检测 @@ -643,17 +698,18 @@ protected function _options_filter(&$options) {} * @param string $key 字段名 * @return void */ - protected function _parseType(&$data,$key) { - if(!isset($this->options['bind'][':'.$key]) && isset($this->fields['_type'][$key])){ + protected function _parseType(&$data, $key) + { + if (!isset($this->options['bind'][':' . $key]) && isset($this->fields['_type'][$key])) { $fieldType = strtolower($this->fields['_type'][$key]); - if(false !== strpos($fieldType,'enum')){ + if (false !== strpos($fieldType, 'enum')) { // 支持ENUM类型优先检测 - }elseif(false === strpos($fieldType,'bigint') && false !== strpos($fieldType,'int')) { - $data[$key] = intval($data[$key]); - }elseif(false !== strpos($fieldType,'float') || false !== strpos($fieldType,'double')){ - $data[$key] = floatval($data[$key]); - }elseif(false !== strpos($fieldType,'bool')){ - $data[$key] = (bool)$data[$key]; + } elseif (false === strpos($fieldType, 'bigint') && false !== strpos($fieldType, 'int')) { + $data[$key] = intval($data[$key]); + } elseif (false !== strpos($fieldType, 'float') || false !== strpos($fieldType, 'double')) { + $data[$key] = floatval($data[$key]); + } elseif (false !== strpos($fieldType, 'bool')) { + $data[$key] = (bool) $data[$key]; } } } @@ -664,12 +720,13 @@ protected function _parseType(&$data,$key) { * @param array $data 当前数据 * @return array */ - protected function _read_data($data) { + protected function _read_data($data) + { // 检查字段映射 - if(!empty($this->_map) && C('READ_DATA_MAP')) { - foreach ($this->_map as $key=>$val){ - if(isset($data[$val])) { - $data[$key] = $data[$val]; + if (!empty($this->_map) && C('READ_DATA_MAP')) { + foreach ($this->_map as $key => $val) { + if (isset($data[$val])) { + $data[$key] = $data[$val]; unset($data[$val]); } } @@ -683,67 +740,73 @@ protected function _read_data($data) { * @param mixed $options 表达式参数 * @return mixed */ - public function find($options=array()) { - if(is_numeric($options) || is_string($options)) { - $where[$this->getPk()] = $options; - $options = array(); - $options['where'] = $where; + public function find($options = array()) + { + if (is_numeric($options) || is_string($options)) { + $where[$this->getPk()] = $options; + $options = array(); + $options['where'] = $where; } // 根据复合主键查找记录 - $pk = $this->getPk(); + $pk = $this->getPk(); if (is_array($options) && (count($options) > 0) && is_array($pk)) { // 根据复合主键查询 $count = 0; foreach (array_keys($options) as $key) { - if (is_int($key)) $count++; - } - if ($count == count($pk)) { + if (is_int($key)) { + $count++; + } + + } + if (count($pk) == $count) { $i = 0; foreach ($pk as $field) { $where[$field] = $options[$i]; unset($options[$i++]); } - $options['where'] = $where; + $options['where'] = $where; } else { return false; } } // 总是查找一条记录 - $options['limit'] = 1; + $options['limit'] = 1; // 分析表达式 - $options = $this->_parseOptions($options); + $options = $this->_parseOptions($options); // 判断查询缓存 - if(isset($options['cache'])){ - $cache = $options['cache']; - $key = is_string($cache['key'])?$cache['key']:md5(serialize($options)); - $data = S($key,'',$cache); - if(false !== $data){ - $this->data = $data; + if (isset($options['cache'])) { + $cache = $options['cache']; + $key = is_string($cache['key']) ? $cache['key'] : md5(serialize($options)); + $data = S($key, '', $cache); + if (false !== $data) { + $this->data = $data; return $data; } } - $resultSet = $this->db->select($options); - if(false === $resultSet) { + $resultSet = $this->db->select($options); + if (false === $resultSet) { return false; } - if(empty($resultSet)) {// 查询结果为空 + if (empty($resultSet)) { +// 查询结果为空 return null; } - if(is_string($resultSet)){ + if (is_string($resultSet)) { return $resultSet; } // 读取数据后的处理 - $data = $this->_read_data($resultSet[0]); - $this->_after_find($data,$options); - $this->data = $data; - if(isset($cache)){ - S($key,$data,$cache); + $data = $this->_read_data($resultSet[0]); + $this->_after_find($data, $options); + $this->data = $data; + if (isset($cache)) { + S($key, $data, $cache); } return $this->data; } // 查询成功的回调方法 - protected function _after_find(&$result,$options) {} + protected function _after_find(&$result, $options) + {} /** * 设置记录的某个字段值 @@ -753,11 +816,12 @@ protected function _after_find(&$result,$options) {} * @param string $value 字段值 * @return boolean */ - public function setField($field,$value='') { - if(is_array($field)) { - $data = $field; - }else{ - $data[$field] = $value; + public function setField($field, $value = '') + { + if (is_array($field)) { + $data = $field; + } else { + $data[$field] = $value; } return $this->save($data); } @@ -770,8 +834,9 @@ public function setField($field,$value='') { * @param integer $lazyTime 延时时间(s) * @return boolean */ - public function setInc($field,$step=1) { - return $this->setField($field,array('exp',$field.'+'.$step)); + public function setInc($field, $step = 1) + { + return $this->setField($field, array('exp', $field . '+' . $step)); } /** @@ -782,8 +847,9 @@ public function setInc($field,$step=1) { * @param integer $lazyTime 延时时间(s) * @return boolean */ - public function setDec($field,$step=1) { - return $this->setField($field,array('exp',$field.'-'.$step)); + public function setDec($field, $step = 1) + { + return $this->setField($field, array('exp', $field . '-' . $step)); } /** @@ -793,64 +859,67 @@ public function setDec($field,$step=1) { * @param string $spea 字段数据间隔符号 NULL返回数组 * @return mixed */ - public function getField($field,$sepa=null) { - $options['field'] = $field; - $options = $this->_parseOptions($options); + public function getField($field, $sepa = null) + { + $options['field'] = $field; + $options = $this->_parseOptions($options); // 判断查询缓存 - if(isset($options['cache'])){ - $cache = $options['cache']; - $key = is_string($cache['key'])?$cache['key']:md5($sepa.serialize($options)); - $data = S($key,'',$cache); - if(false !== $data){ + if (isset($options['cache'])) { + $cache = $options['cache']; + $key = is_string($cache['key']) ? $cache['key'] : md5($sepa . serialize($options)); + $data = S($key, '', $cache); + if (false !== $data) { return $data; } - } - $field = trim($field); - if(strpos($field,',') && false !== $sepa) { // 多字段 - if(!isset($options['limit'])){ - $options['limit'] = is_numeric($sepa)?$sepa:''; + } + $field = trim($field); + if (strpos($field, ',') && false !== $sepa) { + // 多字段 + if (!isset($options['limit'])) { + $options['limit'] = is_numeric($sepa) ? $sepa : ''; } - $resultSet = $this->db->select($options); - if(!empty($resultSet)) { - $_field = explode(',', $field); - $field = array_keys($resultSet[0]); - $key1 = array_shift($field); - $key2 = array_shift($field); - $cols = array(); - $count = count($_field); - foreach ($resultSet as $result){ - $name = $result[$key1]; - if(2==$count) { - $cols[$name] = $result[$key2]; - }else{ - $cols[$name] = is_string($sepa)?implode($sepa,array_slice($result,1)):$result; + $resultSet = $this->db->select($options); + if (!empty($resultSet)) { + $_field = explode(',', $field); + $field = array_keys($resultSet[0]); + $key1 = array_shift($field); + $key2 = array_shift($field); + $cols = array(); + $count = count($_field); + foreach ($resultSet as $result) { + $name = $result[$key1]; + if (2 == $count) { + $cols[$name] = $result[$key2]; + } else { + $cols[$name] = is_string($sepa) ? implode($sepa, array_slice($result, 1)) : $result; } } - if(isset($cache)){ - S($key,$cols,$cache); + if (isset($cache)) { + S($key, $cols, $cache); } return $cols; } - }else{ // 查找一条记录 + } else { + // 查找一条记录 // 返回数据个数 - if(true !== $sepa) {// 当sepa指定为true的时候 返回所有数据 - $options['limit'] = is_numeric($sepa)?$sepa:1; + if (true !== $sepa) { // 当sepa指定为true的时候 返回所有数据 + $options['limit'] = is_numeric($sepa) ? $sepa : 1; } $result = $this->db->select($options); - if(!empty($result)) { - if(true !== $sepa && 1==$options['limit']) { - $data = reset($result[0]); - if(isset($cache)){ - S($key,$data,$cache); - } + if (!empty($result)) { + if (true !== $sepa && 1 == $options['limit']) { + $data = reset($result[0]); + if (isset($cache)) { + S($key, $data, $cache); + } return $data; } - foreach ($result as $val){ - $array[] = $val[$field]; + foreach ($result as $val) { + $array[] = $val[$field]; + } + if (isset($cache)) { + S($key, $array, $cache); } - if(isset($cache)){ - S($key,$array,$cache); - } return $array; } } @@ -863,47 +932,50 @@ public function getField($field,$sepa=null) { * @param mixed $data 创建数据 * @return mixed */ - public function create($data='') { + public function create($data = '') + { // 如果没有传值默认取POST数据 - if(empty($data)) { - $data = I('post.'); - }elseif(is_object($data)){ - $data = get_object_vars($data); + if (empty($data)) { + $data = I('post.'); + } elseif (is_object($data)) { + $data = get_object_vars($data); } // 验证数据 - if(empty($data) || !is_array($data)) { + if (empty($data) || !is_array($data)) { $this->error = L('_DATA_TYPE_INVALID_'); return false; } // 检测提交字段的合法性 - if(isset($this->options['field'])) { // $this->field('field1,field2...')->create() - $fields = $this->options['field']; + if (isset($this->options['field'])) { + // $this->field('field1,field2...')->create() + $fields = $this->options['field']; unset($this->options['field']); } - if(isset($fields)) { - if(is_string($fields)) { - $fields = explode(',',$fields); + if (isset($fields)) { + if (is_string($fields)) { + $fields = explode(',', $fields); } } // 验证完成生成数据对象 - if($this->autoCheckFields) { // 开启字段检测 则过滤非法字段数据 - $fields = $this->getDbFields(); - foreach ($data as $key=>$val){ - if(!in_array($key,$fields)) { + if ($this->autoCheckFields) { + // 开启字段检测 则过滤非法字段数据 + $fields = $this->getDbFields(); + foreach ($data as $key => $val) { + if (!in_array($key, $fields)) { unset($data[$key]); - }elseif(MAGIC_QUOTES_GPC && is_string($val)){ - $data[$key] = stripslashes($val); + } elseif (MAGIC_QUOTES_GPC && is_string($val)) { + $data[$key] = stripslashes($val); } } } // 赋值当前数据对象 - $this->data = $data; + $this->data = $data; // 返回创建的数据以供其他调用 return $data; - } + } /** * 使用正则验证数据 @@ -912,22 +984,25 @@ public function create($data='') { * @param string $rule 验证规则 * @return boolean */ - public function regex($value,$rule) { + public function regex($value, $rule) + { $validate = array( - 'require' => '/\S+/', - 'email' => '/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/', - 'url' => '/^http(s?):\/\/(?:[A-za-z0-9-]+\.)+[A-za-z]{2,4}(:\d+)?(?:[\/\?#][\/=\?%\-&~`@[\]\':+!\.#\w]*)?$/', - 'currency' => '/^\d+(\.\d+)?$/', - 'number' => '/^\d+$/', - 'zip' => '/^\d{6}$/', - 'integer' => '/^[-\+]?\d+$/', - 'double' => '/^[-\+]?\d+(\.\d+)?$/', - 'english' => '/^[A-Za-z]+$/', + 'require' => '/\S+/', + 'email' => '/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/', + 'url' => '/^http(s?):\/\/(?:[A-za-z0-9-]+\.)+[A-za-z]{2,4}(:\d+)?(?:[\/\?#][\/=\?%\-&~`@[\]\':+!\.#\w]*)?$/', + 'currency' => '/^\d+(\.\d+)?$/', + 'number' => '/^\d+$/', + 'zip' => '/^\d{6}$/', + 'integer' => '/^[-\+]?\d+$/', + 'double' => '/^[-\+]?\d+(\.\d+)?$/', + 'english' => '/^[A-Za-z]+$/', ); // 检查是否有内置的正则表达式 - if(isset($validate[strtolower($rule)])) - $rule = $validate[strtolower($rule)]; - return preg_match($rule,$value)===1; + if (isset($validate[strtolower($rule)])) { + $rule = $validate[strtolower($rule)]; + } + + return preg_match($rule, $value) === 1; } /** @@ -938,46 +1013,55 @@ public function regex($value,$rule) { * @param string $type 验证方式 默认为正则验证 * @return boolean */ - public function check($value,$rule,$type='regex'){ - $type = strtolower(trim($type)); - switch($type) { + public function check($value, $rule, $type = 'regex') + { + $type = strtolower(trim($type)); + switch ($type) { case 'in': // 验证是否在某个指定范围之内 逗号分隔字符串或者数组 case 'notin': - $range = is_array($rule)? $rule : explode(',',$rule); - return $type == 'in' ? in_array($value ,$range) : !in_array($value ,$range); + $range = is_array($rule) ? $rule : explode(',', $rule); + return 'in' == $type ? in_array($value, $range) : !in_array($value, $range); case 'between': // 验证是否在某个范围 - case 'notbetween': // 验证是否不在某个范围 - if (is_array($rule)){ - $min = $rule[0]; - $max = $rule[1]; - }else{ - list($min,$max) = explode(',',$rule); + case 'notbetween': // 验证是否不在某个范围 + if (is_array($rule)) { + $min = $rule[0]; + $max = $rule[1]; + } else { + list($min, $max) = explode(',', $rule); } - return $type == 'between' ? $value>=$min && $value<=$max : $value<$min || $value>$max; + return 'between' == $type ? $value >= $min && $value <= $max : $value < $min || $value > $max; case 'equal': // 验证是否等于某个值 - case 'notequal': // 验证是否等于某个值 - return $type == 'equal' ? $value == $rule : $value != $rule; + case 'notequal': // 验证是否等于某个值 + return 'equal' == $type ? $value == $rule : $value != $rule; case 'length': // 验证长度 - $length = mb_strlen($value,'utf-8'); // 当前数据长度 - if(strpos($rule,',')) { // 长度区间 - list($min,$max) = explode(',',$rule); + $length = mb_strlen($value, 'utf-8'); // 当前数据长度 + if (strpos($rule, ',')) { + // 长度区间 + list($min, $max) = explode(',', $rule); return $length >= $min && $length <= $max; - }else{// 指定长度 + } else { +// 指定长度 return $length == $rule; } case 'expire': - list($start,$end) = explode(',',$rule); - if(!is_numeric($start)) $start = strtotime($start); - if(!is_numeric($end)) $end = strtotime($end); + list($start, $end) = explode(',', $rule); + if (!is_numeric($start)) { + $start = strtotime($start); + } + + if (!is_numeric($end)) { + $end = strtotime($end); + } + return NOW_TIME >= $start && NOW_TIME <= $end; case 'ip_allow': // IP 操作许可验证 - return in_array(get_client_ip(),explode(',',$rule)); + return in_array(get_client_ip(), explode(',', $rule)); case 'ip_deny': // IP 操作禁止验证 - return !in_array(get_client_ip(),explode(',',$rule)); + return !in_array(get_client_ip(), explode(',', $rule)); case 'regex': - default: // 默认使用正则验证 可以使用验证类中定义的验证名称 + default: // 默认使用正则验证 可以使用验证类中定义的验证名称 // 检查附加规则 - return $this->regex($value,$rule); + return $this->regex($value, $rule); } } @@ -987,7 +1071,8 @@ public function check($value,$rule,$type='regex'){ * @param string $sql SQL指令 * @return mixed */ - public function query($sql) { + public function query($sql) + { return $this->db->query($sql); } @@ -997,7 +1082,8 @@ public function query($sql) { * @param string $sql SQL指令 * @return false | integer */ - public function execute($sql) { + public function execute($sql) + { return $this->db->execute($sql); } @@ -1009,44 +1095,52 @@ public function execute($sql) { * @param boolean $force 强制重新连接 * @return Model */ - public function db($linkNum='',$config='',$force=false) { - if('' === $linkNum && $this->db) { + public function db($linkNum = '', $config = '', $force = false) + { + if ('' === $linkNum && $this->db) { return $this->db; } - if(!isset($this->_db[$linkNum]) || $force ) { + if (!isset($this->_db[$linkNum]) || $force) { // 创建一个新的实例 - if(!empty($config) && is_string($config) && false === strpos($config,'/')) { // 支持读取配置参数 - $config = C($config); + if (!empty($config) && is_string($config) && false === strpos($config, '/')) { + // 支持读取配置参数 + $config = C($config); } - $this->_db[$linkNum] = Db::getInstance($config); - }elseif(NULL === $config){ + $this->_db[$linkNum] = Db::getInstance($config); + } elseif (null === $config) { $this->_db[$linkNum]->close(); // 关闭数据库连接 unset($this->_db[$linkNum]); - return ; + return; } // 切换数据库连接 - $this->db = $this->_db[$linkNum]; + $this->db = $this->_db[$linkNum]; $this->_after_db(); // 字段检测 - if(!empty($this->name) && $this->autoCheckFields) $this->_checkTableInfo(); + if (!empty($this->name) && $this->autoCheckFields) { + $this->_checkTableInfo(); + } + return $this; } // 数据库切换后回调方法 - protected function _after_db() {} + protected function _after_db() + {} /** * 得到当前的数据对象名称 * @access public * @return string */ - public function getModelName() { - if(empty($this->name)){ - $name = substr(get_class($this),0,-strlen(C('DEFAULT_M_LAYER'))); - if ( $pos = strrpos($name,'\\') ) {//有命名空间 - $this->name = substr($name,$pos+1); - }else{ + public function getModelName() + { + if (empty($this->name)) { + $name = substr(get_class($this), 0, -strlen(C('DEFAULT_M_LAYER'))); + if ($pos = strrpos($name, '\\')) { +//有命名空间 + $this->name = substr($name, $pos + 1); + } else { $this->name = $name; } } @@ -1058,17 +1152,18 @@ public function getModelName() { * @access public * @return string */ - public function getTableName() { - if(empty($this->trueTableName)) { - $tableName = !empty($this->tablePrefix) ? $this->tablePrefix : ''; - if(!empty($this->tableName)) { + public function getTableName() + { + if (empty($this->trueTableName)) { + $tableName = !empty($this->tablePrefix) ? $this->tablePrefix : ''; + if (!empty($this->tableName)) { $tableName .= $this->tableName; - }else{ + } else { $tableName .= parse_name($this->name); } - $this->trueTableName = strtolower($tableName); + $this->trueTableName = strtolower($tableName); } - return (!empty($this->dbName)?$this->dbName.'.':'').$this->trueTableName; + return (!empty($this->dbName) ? $this->dbName . '.' : '') . $this->trueTableName; } /** @@ -1076,10 +1171,11 @@ public function getTableName() { * @access public * @return void */ - public function startTrans() { + public function startTrans() + { $this->commit(); $this->db->startTrans(); - return ; + return; } /** @@ -1087,7 +1183,8 @@ public function startTrans() { * @access public * @return boolean */ - public function commit() { + public function commit() + { return $this->db->commit(); } @@ -1096,7 +1193,8 @@ public function commit() { * @access public * @return boolean */ - public function rollback() { + public function rollback() + { return $this->db->rollback(); } @@ -1105,7 +1203,8 @@ public function rollback() { * @access public * @return string */ - public function getError(){ + public function getError() + { return $this->error; } @@ -1114,7 +1213,8 @@ public function getError(){ * @access public * @return string */ - public function getDbError() { + public function getDbError() + { return $this->db->getError(); } @@ -1123,7 +1223,8 @@ public function getDbError() { * @access public * @return string */ - public function getLastInsID() { + public function getLastInsID() + { return $this->db->getLastInsID(); } @@ -1132,11 +1233,13 @@ public function getLastInsID() { * @access public * @return string */ - public function getLastSql() { + public function getLastSql() + { return $this->db->getLastSql($this->name); } // 鉴于getLastSql比较常用 增加_sql 别名 - public function _sql(){ + public function _sql() + { return $this->getLastSql(); } @@ -1145,7 +1248,8 @@ public function _sql(){ * @access public * @return string */ - public function getPk() { + public function getPk() + { return $this->pk; } @@ -1154,19 +1258,21 @@ public function getPk() { * @access public * @return array */ - public function getDbFields(){ - if(isset($this->options['table'])) {// 动态指定表名 - if(is_array($this->options['table'])){ - $table = key($this->options['table']); - }else{ - $table = $this->options['table']; + public function getDbFields() + { + if (isset($this->options['table'])) { +// 动态指定表名 + if (is_array($this->options['table'])) { + $table = key($this->options['table']); + } else { + $table = $this->options['table']; } - $fields = $this->db->getFields($table); - return $fields ? array_keys($fields) : false; + $fields = $this->db->getFields($table); + return $fields ? array_keys($fields) : false; } - if($this->fields) { - $fields = $this->fields; - unset($fields['_type'],$fields['_pk']); + if ($this->fields) { + $fields = $this->fields; + unset($fields['_type'], $fields['_pk']); return $fields; } return false; @@ -1178,15 +1284,16 @@ public function getDbFields(){ * @param mixed $data 数据 * @return Model */ - public function data($data=''){ - if('' === $data && !empty($this->data)) { + public function data($data = '') + { + if ('' === $data && !empty($this->data)) { return $this->data; } - if(is_object($data)){ - $data = get_object_vars($data); - }elseif(is_string($data)){ - parse_str($data,$data); - }elseif(!is_array($data)){ + if (is_object($data)) { + $data = get_object_vars($data); + } elseif (is_string($data)) { + parse_str($data, $data); + } elseif (!is_array($data)) { E(L('_DATA_TYPE_INVALID_')); } $this->data = $data; @@ -1199,14 +1306,15 @@ public function data($data=''){ * @param mixed $table * @return Model */ - public function table($table) { - $prefix = $this->tablePrefix; - if(is_array($table)) { - $this->options['table'] = $table; - }elseif(!empty($table)) { + public function table($table) + { + $prefix = $this->tablePrefix; + if (is_array($table)) { + $this->options['table'] = $table; + } elseif (!empty($table)) { //将__TABLE_NAME__替换成带前缀的表名 - $table = preg_replace_callback("/__([A-Z0-9_-]+)__/sU", function($match) use($prefix){ return $prefix.strtolower($match[1]);}, $table); - $this->options['table'] = $table; + $table = preg_replace_callback("/__([A-Z0-9_-]+)__/sU", function ($match) use ($prefix) {return $prefix . strtolower($match[1]);}, $table); + $this->options['table'] = $table; } return $this; } @@ -1217,14 +1325,15 @@ public function table($table) { * @param mixed $using * @return Model */ - public function using($using){ - $prefix = $this->tablePrefix; - if(is_array($using)) { - $this->options['using'] = $using; - }elseif(!empty($using)) { + public function using($using) + { + $prefix = $this->tablePrefix; + if (is_array($using)) { + $this->options['using'] = $using; + } elseif (!empty($using)) { //将__TABLE_NAME__替换成带前缀的表名 - $using = preg_replace_callback("/__([A-Z0-9_-]+)__/sU", function($match) use($prefix){ return $prefix.strtolower($match[1]);}, $using); - $this->options['using'] = $using; + $using = preg_replace_callback("/__([A-Z0-9_-]+)__/sU", function ($match) use ($prefix) {return $prefix . strtolower($match[1]);}, $using); + $this->options['using'] = $using; } return $this; } @@ -1236,18 +1345,19 @@ public function using($using){ * @param string $type JOIN类型 * @return Model */ - public function join($join,$type='INNER') { - $prefix = $this->tablePrefix; - if(is_array($join)) { - foreach ($join as $key=>&$_join){ - $_join = preg_replace_callback("/__([A-Z0-9_-]+)__/sU", function($match) use($prefix){ return $prefix.strtolower($match[1]);}, $_join); - $_join = false !== stripos($_join,'JOIN')? $_join : $type.' JOIN ' .$_join; + public function join($join, $type = 'INNER') + { + $prefix = $this->tablePrefix; + if (is_array($join)) { + foreach ($join as $key => &$_join) { + $_join = preg_replace_callback("/__([A-Z0-9_-]+)__/sU", function ($match) use ($prefix) {return $prefix . strtolower($match[1]);}, $_join); + $_join = false !== stripos($_join, 'JOIN') ? $_join : $type . ' JOIN ' . $_join; } - $this->options['join'] = $join; - }elseif(!empty($join)) { + $this->options['join'] = $join; + } elseif (!empty($join)) { //将__TABLE_NAME__字符串替换成带前缀的表名 - $join = preg_replace_callback("/__([A-Z0-9_-]+)__/sU", function($match) use($prefix){ return $prefix.strtolower($match[1]);}, $join); - $this->options['join'][] = false !== stripos($join,'JOIN')? $join : $type.' JOIN '.$join; + $join = preg_replace_callback("/__([A-Z0-9_-]+)__/sU", function ($match) use ($prefix) {return $prefix . strtolower($match[1]);}, $join); + $this->options['join'][] = false !== stripos($join, 'JOIN') ? $join : $type . ' JOIN ' . $join; } return $this; } @@ -1259,30 +1369,34 @@ public function join($join,$type='INNER') { * @param boolean $all * @return Model */ - public function union($union,$all=false) { - if(empty($union)) return $this; - if($all) { - $this->options['union']['_all'] = true; + public function union($union, $all = false) + { + if (empty($union)) { + return $this; + } + + if ($all) { + $this->options['union']['_all'] = true; } - if(is_object($union)) { - $union = get_object_vars($union); + if (is_object($union)) { + $union = get_object_vars($union); } // 转换union表达式 - if(is_string($union) ) { - $prefix = $this->tablePrefix; + if (is_string($union)) { + $prefix = $this->tablePrefix; //将__TABLE_NAME__字符串替换成带前缀的表名 - $options = preg_replace_callback("/__([A-Z0-9_-]+)__/sU", function($match) use($prefix){ return $prefix.strtolower($match[1]);}, $union); - }elseif(is_array($union)){ - if(isset($union[0])) { - $this->options['union'] = array_merge($this->options['union'],$union); + $options = preg_replace_callback("/__([A-Z0-9_-]+)__/sU", function ($match) use ($prefix) {return $prefix . strtolower($match[1]);}, $union); + } elseif (is_array($union)) { + if (isset($union[0])) { + $this->options['union'] = array_merge($this->options['union'], $union); return $this; - }else{ - $options = $union; + } else { + $options = $union; } - }else{ + } else { E(L('_DATA_TYPE_INVALID_')); } - $this->options['union'][] = $options; + $this->options['union'][] = $options; return $this; } @@ -1294,14 +1408,17 @@ public function union($union,$all=false) { * @param string $type * @return Model */ - public function cache($key=true,$expire=null,$type=''){ + public function cache($key = true, $expire = null, $type = '') + { // 增加快捷调用方式 cache(10) 等同于 cache(true, 10) - if(is_numeric($key) && is_null($expire)){ + if (is_numeric($key) && is_null($expire)) { $expire = $key; $key = true; } - if(false !== $key) - $this->options['cache'] = array('key'=>$key,'expire'=>$expire,'type'=>$type); + if (false !== $key) { + $this->options['cache'] = array('key' => $key, 'expire' => $expire, 'type' => $type); + } + return $this; } @@ -1312,18 +1429,21 @@ public function cache($key=true,$expire=null,$type=''){ * @param boolean $except 是否排除 * @return Model */ - public function field($field,$except=false){ - if(true === $field) {// 获取全部字段 - $fields = $this->getDbFields(); - $field = $fields?:'*'; - }elseif($except) {// 字段排除 - if(is_string($field)) { - $field = explode(',',$field); + public function field($field, $except = false) + { + if (true === $field) { +// 获取全部字段 + $fields = $this->getDbFields(); + $field = $fields ?: '*'; + } elseif ($except) { +// 字段排除 + if (is_string($field)) { + $field = explode(',', $field); } - $fields = $this->getDbFields(); - $field = $fields?array_diff($fields,$field):$field; + $fields = $this->getDbFields(); + $field = $fields ? array_diff($fields, $field) : $field; } - $this->options['field'] = $field; + $this->options['field'] = $field; return $this; } @@ -1334,30 +1454,36 @@ public function field($field,$except=false){ * @param array $args 参数 * @return Model */ - public function scope($scope='',$args=NULL){ - if('' === $scope) { - if(isset($this->_scope['default'])) { + public function scope($scope = '', $args = null) + { + if ('' === $scope) { + if (isset($this->_scope['default'])) { // 默认的命名范围 - $options = $this->_scope['default']; - }else{ + $options = $this->_scope['default']; + } else { return $this; } - }elseif(is_string($scope)){ // 支持多个命名范围调用 用逗号分割 - $scopes = explode(',',$scope); - $options = array(); - foreach ($scopes as $name){ - if(!isset($this->_scope[$name])) continue; - $options = array_merge($options,$this->_scope[$name]); + } elseif (is_string($scope)) { + // 支持多个命名范围调用 用逗号分割 + $scopes = explode(',', $scope); + $options = array(); + foreach ($scopes as $name) { + if (!isset($this->_scope[$name])) { + continue; + } + + $options = array_merge($options, $this->_scope[$name]); } - if(!empty($args) && is_array($args)) { - $options = array_merge($options,$args); + if (!empty($args) && is_array($args)) { + $options = array_merge($options, $args); } - }elseif(is_array($scope)){ // 直接传入命名范围定义 - $options = $scope; + } elseif (is_array($scope)) { + // 直接传入命名范围定义 + $options = $scope; } - - if(is_array($options) && !empty($options)){ - $this->options = array_merge($this->options,array_change_key_case($options)); + + if (is_array($options) && !empty($options)) { + $this->options = array_merge($this->options, array_change_key_case($options)); } return $this; } @@ -1369,28 +1495,29 @@ public function scope($scope='',$args=NULL){ * @param mixed $parse 预处理参数 * @return Model */ - public function where($where,$parse=null){ - if(!is_null($parse) && is_string($where)) { - if(!is_array($parse)) { + public function where($where, $parse = null) + { + if (!is_null($parse) && is_string($where)) { + if (!is_array($parse)) { $parse = func_get_args(); array_shift($parse); } - $parse = array_map(array($this->db,'escapeString'),$parse); - $where = vsprintf($where,$parse); - }elseif(is_object($where)){ - $where = get_object_vars($where); - } - if(is_string($where) && '' != $where){ - $map = array(); - $map['_string'] = $where; - $where = $map; - } - if(isset($this->options['where'])){ - $this->options['where'] = array_merge($this->options['where'],$where); - }else{ - $this->options['where'] = $where; - } - + $parse = array_map(array($this->db, 'escapeString'), $parse); + $where = vsprintf($where, $parse); + } elseif (is_object($where)) { + $where = get_object_vars($where); + } + if (is_string($where) && '' != $where) { + $map = array(); + $map['_string'] = $where; + $where = $map; + } + if (isset($this->options['where'])) { + $this->options['where'] = array_merge($this->options['where'], $where); + } else { + $this->options['where'] = $where; + } + return $this; } @@ -1401,11 +1528,12 @@ public function where($where,$parse=null){ * @param mixed $length 查询数量 * @return Model */ - public function limit($offset,$length=null){ - if(is_null($length) && strpos($offset,',')){ - list($offset,$length) = explode(',',$offset); + public function limit($offset, $length = null) + { + if (is_null($length) && strpos($offset, ',')) { + list($offset, $length) = explode(',', $offset); } - $this->options['limit'] = intval($offset).( $length? ','.intval($length) : '' ); + $this->options['limit'] = intval($offset) . ($length ? ',' . intval($length) : ''); return $this; } @@ -1416,11 +1544,12 @@ public function limit($offset,$length=null){ * @param mixed $listRows 每页数量 * @return Model */ - public function page($page,$listRows=null){ - if(is_null($listRows) && strpos($page,',')){ - list($page,$listRows) = explode(',',$page); + public function page($page, $listRows = null) + { + if (is_null($listRows) && strpos($page, ',')) { + list($page, $listRows) = explode(',', $page); } - $this->options['page'] = array(intval($page),intval($listRows)); + $this->options['page'] = array(intval($page), intval($listRows)); return $this; } @@ -1430,8 +1559,9 @@ public function page($page,$listRows=null){ * @param string $comment 注释 * @return Model */ - public function comment($comment){ - $this->options['comment'] = $comment; + public function comment($comment) + { + $this->options['comment'] = $comment; return $this; } @@ -1441,8 +1571,9 @@ public function comment($comment){ * @param boolean $fetch 是否返回sql * @return Model */ - public function fetchSql($fetch){ - $this->options['fetch_sql'] = $fetch; + public function fetchSql($fetch) + { + $this->options['fetch_sql'] = $fetch; return $this; } @@ -1453,18 +1584,19 @@ public function fetchSql($fetch){ * @param mixed $value 绑定的变量及绑定参数 * @return Model */ - public function bind($key,$value=false) { - if(is_array($key)){ - $this->options['bind'] = $key; - }else{ - $num = func_num_args(); - if($num>2){ - $params = func_get_args(); + public function bind($key, $value = false) + { + if (is_array($key)) { + $this->options['bind'] = $key; + } else { + $num = func_num_args(); + if ($num > 2) { + $params = func_get_args(); array_shift($params); - $this->options['bind'][$key] = $params; - }else{ - $this->options['bind'][$key] = $value; - } + $this->options['bind'][$key] = $params; + } else { + $this->options['bind'][$key] = $value; + } } return $this; } @@ -1476,9 +1608,12 @@ public function bind($key,$value=false) { * @param mixed $value 值 * @return Model */ - public function setProperty($name,$value) { - if(property_exists($this,$name)) + public function setProperty($name, $value) + { + if (property_exists($this, $name)) { $this->$name = $value; + } + return $this; } diff --git a/ThinkPHP/Mode/Lite/View.class.php b/ThinkPHP/Mode/Lite/View.class.php index 064343fe1..ec385583b 100644 --- a/ThinkPHP/Mode/Lite/View.class.php +++ b/ThinkPHP/Mode/Lite/View.class.php @@ -9,23 +9,25 @@ // | Author: liu21st // +---------------------------------------------------------------------- namespace Think; + /** * ThinkPHP 视图类 */ -class View { +class View +{ /** * 模板输出变量 * @var tVar * @access protected - */ - protected $tVar = array(); + */ + protected $tVar = array(); /** * 模板主题 * @var theme * @access protected - */ - protected $theme = ''; + */ + protected $theme = ''; /** * 模板变量赋值 @@ -33,10 +35,11 @@ class View { * @param mixed $name * @param mixed $value */ - public function assign($name,$value=''){ - if(is_array($name)) { - $this->tVar = array_merge($this->tVar,$name); - }else { + public function assign($name, $value = '') + { + if (is_array($name)) { + $this->tVar = array_merge($this->tVar, $name); + } else { $this->tVar[$name] = $value; } } @@ -47,11 +50,12 @@ public function assign($name,$value=''){ * @param string $name * @return mixed */ - public function get($name=''){ - if('' === $name) { + public function get($name = '') + { + if ('' === $name) { return $this->tVar; } - return isset($this->tVar[$name])?$this->tVar[$name]:false; + return isset($this->tVar[$name]) ? $this->tVar[$name] : false; } /** @@ -64,12 +68,13 @@ public function get($name=''){ * @param string $prefix 模板缓存前缀 * @return mixed */ - public function display($templateFile='',$charset='',$contentType='',$content='',$prefix='') { + public function display($templateFile = '', $charset = '', $contentType = '', $content = '', $prefix = '') + { G('viewStartTime'); // 解析并获取模板内容 - $content = $this->fetch($templateFile,$content,$prefix); + $content = $this->fetch($templateFile, $content, $prefix); // 输出模板内容 - $this->render($content,$charset,$contentType); + $this->render($content, $charset, $contentType); } /** @@ -80,12 +85,19 @@ public function display($templateFile='',$charset='',$contentType='',$content='' * @param string $contentType 输出类型 * @return mixed */ - private function render($content,$charset='',$contentType=''){ - if(empty($charset)) $charset = C('DEFAULT_CHARSET'); - if(empty($contentType)) $contentType = C('TMPL_CONTENT_TYPE'); + private function render($content, $charset = '', $contentType = '') + { + if (empty($charset)) { + $charset = C('DEFAULT_CHARSET'); + } + + if (empty($contentType)) { + $contentType = C('TMPL_CONTENT_TYPE'); + } + // 网页字符编码 - header('Content-Type:'.$contentType.'; charset='.$charset); - header('Cache-control: '.C('HTTP_CACHE_CONTROL')); // 页面缓存控制 + header('Content-Type:' . $contentType . '; charset=' . $charset); + header('Cache-control: ' . C('HTTP_CACHE_CONTROL')); // 页面缓存控制 header('X-Powered-By:ThinkPHP'); // 输出模板文件 echo $content; @@ -99,54 +111,62 @@ private function render($content,$charset='',$contentType=''){ * @param string $prefix 模板缓存前缀 * @return string */ - public function fetch($templateFile='',$content='',$prefix='') { - if(empty($content)) { - $templateFile = $this->parseTemplate($templateFile); + public function fetch($templateFile = '', $content = '', $prefix = '') + { + if (empty($content)) { + $templateFile = $this->parseTemplate($templateFile); // 模板文件不存在直接返回 - if(!is_file($templateFile)) E(L('_TEMPLATE_NOT_EXIST_').':'.$templateFile); - }else{ - defined('THEME_PATH') or define('THEME_PATH', $this->getThemePath()); + if (!is_file($templateFile)) { + E(L('_TEMPLATE_NOT_EXIST_') . ':' . $templateFile); + } + + } else { + defined('THEME_PATH') or define('THEME_PATH', $this->getThemePath()); } // 页面缓存 ob_start(); ob_implicit_flush(0); - if('php' == strtolower(C('TMPL_ENGINE_TYPE'))) { // 使用PHP原生模板 - $_content = $content; + if ('php' == strtolower(C('TMPL_ENGINE_TYPE'))) { + // 使用PHP原生模板 + $_content = $content; // 模板阵列变量分解成为独立变量 extract($this->tVar, EXTR_OVERWRITE); // 直接载入PHP模板 - empty($_content)?include $templateFile:eval('?>'.$_content); - }else{ + empty($_content) ? include $templateFile : eval('?>' . $_content); + } else { // 视图解析标签 - $params = array('var'=>$this->tVar,'file'=>$templateFile,'content'=>$content,'prefix'=>$prefix); - $_content = !empty($content)?:$templateFile; - if((!empty($content) && $this->checkContentCache($content,$prefix)) || $this->checkCache($templateFile,$prefix)) { // 缓存有效 + $params = array('var' => $this->tVar, 'file' => $templateFile, 'content' => $content, 'prefix' => $prefix); + $_content = !empty($content) ?: $templateFile; + if ((!empty($content) && $this->checkContentCache($content, $prefix)) || $this->checkCache($templateFile, $prefix)) { + // 缓存有效 //载入模版缓存文件 - Storage::load(C('CACHE_PATH').$prefix.md5($_content).C('TMPL_CACHFILE_SUFFIX'),$this->tVar); - }else{ + Storage::load(C('CACHE_PATH') . $prefix . md5($_content) . C('TMPL_CACHFILE_SUFFIX'), $this->tVar); + } else { $tpl = Think::instance('Think\\Template'); // 编译并加载模板文件 - $tpl->fetch($_content,$this->tVar,$prefix); - } + $tpl->fetch($_content, $this->tVar, $prefix); + } } // 获取并清空缓存 $content = ob_get_clean(); // 内容过滤标签 // 系统默认的特殊变量替换 - $replace = array( - '__ROOT__' => __ROOT__, // 当前网站地址 - '__APP__' => __APP__, // 当前应用地址 - '__MODULE__' => __MODULE__, - '__ACTION__' => __ACTION__, // 当前操作地址 - '__SELF__' => __SELF__, // 当前页面地址 - '__CONTROLLER__'=> __CONTROLLER__, - '__URL__' => __CONTROLLER__, - '__PUBLIC__' => __ROOT__.'/Public',// 站点公共目录 + $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); + 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; } @@ -158,23 +178,27 @@ public function fetch($templateFile='',$content='',$prefix='') { * @param string $tmplTemplateFile 模板文件名 * @return boolean */ - protected function checkCache($tmplTemplateFile,$prefix='') { + 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)){ + } + + $tmplCacheFile = C('CACHE_PATH') . $prefix . md5($tmplTemplateFile) . C('TMPL_CACHFILE_SUFFIX'); + if (!Storage::has($tmplCacheFile)) { return false; - }elseif (filemtime($tmplTemplateFile) > Storage::get($tmplCacheFile,'mtime')) { + } elseif (filemtime($tmplTemplateFile) > Storage::get($tmplCacheFile, 'mtime')) { // 模板文件如果有更新则缓存需要更新 return false; - }elseif (C('TMPL_CACHE_TIME') != 0 && time() > Storage::get($tmplCacheFile,'mtime')+C('TMPL_CACHE_TIME')) { + } 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')) { + if (C('LAYOUT_ON')) { + $layoutFile = THEME_PATH . C('LAYOUT_NAME') . C('TMPL_TEMPLATE_SUFFIX'); + if (filemtime($layoutFile) > Storage::get($tmplCacheFile, 'mtime')) { return false; } } @@ -189,13 +213,14 @@ protected function checkCache($tmplTemplateFile,$prefix='') { * @param string $tmplContent 模板内容 * @return boolean */ - protected function checkContentCache($tmplContent,$prefix='') { - if(Storage::has(C('CACHE_PATH').$prefix.md5($tmplContent).C('TMPL_CACHFILE_SUFFIX'))){ + protected function checkContentCache($tmplContent, $prefix = '') + { + if (Storage::has(C('CACHE_PATH') . $prefix . md5($tmplContent) . C('TMPL_CACHFILE_SUFFIX'))) { return true; - }else{ + } else { return false; } - } + } /** * 自动定位模板文件 @@ -203,32 +228,34 @@ protected function checkContentCache($tmplContent,$prefix='') { * @param string $template 模板文件规则 * @return string */ - public function parseTemplate($template='') { - if(is_file($template)) { + public function parseTemplate($template = '') + { + if (is_file($template)) { return $template; } - $depr = C('TMPL_FILE_DEPR'); - $template = str_replace(':', $depr, $template); + $depr = C('TMPL_FILE_DEPR'); + $template = str_replace(':', $depr, $template); // 获取当前模块 - $module = MODULE_NAME; - if(strpos($template,'@')){ // 跨模块调用模版文件 - list($module,$template) = explode('@',$template); + $module = MODULE_NAME; + if (strpos($template, '@')) { + // 跨模块调用模版文件 + list($module, $template) = explode('@', $template); } // 获取当前主题的模版路径 - defined('THEME_PATH') or define('THEME_PATH', $this->getThemePath($module)); + defined('THEME_PATH') or define('THEME_PATH', $this->getThemePath($module)); // 分析模板文件规则 - if('' == $template) { + if ('' == $template) { // 如果模板文件名为空 按照默认规则定位 $template = CONTROLLER_NAME . $depr . ACTION_NAME; - }elseif(false === strpos($template, $depr)){ + } elseif (false === strpos($template, $depr)) { $template = CONTROLLER_NAME . $depr . $template; } - $file = THEME_PATH.$template.C('TMPL_TEMPLATE_SUFFIX'); - if(C('TMPL_LOAD_DEFAULTTHEME') && THEME_NAME != C('DEFAULT_THEME') && !is_file($file)){ + $file = THEME_PATH . $template . C('TMPL_TEMPLATE_SUFFIX'); + if (C('TMPL_LOAD_DEFAULTTHEME') && THEME_NAME != C('DEFAULT_THEME') && !is_file($file)) { // 找不到当前主题模板的时候定位默认主题中的模板 - $file = dirname(THEME_PATH).'/'.C('DEFAULT_THEME').'/'.$template.C('TMPL_TEMPLATE_SUFFIX'); + $file = dirname(THEME_PATH) . '/' . C('DEFAULT_THEME') . '/' . $template . C('TMPL_TEMPLATE_SUFFIX'); } return $file; } @@ -239,16 +266,17 @@ public function parseTemplate($template='') { * @param string $module 模块名 * @return string */ - protected function getThemePath($module=MODULE_NAME){ + protected function getThemePath($module = MODULE_NAME) + { // 获取当前主题名称 $theme = $this->getTemplateTheme(); // 获取当前主题的模版路径 - $tmplPath = C('VIEW_PATH'); // 模块设置独立的视图目录 - if(!$tmplPath){ + $tmplPath = C('VIEW_PATH'); // 模块设置独立的视图目录 + if (!$tmplPath) { // 定义TMPL_PATH 则改变全局的视图目录到模块之外 - $tmplPath = defined('TMPL_PATH')? TMPL_PATH.$module.'/' : APP_PATH.$module.'/'.C('DEFAULT_V_LAYER').'/'; + $tmplPath = defined('TMPL_PATH') ? TMPL_PATH . $module . '/' : APP_PATH . $module . '/' . C('DEFAULT_V_LAYER') . '/'; } - return $tmplPath.$theme; + return $tmplPath . $theme; } /** @@ -257,7 +285,8 @@ protected function getThemePath($module=MODULE_NAME){ * @param mixed $theme 主题名称 * @return View */ - public function theme($theme){ + public function theme($theme) + { $this->theme = $theme; return $this; } @@ -267,27 +296,30 @@ public function theme($theme){ * @access private * @return string */ - private function getTemplateTheme() { - if($this->theme) { // 指定模板主题 + private function getTemplateTheme() + { + if ($this->theme) { + // 指定模板主题 $theme = $this->theme; - }else{ + } else { /* 获取模板主题名称 */ - $theme = C('DEFAULT_THEME'); - if(C('TMPL_DETECT_THEME')) {// 自动侦测模板主题 + $theme = C('DEFAULT_THEME'); + if (C('TMPL_DETECT_THEME')) { +// 自动侦测模板主题 $t = C('VAR_TEMPLATE'); - if (isset($_GET[$t])){ + if (isset($_GET[$t])) { $theme = $_GET[$t]; - }elseif(cookie('think_template')){ + } elseif (cookie('think_template')) { $theme = cookie('think_template'); } - if(!in_array($theme,explode(',',C('THEME_LIST')))){ - $theme = C('DEFAULT_THEME'); + if (!in_array($theme, explode(',', C('THEME_LIST')))) { + $theme = C('DEFAULT_THEME'); } - cookie('think_template',$theme,864000); + cookie('think_template', $theme, 864000); } } - defined('THEME_NAME') || define('THEME_NAME', $theme); // 当前模板主题名称 - return $theme?$theme . '/':''; + defined('THEME_NAME') || define('THEME_NAME', $theme); // 当前模板主题名称 + return $theme ? $theme . '/' : ''; } -} \ No newline at end of file +} diff --git a/ThinkPHP/Mode/Lite/convention.php b/ThinkPHP/Mode/Lite/convention.php index 982377df6..cd9b1a8cb 100644 --- a/ThinkPHP/Mode/Lite/convention.php +++ b/ThinkPHP/Mode/Lite/convention.php @@ -15,149 +15,148 @@ * 配置名称大小写任意,系统会统一转换成小写 * 所有配置参数都可以在生效前动态改变 */ -defined('THINK_PATH') or exit(); -return array( +return array( /* 应用设定 */ - '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'), + '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'), /* Cookie设置 */ - 'COOKIE_EXPIRE' => 0, // Cookie有效期 - 'COOKIE_DOMAIN' => '', // Cookie有效域名 - 'COOKIE_PATH' => '/', // Cookie路径 - 'COOKIE_PREFIX' => '', // Cookie前缀 避免冲突 - 'COOKIE_SECURE' => false, // Cookie安全传输 - 'COOKIE_HTTPONLY' => '', // Cookie httponly设置 + '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函数... + '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' => '', // 指定从服务器序号 + '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, // 子目录缓存级别 + '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, // 每个级别的错误信息 最大记录数 + '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, // 是否记录异常信息日志 + 'LOG_RECORD' => false, // 默认不记录日志 + 'LOG_TYPE' => 'File', // 日志记录类型 默认为文件方式 + 'LOG_LEVEL' => 'EMERG,ALERT,CRIT,ERR', // 允许记录的日志级别 + 'LOG_FILE_SIZE' => 2097152, // 日志文件大小限制 + 'LOG_EXCEPTION_RECORD' => false, // 是否记录异常信息日志 /* SESSION设置 */ - 'SESSION_AUTO_START' => false, // 是否自动开启Session - 'SESSION_OPTIONS' => array(), // session 配置数组 支持type name id path expire domain 等参数 - 'SESSION_TYPE' => '', // session hander类型 默认无需设置 除非扩展了session hander驱动 - 'SESSION_PREFIX' => '', // session 前缀 + 'SESSION_AUTO_START' => false, // 是否自动开启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_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 + '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' => '', // 需要额外加载的标签库(须指定标签库名称),多个以逗号分隔 - + '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,代表以下四种模式: + '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映射定义规则 + '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, // 输入变量是否自动强制转换为字符串 如果开启则数组变量需要手动传入变量修饰符获取变量 + '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', // 数据加密方式 + 'HTTP_CACHE_CONTROL' => 'private', // 网页缓存控制 + 'CHECK_APP_DIR' => true, // 是否检查应用目录是否创建 + 'FILE_UPLOAD_TYPE' => 'Local', // 文件上传方式 + 'DATA_CRYPT_TYPE' => 'Think', // 数据加密方式 ); diff --git a/ThinkPHP/Mode/Lite/functions.php b/ThinkPHP/Mode/Lite/functions.php index 7cf10acdc..53ba8d263 100644 --- a/ThinkPHP/Mode/Lite/functions.php +++ b/ThinkPHP/Mode/Lite/functions.php @@ -20,7 +20,8 @@ * @param mixed $default 默认值 * @return mixed */ -function C($name=null, $value=null,$default=null) { +function C($name = null, $value = null, $default = null) +{ static $_config = array(); // 无参数时获取所有 if (empty($name)) { @@ -30,22 +31,26 @@ function C($name=null, $value=null,$default=null) { if (is_string($name)) { if (!strpos($name, '.')) { $name = strtoupper($name); - if (is_null($value)) + if (is_null($value)) { return isset($_config[$name]) ? $_config[$name] : $default; + } + $_config[$name] = $value; return null; } // 二维数组设置和获取支持 - $name = explode('.', $name); - $name[0] = strtoupper($name[0]); - if (is_null($value)) + $name = explode('.', $name); + $name[0] = strtoupper($name[0]); + if (is_null($value)) { return isset($_config[$name[0]][$name[1]]) ? $_config[$name[0]][$name[1]] : $default; + } + $_config[$name[0]][$name[1]] = $value; return null; } // 批量设置 - if (is_array($name)){ - $_config = array_merge($_config, array_change_key_case($name,CASE_UPPER)); + if (is_array($name)) { + $_config = array_merge($_config, array_change_key_case($name, CASE_UPPER)); return null; } return null; // 避免非法参数 @@ -57,24 +62,25 @@ function C($name=null, $value=null,$default=null) { * @param string $parse 配置解析方法 有些格式需要用户自己解析 * @return array */ -function load_config($file,$parse=CONF_PARSE){ - $ext = pathinfo($file,PATHINFO_EXTENSION); - switch($ext){ +function loadConfig($file, $parse = CONF_PARSE) +{ + $ext = pathinfo($file, PATHINFO_EXTENSION); + switch ($ext) { case 'php': return include $file; case 'ini': return parse_ini_file($file); case 'yaml': - return yaml_parse_file($file); - case 'xml': - return (array)simplexml_load_file($file); + return yamlParseFile($file); + case 'xml': + return (array) simplexml_load_file($file); case 'json': return json_decode(file_get_contents($file), true); default: - if(function_exists($parse)){ + if (function_exists($parse)) { return $parse($file); - }else{ - E(L('_NOT_SUPPORT_').':'.$ext); + } else { + E(L('_NOT_SUPPORT_') . ':' . $ext); } } } @@ -85,7 +91,8 @@ function load_config($file,$parse=CONF_PARSE){ * @return array */ if (!function_exists('yaml_parse_file')) { - function yaml_parse_file($file) { + function yamlParseFile($file) + { vendor('spyc.Spyc'); return Spyc::YAMLLoad($file); } @@ -98,7 +105,8 @@ function yaml_parse_file($file) { * @throws Think\Exception * @return void */ -function E($msg, $code=0) { +function E($msg, $code = 0) +{ throw new Think\Exception($msg, $code); } @@ -119,25 +127,32 @@ function E($msg, $code=0) { * @param integer|string $dec 小数位或者m * @return mixed */ -function G($start,$end='',$dec=4) { - static $_info = array(); - static $_mem = array(); - if(is_float($end)) { // 记录时间 - $_info[$start] = $end; - }elseif(!empty($end)){ // 统计时间和内存使用 - if(!isset($_info[$end])) { - $_info[$end] = microtime(true); +function G($start, $end = '', $dec = 4) +{ + static $_info = array(); + static $_mem = array(); + if (is_float($end)) { + // 记录时间 + $_info[$start] = $end; + } elseif (!empty($end)) { + // 统计时间和内存使用 + if (!isset($_info[$end])) { + $_info[$end] = microtime(true); } - if($dec=='m'){ - if(!isset($_mem[$end])) $_mem[$end] = memory_get_usage(); - return number_format(($_mem[$end]-$_mem[$start])/1024); - }else{ - return number_format(($_info[$end]-$_info[$start]),$dec); + if ('m' == $dec) { + if (!isset($_mem[$end])) { + $_mem[$end] = memory_get_usage(); + } + + return number_format(($_mem[$end] - $_mem[$start]) / 1024); + } else { + return number_format(($_info[$end] - $_info[$start]), $dec); } - }else{ // 记录时间和内存使用 - $_info[$start] = microtime(true); - $_mem[$start] = memory_get_usage(); + } else { + // 记录时间和内存使用 + $_info[$start] = microtime(true); + $_mem[$start] = memory_get_usage(); } return null; } @@ -148,31 +163,32 @@ function G($start,$end='',$dec=4) { * @param mixed $value 语言值或者变量 * @return mixed */ -function L($name=null, $value=null) { +function L($name = null, $value = null) +{ static $_lang = array(); // 空参数返回所有定义 - if (empty($name)){ + if (empty($name)) { return $_lang; } // 判断语言获取(或设置) // 若不存在,直接返回全大写$name if (is_string($name)) { - $name = strtoupper($name); - if (is_null($value)){ + $name = strtoupper($name); + if (is_null($value)) { return isset($_lang[$name]) ? $_lang[$name] : $name; - }elseif(is_array($value)){ + } elseif (is_array($value)) { // 支持变量 $replace = array_keys($value); - foreach($replace as &$v){ - $v = '{$'.$v.'}'; + foreach ($replace as &$v) { + $v = '{$' . $v . '}'; } - return str_replace($replace,$value,isset($_lang[$name]) ? $_lang[$name] : $name); + return str_replace($replace, $value, isset($_lang[$name]) ? $_lang[$name] : $name); } $_lang[$name] = $value; // 语言定义 return null; } // 批量定义 - if (is_array($name)){ + if (is_array($name)) { $_lang = array_merge($_lang, array_change_key_case($name, CASE_UPPER)); } return null; @@ -186,8 +202,9 @@ function L($name=null, $value=null) { * @param boolean $record 是否记录日志 * @return void|array */ -function trace($value='[think]',$label='',$level='DEBUG',$record=false) { - return Think\Think::trace($value,$label,$level,$record); +function trace($value = '[think]', $label = '', $level = 'DEBUG', $record = false) +{ + return Think\Think::trace($value, $label, $level, $record); } /** @@ -195,20 +212,21 @@ function trace($value='[think]',$label='',$level='DEBUG',$record=false) { * @param string $filename 文件名 * @return string */ -function compile($filename) { - $content = php_strip_whitespace($filename); - $content = trim(substr($content, 5)); +function compile($filename) +{ + $content = php_strip_whitespace($filename); + $content = trim(substr($content, 5)); // 替换预编译指令 - $content = preg_replace('/\/\/\[RUNTIME\](.*?)\/\/\[\/RUNTIME\]/s', '', $content); - if(0===strpos($content,'namespace')){ - $content = preg_replace('/namespace\s(.*?);/','namespace \\1{',$content,1); - }else{ - $content = 'namespace {'.$content; + $content = preg_replace('/\/\/\[RUNTIME\](.*?)\/\/\[\/RUNTIME\]/s', '', $content); + if (0 === strpos($content, 'namespace')) { + $content = preg_replace('/namespace\s(.*?);/', 'namespace \\1{', $content, 1); + } else { + $content = 'namespace {' . $content; } - if ('?>' == substr($content, -2)){ - $content = substr($content, 0, -2); + if ('?>' == substr($content, -2)) { + $content = substr($content, 0, -2); } - return $content.'}'; + return $content . '}'; } /** @@ -217,46 +235,48 @@ function compile($filename) { * @param string $layer 视图层(目录)名称 * @return string */ -function T($template='',$layer=''){ +function T($template = '', $layer = '') +{ // 解析模版资源地址 - if(false === strpos($template,'://')){ - $template = 'http://'.str_replace(':', '/',$template); - } - $info = parse_url($template); - $file = $info['host'].(isset($info['path'])?$info['path']:''); - $module = isset($info['user'])?$info['user'].'/':MODULE_NAME.'/'; - $extend = $info['scheme']; - $layer = $layer?$layer:C('DEFAULT_V_LAYER'); + if (false === strpos($template, '://')) { + $template = 'http://' . str_replace(':', '/', $template); + } + $info = parse_url($template); + $file = $info['host'] . (isset($info['path']) ? $info['path'] : ''); + $module = isset($info['user']) ? $info['user'] . '/' : MODULE_NAME . '/'; + $extend = $info['scheme']; + $layer = $layer ? $layer : C('DEFAULT_V_LAYER'); // 获取当前主题的模版路径 - $auto = C('AUTOLOAD_NAMESPACE'); - if($auto && isset($auto[$extend])){ // 扩展资源 - $baseUrl = $auto[$extend].$module.$layer.'/'; - }elseif(C('VIEW_PATH')){ + $auto = C('AUTOLOAD_NAMESPACE'); + if ($auto && isset($auto[$extend])) { + // 扩展资源 + $baseUrl = $auto[$extend] . $module . $layer . '/'; + } elseif (C('VIEW_PATH')) { // 改变模块视图目录 - $baseUrl = C('VIEW_PATH'); - }elseif(defined('TMPL_PATH')){ + $baseUrl = C('VIEW_PATH'); + } elseif (defined('TMPL_PATH')) { // 指定全局视图目录 - $baseUrl = TMPL_PATH.$module; - }else{ - $baseUrl = APP_PATH.$module.$layer.'/'; + $baseUrl = TMPL_PATH . $module; + } else { + $baseUrl = APP_PATH . $module . $layer . '/'; } // 获取主题 - $theme = substr_count($file,'/')<2 ? C('DEFAULT_THEME') : ''; + $theme = substr_count($file, '/') < 2 ? C('DEFAULT_THEME') : ''; // 分析模板文件规则 - $depr = C('TMPL_FILE_DEPR'); - if('' == $file) { + $depr = C('TMPL_FILE_DEPR'); + if ('' == $file) { // 如果模板文件名为空 按照默认规则定位 $file = CONTROLLER_NAME . $depr . ACTION_NAME; - }elseif(false === strpos($file, '/')){ + } elseif (false === strpos($file, '/')) { $file = CONTROLLER_NAME . $depr . $file; - }elseif('/' != $depr){ - $file = substr_count($file,'/')>1 ? substr_replace($file,$depr,strrpos($file,'/'),1) : str_replace('/', $depr, $file); + } elseif ('/' != $depr) { + $file = substr_count($file, '/') > 1 ? substr_replace($file, $depr, strrpos($file, '/'), 1) : str_replace('/', $depr, $file); } - return $baseUrl.($theme?$theme.'/':'').$file.C('TMPL_TEMPLATE_SUFFIX'); + return $baseUrl . ($theme ? $theme . '/' : '') . $file . C('TMPL_TEMPLATE_SUFFIX'); } /** @@ -273,121 +293,139 @@ function T($template='',$layer=''){ * @param mixed $datas 要获取的额外数据源 * @return mixed */ -function I($name,$default='',$filter=null,$datas=null) { - if(strpos($name,'/')){ // 指定修饰符 - list($name,$type) = explode('/',$name,2); - }elseif(C('VAR_AUTO_STRING')){ // 默认强制转换为字符串 - $type = 's'; - } - if(strpos($name,'.')) { // 指定参数来源 - list($method,$name) = explode('.',$name,2); - }else{ // 默认为自动判断 - $method = 'param'; - } - switch(strtolower($method)) { - case 'get' : $input =& $_GET;break; - case 'post' : $input =& $_POST;break; - case 'put' : parse_str(file_get_contents('php://input'), $input);break; - case 'param' : - switch($_SERVER['REQUEST_METHOD']) { +function I($name, $default = '', $filter = null, $datas = null) +{ + if (strpos($name, '/')) { + // 指定修饰符 + list($name, $type) = explode('/', $name, 2); + } elseif (C('VAR_AUTO_STRING')) { + // 默认强制转换为字符串 + $type = 's'; + } + if (strpos($name, '.')) { + // 指定参数来源 + list($method, $name) = explode('.', $name, 2); + } else { + // 默认为自动判断 + $method = 'param'; + } + switch (strtolower($method)) { + case 'get':$input = &$_GET; + break; + case 'post':$input = &$_POST; + break; + case 'put':parse_str(file_get_contents('php://input'), $input); + break; + case 'param': + switch ($_SERVER['REQUEST_METHOD']) { case 'POST': - $input = $_POST; + $input = $_POST; break; case 'PUT': parse_str(file_get_contents('php://input'), $input); break; default: - $input = $_GET; + $input = $_GET; } break; - case 'path' : - $input = array(); - if(!empty($_SERVER['PATH_INFO'])){ - $depr = C('URL_PATHINFO_DEPR'); - $input = explode($depr,trim($_SERVER['PATH_INFO'],$depr)); + case 'path': + $input = array(); + if (!empty($_SERVER['PATH_INFO'])) { + $depr = C('URL_PATHINFO_DEPR'); + $input = explode($depr, trim($_SERVER['PATH_INFO'], $depr)); } break; - case 'request' : $input =& $_REQUEST; break; - case 'session' : $input =& $_SESSION; break; - case 'cookie' : $input =& $_COOKIE; break; - case 'server' : $input =& $_SERVER; break; - case 'globals' : $input =& $GLOBALS; break; - case 'data' : $input =& $datas; break; + case 'request':$input = &$_REQUEST; + break; + case 'session':$input = &$_SESSION; + break; + case 'cookie':$input = &$_COOKIE; + break; + case 'server':$input = &$_SERVER; + break; + case 'globals':$input = &$GLOBALS; + break; + case 'data':$input = &$datas; + break; default: - return NULL; - } - if(''==$name) { // 获取全部变量 - $data = $input; - $filters = isset($filter)?$filter:C('DEFAULT_FILTER'); - if($filters) { - if(is_string($filters)){ - $filters = explode(',',$filters); + return null; + } + if ('' == $name) { + // 获取全部变量 + $data = $input; + $filters = isset($filter) ? $filter : C('DEFAULT_FILTER'); + if ($filters) { + if (is_string($filters)) { + $filters = explode(',', $filters); } - foreach($filters as $filter){ - $data = array_map_recursive($filter,$data); // 参数过滤 + foreach ($filters as $filter) { + $data = arrayMapRecursive($filter, $data); // 参数过滤 } } - }elseif(isset($input[$name])) { // 取值操作 - $data = $input[$name]; - $filters = isset($filter)?$filter:C('DEFAULT_FILTER'); - if($filters) { - if(is_string($filters)){ - $filters = explode(',',$filters); - }elseif(is_int($filters)){ - $filters = array($filters); + } elseif (isset($input[$name])) { + // 取值操作 + $data = $input[$name]; + $filters = isset($filter) ? $filter : C('DEFAULT_FILTER'); + if ($filters) { + if (is_string($filters)) { + $filters = explode(',', $filters); + } elseif (is_int($filters)) { + $filters = array($filters); } - - foreach($filters as $filter){ - if(function_exists($filter)) { - $data = is_array($data) ? array_map_recursive($filter,$data) : $filter($data); // 参数过滤 - }elseif(0===strpos($filter,'/')){ - // 支持正则验证 - if(1 !== preg_match($filter,(string)$data)){ - return isset($default) ? $default : NULL; - } - }else{ - $data = filter_var($data,is_int($filter) ? $filter : filter_id($filter)); - if(false === $data) { - return isset($default) ? $default : NULL; + + foreach ($filters as $filter) { + if (function_exists($filter)) { + $data = is_array($data) ? arrayMapRecursive($filter, $data) : $filter($data); // 参数过滤 + } elseif (0 === strpos($filter, '/')) { + // 支持正则验证 + if (1 !== preg_match($filter, (string) $data)) { + return isset($default) ? $default : null; + } + } else { + $data = filter_var($data, is_int($filter) ? $filter : filter_id($filter)); + if (false === $data) { + return isset($default) ? $default : null; } } } } - if(!empty($type)){ - switch(strtolower($type)){ - case 'a': // 数组 - $data = (array)$data; - break; - case 'd': // 数字 - $data = (int)$data; - break; - case 'f': // 浮点 - $data = (float)$data; - break; - case 'b': // 布尔 - $data = (boolean)$data; - break; - case 's': // 字符串 + if (!empty($type)) { + switch (strtolower($type)) { + case 'a': // 数组 + $data = (array) $data; + break; + case 'd': // 数字 + $data = (int) $data; + break; + case 'f': // 浮点 + $data = (float) $data; + break; + case 'b': // 布尔 + $data = (boolean) $data; + break; + case 's': // 字符串 default: - $data = (string)$data; - } + $data = (string) $data; + } } - }else{ // 变量默认值 - $data = isset($default)?$default:NULL; + } else { + // 变量默认值 + $data = isset($default) ? $default : null; } - is_array($data) && array_walk_recursive($data,'think_filter'); + is_array($data) && array_walk_recursive($data, 'think_filter'); return $data; } -function array_map_recursive($filter, $data) { +function arrayMapRecursive($filter, $data) +{ $result = array(); foreach ($data as $key => $val) { $result[$key] = is_array($val) - ? array_map_recursive($filter, $val) - : call_user_func($filter, $val); + ? arrayMapRecursive($filter, $val) + : call_user_func($filter, $val); } return $result; - } +} /** * 设置和获取统计数据 @@ -403,18 +441,20 @@ function array_map_recursive($filter, $data) { * @param boolean $save 是否保存结果 * @return mixed */ -function N($key, $step=0,$save=false) { - static $_num = array(); +function N($key, $step = 0, $save = false) +{ + static $_num = array(); if (!isset($_num[$key])) { - $_num[$key] = (false !== $save)? S('N_'.$key) : 0; + $_num[$key] = (false !== $save) ? S('N_' . $key) : 0; } - if (empty($step)){ + if (empty($step)) { return $_num[$key]; - }else{ - $_num[$key] = $_num[$key] + (int)$step; + } else { + $_num[$key] = $_num[$key] + (int) $step; } - if(false !== $save){ // 保存结果 - S('N_'.$key,$_num[$key],$save); + if (false !== $save) { + // 保存结果 + S('N_' . $key, $_num[$key], $save); } return null; } @@ -426,9 +466,10 @@ function N($key, $step=0,$save=false) { * @param integer $type 转换类型 * @return string */ -function parse_name($name, $type=0) { +function parseName($name, $type = 0) +{ if ($type) { - return ucfirst(preg_replace_callback('/_([a-zA-Z])/', function($match){return strtoupper($match[1]);}, $name)); + return ucfirst(preg_replace_callback('/_([a-zA-Z])/', function ($match) {return strtoupper($match[1]);}, $name)); } else { return strtolower(trim(preg_replace("/[A-Z]/", "_\\0", $name), "_")); } @@ -439,10 +480,11 @@ function parse_name($name, $type=0) { * @param string $filename 文件地址 * @return boolean */ -function require_cache($filename) { +function requireCache($filename) +{ static $_importFiles = array(); if (!isset($_importFiles[$filename])) { - if (file_exists_case($filename)) { + if (fileExistsCase($filename)) { require $filename; $_importFiles[$filename] = true; } else { @@ -457,11 +499,14 @@ function require_cache($filename) { * @param string $filename 文件地址 * @return boolean */ -function file_exists_case($filename) { +function fileExistsCase($filename) +{ if (is_file($filename)) { if (IS_WIN && APP_DEBUG) { - if (basename(realpath($filename)) != basename($filename)) + if (basename(realpath($filename)) != basename($filename)) { return false; + } + } return true; } @@ -475,36 +520,42 @@ function file_exists_case($filename) { * @param string $ext 导入的文件扩展名 * @return boolean */ -function import($class, $baseUrl = '', $ext=EXT) { +function import($class, $baseUrl = '', $ext = EXT) +{ static $_file = array(); - $class = str_replace(array('.', '#'), array('/', '.'), $class); - if (isset($_file[$class . $baseUrl])) + $class = str_replace(array('.', '#'), array('/', '.'), $class); + if (isset($_file[$class . $baseUrl])) { return true; - else + } else { $_file[$class . $baseUrl] = true; - $class_strut = explode('/', $class); + } + + $class_strut = explode('/', $class); if (empty($baseUrl)) { if ('@' == $class_strut[0] || MODULE_NAME == $class_strut[0]) { //加载当前模块的类库 $baseUrl = MODULE_PATH; $class = substr_replace($class, '', 0, strlen($class_strut[0]) + 1); - }elseif ('Common' == $class_strut[0]) { + } elseif ('Common' == $class_strut[0]) { //加载公共模块的类库 $baseUrl = COMMON_PATH; $class = substr($class, 7); - }elseif (in_array($class_strut[0],array('Think','Org','Behavior','Com','Vendor')) || is_dir(LIB_PATH.$class_strut[0])) { + } elseif (in_array($class_strut[0], array('Think', 'Org', 'Behavior', 'Com', 'Vendor')) || is_dir(LIB_PATH . $class_strut[0])) { // 系统类库包和第三方类库包 $baseUrl = LIB_PATH; - }else { // 加载其他模块的类库 + } else { + // 加载其他模块的类库 $baseUrl = APP_PATH; } } - if (substr($baseUrl, -1) != '/') - $baseUrl .= '/'; - $classfile = $baseUrl . $class . $ext; - if (!class_exists(basename($class),false)) { + if (substr($baseUrl, -1) != '/') { + $baseUrl .= '/'; + } + + $classfile = $baseUrl . $class . $ext; + if (!class_exists(basename($class), false)) { // 如果类不存在 则导入类库文件 - return require_cache($classfile); + return requireCache($classfile); } return null; } @@ -517,22 +568,25 @@ function import($class, $baseUrl = '', $ext=EXT) { * @param string $ext 导入的文件扩展名 * @return void */ -function load($name, $baseUrl='', $ext='.php') { +function load($name, $baseUrl = '', $ext = '.php') +{ $name = str_replace(array('.', '#'), array('/', '.'), $name); if (empty($baseUrl)) { - if (0 === strpos($name, '@/')) {//加载当前模块函数库 - $baseUrl = MODULE_PATH.'Common/'; - $name = substr($name, 2); - } else { //加载其他模块函数库 - $array = explode('/', $name); - $baseUrl = APP_PATH . array_shift($array).'/Common/'; - $name = implode('/',$array); + if (0 === strpos($name, '@/')) { +//加载当前模块函数库 + $baseUrl = MODULE_PATH . 'Common/'; + $name = substr($name, 2); + } else { + //加载其他模块函数库 + $array = explode('/', $name); + $baseUrl = APP_PATH . array_shift($array) . '/Common/'; + $name = implode('/', $array); } } - if (substr($baseUrl, -1) != '/'){ - $baseUrl .= '/'; + if (substr($baseUrl, -1) != '/') { + $baseUrl .= '/'; } - require_cache($baseUrl . $name . $ext); + requireCache($baseUrl . $name . $ext); } /** @@ -542,8 +596,9 @@ function load($name, $baseUrl='', $ext='.php') { * @param string $ext 类库后缀 * @return boolean */ -function vendor($class, $baseUrl = '', $ext='.php') { - if (empty($baseUrl)){ +function vendor($class, $baseUrl = '', $ext = '.php') +{ + if (empty($baseUrl)) { $baseUrl = VENDOR_PATH; } return import($class, $baseUrl, $ext); @@ -555,24 +610,28 @@ function vendor($class, $baseUrl = '', $ext='.php') { * @param string $layer 模型层名称 * @return Think\Model */ -function D($name='',$layer='') { - if(empty($name)) return new Think\Model; - static $_model = array(); - $layer = $layer? : 'Model'; - if(isset($_model[$name.$layer])){ - return $_model[$name.$layer]; - } - $class = parse_res_name($name,$layer); - if(class_exists($class)) { - $model = new $class(basename($name)); - }elseif(false === strpos($name,'/')){ +function D($name = '', $layer = '') +{ + if (empty($name)) { + return new Think\Model; + } + + static $_model = array(); + $layer = $layer ?: 'Model'; + if (isset($_model[$name . $layer])) { + return $_model[$name . $layer]; + } + $class = parseResName($name, $layer); + if (class_exists($class)) { + $model = new $class(basename($name)); + } elseif (false === strpos($name, '/')) { // 自动加载公共模块下面的模型 - $class = '\\Common\\'.$layer.'\\'.$name.$layer; - $model = class_exists($class)? new $class($name) : new Think\Model($name); - }else { - $model = new Think\Model(basename($name)); + $class = '\\Common\\' . $layer . '\\' . $name . $layer; + $model = class_exists($class) ? new $class($name) : new Think\Model($name); + } else { + $model = new Think\Model(basename($name)); } - $_model[$name.$layer] = $model; + $_model[$name . $layer] = $model; return $model; } @@ -583,16 +642,17 @@ function D($name='',$layer='') { * @param mixed $connection 数据库连接信息 * @return Think\Model */ -function M($name='', $tablePrefix='',$connection='') { - static $_model = array(); - if(strpos($name,':')) { - list($class,$name) = explode(':',$name); - }else{ - $class = 'Think\\Model'; +function M($name = '', $tablePrefix = '', $connection = '') +{ + static $_model = array(); + if (strpos($name, ':')) { + list($class, $name) = explode(':', $name); + } else { + $class = 'Think\\Model'; } - $guid = (is_array($connection)?implode('',$connection):$connection).$tablePrefix . $name . '_' . $class; - if (!isset($_model[$guid])){ - $_model[$guid] = new $class($name,$tablePrefix,$connection); + $guid = (is_array($connection) ? implode('', $connection) : $connection) . $tablePrefix . $name . '_' . $class; + if (!isset($_model[$guid])) { + $_model[$guid] = new $class($name, $tablePrefix, $connection); } return $_model[$guid]; } @@ -604,28 +664,32 @@ function M($name='', $tablePrefix='',$connection='') { * @param string $layer 分层名称 * @return string */ -function parse_res_name($name,$layer){ - if(strpos($name,'://')) {// 指定扩展资源 - list($extend,$name) = explode('://',$name); - }else{ - $extend = ''; - } - if(strpos($name,'/')){ // 指定模块 - list($module,$name) = explode('/',$name,2); - }else{ - $module = defined('MODULE_NAME') ? MODULE_NAME : '' ; - } - $array = explode('/',$name); - $class = $module.'\\'.$layer; - foreach($array as $name){ - $class .= '\\'.parse_name($name, 1); +function parseResName($name, $layer) +{ + if (strpos($name, '://')) { +// 指定扩展资源 + list($extend, $name) = explode('://', $name); + } else { + $extend = ''; + } + if (strpos($name, '/')) { + // 指定模块 + list($module, $name) = explode('/', $name, 2); + } else { + $module = defined('MODULE_NAME') ? MODULE_NAME : ''; + } + $array = explode('/', $name); + $class = $module . '\\' . $layer; + foreach ($array as $name) { + $class .= '\\' . parseName($name, 1); } // 导入资源类库 - if($extend){ // 扩展资源 - $class = $extend.'\\'.$class; + if ($extend) { + // 扩展资源 + $class = $extend . '\\' . $class; } - return $class.$layer; + return $class . $layer; } /** @@ -633,17 +697,18 @@ function parse_res_name($name,$layer){ * @param string $name 控制器名 * @return Think\Controller|false */ -function controller($name){ - $class = MODULE_NAME .'\\Controller'; - $array = explode('/',$name); - foreach($array as $name){ - $class .= '\\'.parse_name($name, 1); - } - $class .= $layer; +function controller($name) +{ + $class = MODULE_NAME . '\\Controller'; + $array = explode('/', $name); + foreach ($array as $name) { + $class .= '\\' . parseName($name, 1); + } + $class .= $layer; - if(class_exists($class)) { + if (class_exists($class)) { return new $class(); - }else { + } else { return false; } } @@ -654,24 +719,24 @@ function controller($name){ * @param string $layer 控制层名称 * @return Think\Controller|false */ -function A($name,$layer='') { +function A($name, $layer = '') +{ static $_action = array(); - $layer = $layer? : 'Controller'; - if(isset($_action[$name.$layer])){ - return $_action[$name.$layer]; - } - - $class = parse_res_name($name,$layer); - if(class_exists($class)) { - $action = new $class(); - $_action[$name.$layer] = $action; + $layer = $layer ?: 'Controller'; + if (isset($_action[$name . $layer])) { + return $_action[$name . $layer]; + } + + $class = parseResName($name, $layer); + if (class_exists($class)) { + $action = new $class(); + $_action[$name . $layer] = $action; return $action; - }else { + } else { return false; } } - /** * 远程调用控制器的操作方法 URL 参数格式 [资源://][模块/]控制器/操作 * @param string $url 调用地址 @@ -679,17 +744,18 @@ function A($name,$layer='') { * @param string $layer 要调用的控制层名称 * @return mixed */ -function R($url,$vars=array(),$layer='') { - $info = pathinfo($url); - $action = $info['basename']; - $module = $info['dirname']; - $class = A($module,$layer); - if($class){ - if(is_string($vars)) { - parse_str($vars,$vars); +function R($url, $vars = array(), $layer = '') +{ + $info = pathinfo($url); + $action = $info['basename']; + $module = $info['dirname']; + $class = A($module, $layer); + if ($class) { + if (is_string($vars)) { + parse_str($vars, $vars); } - return call_user_func_array(array(&$class,$action.C('ACTION_SUFFIX')),$vars); - }else{ + return call_user_func_array(array(&$class, $action . C('ACTION_SUFFIX')), $vars); + } else { return false; } } @@ -700,22 +766,24 @@ function R($url,$vars=array(),$layer='') { * @param mixed $params 传入参数 * @return void */ -function tag($tag, &$params=NULL) { - \Think\Hook::listen($tag,$params); +function tag($tag, &$params = null) +{ + \Think\Hook::listen($tag, $params); } /** * 执行某个行为 * @param string $name 行为名称 - * @param string $tag 标签名称(行为类无需传入) + * @param string $tag 标签名称(行为类无需传入) * @param Mixed $params 传入的参数 * @return void */ -function B($name, $tag='',&$params=NULL) { - if(''==$tag){ - $name .= 'Behavior'; +function B($name, $tag = '', &$params = null) +{ + if ('' == $tag) { + $name .= 'Behavior'; } - return \Think\Hook::exec($name,$tag,$params); + return \Think\Hook::exec($name, $tag, $params); } /** @@ -723,15 +791,16 @@ function B($name, $tag='',&$params=NULL) { * @param string $content 代码内容 * @return string */ -function strip_whitespace($content) { - $stripStr = ''; +function stripWhitespace($content) +{ + $stripStr = ''; //分析php源码 $tokens = token_get_all($content); $last_space = false; for ($i = 0, $j = count($tokens); $i < $j; $i++) { if (is_string($tokens[$i])) { $last_space = false; - $stripStr .= $tokens[$i]; + $stripStr .= $tokens[$i]; } else { switch ($tokens[$i][0]) { //过滤各种PHP注释 @@ -741,7 +810,7 @@ function strip_whitespace($content) { //过滤空格 case T_WHITESPACE: if (!$last_space) { - $stripStr .= ' '; + $stripStr .= ' '; $last_space = true; } break; @@ -750,18 +819,18 @@ function strip_whitespace($content) { break; case T_END_HEREDOC: $stripStr .= "THINK;\n"; - for($k = $i+1; $k < $j; $k++) { - if(is_string($tokens[$k]) && $tokens[$k] == ';') { + for ($k = $i + 1; $k < $j; $k++) { + if (is_string($tokens[$k]) && ';' == $tokens[$k]) { $i = $k; break; - } else if($tokens[$k][0] == T_CLOSE_TAG) { + } else if (T_CLOSE_TAG == $tokens[$k][0]) { break; } } break; default: $last_space = false; - $stripStr .= $tokens[$i][1]; + $stripStr .= $tokens[$i][1]; } } } @@ -776,8 +845,9 @@ function strip_whitespace($content) { * @param boolean $strict 是否严谨 默认为true * @return void|string */ -function dump($var, $echo=true, $label=null, $strict=true) { - $label = ($label === null) ? '' : rtrim($label) . ' '; +function dump($var, $echo = true, $label = null, $strict = true) +{ + $label = (null === $label) ? '' : rtrim($label) . ' '; if (!$strict) { if (ini_get('html_errors')) { $output = print_r($var, true); @@ -795,10 +865,12 @@ function dump($var, $echo=true, $label=null, $strict=true) { } } if ($echo) { - echo($output); + echo ($output); return null; - }else + } else { return $output; + } + } /** @@ -806,15 +878,18 @@ function dump($var, $echo=true, $label=null, $strict=true) { * @param string|false $layout 布局名称 为false的时候表示关闭布局 * @return void */ -function layout($layout) { - if(false !== $layout) { +function layout($layout) +{ + if (false !== $layout) { // 开启布局 - C('LAYOUT_ON',true); - if(is_string($layout)) { // 设置新的布局模板 - C('LAYOUT_NAME',$layout); + C('LAYOUT_ON', true); + if (is_string($layout)) { + // 设置新的布局模板 + C('LAYOUT_NAME', $layout); } - }else{// 临时关闭布局 - C('LAYOUT_ON',false); + } else { +// 临时关闭布局 + C('LAYOUT_ON', false); } } @@ -826,34 +901,40 @@ function layout($layout) { * @param boolean $domain 是否显示域名 * @return string */ -function U($url='',$vars='',$suffix=true,$domain=false) { +function U($url = '', $vars = '', $suffix = true, $domain = false) +{ // 解析URL - $info = parse_url($url); - $url = !empty($info['path'])?$info['path']:ACTION_NAME; - if(isset($info['fragment'])) { // 解析锚点 - $anchor = $info['fragment']; - if(false !== strpos($anchor,'?')) { // 解析参数 - list($anchor,$info['query']) = explode('?',$anchor,2); - } - if(false !== strpos($anchor,'@')) { // 解析域名 - list($anchor,$host) = explode('@',$anchor, 2); + $info = parse_url($url); + $url = !empty($info['path']) ? $info['path'] : ACTION_NAME; + if (isset($info['fragment'])) { + // 解析锚点 + $anchor = $info['fragment']; + if (false !== strpos($anchor, '?')) { + // 解析参数 + list($anchor, $info['query']) = explode('?', $anchor, 2); + } + if (false !== strpos($anchor, '@')) { + // 解析域名 + list($anchor, $host) = explode('@', $anchor, 2); } - }elseif(false !== strpos($url,'@')) { // 解析域名 - list($url,$host) = explode('@',$info['path'], 2); + } elseif (false !== strpos($url, '@')) { + // 解析域名 + list($url, $host) = explode('@', $info['path'], 2); } // 解析子域名 - if(isset($host)) { - $domain = $host.(strpos($host,'.')?'':strstr($_SERVER['HTTP_HOST'],'.')); - }elseif($domain===true){ + if (isset($host)) { + $domain = $host . (strpos($host, '.') ? '' : strstr($_SERVER['HTTP_HOST'], '.')); + } elseif (true === $domain) { $domain = $_SERVER['HTTP_HOST']; - if(C('APP_SUB_DOMAIN_DEPLOY') ) { // 开启子域名部署 - $domain = $domain=='localhost'?'localhost':'www'.strstr($_SERVER['HTTP_HOST'],'.'); + if (C('APP_SUB_DOMAIN_DEPLOY')) { + // 开启子域名部署 + $domain = 'localhost' == $domain ? 'localhost' : 'www' . strstr($_SERVER['HTTP_HOST'], '.'); // '子域名'=>array('模块[/控制器]'); foreach (C('APP_SUB_DOMAIN_RULES') as $key => $rule) { - $rule = is_array($rule)?$rule[0]:$rule; - if(false === strpos($key,'*') && 0=== strpos($url,$rule)) { - $domain = $key.strstr($domain,'.'); // 生成对应子域名 - $url = substr_replace($url,'',0,strlen($rule)); + $rule = is_array($rule) ? $rule[0] : $rule; + if (false === strpos($key, '*') && 0 === strpos($url, $rule)) { + $domain = $key . strstr($domain, '.'); // 生成对应子域名 + $url = substr_replace($url, '', 0, strlen($rule)); break; } } @@ -861,105 +942,115 @@ function U($url='',$vars='',$suffix=true,$domain=false) { } // 解析参数 - if(is_string($vars)) { // aaa=1&bbb=2 转换成数组 - parse_str($vars,$vars); - }elseif(!is_array($vars)){ + if (is_string($vars)) { + // aaa=1&bbb=2 转换成数组 + parse_str($vars, $vars); + } elseif (!is_array($vars)) { $vars = array(); } - if(isset($info['query'])) { // 解析地址里面参数 合并到vars - parse_str($info['query'],$params); - $vars = array_merge($params,$vars); + if (isset($info['query'])) { + // 解析地址里面参数 合并到vars + parse_str($info['query'], $params); + $vars = array_merge($params, $vars); } - + // URL组装 - $depr = C('URL_PATHINFO_DEPR'); - $urlCase = C('URL_CASE_INSENSITIVE'); - if($url) { - if(0=== strpos($url,'/')) {// 定义路由 - $route = true; - $url = substr($url,1); - if('/' != $depr) { - $url = str_replace('/',$depr,$url); + $depr = C('URL_PATHINFO_DEPR'); + $urlCase = C('URL_CASE_INSENSITIVE'); + if ($url) { + if (0 === strpos($url, '/')) { +// 定义路由 + $route = true; + $url = substr($url, 1); + if ('/' != $depr) { + $url = str_replace('/', $depr, $url); } - }else{ - if('/' != $depr) { // 安全替换 - $url = str_replace('/',$depr,$url); + } else { + if ('/' != $depr) { + // 安全替换 + $url = str_replace('/', $depr, $url); } // 解析模块、控制器和操作 - $url = trim($url,$depr); - $path = explode($depr,$url); - $var = array(); - $varModule = C('VAR_MODULE'); - $varController = C('VAR_CONTROLLER'); - $varAction = C('VAR_ACTION'); - $var[$varAction] = !empty($path)?array_pop($path):ACTION_NAME; - $var[$varController] = !empty($path)?array_pop($path):CONTROLLER_NAME; - if($urlCase) { - $var[$varController] = parse_name($var[$varController]); + $url = trim($url, $depr); + $path = explode($depr, $url); + $var = array(); + $varModule = C('VAR_MODULE'); + $varController = C('VAR_CONTROLLER'); + $varAction = C('VAR_ACTION'); + $var[$varAction] = !empty($path) ? array_pop($path) : ACTION_NAME; + $var[$varController] = !empty($path) ? array_pop($path) : CONTROLLER_NAME; + if ($urlCase) { + $var[$varController] = parseName($var[$varController]); } - $module = ''; - - if(!empty($path)) { - $var[$varModule] = implode($depr,$path); - }else{ - if(C('MULTI_MODULE')) { - if(MODULE_NAME != C('DEFAULT_MODULE') || !C('MODULE_ALLOW_LIST')){ - $var[$varModule]= MODULE_NAME; + $module = ''; + + if (!empty($path)) { + $var[$varModule] = implode($depr, $path); + } else { + if (C('MULTI_MODULE')) { + if (MODULE_NAME != C('DEFAULT_MODULE') || !C('MODULE_ALLOW_LIST')) { + $var[$varModule] = MODULE_NAME; } } } - if($maps = C('URL_MODULE_MAP')) { - if($_module = array_search(strtolower($var[$varModule]),$maps)){ + if ($maps = C('URL_MODULE_MAP')) { + if ($_module = array_search(strtolower($var[$varModule]), $maps)) { $var[$varModule] = $_module; } } - if(isset($var[$varModule])){ - $module = $var[$varModule]; + if (isset($var[$varModule])) { + $module = $var[$varModule]; unset($var[$varModule]); } - + } } - if(C('URL_MODEL') == 0) { // 普通模式URL转换 - $url = __APP__.'?'.C('VAR_MODULE')."={$module}&".http_build_query(array_reverse($var)); - if($urlCase){ - $url = strtolower($url); - } - if(!empty($vars)) { - $vars = http_build_query($vars); - $url .= '&'.$vars; + if (C('URL_MODEL') == 0) { + // 普通模式URL转换 + $url = __APP__ . '?' . C('VAR_MODULE') . "={$module}&" . http_build_query(array_reverse($var)); + if ($urlCase) { + $url = strtolower($url); } - }else{ // PATHINFO模式或者兼容URL模式 - if(isset($route)) { - $url = __APP__.'/'.rtrim($url,$depr); - }else{ - $module = (defined('BIND_MODULE') && BIND_MODULE==$module )? '' : $module; - $url = __APP__.'/'.($module?$module.MODULE_PATHINFO_DEPR:'').implode($depr,array_reverse($var)); + if (!empty($vars)) { + $vars = http_build_query($vars); + $url .= '&' . $vars; + } + } else { + // PATHINFO模式或者兼容URL模式 + if (isset($route)) { + $url = __APP__ . '/' . rtrim($url, $depr); + } else { + $module = (defined('BIND_MODULE') && BIND_MODULE == $module) ? '' : $module; + $url = __APP__ . '/' . ($module ? $module . MODULE_PATHINFO_DEPR : '') . implode($depr, array_reverse($var)); } - if($urlCase){ - $url = strtolower($url); + if ($urlCase) { + $url = strtolower($url); } - if(!empty($vars)) { // 添加参数 - foreach ($vars as $var => $val){ - if('' !== trim($val)) $url .= $depr . $var . $depr . urlencode($val); - } + if (!empty($vars)) { + // 添加参数 + foreach ($vars as $var => $val) { + if ('' !== trim($val)) { + $url .= $depr . $var . $depr . urlencode($val); + } + + } } - if($suffix) { - $suffix = $suffix===true?C('URL_HTML_SUFFIX'):$suffix; - if($pos = strpos($suffix, '|')){ + if ($suffix) { + $suffix = true === $suffix ? C('URL_HTML_SUFFIX') : $suffix; + if ($pos = strpos($suffix, '|')) { $suffix = substr($suffix, 0, $pos); } - if($suffix && '/' != substr($url,-1)){ - $url .= '.'.ltrim($suffix,'.'); + if ($suffix && '/' != substr($url, -1)) { + $url .= '.' . ltrim($suffix, '.'); } } } - if(isset($anchor)){ - $url .= '#'.$anchor; + if (isset($anchor)) { + $url .= '#' . $anchor; } - if($domain) { - $url = (is_ssl()?'https://':'http://').$domain.$url; + if ($domain) { + $url = (isSsl() ? 'https://' : 'http://') . $domain . $url; } return $url; } @@ -970,18 +1061,20 @@ function U($url='',$vars='',$suffix=true,$domain=false) { * @param array $data 传入的参数 * @return void */ -function W($name, $data=array()) { - return R($name,$data,'Widget'); +function W($name, $data = array()) +{ + return R($name, $data, 'Widget'); } /** * 判断是否SSL协议 * @return boolean */ -function is_ssl() { - if(isset($_SERVER['HTTPS']) && ('1' == $_SERVER['HTTPS'] || 'on' == strtolower($_SERVER['HTTPS']))){ +function isSsl() +{ + if (isset($_SERVER['HTTPS']) && ('1' == $_SERVER['HTTPS'] || 'on' == strtolower($_SERVER['HTTPS']))) { return true; - }elseif(isset($_SERVER['SERVER_PORT']) && ('443' == $_SERVER['SERVER_PORT'] )) { + } elseif (isset($_SERVER['SERVER_PORT']) && ('443' == $_SERVER['SERVER_PORT'])) { return true; } return false; @@ -994,24 +1087,29 @@ function is_ssl() { * @param string $msg 重定向前的提示信息 * @return void */ -function redirect($url, $time=0, $msg='') { +function redirect($url, $time = 0, $msg = '') +{ //多行URL地址支持 - $url = str_replace(array("\n", "\r"), '', $url); - if (empty($msg)) - $msg = "系统将在{$time}秒之后自动跳转到{$url}!"; + $url = str_replace(array("\n", "\r"), '', $url); + if (empty($msg)) { + $msg = "系统将在{$time}秒之后自动跳转到{$url}!"; + } + if (!headers_sent()) { // redirect if (0 === $time) { header('Location: ' . $url); } else { header("refresh:{$time};url={$url}"); - echo($msg); + echo ($msg); } exit(); } else { - $str = ""; - if ($time != 0) + $str = ""; + if (0 != $time) { $str .= $msg; + } + exit($str); } } @@ -1023,28 +1121,34 @@ function redirect($url, $time=0, $msg='') { * @param mixed $options 缓存参数 * @return mixed */ -function S($name,$value='',$options=null) { - static $cache = ''; - if(is_array($options) && empty($cache)){ +function S($name, $value = '', $options = null) +{ + static $cache = ''; + if (is_array($options) && empty($cache)) { // 缓存操作的同时初始化 - $type = isset($options['type'])?$options['type']:''; - $cache = Think\Cache::getInstance($type,$options); - }elseif(is_array($name)) { // 缓存初始化 - $type = isset($name['type'])?$name['type']:''; - $cache = Think\Cache::getInstance($type,$name); + $type = isset($options['type']) ? $options['type'] : ''; + $cache = Think\Cache::getInstance($type, $options); + } elseif (is_array($name)) { + // 缓存初始化 + $type = isset($name['type']) ? $name['type'] : ''; + $cache = Think\Cache::getInstance($type, $name); return $cache; - }elseif(empty($cache)) { // 自动初始化 - $cache = Think\Cache::getInstance(); + } elseif (empty($cache)) { + // 自动初始化 + $cache = Think\Cache::getInstance(); } - if(''=== $value){ // 获取缓存 + if ('' === $value) { + // 获取缓存 return $cache->get($name); - }elseif(is_null($value)) { // 删除缓存 + } elseif (is_null($value)) { + // 删除缓存 return $cache->rm($name); - }else { // 缓存数据 - if(is_array($options)) { - $expire = isset($options['expire'])?$options['expire']:NULL; - }else{ - $expire = is_numeric($options)?$options:NULL; + } else { + // 缓存数据 + if (is_array($options)) { + $expire = isset($options['expire']) ? $options['expire'] : null; + } else { + $expire = is_numeric($options) ? $options : null; } return $cache->set($name, $value, $expire); } @@ -1057,33 +1161,36 @@ function S($name,$value='',$options=null) { * @param string $path 缓存路径 * @return mixed */ -function F($name, $value='', $path=DATA_PATH) { - static $_cache = array(); - $filename = $path . $name . '.php'; +function F($name, $value = '', $path = DATA_PATH) +{ + static $_cache = array(); + $filename = $path . $name . '.php'; if ('' !== $value) { if (is_null($value)) { // 删除缓存 - if(false !== strpos($name,'*')){ - return false; // TODO - }else{ + if (false !== strpos($name, '*')) { + return false; // TODO + } else { unset($_cache[$name]); - return Think\Storage::unlink($filename,'F'); + return Think\Storage::unlink($filename, 'F'); } } else { - Think\Storage::put($filename,serialize($value),'F'); + Think\Storage::put($filename, serialize($value), 'F'); // 缓存数据 - $_cache[$name] = $value; + $_cache[$name] = $value; return null; } } // 获取缓存数据 - if (isset($_cache[$name])) + if (isset($_cache[$name])) { return $_cache[$name]; - if (Think\Storage::has($filename,'F')){ - $value = unserialize(Think\Storage::read($filename,'F')); - $_cache[$name] = $value; + } + + if (Think\Storage::has($filename, 'F')) { + $value = unserialize(Think\Storage::read($filename, 'F')); + $_cache[$name] = $value; } else { - $value = false; + $value = false; } return $value; } @@ -1093,7 +1200,8 @@ function F($name, $value='', $path=DATA_PATH) { * @param mixed $mix 变量 * @return string */ -function to_guid_string($mix) { +function toGuidString($mix) +{ if (is_object($mix)) { return spl_object_hash($mix); } elseif (is_resource($mix)) { @@ -1110,116 +1218,163 @@ function to_guid_string($mix) { * @param mixed $value session值 * @return mixed */ -function session($name='',$value='') { - $prefix = C('SESSION_PREFIX'); - if(is_array($name)) { // session初始化 在session_start 之前调用 - if(isset($name['prefix'])) C('SESSION_PREFIX',$name['prefix']); - if(C('VAR_SESSION_ID') && isset($_REQUEST[C('VAR_SESSION_ID')])){ +function session($name = '', $value = '') +{ + $prefix = C('SESSION_PREFIX'); + if (is_array($name)) { + // session初始化 在session_start 之前调用 + if (isset($name['prefix'])) { + C('SESSION_PREFIX', $name['prefix']); + } + + if (C('VAR_SESSION_ID') && isset($_REQUEST[C('VAR_SESSION_ID')])) { session_id($_REQUEST[C('VAR_SESSION_ID')]); - }elseif(isset($name['id'])) { + } elseif (isset($name['id'])) { session_id($name['id']); } - if('common' != APP_MODE){ // 其它模式可能不支持 + if ('common' != APP_MODE) { + // 其它模式可能不支持 ini_set('session.auto_start', 0); } - if(isset($name['name'])) session_name($name['name']); - if(isset($name['path'])) session_save_path($name['path']); - if(isset($name['domain'])) ini_set('session.cookie_domain', $name['domain']); - if(isset($name['expire'])) ini_set('session.gc_maxlifetime', $name['expire']); - if(isset($name['use_trans_sid'])) ini_set('session.use_trans_sid', $name['use_trans_sid']?1:0); - if(isset($name['use_cookies'])) ini_set('session.use_cookies', $name['use_cookies']?1:0); - if(isset($name['cache_limiter'])) session_cache_limiter($name['cache_limiter']); - if(isset($name['cache_expire'])) session_cache_expire($name['cache_expire']); - if(isset($name['type'])) C('SESSION_TYPE',$name['type']); - if(C('SESSION_TYPE')) { // 读取session驱动 - $type = C('SESSION_TYPE'); - $class = strpos($type,'\\')? $type : 'Think\\Session\\Driver\\'. ucwords(strtolower($type)); - $hander = new $class(); + if (isset($name['name'])) { + session_name($name['name']); + } + + if (isset($name['path'])) { + session_save_path($name['path']); + } + + if (isset($name['domain'])) { + ini_set('session.cookie_domain', $name['domain']); + } + + if (isset($name['expire'])) { + ini_set('session.gc_maxlifetime', $name['expire']); + } + + if (isset($name['use_trans_sid'])) { + ini_set('session.use_trans_sid', $name['use_trans_sid'] ? 1 : 0); + } + + if (isset($name['use_cookies'])) { + ini_set('session.use_cookies', $name['use_cookies'] ? 1 : 0); + } + + if (isset($name['cache_limiter'])) { + session_cache_limiter($name['cache_limiter']); + } + + if (isset($name['cache_expire'])) { + session_cache_expire($name['cache_expire']); + } + + if (isset($name['type'])) { + C('SESSION_TYPE', $name['type']); + } + + if (C('SESSION_TYPE')) { + // 读取session驱动 + $type = C('SESSION_TYPE'); + $class = strpos($type, '\\') ? $type : 'Think\\Session\\Driver\\' . ucwords(strtolower($type)); + $hander = new $class(); session_set_save_handler( - array(&$hander,"open"), - array(&$hander,"close"), - array(&$hander,"read"), - array(&$hander,"write"), - array(&$hander,"destroy"), - array(&$hander,"gc")); + array(&$hander, "open"), + array(&$hander, "close"), + array(&$hander, "read"), + array(&$hander, "write"), + array(&$hander, "destroy"), + array(&$hander, "gc")); } // 启动session - if(C('SESSION_AUTO_START')) session_start(); - }elseif('' === $value){ - if(''===$name){ + if (C('SESSION_AUTO_START')) { + session_start(); + } + + } elseif ('' === $value) { + if ('' === $name) { // 获取全部的session return $prefix ? $_SESSION[$prefix] : $_SESSION; - }elseif(0===strpos($name,'[')) { // session 操作 - if('[pause]'==$name){ // 暂停session + } elseif (0 === strpos($name, '[')) { + // session 操作 + if ('[pause]' == $name) { // 暂停session session_write_close(); - }elseif('[start]'==$name){ // 启动session + } elseif ('[start]' == $name) { + // 启动session session_start(); - }elseif('[destroy]'==$name){ // 销毁session - $_SESSION = array(); + } elseif ('[destroy]' == $name) { + // 销毁session + $_SESSION = array(); session_unset(); session_destroy(); - }elseif('[regenerate]'==$name){ // 重新生成id + } elseif ('[regenerate]' == $name) { + // 重新生成id session_regenerate_id(); } - }elseif(0===strpos($name,'?')){ // 检查session - $name = substr($name,1); - if(strpos($name,'.')){ // 支持数组 - list($name1,$name2) = explode('.',$name); - return $prefix?isset($_SESSION[$prefix][$name1][$name2]):isset($_SESSION[$name1][$name2]); - }else{ - return $prefix?isset($_SESSION[$prefix][$name]):isset($_SESSION[$name]); + } elseif (0 === strpos($name, '?')) { + // 检查session + $name = substr($name, 1); + if (strpos($name, '.')) { + // 支持数组 + list($name1, $name2) = explode('.', $name); + return $prefix ? isset($_SESSION[$prefix][$name1][$name2]) : isset($_SESSION[$name1][$name2]); + } else { + return $prefix ? isset($_SESSION[$prefix][$name]) : isset($_SESSION[$name]); } - }elseif(is_null($name)){ // 清空session - if($prefix) { + } elseif (is_null($name)) { + // 清空session + if ($prefix) { unset($_SESSION[$prefix]); - }else{ + } else { $_SESSION = array(); } - }elseif($prefix){ // 获取session - if(strpos($name,'.')){ - list($name1,$name2) = explode('.',$name); - return isset($_SESSION[$prefix][$name1][$name2])?$_SESSION[$prefix][$name1][$name2]:null; - }else{ - return isset($_SESSION[$prefix][$name])?$_SESSION[$prefix][$name]:null; - } - }else{ - if(strpos($name,'.')){ - list($name1,$name2) = explode('.',$name); - return isset($_SESSION[$name1][$name2])?$_SESSION[$name1][$name2]:null; - }else{ - return isset($_SESSION[$name])?$_SESSION[$name]:null; - } + } elseif ($prefix) { + // 获取session + if (strpos($name, '.')) { + list($name1, $name2) = explode('.', $name); + return isset($_SESSION[$prefix][$name1][$name2]) ? $_SESSION[$prefix][$name1][$name2] : null; + } else { + return isset($_SESSION[$prefix][$name]) ? $_SESSION[$prefix][$name] : null; + } + } else { + if (strpos($name, '.')) { + list($name1, $name2) = explode('.', $name); + return isset($_SESSION[$name1][$name2]) ? $_SESSION[$name1][$name2] : null; + } else { + return isset($_SESSION[$name]) ? $_SESSION[$name] : null; + } } - }elseif(is_null($value)){ // 删除session - if(strpos($name,'.')){ - list($name1,$name2) = explode('.',$name); - if($prefix){ + } elseif (is_null($value)) { + // 删除session + if (strpos($name, '.')) { + list($name1, $name2) = explode('.', $name); + if ($prefix) { unset($_SESSION[$prefix][$name1][$name2]); - }else{ + } else { unset($_SESSION[$name1][$name2]); } - }else{ - if($prefix){ + } else { + if ($prefix) { unset($_SESSION[$prefix][$name]); - }else{ + } else { unset($_SESSION[$name]); } } - }else{ // 设置session - if(strpos($name,'.')){ - list($name1,$name2) = explode('.',$name); - if($prefix){ - $_SESSION[$prefix][$name1][$name2] = $value; - }else{ - $_SESSION[$name1][$name2] = $value; - } - }else{ - if($prefix){ - $_SESSION[$prefix][$name] = $value; - }else{ - $_SESSION[$name] = $value; - } - } + } else { + // 设置session + if (strpos($name, '.')) { + list($name1, $name2) = explode('.', $name); + if ($prefix) { + $_SESSION[$prefix][$name1][$name2] = $value; + } else { + $_SESSION[$name1][$name2] = $value; + } + } else { + if ($prefix) { + $_SESSION[$prefix][$name] = $value; + } else { + $_SESSION[$name] = $value; + } + } } return null; } @@ -1231,70 +1386,76 @@ function session($name='',$value='') { * @param mixed $option cookie参数 * @return mixed */ -function cookie($name='', $value='', $option=null) { +function cookie($name = '', $value = '', $option = null) +{ // 默认设置 $config = array( - 'prefix' => C('COOKIE_PREFIX'), // cookie 名称前缀 - 'expire' => C('COOKIE_EXPIRE'), // cookie 保存时间 - 'path' => C('COOKIE_PATH'), // cookie 保存路径 - 'domain' => C('COOKIE_DOMAIN'), // cookie 有效域名 - 'secure' => C('COOKIE_SECURE'), // cookie 启用安全传输 - 'httponly' => C('COOKIE_HTTPONLY'), // httponly设置 + 'prefix' => C('COOKIE_PREFIX'), // cookie 名称前缀 + 'expire' => C('COOKIE_EXPIRE'), // cookie 保存时间 + 'path' => C('COOKIE_PATH'), // cookie 保存路径 + 'domain' => C('COOKIE_DOMAIN'), // cookie 有效域名 + 'secure' => C('COOKIE_SECURE'), // cookie 启用安全传输 + 'httponly' => C('COOKIE_HTTPONLY'), // httponly设置 ); // 参数设置(会覆盖黙认设置) if (!is_null($option)) { - if (is_numeric($option)) + if (is_numeric($option)) { $option = array('expire' => $option); - elseif (is_string($option)) + } elseif (is_string($option)) { parse_str($option, $option); - $config = array_merge($config, array_change_key_case($option)); + } + + $config = array_merge($config, array_change_key_case($option)); } - if(!empty($config['httponly'])){ + if (!empty($config['httponly'])) { ini_set("session.cookie_httponly", 1); } // 清除指定前缀的所有cookie if (is_null($name)) { - if (empty($_COOKIE)) + if (empty($_COOKIE)) { return null; + } + // 要删除的cookie前缀,不指定则删除config设置的指定前缀 $prefix = empty($value) ? $config['prefix'] : $value; - if (!empty($prefix)) {// 如果前缀为空字符串将不作处理直接返回 + if (!empty($prefix)) { +// 如果前缀为空字符串将不作处理直接返回 foreach ($_COOKIE as $key => $val) { if (0 === stripos($key, $prefix)) { - setcookie($key, '', time() - 3600, $config['path'], $config['domain'],$config['secure'],$config['httponly']); + setcookie($key, '', time() - 3600, $config['path'], $config['domain'], $config['secure'], $config['httponly']); unset($_COOKIE[$key]); } } } return null; - }elseif('' === $name){ + } elseif ('' === $name) { // 获取全部的cookie return $_COOKIE; } $name = $config['prefix'] . str_replace('.', '_', $name); if ('' === $value) { - if(isset($_COOKIE[$name])){ - $value = $_COOKIE[$name]; - if(0===strpos($value,'think:')){ - $value = substr($value,6); - return array_map('urldecode',json_decode(MAGIC_QUOTES_GPC?stripslashes($value):$value,true)); - }else{ + if (isset($_COOKIE[$name])) { + $value = $_COOKIE[$name]; + if (0 === strpos($value, 'think:')) { + $value = substr($value, 6); + return array_map('urldecode', json_decode(MAGIC_QUOTES_GPC ? stripslashes($value) : $value, true)); + } else { return $value; } - }else{ + } else { return null; } } else { if (is_null($value)) { - setcookie($name, '', time() - 3600, $config['path'], $config['domain'],$config['secure'],$config['httponly']); + setcookie($name, '', time() - 3600, $config['path'], $config['domain'], $config['secure'], $config['httponly']); unset($_COOKIE[$name]); // 删除指定cookie } else { // 设置cookie - if(is_array($value)){ - $value = 'think:'.json_encode(array_map('urlencode',$value)); + if (is_array($value)) { + $value = 'think:' . json_encode(array_map('urlencode', $value)); } $expire = !empty($config['expire']) ? time() + intval($config['expire']) : 0; - setcookie($name, $value, $expire, $config['path'], $config['domain'],$config['secure'],$config['httponly']); + setcookie($name, $value, $expire, $config['path'], $config['domain'], $config['secure'], $config['httponly']); $_COOKIE[$name] = $value; } } @@ -1306,73 +1467,76 @@ function cookie($name='', $value='', $option=null) { * @param integer $code 状态码 * @return void */ -function send_http_status($code) { +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' + // 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]); + if (isset($_status[$code])) { + header('HTTP/1.1 ' . $code . ' ' . $_status[$code]); // 确保FastCGI模式下正常 - header('Status:'.$code.' '.$_status[$code]); + header('Status:' . $code . ' ' . $_status[$code]); } } -function think_filter(&$value){ - // TODO 其他安全过滤 +function thinkFilter(&$value) +{ + // TODO 其他安全过滤 - // 过滤查询特殊字符 - if(preg_match('/^(EXP|NEQ|GT|EGT|LT|ELT|OR|XOR|LIKE|NOTLIKE|NOT BETWEEN|NOTBETWEEN|BETWEEN|NOTIN|NOT IN|IN)$/i',$value)){ + // 过滤查询特殊字符 + if (preg_match('/^(EXP|NEQ|GT|EGT|LT|ELT|OR|XOR|LIKE|NOTLIKE|NOT BETWEEN|NOTBETWEEN|BETWEEN|NOTIN|NOT IN|IN)$/i', $value)) { $value .= ' '; } } // 不区分大小写的in_array实现 -function in_array_case($value,$array){ - return in_array(strtolower($value),array_map('strtolower',$array)); +function inArrayCase($value, $array) +{ + return in_array(strtolower($value), array_map('strtolower', $array)); } diff --git a/ThinkPHP/Mode/Sae/convention.php b/ThinkPHP/Mode/Sae/convention.php index b9df74d1d..d38180da0 100644 --- a/ThinkPHP/Mode/Sae/convention.php +++ b/ThinkPHP/Mode/Sae/convention.php @@ -15,25 +15,24 @@ * 配置名称大小写任意,系统会统一转换成小写 * 所有配置参数都可以在生效前动态改变 */ -defined('THINK_PATH') or exit(); -$st = new SaeStorage(); +$st = new SaeStorage(); return array( //SAE下固定mysql配置 - 'DB_TYPE' => 'mysql', // 数据库类型 - 'DB_DEPLOY_TYPE' => 1, - 'DB_RW_SEPARATE' => true, - 'DB_HOST' => SAE_MYSQL_HOST_M.','.SAE_MYSQL_HOST_S, // 服务器地址 - 'DB_NAME' => SAE_MYSQL_DB, // 数据库名 - 'DB_USER' => SAE_MYSQL_USER, // 用户名 - 'DB_PWD' => SAE_MYSQL_PASS, // 密码 - 'DB_PORT' => SAE_MYSQL_PORT, // 端口 + 'DB_TYPE' => 'mysql', // 数据库类型 + 'DB_DEPLOY_TYPE' => 1, + 'DB_RW_SEPARATE' => true, + 'DB_HOST' => SAE_MYSQL_HOST_M . ',' . SAE_MYSQL_HOST_S, // 服务器地址 + 'DB_NAME' => SAE_MYSQL_DB, // 数据库名 + 'DB_USER' => SAE_MYSQL_USER, // 用户名 + 'DB_PWD' => SAE_MYSQL_PASS, // 密码 + 'DB_PORT' => SAE_MYSQL_PORT, // 端口 //更改模板替换变量,让普通能在所有平台下显示 - 'TMPL_PARSE_STRING' => array( + 'TMPL_PARSE_STRING' => array( // __PUBLIC__/upload --> /Public/upload -->http://appname-public.stor.sinaapp.com/upload - '/Public/upload' => $st->getUrl('public','upload') + '/Public/upload' => $st->getUrl('public', 'upload'), ), - 'LOG_TYPE' => 'Sae', - 'DATA_CACHE_TYPE' => 'Memcachesae', - 'CHECK_APP_DIR' => false, - 'FILE_UPLOAD_TYPE' => 'Sae', + 'LOG_TYPE' => 'Sae', + 'DATA_CACHE_TYPE' => 'Memcachesae', + 'CHECK_APP_DIR' => false, + 'FILE_UPLOAD_TYPE' => 'Sae', ); diff --git a/ThinkPHP/Mode/api.php b/ThinkPHP/Mode/api.php index 92c3a8c98..8500bb996 100644 --- a/ThinkPHP/Mode/api.php +++ b/ThinkPHP/Mode/api.php @@ -8,37 +8,37 @@ // +---------------------------------------------------------------------- // | Author: liu21st // +---------------------------------------------------------------------- - + /** * ThinkPHP API模式定义 */ return array( // 配置文件 - 'config' => array( - THINK_PATH.'Conf/convention.php', // 系统惯例配置 - CONF_PATH.'config'.CONF_EXT, // 应用公共配置 + 'config' => array( + THINK_PATH . 'Conf/convention.php', // 系统惯例配置 + CONF_PATH . 'config' . CONF_EXT, // 应用公共配置 ), // 别名定义 - 'alias' => array( - 'Think\Exception' => CORE_PATH . 'Exception'.EXT, - 'Think\Model' => CORE_PATH . 'Model'.EXT, - 'Think\Db' => CORE_PATH . 'Db'.EXT, - 'Think\Cache' => CORE_PATH . 'Cache'.EXT, - 'Think\Cache\Driver\File' => CORE_PATH . 'Cache/Driver/File'.EXT, - 'Think\Storage' => CORE_PATH . 'Storage'.EXT, + 'alias' => array( + 'Think\Exception' => CORE_PATH . 'Exception' . EXT, + 'Think\Model' => CORE_PATH . 'Model' . EXT, + 'Think\Db' => CORE_PATH . 'Db' . EXT, + 'Think\Cache' => CORE_PATH . 'Cache' . EXT, + 'Think\Cache\Driver\File' => CORE_PATH . 'Cache/Driver/File' . EXT, + 'Think\Storage' => CORE_PATH . 'Storage' . EXT, ), // 函数和类文件 - 'core' => array( - MODE_PATH.'Api/functions.php', - COMMON_PATH.'Common/function.php', - MODE_PATH . 'Api/App'.EXT, - MODE_PATH . 'Api/Dispatcher'.EXT, - MODE_PATH . 'Api/Controller'.EXT, - CORE_PATH . 'Behavior'.EXT, + 'core' => array( + MODE_PATH . 'Api/functions.php', + COMMON_PATH . 'Common/function.php', + MODE_PATH . 'Api/App' . EXT, + MODE_PATH . 'Api/Dispatcher' . EXT, + MODE_PATH . 'Api/Controller' . EXT, + CORE_PATH . 'Behavior' . EXT, ), // 行为扩展定义 - 'tags' => array( + 'tags' => array( ), ); diff --git a/ThinkPHP/Mode/common.php b/ThinkPHP/Mode/common.php index 5513773f3..26d5137e5 100644 --- a/ThinkPHP/Mode/common.php +++ b/ThinkPHP/Mode/common.php @@ -8,63 +8,63 @@ // +---------------------------------------------------------------------- // | Author: liu21st // +---------------------------------------------------------------------- - + /** * ThinkPHP 普通模式定义 */ return array( // 配置文件 - 'config' => array( - THINK_PATH.'Conf/convention.php', // 系统惯例配置 - CONF_PATH.'config'.CONF_EXT, // 应用公共配置 + 'config' => array( + THINK_PATH . 'Conf/convention.php', // 系统惯例配置 + CONF_PATH . 'config' . CONF_EXT, // 应用公共配置 ), // 别名定义 - 'alias' => array( - 'Think\Log' => CORE_PATH . 'Log'.EXT, - 'Think\Log\Driver\File' => CORE_PATH . 'Log/Driver/File'.EXT, - 'Think\Exception' => CORE_PATH . 'Exception'.EXT, - 'Think\Model' => CORE_PATH . 'Model'.EXT, - 'Think\Db' => CORE_PATH . 'Db'.EXT, - 'Think\Template' => CORE_PATH . 'Template'.EXT, - 'Think\Cache' => CORE_PATH . 'Cache'.EXT, - 'Think\Cache\Driver\File' => CORE_PATH . 'Cache/Driver/File'.EXT, - 'Think\Storage' => CORE_PATH . 'Storage'.EXT, + 'alias' => array( + 'Think\Log' => CORE_PATH . 'Log' . EXT, + 'Think\Log\Driver\File' => CORE_PATH . 'Log/Driver/File' . EXT, + 'Think\Exception' => CORE_PATH . 'Exception' . EXT, + 'Think\Model' => CORE_PATH . 'Model' . EXT, + 'Think\Db' => CORE_PATH . 'Db' . EXT, + 'Think\Template' => CORE_PATH . 'Template' . EXT, + 'Think\Cache' => CORE_PATH . 'Cache' . EXT, + 'Think\Cache\Driver\File' => CORE_PATH . 'Cache/Driver/File' . EXT, + 'Think\Storage' => CORE_PATH . 'Storage' . EXT, ), // 函数和类文件 - 'core' => array( - THINK_PATH.'Common/functions.php', - COMMON_PATH.'Common/function.php', - CORE_PATH . 'Hook'.EXT, - CORE_PATH . 'App'.EXT, - CORE_PATH . 'Dispatcher'.EXT, + 'core' => array( + THINK_PATH . 'Common/functions.php', + COMMON_PATH . 'Common/function.php', + CORE_PATH . 'Hook' . EXT, + CORE_PATH . 'App' . EXT, + CORE_PATH . 'Dispatcher' . EXT, //CORE_PATH . 'Log'.EXT, - CORE_PATH . 'Route'.EXT, - CORE_PATH . 'Controller'.EXT, - CORE_PATH . 'View'.EXT, - BEHAVIOR_PATH . 'BuildLiteBehavior'.EXT, - BEHAVIOR_PATH . 'ParseTemplateBehavior'.EXT, - BEHAVIOR_PATH . 'ContentReplaceBehavior'.EXT, + CORE_PATH . 'Route' . EXT, + CORE_PATH . 'Controller' . EXT, + CORE_PATH . 'View' . EXT, + BEHAVIOR_PATH . 'BuildLiteBehavior' . EXT, + BEHAVIOR_PATH . 'ParseTemplateBehavior' . EXT, + BEHAVIOR_PATH . 'ContentReplaceBehavior' . EXT, ), // 行为扩展定义 - 'tags' => array( - 'app_init' => array( + 'tags' => array( + 'app_init' => array( 'Behavior\BuildLiteBehavior', // 生成运行Lite文件 - ), - 'app_begin' => array( + ), + 'app_begin' => array( 'Behavior\ReadHtmlCacheBehavior', // 读取静态缓存 ), - 'app_end' => array( + 'app_end' => array( 'Behavior\ShowPageTraceBehavior', // 页面Trace显示 ), - 'view_parse' => array( + 'view_parse' => array( 'Behavior\ParseTemplateBehavior', // 模板解析 支持PHP、内置模板引擎和第三方模板引擎 ), - 'template_filter'=> array( + 'template_filter' => array( 'Behavior\ContentReplaceBehavior', // 模板输出替换 ), - 'view_filter' => array( + 'view_filter' => array( 'Behavior\WriteHtmlCacheBehavior', // 写入静态缓存 ), ), diff --git a/ThinkPHP/Mode/lite.php b/ThinkPHP/Mode/lite.php index 22f1cc2e4..7f4c7aead 100644 --- a/ThinkPHP/Mode/lite.php +++ b/ThinkPHP/Mode/lite.php @@ -8,40 +8,40 @@ // +---------------------------------------------------------------------- // | Author: liu21st // +---------------------------------------------------------------------- - + /** * ThinkPHP Lite模式定义 */ return array( // 配置文件 - 'config' => array( - MODE_PATH.'Lite/convention.php', // 系统惯例配置 - CONF_PATH.'config'.CONF_EXT, // 应用公共配置 + 'config' => array( + MODE_PATH . 'Lite/convention.php', // 系统惯例配置 + CONF_PATH . 'config' . CONF_EXT, // 应用公共配置 ), // 别名定义 - 'alias' => array( - 'Think\Exception' => CORE_PATH . 'Exception'.EXT, - 'Think\Model' => CORE_PATH . 'Model'.EXT, - 'Think\Db' => CORE_PATH . 'Db'.EXT, - 'Think\Cache' => CORE_PATH . 'Cache'.EXT, - 'Think\Cache\Driver\File' => CORE_PATH . 'Cache/Driver/File'.EXT, - 'Think\Storage' => CORE_PATH . 'Storage'.EXT, + 'alias' => array( + 'Think\Exception' => CORE_PATH . 'Exception' . EXT, + 'Think\Model' => CORE_PATH . 'Model' . EXT, + 'Think\Db' => CORE_PATH . 'Db' . EXT, + 'Think\Cache' => CORE_PATH . 'Cache' . EXT, + 'Think\Cache\Driver\File' => CORE_PATH . 'Cache/Driver/File' . EXT, + 'Think\Storage' => CORE_PATH . 'Storage' . EXT, ), // 函数和类文件 - 'core' => array( - MODE_PATH.'Lite/functions.php', - COMMON_PATH.'Common/function.php', - CORE_PATH . 'Hook'.EXT, - CORE_PATH . 'App'.EXT, - CORE_PATH . 'Dispatcher'.EXT, + 'core' => array( + MODE_PATH . 'Lite/functions.php', + COMMON_PATH . 'Common/function.php', + CORE_PATH . 'Hook' . EXT, + CORE_PATH . 'App' . EXT, + CORE_PATH . 'Dispatcher' . EXT, //CORE_PATH . 'Log'.EXT, - CORE_PATH . 'Route'.EXT, - CORE_PATH . 'Controller'.EXT, - CORE_PATH . 'View'.EXT, + CORE_PATH . 'Route' . EXT, + CORE_PATH . 'Controller' . EXT, + CORE_PATH . 'View' . EXT, ), // 行为扩展定义 - 'tags' => array( + 'tags' => array( ), ); diff --git a/ThinkPHP/Mode/sae.php b/ThinkPHP/Mode/sae.php index 4a9911085..6822103d4 100644 --- a/ThinkPHP/Mode/sae.php +++ b/ThinkPHP/Mode/sae.php @@ -8,60 +8,60 @@ // +---------------------------------------------------------------------- // | Author: luofei614 // +---------------------------------------------------------------------- - + /** * ThinkPHP SAE应用模式定义文件 */ return array( // 配置文件 - 'config' => array( - THINK_PATH.'Conf/convention.php', // 系统惯例配置 - CONF_PATH.'config'.CONF_EXT, // 应用公共配置 - MODE_PATH.'Sae/convention.php',//[sae] sae的惯例配置 + 'config' => array( + THINK_PATH . 'Conf/convention.php', // 系统惯例配置 + CONF_PATH . 'config' . CONF_EXT, // 应用公共配置 + MODE_PATH . 'Sae/convention.php', //[sae] sae的惯例配置 ), // 别名定义 - 'alias' => array( - 'Think\Log' => CORE_PATH . 'Log'.EXT, - 'Think\Log\Driver\File' => CORE_PATH . 'Log/Driver/File'.EXT, - 'Think\Exception' => CORE_PATH . 'Exception'.EXT, - 'Think\Model' => CORE_PATH . 'Model'.EXT, - 'Think\Db' => CORE_PATH . 'Db'.EXT, - 'Think\Template' => CORE_PATH . 'Template'.EXT, - 'Think\Cache' => CORE_PATH . 'Cache'.EXT, - 'Think\Cache\Driver\File' => CORE_PATH . 'Cache/Driver/File'.EXT, - 'Think\Storage' => CORE_PATH . 'Storage'.EXT, + 'alias' => array( + 'Think\Log' => CORE_PATH . 'Log' . EXT, + 'Think\Log\Driver\File' => CORE_PATH . 'Log/Driver/File' . EXT, + 'Think\Exception' => CORE_PATH . 'Exception' . EXT, + 'Think\Model' => CORE_PATH . 'Model' . EXT, + 'Think\Db' => CORE_PATH . 'Db' . EXT, + 'Think\Template' => CORE_PATH . 'Template' . EXT, + 'Think\Cache' => CORE_PATH . 'Cache' . EXT, + 'Think\Cache\Driver\File' => CORE_PATH . 'Cache/Driver/File' . EXT, + 'Think\Storage' => CORE_PATH . 'Storage' . EXT, ), // 函数和类文件 - 'core' => array( - THINK_PATH.'Common/functions.php', - COMMON_PATH.'Common/function.php', - CORE_PATH . 'Hook'.EXT, - CORE_PATH . 'App'.EXT, - CORE_PATH . 'Dispatcher'.EXT, + 'core' => array( + THINK_PATH . 'Common/functions.php', + COMMON_PATH . 'Common/function.php', + CORE_PATH . 'Hook' . EXT, + CORE_PATH . 'App' . EXT, + CORE_PATH . 'Dispatcher' . EXT, //CORE_PATH . 'Log'.EXT, - CORE_PATH . 'Route'.EXT, - CORE_PATH . 'Controller'.EXT, - CORE_PATH . 'View'.EXT, - BEHAVIOR_PATH . 'ParseTemplateBehavior'.EXT, - BEHAVIOR_PATH . 'ContentReplaceBehavior'.EXT, + CORE_PATH . 'Route' . EXT, + CORE_PATH . 'Controller' . EXT, + CORE_PATH . 'View' . EXT, + BEHAVIOR_PATH . 'ParseTemplateBehavior' . EXT, + BEHAVIOR_PATH . 'ContentReplaceBehavior' . EXT, ), // 行为扩展定义 - 'tags' => array( - 'app_begin' => array( + 'tags' => array( + 'app_begin' => array( 'Behavior\ReadHtmlCacheBehavior', // 读取静态缓存 ), - 'app_end' => array( + 'app_end' => array( 'Behavior\ShowPageTraceBehavior', // 页面Trace显示 ), - 'view_parse' => array( + 'view_parse' => array( 'Behavior\ParseTemplateBehavior', // 模板解析 支持PHP、内置模板引擎和第三方模板引擎 ), - 'template_filter'=> array( + 'template_filter' => array( 'Behavior\ContentReplaceBehavior', // 模板输出替换 ), - 'view_filter' => array( + 'view_filter' => array( 'Behavior\WriteHtmlCacheBehavior', // 写入静态缓存 ), ), diff --git a/ThinkPHP/ThinkPHP.php b/ThinkPHP/ThinkPHP.php index 16970a732..c66d876b4 100644 --- a/ThinkPHP/ThinkPHP.php +++ b/ThinkPHP/ThinkPHP.php @@ -14,84 +14,87 @@ //---------------------------------- // 记录开始运行时间 -$GLOBALS['_beginTime'] = microtime(TRUE); +$GLOBALS['_beginTime'] = microtime(true); // 记录内存初始使用 -define('MEMORY_LIMIT_ON',function_exists('memory_get_usage')); -if(MEMORY_LIMIT_ON) $GLOBALS['_startUseMems'] = memory_get_usage(); +define('MEMORY_LIMIT_ON', function_exists('memory_get_usage')); +if (MEMORY_LIMIT_ON) { + $GLOBALS['_startUseMems'] = memory_get_usage(); +} // 版本信息 -const THINK_VERSION = '3.2.3'; +const THINK_VERSION = '3.2.3'; // URL 模式定义 -const URL_COMMON = 0; //普通模式 -const URL_PATHINFO = 1; //PATHINFO模式 -const URL_REWRITE = 2; //REWRITE模式 -const URL_COMPAT = 3; // 兼容模式 +const URL_COMMON = 0; //普通模式 +const URL_PATHINFO = 1; //PATHINFO模式 +const URL_REWRITE = 2; //REWRITE模式 +const URL_COMPAT = 3; // 兼容模式 // 类文件后缀 -const EXT = '.class.php'; +const EXT = '.class.php'; // 系统常量定义 -defined('THINK_PATH') or define('THINK_PATH', __DIR__.'/'); -defined('APP_PATH') or define('APP_PATH', dirname($_SERVER['SCRIPT_FILENAME']).'/'); -defined('APP_STATUS') or define('APP_STATUS', ''); // 应用状态 加载对应的配置文件 -defined('APP_DEBUG') or define('APP_DEBUG', false); // 是否调试模式 +defined('THINK_PATH') or define('THINK_PATH', __DIR__ . '/'); +defined('APP_PATH') or define('APP_PATH', dirname($_SERVER['SCRIPT_FILENAME']) . '/'); +defined('APP_STATUS') or define('APP_STATUS', ''); // 应用状态 加载对应的配置文件 +defined('APP_DEBUG') or define('APP_DEBUG', false); // 是否调试模式 -if(function_exists('saeAutoLoader')){// 自动识别SAE环境 - defined('APP_MODE') or define('APP_MODE', 'sae'); - defined('STORAGE_TYPE') or define('STORAGE_TYPE', 'Sae'); -}else{ - defined('APP_MODE') or define('APP_MODE', 'common'); // 应用模式 默认为普通模式 - defined('STORAGE_TYPE') or define('STORAGE_TYPE', 'File'); // 存储类型 默认为File +if (function_exists('saeAutoLoader')) { +// 自动识别SAE环境 + defined('APP_MODE') or define('APP_MODE', 'sae'); + defined('STORAGE_TYPE') or define('STORAGE_TYPE', 'Sae'); +} else { + defined('APP_MODE') or define('APP_MODE', 'common'); // 应用模式 默认为普通模式 + defined('STORAGE_TYPE') or define('STORAGE_TYPE', 'File'); // 存储类型 默认为File } -defined('RUNTIME_PATH') or define('RUNTIME_PATH', APP_PATH.'Runtime/'); // 系统运行时目录 -defined('LIB_PATH') or define('LIB_PATH', realpath(THINK_PATH.'Library').'/'); // 系统核心类库目录 -defined('CORE_PATH') or define('CORE_PATH', LIB_PATH.'Think/'); // Think类库目录 -defined('BEHAVIOR_PATH')or define('BEHAVIOR_PATH', LIB_PATH.'Behavior/'); // 行为类库目录 -defined('MODE_PATH') or define('MODE_PATH', THINK_PATH.'Mode/'); // 系统应用模式目录 -defined('VENDOR_PATH') or define('VENDOR_PATH', LIB_PATH.'Vendor/'); // 第三方类库目录 -defined('COMMON_PATH') or define('COMMON_PATH', APP_PATH.'Common/'); // 应用公共目录 -defined('CONF_PATH') or define('CONF_PATH', COMMON_PATH.'Conf/'); // 应用配置目录 -defined('LANG_PATH') or define('LANG_PATH', COMMON_PATH.'Lang/'); // 应用语言目录 -defined('HTML_PATH') or define('HTML_PATH', APP_PATH.'Html/'); // 应用静态目录 -defined('LOG_PATH') or define('LOG_PATH', RUNTIME_PATH.'Logs/'); // 应用日志目录 -defined('TEMP_PATH') or define('TEMP_PATH', RUNTIME_PATH.'Temp/'); // 应用缓存目录 -defined('DATA_PATH') or define('DATA_PATH', RUNTIME_PATH.'Data/'); // 应用数据目录 -defined('CACHE_PATH') or define('CACHE_PATH', RUNTIME_PATH.'Cache/'); // 应用模板缓存目录 -defined('CONF_EXT') or define('CONF_EXT', '.php'); // 配置文件后缀 -defined('CONF_PARSE') or define('CONF_PARSE', ''); // 配置文件解析方法 -defined('ADDON_PATH') or define('ADDON_PATH', APP_PATH.'Addon'); +defined('RUNTIME_PATH') or define('RUNTIME_PATH', APP_PATH . 'Runtime/'); // 系统运行时目录 +defined('LIB_PATH') or define('LIB_PATH', realpath(THINK_PATH . 'Library') . '/'); // 系统核心类库目录 +defined('CORE_PATH') or define('CORE_PATH', LIB_PATH . 'Think/'); // Think类库目录 +defined('BEHAVIOR_PATH') or define('BEHAVIOR_PATH', LIB_PATH . 'Behavior/'); // 行为类库目录 +defined('MODE_PATH') or define('MODE_PATH', THINK_PATH . 'Mode/'); // 系统应用模式目录 +defined('VENDOR_PATH') or define('VENDOR_PATH', LIB_PATH . 'Vendor/'); // 第三方类库目录 +defined('COMMON_PATH') or define('COMMON_PATH', APP_PATH . 'Common/'); // 应用公共目录 +defined('CONF_PATH') or define('CONF_PATH', COMMON_PATH . 'Conf/'); // 应用配置目录 +defined('LANG_PATH') or define('LANG_PATH', COMMON_PATH . 'Lang/'); // 应用语言目录 +defined('HTML_PATH') or define('HTML_PATH', APP_PATH . 'Html/'); // 应用静态目录 +defined('LOG_PATH') or define('LOG_PATH', RUNTIME_PATH . 'Logs/'); // 应用日志目录 +defined('TEMP_PATH') or define('TEMP_PATH', RUNTIME_PATH . 'Temp/'); // 应用缓存目录 +defined('DATA_PATH') or define('DATA_PATH', RUNTIME_PATH . 'Data/'); // 应用数据目录 +defined('CACHE_PATH') or define('CACHE_PATH', RUNTIME_PATH . 'Cache/'); // 应用模板缓存目录 +defined('CONF_EXT') or define('CONF_EXT', '.php'); // 配置文件后缀 +defined('CONF_PARSE') or define('CONF_PARSE', ''); // 配置文件解析方法 +defined('ADDON_PATH') or define('ADDON_PATH', APP_PATH . 'Addon'); // 系统信息 -if(version_compare(PHP_VERSION,'5.4.0','<')) { - ini_set('magic_quotes_runtime',0); - define('MAGIC_QUOTES_GPC',get_magic_quotes_gpc()? true : false); -}else{ - define('MAGIC_QUOTES_GPC',false); +if (version_compare(PHP_VERSION, '5.4.0', '<')) { + ini_set('magic_quotes_runtime', 0); + define('MAGIC_QUOTES_GPC', get_magic_quotes_gpc() ? true : false); +} else { + define('MAGIC_QUOTES_GPC', false); } -define('IS_CGI',(0 === strpos(PHP_SAPI,'cgi') || false !== strpos(PHP_SAPI,'fcgi')) ? 1 : 0 ); -define('IS_WIN',strstr(PHP_OS, 'WIN') ? 1 : 0 ); -define('IS_CLI',PHP_SAPI=='cli'? 1 : 0); +define('IS_CGI', (0 === strpos(PHP_SAPI, 'cgi') || false !== strpos(PHP_SAPI, 'fcgi')) ? 1 : 0); +define('IS_WIN', strstr(PHP_OS, 'WIN') ? 1 : 0); +define('IS_CLI', PHP_SAPI == 'cli' ? 1 : 0); -if(!IS_CLI) { +if (!IS_CLI) { // 当前文件名 - if(!defined('_PHP_FILE_')) { - if(IS_CGI) { + if (!defined('_PHP_FILE_')) { + if (IS_CGI) { //CGI/FASTCGI模式下 - $_temp = explode('.php',$_SERVER['PHP_SELF']); - define('_PHP_FILE_', rtrim(str_replace($_SERVER['HTTP_HOST'],'',$_temp[0].'.php'),'/')); - }else { - define('_PHP_FILE_', rtrim($_SERVER['SCRIPT_NAME'],'/')); + $_temp = explode('.php', $_SERVER['PHP_SELF']); + define('_PHP_FILE_', rtrim(str_replace($_SERVER['HTTP_HOST'], '', $_temp[0] . '.php'), '/')); + } else { + define('_PHP_FILE_', rtrim($_SERVER['SCRIPT_NAME'], '/')); } } - if(!defined('__ROOT__')) { - $_root = rtrim(dirname(_PHP_FILE_),'/'); - define('__ROOT__', (($_root=='/' || $_root=='\\')?'':$_root)); + if (!defined('__ROOT__')) { + $_root = rtrim(dirname(_PHP_FILE_), '/'); + define('__ROOT__', (('/' == $_root || '\\' == $_root) ? '' : $_root)); } } // 加载核心Think类 -require CORE_PATH.'Think'.EXT; -// 应用初始化 -Think\Think::start(); \ No newline at end of file +require CORE_PATH . 'Think' . EXT; +// 应用初始化 +Think\Think::start(); diff --git a/index.php b/index.php index 10d1083ef..aa6cf840d 100644 --- a/index.php +++ b/index.php @@ -12,15 +12,17 @@ // 应用入口文件 // 检测PHP环境 -if(version_compare(PHP_VERSION,'5.3.0','<')) die('require PHP > 5.3.0 !'); +if (version_compare(PHP_VERSION, '5.3.0', '<')) { + die('require PHP > 5.3.0 !'); +} // 开启调试模式 建议开发阶段开启 部署阶段注释或者设为false -define('APP_DEBUG',True); +define('APP_DEBUG', true); // 定义应用目录 -define('APP_PATH','./Application/'); +define('APP_PATH', './Application/'); // 引入ThinkPHP入口文件 require './ThinkPHP/ThinkPHP.php'; -// 亲^_^ 后面不需要任何代码了 就是如此简单 \ No newline at end of file +// 亲^_^ 后面不需要任何代码了 就是如此简单 From 0e425b5e1a77a90973234e05803408d68abf7513 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Sun, 4 Oct 2015 14:50:22 +0800 Subject: [PATCH 099/166] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E6=9B=B4=E5=90=8D=E7=9A=84=E5=87=BD=E6=95=B0=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Common/functions.php | 43 +++++++++++---------- ThinkPHP/Library/Think/Controller.class.php | 5 ++- ThinkPHP/Mode/Api/functions.php | 22 +++++------ ThinkPHP/Mode/Lite/functions.php | 26 ++++++------- 4 files changed, 49 insertions(+), 47 deletions(-) diff --git a/ThinkPHP/Common/functions.php b/ThinkPHP/Common/functions.php index 024e21fec..0231ee127 100644 --- a/ThinkPHP/Common/functions.php +++ b/ThinkPHP/Common/functions.php @@ -62,7 +62,7 @@ function C($name = null, $value = null, $default = null) * @param string $parse 配置解析方法 有些格式需要用户自己解析 * @return array */ -function loadConfig($file, $parse = CONF_PARSE) +function load_config($file, $parse = CONF_PARSE) { $ext = pathinfo($file, PATHINFO_EXTENSION); switch ($ext) { @@ -71,7 +71,7 @@ function loadConfig($file, $parse = CONF_PARSE) case 'ini': return parse_ini_file($file); case 'yaml': - return yamlParseFile($file); + return yaml_parse_file($file); case 'xml': return (array) simplexml_load_file($file); case 'json': @@ -91,7 +91,7 @@ function loadConfig($file, $parse = CONF_PARSE) * @return array */ if (!function_exists('yaml_parse_file')) { - function yamlParseFile($file) + function yaml_parse_file($file) { vendor('spyc.Spyc'); return Spyc::YAMLLoad($file); @@ -651,7 +651,7 @@ function D($name = '', $layer = '') return $_model[$name . $layer]; } - $class = parseResName($name, $layer); + $class = parse_res_name($name, $layer); if (class_exists($class)) { $model = new $class(basename($name)); } elseif (false === strpos($name, '/')) { @@ -701,7 +701,7 @@ function M($name = '', $tablePrefix = '', $connection = '') * @param integer $level 控制器层次 * @return string */ -function parseResName($name, $layer, $level = 1) +function parse_res_name($name, $layer, $level = 1) { if (strpos($name, '://')) { // 指定扩展资源 @@ -776,7 +776,7 @@ function A($name, $layer = '', $level = 0) return $_action[$name . $layer]; } - $class = parseResName($name, $layer, $level); + $class = parse_res_name($name, $layer, $level); if (class_exists($class)) { $action = new $class(); $_action[$name . $layer] = $action; @@ -840,7 +840,7 @@ function B($name, $tag = '', &$params = null) * @param string $content 代码内容 * @return string */ -function stripWhitespace($content) +function strip_whitespace($content) { $stripStr = ''; //分析php源码 @@ -893,7 +893,7 @@ function stripWhitespace($content) * @param integer $code 异常代码 默认为0 * @return void */ -function throwException($msg, $type = 'Think\\Exception', $code = 0) +function throw_exception($msg, $type = 'Think\\Exception', $code = 0) { Think\Log::record('建议使用E方法替代throw_exception', Think\Log::NOTICE); if (class_exists($type, false)) { @@ -1130,7 +1130,7 @@ function U($url = '', $vars = '', $suffix = true, $domain = false) $url .= '#' . $anchor; } if ($domain) { - $url = (isSsl() ? 'https://' : 'http://') . $domain . $url; + $url = (is_ssl() ? 'https://' : 'http://') . $domain . $url; } return $url; } @@ -1150,7 +1150,7 @@ function W($name, $data = array()) * 判断是否SSL协议 * @return boolean */ -function isSsl() +function is_ssl() { if (isset($_SERVER['HTTPS']) && ('1' == $_SERVER['HTTPS'] || 'on' == strtolower($_SERVER['HTTPS']))) { return true; @@ -1280,7 +1280,7 @@ function F($name, $value = '', $path = DATA_PATH) * @param mixed $mix 变量 * @return string */ -function toGuidString($mix) +function to_guid_string($mix) { if (is_object($mix)) { return spl_object_hash($mix); @@ -1302,7 +1302,7 @@ function toGuidString($mix) * @param string $encoding 数据编码 * @return string */ -function xmlEncode($data, $root = 'think', $item = 'item', $attr = '', $id = 'id', $encoding = 'utf-8') +function xml_encode($data, $root = 'think', $item = 'item', $attr = '', $id = 'id', $encoding = 'utf-8') { if (is_array($attr)) { $_attr = array(); @@ -1327,7 +1327,7 @@ function xmlEncode($data, $root = 'think', $item = 'item', $attr = '', $id = 'id * @param string $id 数字索引key转换为的属性名 * @return string */ -function dataToXml($data, $item = 'item', $id = 'id') +function data_to_xml($data, $item = 'item', $id = 'id') { $xml = $attr = ''; foreach ($data as $key => $val) { @@ -1426,7 +1426,8 @@ function session($name = '', $value = '') return $prefix ? $_SESSION[$prefix] : $_SESSION; } elseif (0 === strpos($name, '[')) { // session 操作 - if ('[pause]' == $name) { // 暂停session + if ('[pause]' == $name) { + // 暂停session session_write_close(); } elseif ('[start]' == $name) { // 启动session @@ -1549,7 +1550,7 @@ function cookie($name = '', $value = '', $option = null) // 要删除的cookie前缀,不指定则删除config设置的指定前缀 $prefix = empty($value) ? $config['prefix'] : $value; if (!empty($prefix)) { -// 如果前缀为空字符串将不作处理直接返回 + // 如果前缀为空字符串将不作处理直接返回 foreach ($_COOKIE as $key => $val) { if (0 === stripos($key, $prefix)) { setcookie($key, '', time() - 3600, $config['path'], $config['domain'], $config['secure'], $config['httponly']); @@ -1597,7 +1598,7 @@ function cookie($name = '', $value = '', $option = null) * @var string $path 文件路径 * @return void */ -function loadExtFile($path) +function load_ext_file($path) { // 加载自定义外部文件 if ($files = C('LOAD_EXT_FILE')) { @@ -1619,7 +1620,7 @@ function loadExtFile($path) foreach ($configs as $key => $config) { $file = is_file($config) ? $config : $path . 'Conf/' . $config . CONF_EXT; if (is_file($file)) { - is_numeric($key) ? C(loadConfig($file)) : C($key, loadConfig($file)); + is_numeric($key) ? C(load_Config($file)) : C($key, load_Config($file)); } } } @@ -1631,7 +1632,7 @@ function loadExtFile($path) * @param boolean $adv 是否进行高级模式获取(有可能被伪装) * @return mixed */ -function getClientIp($type = 0, $adv = false) +function get_client_ip($type = 0, $adv = false) { $type = $type ? 1 : 0; static $ip = null; @@ -1667,7 +1668,7 @@ function getClientIp($type = 0, $adv = false) * @param integer $code 状态码 * @return void */ -function sendHttpStatus($code) +function send_http_status($code) { static $_status = array( // Informational 1xx @@ -1725,7 +1726,7 @@ function sendHttpStatus($code) } } -function thinkFilter(&$value) +function think_filter(&$value) { // TODO 其他安全过滤 @@ -1736,7 +1737,7 @@ function thinkFilter(&$value) } // 不区分大小写的in_array实现 -function inArrayCase($value, $array) +function in_array_case($value, $array) { return in_array(strtolower($value), array_map('strtolower', $array)); } diff --git a/ThinkPHP/Library/Think/Controller.class.php b/ThinkPHP/Library/Think/Controller.class.php index 77883f7c6..702514b90 100644 --- a/ThinkPHP/Library/Think/Controller.class.php +++ b/ThinkPHP/Library/Think/Controller.class.php @@ -13,13 +13,14 @@ /** * ThinkPHP 控制器基类 抽象类 */ -class Controller +abstract class Controller { /** * 视图实例对象 * @var view * @access protected - */abstract protected $view = null; + */ + protected $view = null; /** * 控制器参数 diff --git a/ThinkPHP/Mode/Api/functions.php b/ThinkPHP/Mode/Api/functions.php index 3931ae7f9..c33e43ce8 100644 --- a/ThinkPHP/Mode/Api/functions.php +++ b/ThinkPHP/Mode/Api/functions.php @@ -62,7 +62,7 @@ function C($name = null, $value = null, $default = null) * @param string $parse 配置解析方法 有些格式需要用户自己解析 * @return void */ -function loadConfig($file, $parse = CONF_PARSE) +function load_config($file, $parse = CONF_PARSE) { $ext = pathinfo($file, PATHINFO_EXTENSION); switch ($ext) { @@ -551,7 +551,7 @@ function D($name = '', $layer = '') return $_model[$name . $layer]; } - $class = parseResName($name, $layer); + $class = parse_res_name($name, $layer); if (class_exists($class)) { $model = new $class(basename($name)); } elseif (false === strpos($name, '/')) { @@ -596,7 +596,7 @@ function M($name = '', $tablePrefix = '', $connection = '') * @param string $layer 分层名称 * @return string */ -function parseResName($name, $layer, $level = 1) +function parse_res_name($name, $layer, $level = 1) { if (strpos($name, '://')) { // 指定扩展资源 @@ -639,7 +639,7 @@ function A($name, $layer = '', $level = '') return $_action[$name . $layer]; } - $class = parseResName($name, $layer, $level); + $class = parse_res_name($name, $layer, $level); if (class_exists($class)) { $action = new $class(); $_action[$name . $layer] = $action; @@ -693,7 +693,7 @@ function B($name, &$params = null) * @param string $content 代码内容 * @return string */ -function stripWhitespace($content) +function strip_whitespace($content) { $stripStr = ''; //分析php源码 @@ -895,7 +895,7 @@ function F($name, $value = '', $path = DATA_PATH) * @param mixed $mix 变量 * @return string */ -function toGuidString($mix) +function to_guid_string($mix) { if (is_object($mix)) { return spl_object_hash($mix); @@ -917,7 +917,7 @@ function toGuidString($mix) * @param string $encoding 数据编码 * @return string */ -function xmlEncode($data, $root = 'think', $item = 'item', $attr = '', $id = 'id', $encoding = 'utf-8') +function xml_encode($data, $root = 'think', $item = 'item', $attr = '', $id = 'id', $encoding = 'utf-8') { if (is_array($attr)) { $_attr = array(); @@ -942,7 +942,7 @@ function xmlEncode($data, $root = 'think', $item = 'item', $attr = '', $id = 'id * @param string $id 数字索引key转换为的属性名 * @return string */ -function dataToXml($data, $item = 'item', $id = 'id') +function data_to_xml($data, $item = 'item', $id = 'id') { $xml = $attr = ''; foreach ($data as $key => $val) { @@ -1249,7 +1249,7 @@ function getClientIp($type = 0) * @param integer $code 状态码 * @return void */ -function sendHttpStatus($code) +function send_http_status($code) { static $_status = array( // Success 2xx @@ -1273,12 +1273,12 @@ function sendHttpStatus($code) } // 不区分大小写的in_array实现 -function inArrayCase($value, $array) +function in_array_case($value, $array) { return in_array(strtolower($value), array_map('strtolower', $array)); } -function thinkFilter(&$value) +function think_filter(&$value) { // TODO 其他安全过滤 diff --git a/ThinkPHP/Mode/Lite/functions.php b/ThinkPHP/Mode/Lite/functions.php index 53ba8d263..f480ecd4b 100644 --- a/ThinkPHP/Mode/Lite/functions.php +++ b/ThinkPHP/Mode/Lite/functions.php @@ -62,7 +62,7 @@ function C($name = null, $value = null, $default = null) * @param string $parse 配置解析方法 有些格式需要用户自己解析 * @return array */ -function loadConfig($file, $parse = CONF_PARSE) +function load_config($file, $parse = CONF_PARSE) { $ext = pathinfo($file, PATHINFO_EXTENSION); switch ($ext) { @@ -71,7 +71,7 @@ function loadConfig($file, $parse = CONF_PARSE) case 'ini': return parse_ini_file($file); case 'yaml': - return yamlParseFile($file); + return yaml_parse_file($file); case 'xml': return (array) simplexml_load_file($file); case 'json': @@ -91,7 +91,7 @@ function loadConfig($file, $parse = CONF_PARSE) * @return array */ if (!function_exists('yaml_parse_file')) { - function yamlParseFile($file) + function yaml_parse_file($file) { vendor('spyc.Spyc'); return Spyc::YAMLLoad($file); @@ -621,7 +621,7 @@ function D($name = '', $layer = '') if (isset($_model[$name . $layer])) { return $_model[$name . $layer]; } - $class = parseResName($name, $layer); + $class = parse_res_name($name, $layer); if (class_exists($class)) { $model = new $class(basename($name)); } elseif (false === strpos($name, '/')) { @@ -664,7 +664,7 @@ function M($name = '', $tablePrefix = '', $connection = '') * @param string $layer 分层名称 * @return string */ -function parseResName($name, $layer) +function parse_res_name($name, $layer) { if (strpos($name, '://')) { // 指定扩展资源 @@ -727,7 +727,7 @@ function A($name, $layer = '') return $_action[$name . $layer]; } - $class = parseResName($name, $layer); + $class = parse_res_name($name, $layer); if (class_exists($class)) { $action = new $class(); $_action[$name . $layer] = $action; @@ -791,7 +791,7 @@ function B($name, $tag = '', &$params = null) * @param string $content 代码内容 * @return string */ -function stripWhitespace($content) +function strip_whitespace($content) { $stripStr = ''; //分析php源码 @@ -1050,7 +1050,7 @@ function U($url = '', $vars = '', $suffix = true, $domain = false) $url .= '#' . $anchor; } if ($domain) { - $url = (isSsl() ? 'https://' : 'http://') . $domain . $url; + $url = (is_ssl() ? 'https://' : 'http://') . $domain . $url; } return $url; } @@ -1070,7 +1070,7 @@ function W($name, $data = array()) * 判断是否SSL协议 * @return boolean */ -function isSsl() +function is_ssl() { if (isset($_SERVER['HTTPS']) && ('1' == $_SERVER['HTTPS'] || 'on' == strtolower($_SERVER['HTTPS']))) { return true; @@ -1200,7 +1200,7 @@ function F($name, $value = '', $path = DATA_PATH) * @param mixed $mix 变量 * @return string */ -function toGuidString($mix) +function to_guid_string($mix) { if (is_object($mix)) { return spl_object_hash($mix); @@ -1467,7 +1467,7 @@ function cookie($name = '', $value = '', $option = null) * @param integer $code 状态码 * @return void */ -function sendHttpStatus($code) +function send_http_status($code) { static $_status = array( // Informational 1xx @@ -1525,7 +1525,7 @@ function sendHttpStatus($code) } } -function thinkFilter(&$value) +function think_filter(&$value) { // TODO 其他安全过滤 @@ -1536,7 +1536,7 @@ function thinkFilter(&$value) } // 不区分大小写的in_array实现 -function inArrayCase($value, $array) +function in_array_case($value, $array) { return in_array(strtolower($value), array_map('strtolower', $array)); } From 4727cb9b0b21c4c6095b9fc953c8a2702e7bb82e Mon Sep 17 00:00:00 2001 From: thinkphp Date: Wed, 7 Oct 2015 10:57:24 +0800 Subject: [PATCH 100/166] =?UTF-8?q?=E6=94=B9=E8=BF=9BBuild=E7=B1=BB?= =?UTF-8?q?=EF=BC=8C=E6=94=AF=E6=8C=81=E6=89=B9=E9=87=8F=E7=94=9F=E6=88=90?= =?UTF-8?q?=E6=8E=A7=E5=88=B6=E5=99=A8=E5=92=8C=E6=A8=A1=E5=9E=8B=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Build.class.php | 82 ++++++++++++++------------ 1 file changed, 44 insertions(+), 38 deletions(-) diff --git a/ThinkPHP/Library/Think/Build.class.php b/ThinkPHP/Library/Think/Build.class.php index f0503d373..626854c76 100644 --- a/ThinkPHP/Library/Think/Build.class.php +++ b/ThinkPHP/Library/Think/Build.class.php @@ -18,17 +18,24 @@ class Build protected static $controller = 'show(\'

:)

欢迎使用 ThinkPHP


版本 V{$Think.version}
\',\'utf-8\'); + +class [CONTROLLER]Controller extends Controller +{ + public function index() + { + [CONTENT] } }'; protected static $model = 'show(\'

:)

欢迎使用 ThinkPHP


版本 V{$Think.version}
\',\'utf-8\');' : ''; + + foreach ($list as $controller) { + $file = APP_PATH . $module . '/Controller/' . $controller . 'Controller' . EXT; + if (!is_file($file)) { + $content = str_replace(array('[MODULE]', '[CONTROLLER]', '[CONTENT]'), array($module, $controller, $hello), self::$controller); + if (!C('APP_USE_NAMESPACE')) { + $content = preg_replace('/namespace\s(.*?);/', '', $content, 1); + } + $dir = dirname($file); + if (!is_dir($dir)) { + mkdir($dir, 0755, true); + } + file_put_contents($file, $content); } - file_put_contents($file, $content); } } // 创建模型类 - public static function buildModel($module, $model) + public static function buildModel($module, $models) { - $file = APP_PATH . $module . '/Model/' . $model . 'Model' . EXT; - if (!is_file($file)) { - $content = str_replace(array('[MODULE]', '[MODEL]'), array($module, $model), self::$model); - if (!C('APP_USE_NAMESPACE')) { - $content = preg_replace('/namespace\s(.*?);/', '', $content, 1); - } - $dir = dirname($file); - if (!is_dir($dir)) { - mkdir($dir, 0755, true); + $list = is_array($models) ? $models : explode(',', $models); + foreach ($list as $model) { + $file = APP_PATH . $module . '/Model/' . $model . 'Model' . EXT; + if (!is_file($file)) { + $content = str_replace(array('[MODULE]', '[MODEL]'), array($module, $model), self::$model); + if (!C('APP_USE_NAMESPACE')) { + $content = preg_replace('/namespace\s(.*?);/', '', $content, 1); + } + $dir = dirname($file); + if (!is_dir($dir)) { + mkdir($dir, 0755, true); + } + file_put_contents($file, $content); } - file_put_contents($file, $content); } } @@ -187,7 +194,6 @@ public static function buildDirSecure($dirs = array()) foreach ($dirs as $dir) { file_put_contents($dir . $filename, $content); } - } } } From ec127e5e8ad9c51a5c7b776246567c6b4fb833be Mon Sep 17 00:00:00 2001 From: thinkphp Date: Wed, 7 Oct 2015 11:21:23 +0800 Subject: [PATCH 101/166] =?UTF-8?q?=E6=94=B9=E8=BF=9BBuild=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Build.class.php | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/ThinkPHP/Library/Think/Build.class.php b/ThinkPHP/Library/Think/Build.class.php index 626854c76..a157591ba 100644 --- a/ThinkPHP/Library/Think/Build.class.php +++ b/ThinkPHP/Library/Think/Build.class.php @@ -95,14 +95,10 @@ public static function buildAppDir($module) file_put_contents(APP_PATH . $module . '/Conf/config' . CONF_EXT, '.php' == CONF_EXT ? "'配置值'\n);" : ''); } - // 生成模块的测试控制器 - if (defined('BUILD_CONTROLLER_LIST')) { - self::buildController($module, BUILD_CONTROLLER_LIST); - } else { - // 生成默认的控制器 - self::buildController($module, C('DEFAULT_CONTROLLER'), true); - } - // 生成模块的模型 + // 自动生成控制器类 + self::buildController($module, defined('BUILD_CONTROLLER_LIST') ? BUILD_CONTROLLER_LIST : C('DEFAULT_CONTROLLER')); + + // 自动生成模型类 if (defined('BUILD_MODEL_LIST')) { self::buildModel($module, BUILD_MODEL_LIST); } @@ -138,13 +134,14 @@ public static function buildRuntime() } // 创建控制器类 - public static function buildController($module, $controllers, $default = false) + public static function buildController($module, $controllers) { $list = is_array($controllers) ? $controllers : explode(',', $controllers); - $hello = $default ? '$this->show(\'

:)

欢迎使用 ThinkPHP


版本 V{$Think.version}
\',\'utf-8\');' : ''; + $hello = '$this->show(\'

:)

欢迎使用 ThinkPHP


版本 V{$Think.version}
\',\'utf-8\');'; foreach ($list as $controller) { - $file = APP_PATH . $module . '/Controller/' . $controller . 'Controller' . EXT; + $hello = C('DEFAULT_CONTROLLER') == $controller ? $hello : ''; + $file = APP_PATH . $module . '/Controller/' . $controller . 'Controller' . EXT; if (!is_file($file)) { $content = str_replace(array('[MODULE]', '[CONTROLLER]', '[CONTENT]'), array($module, $controller, $hello), self::$controller); if (!C('APP_USE_NAMESPACE')) { From 43362b9a08878f44984cc7ec93534c486322f7de Mon Sep 17 00:00:00 2001 From: thinkphp Date: Wed, 7 Oct 2015 12:49:58 +0800 Subject: [PATCH 102/166] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Common/functions.php | 56 ++++++++++++++++---------------- ThinkPHP/Mode/Api/functions.php | 26 +++++++-------- ThinkPHP/Mode/Lite/functions.php | 20 ++++++------ 3 files changed, 51 insertions(+), 51 deletions(-) diff --git a/ThinkPHP/Common/functions.php b/ThinkPHP/Common/functions.php index 0231ee127..490da7049 100644 --- a/ThinkPHP/Common/functions.php +++ b/ThinkPHP/Common/functions.php @@ -332,16 +332,16 @@ function I($name, $default = '', $filter = null, $datas = null) break; case 'param': switch ($_SERVER['REQUEST_METHOD']) { - case 'POST': + case 'POST': $input = $_POST; break; - case 'PUT': + case 'PUT': if (is_null($_PUT)) { parse_str(file_get_contents('php://input'), $_PUT); } $input = $_PUT; break; - default: + default: $input = $_GET; } break; @@ -382,7 +382,7 @@ function I($name, $default = '', $filter = null, $datas = null) $filters = explode(',', $filters); } foreach ($filters as $filter) { - $data = arrayMapRecursive($filter, $data); // 参数过滤 + $data = array_map_recursive($filter, $data); // 参数过滤 } } } elseif (isset($input[$name])) { @@ -406,7 +406,7 @@ function I($name, $default = '', $filter = null, $datas = null) if (is_array($filters)) { foreach ($filters as $filter) { if (function_exists($filter)) { - $data = is_array($data) ? arrayMapRecursive($filter, $data) : $filter($data); // 参数过滤 + $data = is_array($data) ? array_map_recursive($filter, $data) : $filter($data); // 参数过滤 } else { $data = filter_var($data, is_int($filter) ? $filter : filter_id($filter)); if (false === $data) { @@ -418,19 +418,19 @@ function I($name, $default = '', $filter = null, $datas = null) } if (!empty($type)) { switch (strtolower($type)) { - case 'a': // 数组 + case 'a': // 数组 $data = (array) $data; break; - case 'd': // 数字 + case 'd': // 数字 $data = (int) $data; break; - case 'f': // 浮点 + case 'f': // 浮点 $data = (float) $data; break; - case 'b': // 布尔 + case 'b': // 布尔 $data = (boolean) $data; break; - case 's': // 字符串 + case 's':// 字符串 default: $data = (string) $data; } @@ -443,12 +443,12 @@ function I($name, $default = '', $filter = null, $datas = null) return $data; } -function arrayMapRecursive($filter, $data) +function array_map_recursive($filter, $data) { $result = array(); foreach ($data as $key => $val) { $result[$key] = is_array($val) - ? arrayMapRecursive($filter, $val) + ? array_map_recursive($filter, $val) : call_user_func($filter, $val); } return $result; @@ -493,7 +493,7 @@ function N($key, $step = 0, $save = false) * @param integer $type 转换类型 * @return string */ -function parseName($name, $type = 0) +function parse_name($name, $type = 0) { if ($type) { return ucfirst(preg_replace_callback('/_([a-zA-Z])/', function ($match) {return strtoupper($match[1]);}, $name)); @@ -507,11 +507,11 @@ function parseName($name, $type = 0) * @param string $filename 文件地址 * @return boolean */ -function requireCache($filename) +function require_cache($filename) { static $_importFiles = array(); if (!isset($_importFiles[$filename])) { - if (fileExistsCase($filename)) { + if (file_exists_case($filename)) { require $filename; $_importFiles[$filename] = true; } else { @@ -526,7 +526,7 @@ function requireCache($filename) * @param string $filename 文件地址 * @return boolean */ -function fileExistsCase($filename) +function file_exists_case($filename) { if (is_file($filename)) { if (IS_WIN && APP_DEBUG) { @@ -582,7 +582,7 @@ function import($class, $baseUrl = '', $ext = EXT) $classfile = $baseUrl . $class . $ext; if (!class_exists(basename($class), false)) { // 如果类不存在 则导入类库文件 - return requireCache($classfile); + return require_cache($classfile); } return null; } @@ -600,7 +600,7 @@ function load($name, $baseUrl = '', $ext = '.php') $name = str_replace(array('.', '#'), array('/', '.'), $name); if (empty($baseUrl)) { if (0 === strpos($name, '@/')) { -//加载当前模块函数库 + //加载当前模块函数库 $baseUrl = MODULE_PATH . 'Common/'; $name = substr($name, 2); } else { @@ -614,7 +614,7 @@ function load($name, $baseUrl = '', $ext = '.php') $baseUrl .= '/'; } - requireCache($baseUrl . $name . $ext); + require_cache($baseUrl . $name . $ext); } /** @@ -704,7 +704,7 @@ function M($name = '', $tablePrefix = '', $connection = '') function parse_res_name($name, $layer, $level = 1) { if (strpos($name, '://')) { -// 指定扩展资源 + // 指定扩展资源 list($extend, $name) = explode('://', $name); } else { $extend = ''; @@ -717,12 +717,12 @@ function parse_res_name($name, $layer, $level = 1) } $array = explode('/', $name); if (!C('APP_USE_NAMESPACE')) { - $class = parseName($name, 1); + $class = parse_name($name, 1); import($module . '/' . $layer . '/' . $class . $layer); } else { $class = $module . '\\' . $layer; foreach ($array as $name) { - $class .= '\\' . parseName($name, 1); + $class .= '\\' . parse_name($name, 1); } // 导入资源类库 if ($extend) { @@ -743,13 +743,13 @@ function controller($name, $path = '') { $layer = C('DEFAULT_C_LAYER'); if (!C('APP_USE_NAMESPACE')) { - $class = parseName($name, 1) . $layer; + $class = parse_name($name, 1) . $layer; import(MODULE_NAME . '/' . $layer . '/' . $class); } else { $class = ($path ? basename(ADDON_PATH) . '\\' . $path : MODULE_NAME) . '\\' . $layer; $array = explode('/', $name); foreach ($array as $name) { - $class .= '\\' . parseName($name, 1); + $class .= '\\' . parse_name($name, 1); } $class .= $layer; } @@ -1026,7 +1026,7 @@ function U($url = '', $vars = '', $suffix = true, $domain = false) $urlCase = C('URL_CASE_INSENSITIVE'); if ($url) { if (0 === strpos($url, '/')) { -// 定义路由 + // 定义路由 $route = true; $url = substr($url, 1); if ('/' != $depr) { @@ -1060,7 +1060,7 @@ function U($url = '', $vars = '', $suffix = true, $domain = false) } } if ($urlCase) { - $var[$varController] = parseName($var[$varController]); + $var[$varController] = parse_name($var[$varController]); } $module = ''; @@ -1315,7 +1315,7 @@ function xml_encode($data, $root = 'think', $item = 'item', $attr = '', $id = 'i $attr = empty($attr) ? '' : " {$attr}"; $xml = ""; $xml .= "<{$root}{$attr}>"; - $xml .= dataToXml($data, $item, $id); + $xml .= data_to_xml($data, $item, $id); $xml .= ""; return $xml; } @@ -1336,7 +1336,7 @@ function data_to_xml($data, $item = 'item', $id = 'id') $key = $item; } $xml .= "<{$key}{$attr}>"; - $xml .= (is_array($val) || is_object($val)) ? dataToXml($val, $item, $id) : $val; + $xml .= (is_array($val) || is_object($val)) ? data_to_xml($val, $item, $id) : $val; $xml .= ""; } return $xml; diff --git a/ThinkPHP/Mode/Api/functions.php b/ThinkPHP/Mode/Api/functions.php index c33e43ce8..9813aa140 100644 --- a/ThinkPHP/Mode/Api/functions.php +++ b/ThinkPHP/Mode/Api/functions.php @@ -398,7 +398,7 @@ function N($key, $step = 0, $save = false) * @param integer $type 转换类型 * @return string */ -function parseName($name, $type = 0) +function parse_name($name, $type = 0) { if ($type) { return ucfirst(preg_replace_callback('/_([a-zA-Z])/', function ($match) {return strtoupper($match[1]);}, $name)); @@ -412,11 +412,11 @@ function parseName($name, $type = 0) * @param string $filename 文件地址 * @return boolean */ -function requireCache($filename) +function require_cache($filename) { static $_importFiles = array(); if (!isset($_importFiles[$filename])) { - if (fileExistsCase($filename)) { + if (file_exists_case($filename)) { require $filename; $_importFiles[$filename] = true; } else { @@ -431,7 +431,7 @@ function requireCache($filename) * @param string $filename 文件地址 * @return boolean */ -function fileExistsCase($filename) +function file_exists_case($filename) { if (is_file($filename)) { if (IS_WIN && APP_DEBUG) { @@ -483,7 +483,7 @@ function import($class, $baseUrl = '', $ext = EXT) $classfile = $baseUrl . $class . $ext; if (!class_exists(basename($class), false)) { // 如果类不存在 则导入类库文件 - return requireCache($classfile); + return require_cache($classfile); } } @@ -500,7 +500,7 @@ function load($name, $baseUrl = '', $ext = '.php') $name = str_replace(array('.', '#'), array('/', '.'), $name); if (empty($baseUrl)) { if (0 === strpos($name, '@/')) { -//加载当前模块函数库 + //加载当前模块函数库 $baseUrl = MODULE_PATH . 'Common/'; $name = substr($name, 2); } else { @@ -514,7 +514,7 @@ function load($name, $baseUrl = '', $ext = '.php') $baseUrl .= '/'; } - requireCache($baseUrl . $name . $ext); + require_cache($baseUrl . $name . $ext); } /** @@ -613,7 +613,7 @@ function parse_res_name($name, $layer, $level = 1) $array = explode('/', $name); $class = $module . '\\' . $layer; foreach ($array as $name) { - $class .= '\\' . parseName($name, 1); + $class .= '\\' . parse_name($name, 1); } // 导入资源类库 if ($extend) { @@ -930,7 +930,7 @@ function xml_encode($data, $root = 'think', $item = 'item', $attr = '', $id = 'i $attr = empty($attr) ? '' : " {$attr}"; $xml = ""; $xml .= "<{$root}{$attr}>"; - $xml .= dataToXml($data, $item, $id); + $xml .= data_to_xml($data, $item, $id); $xml .= ""; return $xml; } @@ -951,7 +951,7 @@ function data_to_xml($data, $item = 'item', $id = 'id') $key = $item; } $xml .= "<{$key}{$attr}>"; - $xml .= (is_array($val) || is_object($val)) ? dataToXml($val, $item, $id) : $val; + $xml .= (is_array($val) || is_object($val)) ? data_to_xml($val, $item, $id) : $val; $xml .= ""; } return $xml; @@ -1140,7 +1140,7 @@ function cookie($name, $value = '', $option = null) // 要删除的cookie前缀,不指定则删除config设置的指定前缀 $prefix = empty($value) ? $config['prefix'] : $value; if (!empty($prefix)) { -// 如果前缀为空字符串将不作处理直接返回 + // 如果前缀为空字符串将不作处理直接返回 foreach ($_COOKIE as $key => $val) { if (0 === stripos($key, $prefix)) { setcookie($key, '', time() - 3600, $config['path'], $config['domain']); @@ -1183,7 +1183,7 @@ function cookie($name, $value = '', $option = null) * 加载动态扩展文件 * @return void */ -function loadExtFile($path) +function load_ext_file($path) { // 加载自定义外部文件 if (C('LOAD_EXT_FILE')) { @@ -1217,7 +1217,7 @@ function loadExtFile($path) * @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字 * @return mixed */ -function getClientIp($type = 0) +function get_client_ip($type = 0) { $type = $type ? 1 : 0; static $ip = null; diff --git a/ThinkPHP/Mode/Lite/functions.php b/ThinkPHP/Mode/Lite/functions.php index f480ecd4b..21b1f599e 100644 --- a/ThinkPHP/Mode/Lite/functions.php +++ b/ThinkPHP/Mode/Lite/functions.php @@ -466,7 +466,7 @@ function N($key, $step = 0, $save = false) * @param integer $type 转换类型 * @return string */ -function parseName($name, $type = 0) +function parse_name($name, $type = 0) { if ($type) { return ucfirst(preg_replace_callback('/_([a-zA-Z])/', function ($match) {return strtoupper($match[1]);}, $name)); @@ -480,11 +480,11 @@ function parseName($name, $type = 0) * @param string $filename 文件地址 * @return boolean */ -function requireCache($filename) +function require_cache($filename) { static $_importFiles = array(); if (!isset($_importFiles[$filename])) { - if (fileExistsCase($filename)) { + if (file_exists_case($filename)) { require $filename; $_importFiles[$filename] = true; } else { @@ -499,7 +499,7 @@ function requireCache($filename) * @param string $filename 文件地址 * @return boolean */ -function fileExistsCase($filename) +function file_exists_case($filename) { if (is_file($filename)) { if (IS_WIN && APP_DEBUG) { @@ -555,7 +555,7 @@ function import($class, $baseUrl = '', $ext = EXT) $classfile = $baseUrl . $class . $ext; if (!class_exists(basename($class), false)) { // 如果类不存在 则导入类库文件 - return requireCache($classfile); + return require_cache($classfile); } return null; } @@ -573,7 +573,7 @@ function load($name, $baseUrl = '', $ext = '.php') $name = str_replace(array('.', '#'), array('/', '.'), $name); if (empty($baseUrl)) { if (0 === strpos($name, '@/')) { -//加载当前模块函数库 + //加载当前模块函数库 $baseUrl = MODULE_PATH . 'Common/'; $name = substr($name, 2); } else { @@ -586,7 +586,7 @@ function load($name, $baseUrl = '', $ext = '.php') if (substr($baseUrl, -1) != '/') { $baseUrl .= '/'; } - requireCache($baseUrl . $name . $ext); + require_cache($baseUrl . $name . $ext); } /** @@ -681,7 +681,7 @@ function parse_res_name($name, $layer) $array = explode('/', $name); $class = $module . '\\' . $layer; foreach ($array as $name) { - $class .= '\\' . parseName($name, 1); + $class .= '\\' . parse_name($name, 1); } // 导入资源类库 if ($extend) { @@ -702,7 +702,7 @@ function controller($name) $class = MODULE_NAME . '\\Controller'; $array = explode('/', $name); foreach ($array as $name) { - $class .= '\\' . parseName($name, 1); + $class .= '\\' . parse_name($name, 1); } $class .= $layer; @@ -980,7 +980,7 @@ function U($url = '', $vars = '', $suffix = true, $domain = false) $var[$varAction] = !empty($path) ? array_pop($path) : ACTION_NAME; $var[$varController] = !empty($path) ? array_pop($path) : CONTROLLER_NAME; if ($urlCase) { - $var[$varController] = parseName($var[$varController]); + $var[$varController] = parse_name($var[$varController]); } $module = ''; From 22e5e7fa705ac6ffeb534c3e60f5fb081a1550b9 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Wed, 7 Oct 2015 20:51:38 +0800 Subject: [PATCH 103/166] =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Common/functions.php | 32 +++++++++++++------------- ThinkPHP/Library/Think/Route.class.php | 2 +- ThinkPHP/Mode/Api/functions.php | 27 +++++++++++----------- ThinkPHP/Mode/Lite/functions.php | 29 ++++++++++++----------- 4 files changed, 46 insertions(+), 44 deletions(-) diff --git a/ThinkPHP/Common/functions.php b/ThinkPHP/Common/functions.php index 0231ee127..3e204b1e8 100644 --- a/ThinkPHP/Common/functions.php +++ b/ThinkPHP/Common/functions.php @@ -382,7 +382,7 @@ function I($name, $default = '', $filter = null, $datas = null) $filters = explode(',', $filters); } foreach ($filters as $filter) { - $data = arrayMapRecursive($filter, $data); // 参数过滤 + $data = array_map_recursive($filter, $data); // 参数过滤 } } } elseif (isset($input[$name])) { @@ -406,7 +406,7 @@ function I($name, $default = '', $filter = null, $datas = null) if (is_array($filters)) { foreach ($filters as $filter) { if (function_exists($filter)) { - $data = is_array($data) ? arrayMapRecursive($filter, $data) : $filter($data); // 参数过滤 + $data = is_array($data) ? array_map_recursive($filter, $data) : $filter($data); // 参数过滤 } else { $data = filter_var($data, is_int($filter) ? $filter : filter_id($filter)); if (false === $data) { @@ -443,12 +443,12 @@ function I($name, $default = '', $filter = null, $datas = null) return $data; } -function arrayMapRecursive($filter, $data) +function array_map_recursive($filter, $data) { $result = array(); foreach ($data as $key => $val) { $result[$key] = is_array($val) - ? arrayMapRecursive($filter, $val) + ? array_map_recursive($filter, $val) : call_user_func($filter, $val); } return $result; @@ -493,7 +493,7 @@ function N($key, $step = 0, $save = false) * @param integer $type 转换类型 * @return string */ -function parseName($name, $type = 0) +function parse_name($name, $type = 0) { if ($type) { return ucfirst(preg_replace_callback('/_([a-zA-Z])/', function ($match) {return strtoupper($match[1]);}, $name)); @@ -507,11 +507,11 @@ function parseName($name, $type = 0) * @param string $filename 文件地址 * @return boolean */ -function requireCache($filename) +function require_cache($filename) { static $_importFiles = array(); if (!isset($_importFiles[$filename])) { - if (fileExistsCase($filename)) { + if (file_exists_case($filename)) { require $filename; $_importFiles[$filename] = true; } else { @@ -526,7 +526,7 @@ function requireCache($filename) * @param string $filename 文件地址 * @return boolean */ -function fileExistsCase($filename) +function file_exists_case($filename) { if (is_file($filename)) { if (IS_WIN && APP_DEBUG) { @@ -582,7 +582,7 @@ function import($class, $baseUrl = '', $ext = EXT) $classfile = $baseUrl . $class . $ext; if (!class_exists(basename($class), false)) { // 如果类不存在 则导入类库文件 - return requireCache($classfile); + return require_cache($classfile); } return null; } @@ -600,7 +600,7 @@ function load($name, $baseUrl = '', $ext = '.php') $name = str_replace(array('.', '#'), array('/', '.'), $name); if (empty($baseUrl)) { if (0 === strpos($name, '@/')) { -//加载当前模块函数库 + //加载当前模块函数库 $baseUrl = MODULE_PATH . 'Common/'; $name = substr($name, 2); } else { @@ -614,7 +614,7 @@ function load($name, $baseUrl = '', $ext = '.php') $baseUrl .= '/'; } - requireCache($baseUrl . $name . $ext); + require_cache($baseUrl . $name . $ext); } /** @@ -717,12 +717,12 @@ function parse_res_name($name, $layer, $level = 1) } $array = explode('/', $name); if (!C('APP_USE_NAMESPACE')) { - $class = parseName($name, 1); + $class = parse_name($name, 1); import($module . '/' . $layer . '/' . $class . $layer); } else { $class = $module . '\\' . $layer; foreach ($array as $name) { - $class .= '\\' . parseName($name, 1); + $class .= '\\' . parse_name($name, 1); } // 导入资源类库 if ($extend) { @@ -743,13 +743,13 @@ function controller($name, $path = '') { $layer = C('DEFAULT_C_LAYER'); if (!C('APP_USE_NAMESPACE')) { - $class = parseName($name, 1) . $layer; + $class = parse_name($name, 1) . $layer; import(MODULE_NAME . '/' . $layer . '/' . $class); } else { $class = ($path ? basename(ADDON_PATH) . '\\' . $path : MODULE_NAME) . '\\' . $layer; $array = explode('/', $name); foreach ($array as $name) { - $class .= '\\' . parseName($name, 1); + $class .= '\\' . parse_name($name, 1); } $class .= $layer; } @@ -1060,7 +1060,7 @@ function U($url = '', $vars = '', $suffix = true, $domain = false) } } if ($urlCase) { - $var[$varController] = parseName($var[$varController]); + $var[$varController] = parse_name($var[$varController]); } $module = ''; diff --git a/ThinkPHP/Library/Think/Route.class.php b/ThinkPHP/Library/Think/Route.class.php index bdbd42817..80bdec8cf 100644 --- a/ThinkPHP/Library/Think/Route.class.php +++ b/ThinkPHP/Library/Think/Route.class.php @@ -74,7 +74,7 @@ public static function check() $len2 = substr_count($rule, '/'); if ($len1 >= $len2 || strpos($rule, '[')) { if ('$' == substr($rule, -1, 1)) { -// 完整匹配 + // 完整匹配 if ($len1 != $len2) { continue; } else { diff --git a/ThinkPHP/Mode/Api/functions.php b/ThinkPHP/Mode/Api/functions.php index c33e43ce8..133869466 100644 --- a/ThinkPHP/Mode/Api/functions.php +++ b/ThinkPHP/Mode/Api/functions.php @@ -349,12 +349,12 @@ function I($name, $default = '', $filter = null, $datas = null) return $data; } -function arrayMapRecursive($filter, $data) +function array_map_recursive($filter, $data) { $result = array(); foreach ($data as $key => $val) { $result[$key] = is_array($val) - ? arrayMapRecursive($filter, $val) + ? array_map_recursive($filter, $val) : call_user_func($filter, $val); } return $result; @@ -398,7 +398,7 @@ function N($key, $step = 0, $save = false) * @param integer $type 转换类型 * @return string */ -function parseName($name, $type = 0) +function parse_name($name, $type = 0) { if ($type) { return ucfirst(preg_replace_callback('/_([a-zA-Z])/', function ($match) {return strtoupper($match[1]);}, $name)); @@ -412,11 +412,11 @@ function parseName($name, $type = 0) * @param string $filename 文件地址 * @return boolean */ -function requireCache($filename) +function require_cache($filename) { static $_importFiles = array(); if (!isset($_importFiles[$filename])) { - if (fileExistsCase($filename)) { + if (file_exists_case($filename)) { require $filename; $_importFiles[$filename] = true; } else { @@ -431,7 +431,7 @@ function requireCache($filename) * @param string $filename 文件地址 * @return boolean */ -function fileExistsCase($filename) +function file_exists_case($filename) { if (is_file($filename)) { if (IS_WIN && APP_DEBUG) { @@ -483,7 +483,7 @@ function import($class, $baseUrl = '', $ext = EXT) $classfile = $baseUrl . $class . $ext; if (!class_exists(basename($class), false)) { // 如果类不存在 则导入类库文件 - return requireCache($classfile); + return require_cache($classfile); } } @@ -500,7 +500,7 @@ function load($name, $baseUrl = '', $ext = '.php') $name = str_replace(array('.', '#'), array('/', '.'), $name); if (empty($baseUrl)) { if (0 === strpos($name, '@/')) { -//加载当前模块函数库 + //加载当前模块函数库 $baseUrl = MODULE_PATH . 'Common/'; $name = substr($name, 2); } else { @@ -514,7 +514,7 @@ function load($name, $baseUrl = '', $ext = '.php') $baseUrl .= '/'; } - requireCache($baseUrl . $name . $ext); + require_cache($baseUrl . $name . $ext); } /** @@ -613,7 +613,7 @@ function parse_res_name($name, $layer, $level = 1) $array = explode('/', $name); $class = $module . '\\' . $layer; foreach ($array as $name) { - $class .= '\\' . parseName($name, 1); + $class .= '\\' . parse_name($name, 1); } // 导入资源类库 if ($extend) { @@ -1038,7 +1038,8 @@ function session($name, $value = '') } elseif ('' === $value) { if (0 === strpos($name, '[')) { // session 操作 - if ('[pause]' == $name) { // 暂停session + if ('[pause]' == $name) { + // 暂停session session_write_close(); } elseif ('[start]' == $name) { // 启动session @@ -1183,7 +1184,7 @@ function cookie($name, $value = '', $option = null) * 加载动态扩展文件 * @return void */ -function loadExtFile($path) +function load_ext_file($path) { // 加载自定义外部文件 if (C('LOAD_EXT_FILE')) { @@ -1217,7 +1218,7 @@ function loadExtFile($path) * @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字 * @return mixed */ -function getClientIp($type = 0) +function get_client_ip($type = 0) { $type = $type ? 1 : 0; static $ip = null; diff --git a/ThinkPHP/Mode/Lite/functions.php b/ThinkPHP/Mode/Lite/functions.php index f480ecd4b..3a5b4eb9f 100644 --- a/ThinkPHP/Mode/Lite/functions.php +++ b/ThinkPHP/Mode/Lite/functions.php @@ -359,7 +359,7 @@ function I($name, $default = '', $filter = null, $datas = null) $filters = explode(',', $filters); } foreach ($filters as $filter) { - $data = arrayMapRecursive($filter, $data); // 参数过滤 + $data = array_map_recursive($filter, $data); // 参数过滤 } } } elseif (isset($input[$name])) { @@ -375,7 +375,7 @@ function I($name, $default = '', $filter = null, $datas = null) foreach ($filters as $filter) { if (function_exists($filter)) { - $data = is_array($data) ? arrayMapRecursive($filter, $data) : $filter($data); // 参数过滤 + $data = is_array($data) ? array_map_recursive($filter, $data) : $filter($data); // 参数过滤 } elseif (0 === strpos($filter, '/')) { // 支持正则验证 if (1 !== preg_match($filter, (string) $data)) { @@ -416,12 +416,12 @@ function I($name, $default = '', $filter = null, $datas = null) return $data; } -function arrayMapRecursive($filter, $data) +function array_map_recursive($filter, $data) { $result = array(); foreach ($data as $key => $val) { $result[$key] = is_array($val) - ? arrayMapRecursive($filter, $val) + ? array_map_recursive($filter, $val) : call_user_func($filter, $val); } return $result; @@ -466,7 +466,7 @@ function N($key, $step = 0, $save = false) * @param integer $type 转换类型 * @return string */ -function parseName($name, $type = 0) +function parse_name($name, $type = 0) { if ($type) { return ucfirst(preg_replace_callback('/_([a-zA-Z])/', function ($match) {return strtoupper($match[1]);}, $name)); @@ -480,11 +480,11 @@ function parseName($name, $type = 0) * @param string $filename 文件地址 * @return boolean */ -function requireCache($filename) +function require_cache($filename) { static $_importFiles = array(); if (!isset($_importFiles[$filename])) { - if (fileExistsCase($filename)) { + if (file_exists_case($filename)) { require $filename; $_importFiles[$filename] = true; } else { @@ -499,7 +499,7 @@ function requireCache($filename) * @param string $filename 文件地址 * @return boolean */ -function fileExistsCase($filename) +function file_exists_case($filename) { if (is_file($filename)) { if (IS_WIN && APP_DEBUG) { @@ -555,7 +555,7 @@ function import($class, $baseUrl = '', $ext = EXT) $classfile = $baseUrl . $class . $ext; if (!class_exists(basename($class), false)) { // 如果类不存在 则导入类库文件 - return requireCache($classfile); + return require_cache($classfile); } return null; } @@ -586,7 +586,7 @@ function load($name, $baseUrl = '', $ext = '.php') if (substr($baseUrl, -1) != '/') { $baseUrl .= '/'; } - requireCache($baseUrl . $name . $ext); + require_cache($baseUrl . $name . $ext); } /** @@ -681,7 +681,7 @@ function parse_res_name($name, $layer) $array = explode('/', $name); $class = $module . '\\' . $layer; foreach ($array as $name) { - $class .= '\\' . parseName($name, 1); + $class .= '\\' . parse_name($name, 1); } // 导入资源类库 if ($extend) { @@ -702,7 +702,7 @@ function controller($name) $class = MODULE_NAME . '\\Controller'; $array = explode('/', $name); foreach ($array as $name) { - $class .= '\\' . parseName($name, 1); + $class .= '\\' . parse_name($name, 1); } $class .= $layer; @@ -980,7 +980,7 @@ function U($url = '', $vars = '', $suffix = true, $domain = false) $var[$varAction] = !empty($path) ? array_pop($path) : ACTION_NAME; $var[$varController] = !empty($path) ? array_pop($path) : CONTROLLER_NAME; if ($urlCase) { - $var[$varController] = parseName($var[$varController]); + $var[$varController] = parse_name($var[$varController]); } $module = ''; @@ -1296,7 +1296,8 @@ function session($name = '', $value = '') return $prefix ? $_SESSION[$prefix] : $_SESSION; } elseif (0 === strpos($name, '[')) { // session 操作 - if ('[pause]' == $name) { // 暂停session + if ('[pause]' == $name) { + // 暂停session session_write_close(); } elseif ('[start]' == $name) { // 启动session From 94d5c5ef980be6a3f31d6938e5cbf997f6cdb4a2 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Thu, 8 Oct 2015 14:19:21 +0800 Subject: [PATCH 104/166] =?UTF-8?q?=E8=A7=84=E8=8C=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/App.class.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ThinkPHP/Library/Think/App.class.php b/ThinkPHP/Library/Think/App.class.php index fedf108bf..53b3d8773 100644 --- a/ThinkPHP/Library/Think/App.class.php +++ b/ThinkPHP/Library/Think/App.class.php @@ -121,6 +121,7 @@ public static function exec() } return; } + public static function invokeAction($module, $action) { if (!preg_match('/^[A-Za-z](\w)*$/', $action)) { @@ -191,6 +192,7 @@ public static function invokeAction($module, $action) throw new \ReflectionException(); } } + /** * 运行应用实例 入口文件使用的快捷方法 * @access public From 6e09a9727ccf6d020e17e9250e3b80ba6cd65356 Mon Sep 17 00:00:00 2001 From: peablog Date: Thu, 8 Oct 2015 21:27:17 +0800 Subject: [PATCH 105/166] =?UTF-8?q?=E4=BF=AE=E6=94=B9URL=5FPARAMS=5FFILTER?= =?UTF-8?q?=5FTYPE=E9=85=8D=E7=BD=AE=E5=8F=82=E6=95=B0=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/App.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ThinkPHP/Library/Think/App.class.php b/ThinkPHP/Library/Think/App.class.php index 53b3d8773..aa559f03b 100644 --- a/ThinkPHP/Library/Think/App.class.php +++ b/ThinkPHP/Library/Think/App.class.php @@ -166,8 +166,8 @@ public static function invokeAction($module, $action) } } // 开启绑定参数过滤机制 - if (C('URL_PARAMS_SAFE')) { - $filters = C('URL_PARAMS_FILTER') ?: C('DEFAULT_FILTER'); + if (C('URL_PARAMS_FILTER')) { + $filters = C('URL_PARAMS_FILTER_TYPE') ?: C('DEFAULT_FILTER'); if ($filters) { $filters = explode(',', $filters); foreach ($filters as $filter) { From 7d460d2577775b5947b979ffb9024c24b6afb585 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Fri, 9 Oct 2015 15:11:41 +0800 Subject: [PATCH 106/166] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Model.class.php | 67 +++++++++++++------------- 1 file changed, 34 insertions(+), 33 deletions(-) diff --git a/ThinkPHP/Library/Think/Model.class.php b/ThinkPHP/Library/Think/Model.class.php index 77f69abeb..1b2f12b87 100644 --- a/ThinkPHP/Library/Think/Model.class.php +++ b/ThinkPHP/Library/Think/Model.class.php @@ -252,7 +252,7 @@ public function __call($method, $args) $where[$name] = $args[0]; return $this->where($where)->getField($args[1]); } elseif (isset($this->_scope[$method])) { -// 命名范围的单独调用支持 + // 命名范围的单独调用支持 return $this->scope($method, $args[0]); } else { E(__CLASS__ . ':' . $method . L('_METHOD_NOT_EXIST_')); @@ -824,7 +824,7 @@ public function find($options = array()) return false; } if (empty($resultSet)) { -// 查询结果为空 + // 查询结果为空 return null; } if (is_string($resultSet)) { @@ -921,7 +921,7 @@ public function setField($field, $value = '') public function setInc($field, $step = 1, $lazyTime = 0) { if ($lazyTime > 0) { -// 延迟写入 + // 延迟写入 $condition = $this->options['where']; $guid = md5($this->name . '_' . $field . '_' . serialize($condition)); $step = $this->lazyWrite($guid, $step, $lazyTime); @@ -945,7 +945,7 @@ public function setInc($field, $step = 1, $lazyTime = 0) public function setDec($field, $step = 1, $lazyTime = 0) { if ($lazyTime > 0) { -// 延迟写入 + // 延迟写入 $condition = $this->options['where']; $guid = md5($this->name . '_' . $field . '_' . serialize($condition)); $step = $this->lazyWrite($guid, -$step, $lazyTime); @@ -1251,8 +1251,8 @@ private function autoOperation(&$data, $type) } switch (trim($auto[3])) { - case 'function': // 使用函数进行填充 字段的值作为参数 - case 'callback': // 使用回调方法 + case 'function':// 使用函数进行填充 字段的值作为参数 + case 'callback': // 使用回调方法 $args = isset($auto[4]) ? (array) $auto[4] : array(); if (isset($data[$auto[0]])) { array_unshift($args, $data[$auto[0]]); @@ -1263,17 +1263,17 @@ private function autoOperation(&$data, $type) $data[$auto[0]] = call_user_func_array(array(&$this, $auto[1]), $args); } break; - case 'field': // 用其它字段的值进行填充 + case 'field': // 用其它字段的值进行填充 $data[$auto[0]] = $data[$auto[1]]; break; - case 'ignore': // 为空忽略 + case 'ignore': // 为空忽略 if ($auto[1] === $data[$auto[0]]) { unset($data[$auto[0]]); } break; case 'string': - default: // 默认作为字符串填充 + default: // 默认作为字符串填充 $data[$auto[0]] = $auto[1]; } if (isset($data[$auto[0]]) && false === $data[$auto[0]]) { @@ -1327,13 +1327,13 @@ protected function autoValidation($data, $type) $val[4] = isset($val[4]) ? $val[4] : 'regex'; // 判断验证条件 switch ($val[3]) { - case self::MUST_VALIDATE: // 必须验证 不管表单是否有设置该字段 + case self::MUST_VALIDATE: // 必须验证 不管表单是否有设置该字段 if (false === $this->_validationField($data, $val)) { return false; } break; - case self::VALUE_VALIDATE: // 值不为空的时候才验证 + case self::VALUE_VALIDATE: // 值不为空的时候才验证 if ('' != trim($data[$val[0]])) { if (false === $this->_validationField($data, $val)) { return false; @@ -1341,7 +1341,7 @@ protected function autoValidation($data, $type) } break; - default: // 默认表单存在该字段就验证 + default: // 默认表单存在该字段就验证 if (isset($data[$val[0]])) { if (false === $this->_validationField($data, $val)) { return false; @@ -1371,9 +1371,10 @@ protected function autoValidation($data, $type) protected function _validationField($data, $val) { if ($this->patchValidate && isset($this->error[$val[0]])) { + //当前字段已经有规则验证没有通过 return; } - //当前字段已经有规则验证没有通过 + if (false === $this->_validationFieldItem($data, $val)) { if ($this->patchValidate) { $this->error[$val[0]] = $val[2]; @@ -1395,8 +1396,8 @@ protected function _validationField($data, $val) protected function _validationFieldItem($data, $val) { switch (strtolower(trim($val[4]))) { - case 'function': // 使用函数进行验证 - case 'callback': // 调用方法进行验证 + case 'function':// 使用函数进行验证 + case 'callback': // 调用方法进行验证 $args = isset($val[6]) ? (array) $val[6] : array(); if (is_string($val[0]) && strpos($val[0], ',')) { $val[0] = explode(',', $val[0]); @@ -1417,9 +1418,9 @@ protected function _validationFieldItem($data, $val) } else { return call_user_func_array(array(&$this, $val[1]), $args); } - case 'confirm': // 验证两个字段是否相同 + case 'confirm': // 验证两个字段是否相同 return $data[$val[0]] == $data[$val[1]]; - case 'unique': // 验证某个值是否唯一 + case 'unique': // 验证某个值是否唯一 if (is_string($val[0]) && strpos($val[0], ',')) { $val[0] = explode(',', $val[0]); } @@ -1446,7 +1447,7 @@ protected function _validationFieldItem($data, $val) $this->options = $options; return true; - default: // 检查附加规则 + default: // 检查附加规则 return $this->check($data[$val[0]], $val[1], $val[4]); } } @@ -1463,12 +1464,12 @@ public function check($value, $rule, $type = 'regex') { $type = strtolower(trim($type)); switch ($type) { - case 'in': // 验证是否在某个指定范围之内 逗号分隔字符串或者数组 + case 'in':// 验证是否在某个指定范围之内 逗号分隔字符串或者数组 case 'notin': $range = is_array($rule) ? $rule : explode(',', $rule); return 'in' == $type ? in_array($value, $range) : !in_array($value, $range); - case 'between': // 验证是否在某个范围 - case 'notbetween': // 验证是否不在某个范围 + case 'between':// 验证是否在某个范围 + case 'notbetween': // 验证是否不在某个范围 if (is_array($rule)) { $min = $rule[0]; $max = $rule[1]; @@ -1476,17 +1477,17 @@ public function check($value, $rule, $type = 'regex') list($min, $max) = explode(',', $rule); } return 'between' == $type ? $value >= $min && $value <= $max : $value < $min || $value > $max; - case 'equal': // 验证是否等于某个值 - case 'notequal': // 验证是否等于某个值 + case 'equal':// 验证是否等于某个值 + case 'notequal': // 验证是否等于某个值 return 'equal' == $type ? $value == $rule : $value != $rule; - case 'length': // 验证长度 - $length = mb_strlen($value, 'utf-8'); // 当前数据长度 + case 'length': // 验证长度 + $length = mb_strlen($value, 'utf-8'); // 当前数据长度 if (strpos($rule, ',')) { // 长度区间 list($min, $max) = explode(',', $rule); return $length >= $min && $length <= $max; } else { -// 指定长度 + // 指定长度 return $length == $rule; } case 'expire': @@ -1500,12 +1501,12 @@ public function check($value, $rule, $type = 'regex') } return NOW_TIME >= $start && NOW_TIME <= $end; - case 'ip_allow': // IP 操作许可验证 + case 'ip_allow': // IP 操作许可验证 return in_array(get_client_ip(), explode(',', $rule)); - case 'ip_deny': // IP 操作禁止验证 + case 'ip_deny': // IP 操作禁止验证 return !in_array(get_client_ip(), explode(',', $rule)); case 'regex': - default: // 默认使用正则验证 可以使用验证类中定义的验证名称 + default: // 默认使用正则验证 可以使用验证类中定义的验证名称 // 检查附加规则 return $this->regex($value, $rule); } @@ -1634,7 +1635,7 @@ public function getModelName() if (empty($this->name)) { $name = substr(get_class($this), 0, -strlen(C('DEFAULT_M_LAYER'))); if ($pos = strrpos($name, '\\')) { -//有命名空间 + //有命名空间 $this->name = substr($name, $pos + 1); } else { $this->name = $name; @@ -1757,7 +1758,7 @@ public function getPk() public function getDbFields() { if (isset($this->options['table'])) { -// 动态指定表名 + // 动态指定表名 if (is_array($this->options['table'])) { $table = key($this->options['table']); } else { @@ -1932,11 +1933,11 @@ public function cache($key = true, $expire = null, $type = '') public function field($field, $except = false) { if (true === $field) { -// 获取全部字段 + // 获取全部字段 $fields = $this->getDbFields(); $field = $fields ?: '*'; } elseif ($except) { -// 字段排除 + // 字段排除 if (is_string($field)) { $field = explode(',', $field); } From 1afcd9dcf48228cc6a722a4b7968811343bee053 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Tue, 13 Oct 2015 14:52:09 +0800 Subject: [PATCH 107/166] =?UTF-8?q?=E6=94=B9=E8=BF=9B=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E7=BC=93=E5=AD=98=E6=96=87=E4=BB=B6=E7=9A=84=E5=91=BD=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Controller.class.php | 2 +- ThinkPHP/Library/Think/Model.class.php | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/ThinkPHP/Library/Think/Controller.class.php b/ThinkPHP/Library/Think/Controller.class.php index 702514b90..aa1149b8d 100644 --- a/ThinkPHP/Library/Think/Controller.class.php +++ b/ThinkPHP/Library/Think/Controller.class.php @@ -283,7 +283,7 @@ protected function redirect($url, $params = array(), $delay = 0, $msg = '') private function dispatchJump($message, $status = 1, $jumpUrl = '', $ajax = false) { if (true === $ajax || IS_AJAX) { -// AJAX提交 + // AJAX提交 $data = is_array($ajax) ? $ajax : array(); $data['info'] = $message; $data['status'] = $status; diff --git a/ThinkPHP/Library/Think/Model.class.php b/ThinkPHP/Library/Think/Model.class.php index 1b2f12b87..4382390d5 100644 --- a/ThinkPHP/Library/Think/Model.class.php +++ b/ThinkPHP/Library/Think/Model.class.php @@ -114,8 +114,7 @@ protected function _checkTableInfo() if (empty($this->fields)) { // 如果数据表字段没有定义则自动获取 if (C('DB_FIELDS_CACHE')) { - $db = $this->dbName ?: C('DB_NAME'); - $fields = F('_fields/' . strtolower($db . '.' . $this->tablePrefix . $this->name)); + $fields = F('_fields/' . strtolower($this->getTableName())); if ($fields) { $this->fields = $fields; if (!empty($fields['_pk'])) { @@ -138,7 +137,8 @@ public function flush() { // 缓存不存在则查询数据表信息 $this->db->setModel($this->name); - $fields = $this->db->getFields($this->getTableName()); + $tableName = $this->getTableName(); + $fields = $this->db->getFields($tableName); if (!$fields) { // 无法获取字段信息 return false; @@ -173,8 +173,7 @@ public function flush() // 2008-3-7 增加缓存开关控制 if (C('DB_FIELDS_CACHE')) { // 永久缓存数据表信息 - $db = $this->dbName ?: C('DB_NAME'); - F('_fields/' . strtolower($db . '.' . $this->tablePrefix . $this->name), $this->fields); + F('_fields/' . strtolower($tableName), $this->fields); } } From 4495772ae1697c95a0d6ec7dd65dd846161b5b24 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Wed, 14 Oct 2015 18:36:54 +0800 Subject: [PATCH 108/166] =?UTF-8?q?=E6=94=B9=E8=BF=9BGd=E9=A9=B1=E5=8A=A8?= =?UTF-8?q?=E7=B1=BB=E5=BA=93=E5=AF=B9PNG=E5=92=8C=E6=89=93=E5=BC=80?= =?UTF-8?q?=E8=BF=9C=E7=A8=8B=E5=9B=BE=E7=89=87=E7=9A=84=E6=94=AF=E6=8C=81?= =?UTF-8?q?=20=E6=84=9F=E8=B0=A2=E7=BD=91=E5=8F=8B=E5=B9=BB=E7=84=B6?= =?UTF-8?q?=E7=BE=BF=E9=A6=A8=E7=9A=84=E5=8F=8D=E9=A6=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Library/Think/Image/Driver/Gd.class.php | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/ThinkPHP/Library/Think/Image/Driver/Gd.class.php b/ThinkPHP/Library/Think/Image/Driver/Gd.class.php index 9ddc35548..2186f8f2e 100644 --- a/ThinkPHP/Library/Think/Image/Driver/Gd.class.php +++ b/ThinkPHP/Library/Think/Image/Driver/Gd.class.php @@ -44,7 +44,8 @@ public function __construct($imgname = null) public function open($imgname) { //检测图像文件 - if (!is_file($imgname)) { + //当本地文件时才判断如下if语句,否则如果是http外网图片时不判断 + if (substr($imgname, 0, 4) != 'http' && !is_file($imgname)) { E('不存在的图像文件'); } @@ -104,6 +105,11 @@ public function save($imgname, $type = null, $quality = 80, $interlace = true) imagejpeg($this->img, $imgname, $quality); } elseif ('gif' == $type && !empty($this->gif)) { $this->gif->save($imgname); + } elseif ('png' == $type) { + //设定保存完整的 alpha 通道信息 + imagesavealpha($this->img, true); + //ImagePNG生成图像的质量范围从0到9的 + imagepng($this->img, $imgname, $quality / 10); } else { $fun = 'image' . $type; $fun($this->img, $imgname); @@ -200,7 +206,10 @@ public function crop($w, $h, $x = 0, $y = 0, $width = null, $height = null) // 调整默认颜色 $color = imagecolorallocate($img, 255, 255, 255); imagefill($img, 0, 0, $color); - + //取消默认的混色模式(优化原来生成的png图片为非透明的BUG) + if ('png' == $this->info['type']) { + imagealphablending($img, false); + } //裁剪 imagecopyresampled($img, $this->img, 0, 0, $x, $y, $width, $height, $w, $h); imagedestroy($this->img); //销毁原图 @@ -306,7 +315,7 @@ public function thumb($width, $height, $type = Image::IMAGE_THUMB_SCALE) //裁剪 imagecopyresampled($img, $this->img, $posx, $posy, $x, $y, $neww, $newh, $w, $h); - imagedestroy($this->img); //销毁原图 + imagedestroy($this->img); //销毁原图 $this->img = $img; } while (!empty($this->gif) && $this->gifNext()); @@ -413,7 +422,7 @@ public function water($source, $locate = Image::IMAGE_WATER_SOUTHEAST, $alpha = break; default: - /* 自定义水印坐标 */ + /* 自定义水印坐标 */ if (is_array($locate)) { list($x, $y) = $locate; } else { @@ -526,7 +535,7 @@ public function text($text, $font, $size, $color = '#00000000', break; default: - /* 自定义文字坐标 */ + /* 自定义文字坐标 */ if (is_array($locate)) { list($posx, $posy) = $locate; $x += $posx; From d3c16c91fe86b14894ee0b99f5c8686f99563c5b Mon Sep 17 00:00:00 2001 From: ouzhigang Date: Wed, 28 Oct 2015 12:31:00 +0800 Subject: [PATCH 109/166] =?UTF-8?q?=E8=A7=A3=E5=86=B3MongoModel=E7=9A=84se?= =?UTF-8?q?lect=E6=96=B9=E6=B3=95=E4=B8=8D=E8=83=BD=E6=8E=92=E5=BA=8F?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Library/Think/Model/MongoModel.class.php | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/ThinkPHP/Library/Think/Model/MongoModel.class.php b/ThinkPHP/Library/Think/Model/MongoModel.class.php index 551b9461f..0b374f409 100644 --- a/ThinkPHP/Library/Think/Model/MongoModel.class.php +++ b/ThinkPHP/Library/Think/Model/MongoModel.class.php @@ -237,6 +237,44 @@ protected function _options_filter(&$options) } } + /** + * 查询多行数据 + * @access public + * @param mixed $options 表达式参数 + * @return mixed + */ + public function select($options = array()) { + if( is_numeric($options) || is_string($options)) { + $id = $this->getPk(); + $where[$id] = $options; + $options = array(); + $options['where'] = $where; + } + // 分析表达式 + $options = $this->_parseOptions($options); + $result = $this->db->select($options); + if(false === $result) { + return false; + } + + if(empty($result)) {// 查询结果为空 + return null; + } + else{ + $this->checkMongoId($result); + } + + //$result是以主键为key的,所以需要处理一下 + $data = array(); + foreach($result as $v) + $data[] = $v; + + $this->data = $data; + $this->_after_select($this->data, $options); + + return $this->data; + } + /** * 查询数据 * @access public From 0246cbca01c1485e55503dea11217c8d9e581f06 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Wed, 4 Nov 2015 18:20:09 +0800 Subject: [PATCH 110/166] =?UTF-8?q?=E6=94=B9=E8=BF=9B=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=BA=93=E9=A9=B1=E5=8A=A8=E7=B1=BB=E5=AF=B9order=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=E7=9A=84=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Db/Driver.class.php | 31 ++++++++++++++-------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/ThinkPHP/Library/Think/Db/Driver.class.php b/ThinkPHP/Library/Think/Db/Driver.class.php index 820ecc16f..f88de00a3 100644 --- a/ThinkPHP/Library/Think/Db/Driver.class.php +++ b/ThinkPHP/Library/Think/Db/Driver.class.php @@ -380,7 +380,7 @@ public function error() // 记录错误日志 trace($this->error, '', 'ERR'); if ($this->config['debug']) { -// 开启数据库调试模式 + // 开启数据库调试模式 E($this->error); } else { return $this->error; @@ -411,7 +411,7 @@ protected function parseSet($data) } elseif (is_null($val)) { $set[] = $this->parseKey($key) . '=NULL'; } elseif (is_scalar($val)) { -// 过滤非标量数据 + // 过滤非标量数据 if (0 === strpos($val, ':') && in_array($val, array_keys($this->bind))) { $set[] = $this->parseKey($key) . '=' . $this->escapeString($val); } else { @@ -509,7 +509,7 @@ protected function parseField($fields) protected function parseTable($tables) { if (is_array($tables)) { -// 支持别名定义 + // 支持别名定义 $array = array(); foreach ($tables as $table => $alias) { if (!is_numeric($table)) { @@ -604,7 +604,7 @@ protected function parseWhereItem($key, $val) // 比较运算 $whereStr .= $key . ' ' . $this->exp[$exp] . ' ' . $this->parseValue($val[1]); } elseif (preg_match('/^(notlike|like)$/', $exp)) { -// 模糊查找 + // 模糊查找 if (is_array($val[1])) { $likeLogic = isset($val[2]) ? strtoupper($val[2]) : 'OR'; if (in_array($likeLogic, array('AND', 'OR', 'XOR'))) { @@ -744,17 +744,26 @@ protected function parseJoin($join) */ protected function parseOrder($order) { + $array = array(); if (is_array($order)) { - $array = array(); foreach ($order as $key => $val) { if (is_numeric($key)) { $array[] = $this->parseKey($val); } else { - $array[] = $this->parseKey($key) . ' ' . $val; + $sort = in_array(strtolower($val), array('asc', 'desc')) ? ' ' . $val : ''; + $array[] = $this->parseKey($key) . $sort; + } + } + } else { + foreach (explode(',', $order) as $val) { + if (preg_match('/\s+(ASC|DESC)$/i', rtrim($val), $match, PREG_OFFSET_CAPTURE)) { + $array[] = $this->parseKey(ltrim(substr($val, 0, $match[0][1]))) . ' ' . $match[1][0]; + } else { + $array[] = $this->parseKey($val); } } - $order = implode(',', $array); } + $order = implode(',', $array); return !empty($order) ? ' ORDER BY ' . $order : ''; } @@ -984,7 +993,7 @@ public function update($data, $options) $table = $this->parseTable($options['table']); $sql = 'UPDATE ' . $table . $this->parseSet($data); if (strpos($table, ',')) { -// 多表更新支持JOIN操作 + // 多表更新支持JOIN操作 $sql .= $this->parseJoin(!empty($options['join']) ? $options['join'] : ''); } $sql .= $this->parseWhere(!empty($options['where']) ? $options['where'] : ''); @@ -1010,7 +1019,7 @@ public function delete($options = array()) $table = $this->parseTable($options['table']); $sql = 'DELETE FROM ' . $table; if (strpos($table, ',')) { -// 多表删除支持USING和JOIN操作 + // 多表删除支持USING和JOIN操作 if (!empty($options['using'])) { $sql .= ' USING ' . $this->parseTable($options['using']) . ' '; } @@ -1150,7 +1159,7 @@ public function setModel($model) protected function debug($start) { if ($this->config['debug']) { -// 开启数据库调试模式 + // 开启数据库调试模式 if ($start) { G('queryStartTime'); } else { @@ -1210,7 +1219,7 @@ protected function multiConnect($master = false) $r = $m; } else { if (is_numeric($this->config['slave_no'])) { -// 指定服务器读 + // 指定服务器读 $r = $this->config['slave_no']; } else { // 读操作连接从服务器 From 3a169e0427bff7935752926e50fcefc472889a58 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Wed, 4 Nov 2015 23:06:31 +0800 Subject: [PATCH 111/166] =?UTF-8?q?=E6=94=B9=E8=BF=9Bparseorder?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Common/functions.php | 16 ++++++++-------- ThinkPHP/Library/Think/Db/Driver.class.php | 6 ++++-- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/ThinkPHP/Common/functions.php b/ThinkPHP/Common/functions.php index 490da7049..d8e8770cf 100644 --- a/ThinkPHP/Common/functions.php +++ b/ThinkPHP/Common/functions.php @@ -332,16 +332,16 @@ function I($name, $default = '', $filter = null, $datas = null) break; case 'param': switch ($_SERVER['REQUEST_METHOD']) { - case 'POST': + case 'POST': $input = $_POST; break; - case 'PUT': + case 'PUT': if (is_null($_PUT)) { parse_str(file_get_contents('php://input'), $_PUT); } $input = $_PUT; break; - default: + default: $input = $_GET; } break; @@ -418,19 +418,19 @@ function I($name, $default = '', $filter = null, $datas = null) } if (!empty($type)) { switch (strtolower($type)) { - case 'a': // 数组 + case 'a': // 数组 $data = (array) $data; break; - case 'd': // 数字 + case 'd': // 数字 $data = (int) $data; break; - case 'f': // 浮点 + case 'f': // 浮点 $data = (float) $data; break; - case 'b': // 布尔 + case 'b': // 布尔 $data = (boolean) $data; break; - case 's':// 字符串 + case 's': // 字符串 default: $data = (string) $data; } diff --git a/ThinkPHP/Library/Think/Db/Driver.class.php b/ThinkPHP/Library/Think/Db/Driver.class.php index f88de00a3..f09249753 100644 --- a/ThinkPHP/Library/Think/Db/Driver.class.php +++ b/ThinkPHP/Library/Think/Db/Driver.class.php @@ -748,7 +748,9 @@ protected function parseOrder($order) if (is_array($order)) { foreach ($order as $key => $val) { if (is_numeric($key)) { - $array[] = $this->parseKey($val); + if (false === strpos($val, '(')) { + $array[] = $this->parseKey($val); + } } else { $sort = in_array(strtolower($val), array('asc', 'desc')) ? ' ' . $val : ''; $array[] = $this->parseKey($key) . $sort; @@ -758,7 +760,7 @@ protected function parseOrder($order) foreach (explode(',', $order) as $val) { if (preg_match('/\s+(ASC|DESC)$/i', rtrim($val), $match, PREG_OFFSET_CAPTURE)) { $array[] = $this->parseKey(ltrim(substr($val, 0, $match[0][1]))) . ' ' . $match[1][0]; - } else { + } elseif (false === strpos($val, '(')) { $array[] = $this->parseKey($val); } } From 4460d0d6aa8bc3a6269e145d5ab319b144aa13a9 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Wed, 4 Nov 2015 23:38:11 +0800 Subject: [PATCH 112/166] =?UTF-8?q?=E5=AE=8C=E5=96=84parseLimit=E6=96=B9?= =?UTF-8?q?=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Db/Driver.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ThinkPHP/Library/Think/Db/Driver.class.php b/ThinkPHP/Library/Think/Db/Driver.class.php index f09249753..13fbc1765 100644 --- a/ThinkPHP/Library/Think/Db/Driver.class.php +++ b/ThinkPHP/Library/Think/Db/Driver.class.php @@ -718,7 +718,7 @@ protected function parseThinkWhere($key, $val) */ protected function parseLimit($limit) { - return !empty($limit) ? ' LIMIT ' . $limit . ' ' : ''; + return (!empty($limit) && false === strpos($limit, '(')) ? ' LIMIT ' . $limit . ' ' : ''; } /** From 9e31fef805af3734347ce9e8283bfe2b56960bdc Mon Sep 17 00:00:00 2001 From: thinkphp Date: Thu, 5 Nov 2015 17:48:02 +0800 Subject: [PATCH 113/166] =?UTF-8?q?=E6=94=B9=E8=BF=9Bparseorder=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E4=B8=BA=E7=A9=BA=E7=9A=84=E6=83=85=E5=86=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Db/Driver.class.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ThinkPHP/Library/Think/Db/Driver.class.php b/ThinkPHP/Library/Think/Db/Driver.class.php index 13fbc1765..9ed7c3339 100644 --- a/ThinkPHP/Library/Think/Db/Driver.class.php +++ b/ThinkPHP/Library/Think/Db/Driver.class.php @@ -745,6 +745,9 @@ protected function parseJoin($join) protected function parseOrder($order) { $array = array(); + if (empty($order)) { + return ''; + } if (is_array($order)) { foreach ($order as $key => $val) { if (is_numeric($key)) { From 081bb8c192203991f96e8546033e96139511d065 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Thu, 5 Nov 2015 17:51:46 +0800 Subject: [PATCH 114/166] =?UTF-8?q?=E6=94=B9=E8=BF=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Db/Driver.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ThinkPHP/Library/Think/Db/Driver.class.php b/ThinkPHP/Library/Think/Db/Driver.class.php index 9ed7c3339..7e3e332ed 100644 --- a/ThinkPHP/Library/Think/Db/Driver.class.php +++ b/ThinkPHP/Library/Think/Db/Driver.class.php @@ -744,10 +744,10 @@ protected function parseJoin($join) */ protected function parseOrder($order) { - $array = array(); if (empty($order)) { return ''; } + $array = array(); if (is_array($order)) { foreach ($order as $key => $val) { if (is_numeric($key)) { From 21cffd0a0c680f7833f25154435d15af10b533da Mon Sep 17 00:00:00 2001 From: thinkphp Date: Fri, 6 Nov 2015 21:39:13 +0800 Subject: [PATCH 115/166] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E8=A7=86=E5=9B=BE?= =?UTF-8?q?=E6=A8=A1=E5=9E=8B=E6=89=A9=E5=B1=95=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Model/ViewModel.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ThinkPHP/Library/Think/Model/ViewModel.class.php b/ThinkPHP/Library/Think/Model/ViewModel.class.php index bfc494435..94f2599f6 100644 --- a/ThinkPHP/Library/Think/Model/ViewModel.class.php +++ b/ThinkPHP/Library/Think/Model/ViewModel.class.php @@ -45,7 +45,7 @@ public function getTableName() $prefix = $this->tablePrefix; $tableName = preg_replace_callback("/__([A-Z_-]+)__/sU", function ($match) use ($prefix) {return $prefix . strtolower($match[1]);}, $tableName); } else { - $class = $key . 'Model'; + $class = parse_res_name($key, C('DEFAULT_M_LAYER')); $Model = class_exists($class) ? new $class() : M($key); $tableName .= $Model->getTableName(); } @@ -102,7 +102,7 @@ protected function _options_filter(&$options) private function _checkFields($name, $fields) { if (false !== $pos = array_search('*', $fields)) { -// 定义所有字段 + // 定义所有字段 $fields = array_merge($fields, M($name)->getDbFields()); unset($fields[$pos]); } From 4e01aee556a24fc1a7cde63b949f931dfcf084e1 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Fri, 6 Nov 2015 21:45:49 +0800 Subject: [PATCH 116/166] =?UTF-8?q?=E6=94=B9=E8=BF=9B=E8=A7=86=E5=9B=BE?= =?UTF-8?q?=E6=A8=A1=E5=9E=8B=E7=9A=84checkCondition=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Model/ViewModel.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ThinkPHP/Library/Think/Model/ViewModel.class.php b/ThinkPHP/Library/Think/Model/ViewModel.class.php index 94f2599f6..fb455740f 100644 --- a/ThinkPHP/Library/Think/Model/ViewModel.class.php +++ b/ThinkPHP/Library/Think/Model/ViewModel.class.php @@ -132,7 +132,7 @@ protected function checkCondition($where) } } } - $where = array_merge($where, $view); + $where = array_merge($view, array_diff_key(array_merge($where, $view), $view)); } return $where; } From 4f8326c84a475f0fbf3ced3ea824b4009980c72a Mon Sep 17 00:00:00 2001 From: thinkphp Date: Fri, 6 Nov 2015 22:13:51 +0800 Subject: [PATCH 117/166] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=BA=93=E9=9A=8F=E6=9C=BA=E6=8E=92=E5=BA=8F=E6=94=AF=E6=8C=81?= =?UTF-8?q?=20=E7=94=A8=E6=B3=95=20order('[RAND]')?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Db/Driver.class.php | 3 +++ ThinkPHP/Library/Think/Db/Driver/Firebird.class.php | 11 +++++++++++ ThinkPHP/Library/Think/Db/Driver/Mysql.class.php | 10 ++++++++++ ThinkPHP/Library/Think/Db/Driver/Oracle.class.php | 10 ++++++++++ ThinkPHP/Library/Think/Db/Driver/Pgsql.class.php | 9 +++++++++ ThinkPHP/Library/Think/Db/Driver/Sqlite.class.php | 10 ++++++++++ 6 files changed, 53 insertions(+) diff --git a/ThinkPHP/Library/Think/Db/Driver.class.php b/ThinkPHP/Library/Think/Db/Driver.class.php index 7e3e332ed..b57ede541 100644 --- a/ThinkPHP/Library/Think/Db/Driver.class.php +++ b/ThinkPHP/Library/Think/Db/Driver.class.php @@ -759,6 +759,9 @@ protected function parseOrder($order) $array[] = $this->parseKey($key) . $sort; } } + } elseif ('[RAND]' == $order) { + // 随机排序 + $array[] = $this->parseRand(); } else { foreach (explode(',', $order) as $val) { if (preg_match('/\s+(ASC|DESC)$/i', rtrim($val), $match, PREG_OFFSET_CAPTURE)) { diff --git a/ThinkPHP/Library/Think/Db/Driver/Firebird.class.php b/ThinkPHP/Library/Think/Db/Driver/Firebird.class.php index 56a01f043..3a2987b04 100644 --- a/ThinkPHP/Library/Think/Db/Driver/Firebird.class.php +++ b/ThinkPHP/Library/Think/Db/Driver/Firebird.class.php @@ -162,4 +162,15 @@ public function parseLimit($limit) } return $limitStr; } + + /** + * 随机排序 + * @access protected + * @return string + */ + protected function parseRand() + { + return 'rand()'; + } + } diff --git a/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php b/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php index b999ff782..975d6c933 100644 --- a/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php +++ b/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php @@ -107,6 +107,16 @@ protected function parseKey(&$key) return $key; } + /** + * 随机排序 + * @access protected + * @return string + */ + protected function parseRand() + { + return 'rand()'; + } + /** * 批量插入记录 * @access public diff --git a/ThinkPHP/Library/Think/Db/Driver/Oracle.class.php b/ThinkPHP/Library/Think/Db/Driver/Oracle.class.php index 6059ad66a..84152e3f5 100644 --- a/ThinkPHP/Library/Think/Db/Driver/Oracle.class.php +++ b/ThinkPHP/Library/Think/Db/Driver/Oracle.class.php @@ -185,4 +185,14 @@ protected function parseLock($lock = false) return ' FOR UPDATE NOWAIT '; } + + /** + * 随机排序 + * @access protected + * @return string + */ + protected function parseRand() + { + return 'DBMS_RANDOM.value'; + } } diff --git a/ThinkPHP/Library/Think/Db/Driver/Pgsql.class.php b/ThinkPHP/Library/Think/Db/Driver/Pgsql.class.php index 0b27cbf18..4ab97d917 100644 --- a/ThinkPHP/Library/Think/Db/Driver/Pgsql.class.php +++ b/ThinkPHP/Library/Think/Db/Driver/Pgsql.class.php @@ -94,4 +94,13 @@ public function parseLimit($limit) return $limitStr; } + /** + * 随机排序 + * @access protected + * @return string + */ + protected function parseRand() + { + return 'RANDOM()'; + } } diff --git a/ThinkPHP/Library/Think/Db/Driver/Sqlite.class.php b/ThinkPHP/Library/Think/Db/Driver/Sqlite.class.php index 1bfb6190a..b413100df 100644 --- a/ThinkPHP/Library/Think/Db/Driver/Sqlite.class.php +++ b/ThinkPHP/Library/Think/Db/Driver/Sqlite.class.php @@ -102,4 +102,14 @@ public function parseLimit($limit) } return $limitStr; } + + /** + * 随机排序 + * @access protected + * @return string + */ + protected function parseRand() + { + return 'RANDOM()'; + } } From a0de9c1929018b6c1f72bf84a5a7c2cb6c1170a2 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Sat, 7 Nov 2015 20:58:46 +0800 Subject: [PATCH 118/166] =?UTF-8?q?=E4=BF=AE=E6=AD=A3pgsql=E9=A9=B1?= =?UTF-8?q?=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Db/Driver/Pgsql.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ThinkPHP/Library/Think/Db/Driver/Pgsql.class.php b/ThinkPHP/Library/Think/Db/Driver/Pgsql.class.php index 4ab97d917..f887c742e 100644 --- a/ThinkPHP/Library/Think/Db/Driver/Pgsql.class.php +++ b/ThinkPHP/Library/Think/Db/Driver/Pgsql.class.php @@ -42,7 +42,7 @@ protected function parseDsn($config) public function getFields($tableName) { list($tableName) = explode(' ', $tableName); - $result = $this->query('select fields_name as "field",fields_type as "type",fields_not_null as "null",fields_key_name as "key",fields_default as "default",fields_default as "extra" from table_msg(' . $tableName . ');'); + $result = $this->query('select fields_name as "field",fields_type as "type",fields_not_null as "null",fields_key_name as "key",fields_default as "default",fields_default as "extra" from table_msg(\'' . $tableName . '\');'); $info = array(); if ($result) { foreach ($result as $key => $val) { From de9ae5fac3f09cfb53283eb3db047916a8a049cf Mon Sep 17 00:00:00 2001 From: ouzhigang Date: Sat, 14 Nov 2015 21:50:03 +0800 Subject: [PATCH 119/166] =?UTF-8?q?=E8=A7=A3=E5=86=B3MongoModel=E7=9A=84se?= =?UTF-8?q?lect=E6=96=B9=E6=B3=95=E4=B8=8D=E8=83=BD=E6=8E=92=E5=BA=8F?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Library/Think/Model/MongoModel.class.php | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/ThinkPHP/Library/Think/Model/MongoModel.class.php b/ThinkPHP/Library/Think/Model/MongoModel.class.php index 0b374f409..c1e9f6015 100644 --- a/ThinkPHP/Library/Think/Model/MongoModel.class.php +++ b/ThinkPHP/Library/Think/Model/MongoModel.class.php @@ -243,37 +243,37 @@ protected function _options_filter(&$options) * @param mixed $options 表达式参数 * @return mixed */ - public function select($options = array()) { - if( is_numeric($options) || is_string($options)) { - $id = $this->getPk(); - $where[$id] = $options; - $options = array(); + public function select($options = array()) + { + if (is_numeric($options) || is_string($options)) { + $id = $this->getPk(); + $where[$id] = $options; + $options = array(); $options['where'] = $where; - } + } // 分析表达式 $options = $this->_parseOptions($options); - $result = $this->db->select($options); - if(false === $result) { + $result = $this->db->select($options); + if (false === $result) { return false; } - if(empty($result)) {// 查询结果为空 + if (empty($result)) { + // 查询结果为空 return null; - } - else{ + } else { $this->checkMongoId($result); } //$result是以主键为key的,所以需要处理一下 $data = array(); - foreach($result as $v) - $data[] = $v; + foreach ($result as $v) + $data[] = $v; $this->data = $data; - $this->_after_select($this->data, $options); - + $this->_after_select($this->data, $options); return $this->data; - } + } /** * 查询数据 From f359efebd61a8b0e33c0d3fadd7bf876f6bf9932 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Thu, 19 Nov 2015 21:54:49 +0800 Subject: [PATCH 120/166] =?UTF-8?q?=E6=94=B9=E8=BF=9BI=E5=87=BD=E6=95=B0?= =?UTF-8?q?=E5=AE=8C=E5=96=84=E5=A4=9A=E4=B8=AA=E5=87=BD=E6=95=B0=E7=9A=84?= =?UTF-8?q?=E8=BF=87=E6=BB=A4=E7=9A=84=E7=A9=BA=E6=A0=BC=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Common/functions.php | 1 + 1 file changed, 1 insertion(+) diff --git a/ThinkPHP/Common/functions.php b/ThinkPHP/Common/functions.php index d8e8770cf..f91d29445 100644 --- a/ThinkPHP/Common/functions.php +++ b/ThinkPHP/Common/functions.php @@ -405,6 +405,7 @@ function I($name, $default = '', $filter = null, $datas = null) if (is_array($filters)) { foreach ($filters as $filter) { + $filter = trim($filter); if (function_exists($filter)) { $data = is_array($data) ? array_map_recursive($filter, $data) : $filter($data); // 参数过滤 } else { From 70e3097a1e34be8dbde7b2495d45b611c87b8cef Mon Sep 17 00:00:00 2001 From: thinkphp Date: Wed, 25 Nov 2015 17:18:38 +0800 Subject: [PATCH 121/166] =?UTF-8?q?=E6=94=B9=E8=BF=9Bload=5Fext=5Ffile(COM?= =?UTF-8?q?MON=5FPATH)=E7=9A=84=E4=BD=8D=E7=BD=AE=20=E9=81=BF=E5=85=8D?= =?UTF-8?q?=E5=9B=A0=E5=AE=9A=E4=B9=89=E4=BA=86=E6=89=A9=E5=B1=95=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E8=80=8Capp=5Finit=E9=92=A9=E5=AD=90=E8=AF=BB?= =?UTF-8?q?=E5=8F=96=E4=B8=8D=E5=88=B0=E7=9A=84=E6=83=85=E5=86=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/App.class.php | 5 ++-- .../Library/Think/Model/MongoModel.class.php | 24 ++++++++++--------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/ThinkPHP/Library/Think/App.class.php b/ThinkPHP/Library/Think/App.class.php index 53b3d8773..60e09d0a2 100644 --- a/ThinkPHP/Library/Think/App.class.php +++ b/ThinkPHP/Library/Think/App.class.php @@ -24,9 +24,6 @@ class App */ public static function init() { - // 加载动态应用公共文件和配置 - load_ext_file(COMMON_PATH); - // 日志目录转换为绝对路径 默认情况下存储到公共模块下面 C('LOG_PATH', realpath(LOG_PATH) . '/Common/'); @@ -200,6 +197,8 @@ public static function invokeAction($module, $action) */ public static function run() { + // 加载动态应用公共文件和配置 + load_ext_file(COMMON_PATH); // 应用初始化标签 Hook::listen('app_init'); App::init(); diff --git a/ThinkPHP/Library/Think/Model/MongoModel.class.php b/ThinkPHP/Library/Think/Model/MongoModel.class.php index 0b374f409..67afdb481 100644 --- a/ThinkPHP/Library/Think/Model/MongoModel.class.php +++ b/ThinkPHP/Library/Think/Model/MongoModel.class.php @@ -237,19 +237,20 @@ protected function _options_filter(&$options) } } - /** + /** * 查询多行数据 * @access public * @param mixed $options 表达式参数 * @return mixed */ - public function select($options = array()) { - if( is_numeric($options) || is_string($options)) { - $id = $this->getPk(); + public function select($options = array()) + { + if( is_numeric($options) || is_string($options)) { + $id = $this->getPk(); $where[$id] = $options; $options = array(); $options['where'] = $where; - } + } // 分析表达式 $options = $this->_parseOptions($options); $result = $this->db->select($options); @@ -266,15 +267,16 @@ public function select($options = array()) { //$result是以主键为key的,所以需要处理一下 $data = array(); - foreach($result as $v) - $data[] = $v; + foreach($result as $v){ + $data[] = $v; + } $this->data = $data; $this->_after_select($this->data, $options); return $this->data; - } - + } + /** * 查询数据 * @access public @@ -296,7 +298,7 @@ public function find($options = array()) return false; } if (empty($result)) { -// 查询结果为空 + // 查询结果为空 return null; } else { $this->checkMongoId($result); @@ -368,7 +370,7 @@ public function getField($field, $sepa = null) } else { // 返回数据个数 if (true !== $sepa) { -// 当sepa指定为true的时候 返回所有数据 + // 当sepa指定为true的时候 返回所有数据 $options['limit'] = is_numeric($sepa) ? $sepa : 1; } // 查找符合的记录 $result = $this->db->select($options); From 660aba5795be59f6d1d8fc64d020a80b0728a3e8 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Thu, 26 Nov 2015 11:10:06 +0800 Subject: [PATCH 122/166] =?UTF-8?q?=E6=94=B9=E8=BF=9BRedis=E9=A9=B1?= =?UTF-8?q?=E5=8A=A8=E6=94=AF=E6=8C=81=E5=AF=86=E7=A0=81=E8=BF=9E=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Cache/Driver/Redis.class.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ThinkPHP/Library/Think/Cache/Driver/Redis.class.php b/ThinkPHP/Library/Think/Cache/Driver/Redis.class.php index eaca5ee3f..b0bb97f0c 100644 --- a/ThinkPHP/Library/Think/Cache/Driver/Redis.class.php +++ b/ThinkPHP/Library/Think/Cache/Driver/Redis.class.php @@ -31,6 +31,7 @@ public function __construct($options = array()) $options = array_merge(array( 'host' => C('REDIS_HOST') ?: '127.0.0.1', 'port' => C('REDIS_PORT') ?: 6379, + 'password' => C('REDIS_PASSWORD') ?: '', 'timeout' => C('DATA_CACHE_TIMEOUT') ?: false, 'persistent' => false, ), $options); @@ -40,9 +41,13 @@ public function __construct($options = array()) $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; false === $options['timeout'] ? + $this->handler = new \Redis; + false === $options['timeout'] ? $this->handler->$func($options['host'], $options['port']) : $this->handler->$func($options['host'], $options['port'], $options['timeout']); + if ('' != $options['password']) { + $this->handler->auth($options['password']); + } } /** From b73b2a26014f4704b8d0c20c000f0c7b15e0064c Mon Sep 17 00:00:00 2001 From: thinkphp Date: Fri, 27 Nov 2015 12:20:12 +0800 Subject: [PATCH 123/166] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E5=AD=90=E5=9F=9F?= =?UTF-8?q?=E5=90=8D=E9=83=A8=E7=BD=B2=E7=BB=91=E5=AE=9A=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=E5=92=8C=E5=85=A5=E5=8F=A3=E6=96=87=E4=BB=B6=E4=B8=AD=E7=9A=84?= =?UTF-8?q?=E7=BB=91=E5=AE=9A=E6=A8=A1=E5=9D=97=E5=8F=AF=E8=83=BD=E5=86=B2?= =?UTF-8?q?=E7=AA=81=E7=9A=84=E8=AD=A6=E5=91=8A=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Dispatcher.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ThinkPHP/Library/Think/Dispatcher.class.php b/ThinkPHP/Library/Think/Dispatcher.class.php index a276e4ea4..ffb5b901f 100644 --- a/ThinkPHP/Library/Think/Dispatcher.class.php +++ b/ThinkPHP/Library/Think/Dispatcher.class.php @@ -84,11 +84,11 @@ public static function dispatch() } $array = explode('/', $rule); // 模块绑定 - define('BIND_MODULE', array_shift($array)); + defined('BIND_MODULE') or define('BIND_MODULE', array_shift($array)); // 控制器绑定 if (!empty($array)) { $controller = array_shift($array); - if ($controller) { + if ($controller && !defined('BIND_MODULE')) { define('BIND_CONTROLLER', $controller); } } From 999bbf7df3fb03df8b7cafada864dcf560d7bf58 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Sat, 28 Nov 2015 15:33:30 +0800 Subject: [PATCH 124/166] =?UTF-8?q?=E6=94=B9=E8=BF=9Bsqlite=E9=A9=B1?= =?UTF-8?q?=E5=8A=A8getFields=E6=96=B9=E6=B3=95=E6=94=AF=E6=8C=81sqlite3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Db/Driver/Sqlite.class.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ThinkPHP/Library/Think/Db/Driver/Sqlite.class.php b/ThinkPHP/Library/Think/Db/Driver/Sqlite.class.php index b413100df..24cb6ccdf 100644 --- a/ThinkPHP/Library/Think/Db/Driver/Sqlite.class.php +++ b/ThinkPHP/Library/Think/Db/Driver/Sqlite.class.php @@ -43,13 +43,13 @@ public function getFields($tableName) $info = array(); if ($result) { foreach ($result as $key => $val) { - $info[$val['field']] = array( - 'name' => $val['field'], + $info[$val['name']] = array( + 'name' => $val['name'], 'type' => $val['type'], - 'notnull' => (bool) ('' === $val['null']), // not null is empty, null is yes - 'default' => $val['default'], - 'primary' => (strtolower($val['dey']) == 'pri'), - 'autoinc' => (strtolower($val['extra']) == 'auto_increment'), + 'notnull' => (bool) (1 === $val['notnull']), + 'default' => $val['dflt_value'], + 'primary' => '1' == $val['pk'], + 'autoinc' => false, ); } } From d63b78ad3f4a7b44d2e4634a2e7621d1dd8d47b0 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Mon, 30 Nov 2015 17:38:42 +0800 Subject: [PATCH 125/166] =?UTF-8?q?=E5=A2=9E=E5=8A=A0master=E8=BF=9E?= =?UTF-8?q?=E8=B4=AF=E6=93=8D=E4=BD=9C=E6=96=B9=E6=B3=95=20=E5=8F=AF?= =?UTF-8?q?=E4=BB=A5=E6=94=AF=E6=8C=81=E4=B8=BB=E4=BB=8E=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=BA=93=E7=9A=84=E4=B8=BB=E5=BA=93=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Db/Driver.class.php | 7 ++++--- ThinkPHP/Library/Think/Model.class.php | 7 +------ 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/ThinkPHP/Library/Think/Db/Driver.class.php b/ThinkPHP/Library/Think/Db/Driver.class.php index b57ede541..09b251fbd 100644 --- a/ThinkPHP/Library/Think/Db/Driver.class.php +++ b/ThinkPHP/Library/Think/Db/Driver.class.php @@ -142,11 +142,12 @@ public function free() * @access public * @param string $str sql指令 * @param boolean $fetchSql 不执行只是获取SQL + * @param boolean $master 是否在主服务器读操作 * @return mixed */ - public function query($str, $fetchSql = false) + public function query($str, $fetchSql = false, $master = false) { - $this->initConnect(false); + $this->initConnect($master); if (!$this->_linkID) { return false; } @@ -1054,7 +1055,7 @@ public function select($options = array()) $this->model = $options['model']; $this->parseBind(!empty($options['bind']) ? $options['bind'] : array()); $sql = $this->buildSelectSql($options); - $result = $this->query($sql, !empty($options['fetch_sql']) ? true : false); + $result = $this->query($sql, !empty($options['fetch_sql']) ? true : false, !empty($options['master']) ? true : false); return $result; } diff --git a/ThinkPHP/Library/Think/Model.class.php b/ThinkPHP/Library/Think/Model.class.php index 4382390d5..4de19f3a6 100644 --- a/ThinkPHP/Library/Think/Model.class.php +++ b/ThinkPHP/Library/Think/Model.class.php @@ -61,7 +61,7 @@ class Model // 是否批处理验证 protected $patchValidate = false; // 链操作方法列表 - protected $methods = array('strict', 'order', 'alias', 'having', 'group', 'lock', 'distinct', 'auto', 'filter', 'validate', 'result', 'token', 'index', 'force'); + protected $methods = array('strict', 'order', 'alias', 'having', 'group', 'lock', 'distinct', 'auto', 'filter', 'validate', 'result', 'token', 'index', 'force', 'master'); /** * 架构函数 @@ -708,11 +708,6 @@ protected function _parseOptions($options = array()) if (is_scalar($val)) { $this->_parseType($options['where'], $key); } - } elseif (!is_numeric($key) && '_' != substr($key, 0, 1) && false === strpos($key, '.') && false === strpos($key, '(') && false === strpos($key, '|') && false === strpos($key, '&')) { - if (!empty($this->options['strict'])) { - E(L('_ERROR_QUERY_EXPRESS_') . ':[' . $key . '=>' . $val . ']'); - } - unset($options['where'][$key]); } } } From f7de0f724a2073f5a535e9a4076ddffa573c4196 Mon Sep 17 00:00:00 2001 From: ouzhigang Date: Thu, 3 Dec 2015 10:36:16 +0800 Subject: [PATCH 126/166] =?UTF-8?q?=E4=BF=AE=E6=AD=A3sqlite=E4=B8=8B?= =?UTF-8?q?=E8=8E=B7=E5=8F=96=E5=AD=97=E6=AE=B5=E5=AD=98=E5=9C=A8=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Db/Driver/Sqlite.class.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ThinkPHP/Library/Think/Db/Driver/Sqlite.class.php b/ThinkPHP/Library/Think/Db/Driver/Sqlite.class.php index b413100df..2e57c15f6 100644 --- a/ThinkPHP/Library/Think/Db/Driver/Sqlite.class.php +++ b/ThinkPHP/Library/Think/Db/Driver/Sqlite.class.php @@ -43,13 +43,13 @@ public function getFields($tableName) $info = array(); if ($result) { foreach ($result as $key => $val) { - $info[$val['field']] = array( - 'name' => $val['field'], + $info[$val['name']] = array( + 'name' => $val['name'], 'type' => $val['type'], - 'notnull' => (bool) ('' === $val['null']), // not null is empty, null is yes - 'default' => $val['default'], - 'primary' => (strtolower($val['dey']) == 'pri'), - 'autoinc' => (strtolower($val['extra']) == 'auto_increment'), + 'notnull' => boolval($val['notnull']), // not null is empty, null is yes + 'default' => $val['dflt_value'], + 'primary' => boolval($val['pk']), //sqlite3下autoinc必须是主键,而主键又不能重复指派的,所以下面的autoinc值也是$val['pk'] + 'autoinc' => boolval($val['pk']), ); } } From fc8c42f855c53015436026dfaf523feffb16bf30 Mon Sep 17 00:00:00 2001 From: Geeker Wang Date: Sun, 13 Dec 2015 17:14:30 +0800 Subject: [PATCH 127/166] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E2=80=98PARSE=5FVAR?= =?UTF-8?q?=E2=80=99=E4=BE=BF=E4=BA=8E=E5=9C=A8debug=E4=B8=8B=E5=9C=A8?= =?UTF-8?q?=E6=B5=8F=E8=A7=88=E5=99=A8=E6=8E=A7=E5=88=B6=E5=8F=B0=E4=B8=AD?= =?UTF-8?q?=E6=9F=A5=E7=9C=8B=E9=A1=B5=E9=9D=A2=E8=BE=93=E5=87=BA=E5=8F=98?= =?UTF-8?q?=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在开发时(debug),为了便于前端程序员查看后端PHP分配过来的变量,将后台thinkPHP通过assign分配过来的变量以json对象形式放在页面中。 前端程序员可以在浏览器中通过输入:PARSE_VAR 来查看PHP分配给页面的变量。 --- ThinkPHP/Library/Think/View.class.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ThinkPHP/Library/Think/View.class.php b/ThinkPHP/Library/Think/View.class.php index b5731bbc3..f6c5836c6 100644 --- a/ThinkPHP/Library/Think/View.class.php +++ b/ThinkPHP/Library/Think/View.class.php @@ -146,6 +146,10 @@ public function fetch($templateFile = '', $content = '', $prefix = '') $content = ob_get_clean(); // 内容过滤标签 Hook::listen('view_filter', $content); + if(APP_DEBUG){ // debug模式时,将后台分配变量输出到浏览器控制台 + $parseVar = empty($this->tVar) ? json_encode(array()) : json_encode($this->tVar); + $content = $content.''; + } // 输出模板文件 return $content; } From d8a2cafb90eeda8f80c24613d1b8f5ba9f1da357 Mon Sep 17 00:00:00 2001 From: xiaohome Date: Fri, 25 Dec 2015 20:34:22 +0800 Subject: [PATCH 128/166] =?UTF-8?q?=E5=88=A0=E9=99=A4=E4=B8=AD=E5=9B=BD=20?= =?UTF-8?q?=E6=BA=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- composer.json | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/composer.json b/composer.json index fd56d75fa..5154e2e0e 100644 --- a/composer.json +++ b/composer.json @@ -14,9 +14,5 @@ "require": { "php": ">=5.3.0" }, - "minimum-stability": "dev", - "repositories": [ - {"type": "composer", "url": "http://packagist.phpcomposer.com"}, - {"packagist": false} - ] + "minimum-stability": "dev" } From 9c76972ba7b395fdc5c9ce5e5bf52696cf8bade4 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Tue, 29 Dec 2015 16:00:25 +0800 Subject: [PATCH 129/166] =?UTF-8?q?=E6=94=B9=E8=BF=9Bmodel=E7=B1=BB?= =?UTF-8?q?=E7=9A=84lazyWrite=E6=96=B9=E6=B3=95=20=E9=81=BF=E5=85=8D?= =?UTF-8?q?=E5=8F=97=E7=BC=93=E5=AD=98=E6=9C=89=E6=95=88=E6=9C=9F=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE=E5=BD=B1=E5=93=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Model.class.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ThinkPHP/Library/Think/Model.class.php b/ThinkPHP/Library/Think/Model.class.php index 4de19f3a6..897c72d7e 100644 --- a/ThinkPHP/Library/Think/Model.class.php +++ b/ThinkPHP/Library/Think/Model.class.php @@ -972,14 +972,14 @@ protected function lazyWrite($guid, $step, $lazyTime) return $value + $step; } else { // 追加数据到缓存 - S($guid, $value + $step); + S($guid, $value + $step, 0); return false; } } else { // 没有缓存数据 - S($guid, $step); + S($guid, $step, 0); // 计时开始 - S($guid . '_time', NOW_TIME); + S($guid . '_time', NOW_TIME, 0); return false; } } From 2f2b5b2b766fc1ae8fed682a1def0b634d3fc2e4 Mon Sep 17 00:00:00 2001 From: oldrind <1401019000@qq.com> Date: Sat, 9 Jan 2016 20:02:20 +0800 Subject: [PATCH 130/166] =?UTF-8?q?=E6=94=B9=E8=BF=9B=E8=B7=AF=E7=94=B1?= =?UTF-8?q?=EF=BC=8C=E6=94=AF=E6=8C=81=E6=8C=89=E8=B7=AF=E7=94=B1=E7=94=9F?= =?UTF-8?q?=E6=88=90url=E5=9C=B0=E5=9D=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Common/functions.php | 33 +- ThinkPHP/Library/Think/Dispatcher.class.php | 208 ++++--- ThinkPHP/Library/Think/Route.class.php | 615 ++++++++++++-------- 3 files changed, 519 insertions(+), 337 deletions(-) diff --git a/ThinkPHP/Common/functions.php b/ThinkPHP/Common/functions.php index f91d29445..c81f9bddd 100644 --- a/ThinkPHP/Common/functions.php +++ b/ThinkPHP/Common/functions.php @@ -1014,7 +1014,7 @@ function U($url = '', $vars = '', $suffix = true, $domain = false) // aaa=1&bbb=2 转换成数组 parse_str($vars, $vars); } elseif (!is_array($vars)) { - $vars = array(); + $vars = []; } if (isset($info['query'])) { // 解析地址里面参数 合并到vars @@ -1041,7 +1041,7 @@ function U($url = '', $vars = '', $suffix = true, $domain = false) // 解析模块、控制器和操作 $url = trim($url, $depr); $path = explode($depr, $url); - $var = array(); + $var = []; $varModule = C('VAR_MODULE'); $varController = C('VAR_CONTROLLER'); $varAction = C('VAR_ACTION'); @@ -1068,7 +1068,17 @@ function U($url = '', $vars = '', $suffix = true, $domain = false) if (!empty($path)) { $var[$varModule] = implode($depr, $path); } else { - if (C('MULTI_MODULE')) { + // 如果为插件,自动转换路径 + if (CONTROLLER_PATH) { + $var[$varModule] = MODULE_NAME; + $varAddon = C('VAR_ADDON'); + if (MODULE_NAME != C('DEFAULT_MODULE')) { + $var[$varController] = MODULE_NAME; + } + + $vars = array_merge([$varAddon => CONTROLLER_PATH], $vars); + + } elseif (C('MULTI_MODULE')) { if (MODULE_NAME != C('DEFAULT_MODULE') || !C('MODULE_ALLOW_LIST')) { $var[$varModule] = MODULE_NAME; } @@ -1080,14 +1090,14 @@ function U($url = '', $vars = '', $suffix = true, $domain = false) } } if (isset($var[$varModule])) { - $module = $var[$varModule]; + $module = defined('BIND_MODULE') && BIND_MODULE == $module ? '' : $var[$varModule]; unset($var[$varModule]); } } } - if (C('URL_MODEL') == 0) { + if (0 == C('URL_MODEL')) { // 普通模式URL转换 $url = __APP__ . '?' . C('VAR_MODULE') . "={$module}&" . http_build_query(array_reverse($var)); if ($urlCase) { @@ -1102,8 +1112,16 @@ function U($url = '', $vars = '', $suffix = true, $domain = false) if (isset($route)) { $url = __APP__ . '/' . rtrim($url, $depr); } else { - $module = (defined('BIND_MODULE') && BIND_MODULE == $module) ? '' : $module; - $url = __APP__ . '/' . ($module ? $module . MODULE_PATHINFO_DEPR : '') . implode($depr, array_reverse($var)); + $path = implode($depr, array_reverse($var)); + if (C('URL_ROUTER_ON')) { + $url = Think\Route::reverse($path, $vars, $depr, $suffix); + if (!$url) { + $url = $path; + } + } else { + $url = $path; + } + $url = __APP__ . '/' . ($module ? $module . MODULE_PATHINFO_DEPR : '') . $url; } if ($urlCase) { $url = strtolower($url); @@ -1114,7 +1132,6 @@ function U($url = '', $vars = '', $suffix = true, $domain = false) if ('' !== trim($val)) { $url .= $depr . $var . $depr . urlencode($val); } - } } if ($suffix) { diff --git a/ThinkPHP/Library/Think/Dispatcher.class.php b/ThinkPHP/Library/Think/Dispatcher.class.php index ffb5b901f..8d8376b63 100644 --- a/ThinkPHP/Library/Think/Dispatcher.class.php +++ b/ThinkPHP/Library/Think/Dispatcher.class.php @@ -14,7 +14,6 @@ * ThinkPHP内置的Dispatcher类 * 完成URL解析、路由和调度 */ - class Dispatcher { @@ -25,31 +24,23 @@ class Dispatcher */ public static function dispatch() { - $varPath = C('VAR_PATHINFO'); - $varAddon = C('VAR_ADDON'); - $varModule = C('VAR_MODULE'); - $varController = C('VAR_CONTROLLER'); - $varAction = C('VAR_ACTION'); - $urlCase = C('URL_CASE_INSENSITIVE'); - if (isset($_GET[$varPath])) { - // 判断URL里面是否有兼容模式参数 + $varPath = C('VAR_PATHINFO'); + $urlCase = C('URL_CASE_INSENSITIVE'); + if (isset($_GET[$varPath])) { // 判断URL里面是否有兼容模式参数 $_SERVER['PATH_INFO'] = $_GET[$varPath]; unset($_GET[$varPath]); - } elseif (IS_CLI) { - // CLI模式下 index.php module/controller/action/params/... + } elseif (IS_CLI) { // CLI模式下 index.php module/controller/action/params/... $_SERVER['PATH_INFO'] = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : ''; } // 开启子域名部署 if (C('APP_SUB_DOMAIN_DEPLOY')) { $rules = C('APP_SUB_DOMAIN_RULES'); - if (isset($rules[$_SERVER['HTTP_HOST']])) { - // 完整域名或者IP配置 + if (isset($rules[$_SERVER['HTTP_HOST']])) { // 完整域名或者IP配置 define('APP_DOMAIN', $_SERVER['HTTP_HOST']); // 当前完整域名 $rule = $rules[APP_DOMAIN]; } else { - if (strpos(C('APP_DOMAIN_SUFFIX'), '.')) { - // com.cn net.cn + if (strpos(C('APP_DOMAIN_SUFFIX'), '.')) { // com.cn net.cn $domain = array_slice(explode('.', $_SERVER['HTTP_HOST']), 0, -3); } else { $domain = array_slice(explode('.', $_SERVER['HTTP_HOST']), 0, -2); @@ -67,11 +58,11 @@ public static function dispatch() $rule = $rules[$subDomain]; } elseif (isset($rules['*.' . $domain2]) && !empty($domain3)) { // 泛三级域名 - $rule = $rules['*.' . $domain2]; + $rule = $rules['*.' . $domain2]; $panDomain = $domain3; } elseif (isset($rules['*']) && !empty($domain2) && 'www' != $domain2) { // 泛二级域名 - $rule = $rules['*']; + $rule = $rules['*']; $panDomain = $domain2; } } @@ -84,11 +75,11 @@ public static function dispatch() } $array = explode('/', $rule); // 模块绑定 - defined('BIND_MODULE') or define('BIND_MODULE', array_shift($array)); - // 控制器绑定 + define('BIND_MODULE', array_shift($array)); + // 控制器绑定 if (!empty($array)) { $controller = array_shift($array); - if ($controller && !defined('BIND_MODULE')) { + if ($controller) { define('BIND_CONTROLLER', $controller); } } @@ -116,7 +107,7 @@ public static function dispatch() break; } elseif (!empty($_SERVER[$type])) { $_SERVER['PATH_INFO'] = (0 === strpos($_SERVER[$type], $_SERVER['SCRIPT_NAME'])) ? - substr($_SERVER[$type], strlen($_SERVER['SCRIPT_NAME'])) : $_SERVER[$type]; + substr($_SERVER[$type], strlen($_SERVER['SCRIPT_NAME'])) : $_SERVER[$type]; break; } } @@ -129,29 +120,31 @@ public static function dispatch() $_SERVER['PATH_INFO'] = ''; define('__INFO__', ''); define('__EXT__', ''); + $paths = array(); } else { - define('__INFO__', trim($_SERVER['PATH_INFO'], '/')); // URL后缀 define('__EXT__', strtolower(pathinfo($_SERVER['PATH_INFO'], PATHINFO_EXTENSION))); - $_SERVER['PATH_INFO'] = __INFO__; - if (!defined('BIND_MODULE') && (!C('URL_ROUTER_ON') || !Route::check())) { - if (__INFO__ && C('MULTI_MODULE')) { - // 获取模块名 - $paths = explode($depr, __INFO__, 2); - $_GET[$varModule] = preg_replace('/\.' . __EXT__ . '$/i', '', $paths[0]); - $_SERVER['PATH_INFO'] = isset($paths[1]) ? $paths[1] : ''; + // 检查禁止访问的URL后缀 + if ($denySuffix = C('URL_DENY_SUFFIX')) { + if (in_array(__EXT__, explode('|', strtolower(str_replace('.', '', $denySuffix))))) { + send_http_status(404); + exit; } } + define('__INFO__', trim($_SERVER['PATH_INFO'], '/')); + // 去除URL后缀 + $_SERVER['PATH_INFO'] = preg_replace('/\.' . __EXT__ . '$/i', '', __INFO__); + $paths = explode($depr, trim($_SERVER['PATH_INFO'], $depr)); } // URL常量 define('__SELF__', strip_tags($_SERVER[C('URL_REQUEST_URI')])); // 获取模块名称 - define('MODULE_NAME', defined('BIND_MODULE') ? BIND_MODULE : self::getModule($varModule)); + define('MODULE_NAME', self::getModule($paths)); // 检测模块是否存在 - if (MODULE_NAME && !in_array_case(MODULE_NAME, C('MODULE_DENY_LIST')) && is_dir(APP_PATH . MODULE_NAME)) { + if (MODULE_NAME && is_dir(APP_PATH . MODULE_NAME)) { // 定义当前模块路径 define('MODULE_PATH', APP_PATH . MODULE_NAME . '/'); // 定义当前模块的模版缓存路径 @@ -159,7 +152,7 @@ public static function dispatch() // 定义当前模块的日志目录 C('LOG_PATH', realpath(LOG_PATH) . '/' . MODULE_NAME . '/'); - // 模块检测 + // 模块配置文件开始载入检测位 Hook::listen('module_check'); // 加载模块配置文件 @@ -188,13 +181,13 @@ public static function dispatch() } // 加载模块函数文件 - if (is_file(MODULE_PATH . 'Common/function.php')) { + if (is_file(MODULE_PATH . 'Common/function.php')) include MODULE_PATH . 'Common/function.php'; - } - - $urlCase = C('URL_CASE_INSENSITIVE'); // 加载模块的扩展配置文件 load_ext_file(MODULE_PATH); + + // 模块配置文件加载完成检测位 + Hook::listen('module_config'); } else { E(L('_MODULE_NOT_EXIST_') . ':' . MODULE_NAME); } @@ -220,51 +213,25 @@ public static function dispatch() // 模块URL地址 $moduleName = defined('MODULE_ALIAS') ? MODULE_ALIAS : MODULE_NAME; define('__MODULE__', (defined('BIND_MODULE') || !C('MULTI_MODULE')) ? __APP__ : __APP__ . '/' . ($urlCase ? strtolower($moduleName) : $moduleName)); + // 获取控制器和操作名 + define('CONTROLLER_NAME', self::getController($paths, $urlCase)); + define('ACTION_NAME', self::getAction($paths, $urlCase)); - if ('' != $_SERVER['PATH_INFO'] && (!C('URL_ROUTER_ON') || !Route::check())) { - // 检测路由规则 如果没有则按默认规则调度URL - Hook::listen('path_info'); - // 检查禁止访问的URL后缀 - if (C('URL_DENY_SUFFIX') && preg_match('/\.(' . trim(C('URL_DENY_SUFFIX'), '.') . ')$/i', $_SERVER['PATH_INFO'])) { - send_http_status(404); - exit; - } - - // 去除URL后缀 - $_SERVER['PATH_INFO'] = preg_replace(C('URL_HTML_SUFFIX') ? '/\.(' . trim(C('URL_HTML_SUFFIX'), '.') . ')$/i' : '/\.' . __EXT__ . '$/i', '', $_SERVER['PATH_INFO']); - - $depr = C('URL_PATHINFO_DEPR'); - $paths = explode($depr, trim($_SERVER['PATH_INFO'], $depr)); - - if (!defined('BIND_CONTROLLER')) { - // 获取控制器 - if (C('CONTROLLER_LEVEL') > 1) { - // 控制器层次 - $_GET[$varController] = implode('/', array_slice($paths, 0, C('CONTROLLER_LEVEL'))); - $paths = array_slice($paths, C('CONTROLLER_LEVEL')); - } else { - $_GET[$varController] = array_shift($paths); - } - } - // 获取操作 - if (!defined('BIND_ACTION')) { - $_GET[$varAction] = array_shift($paths); - } + if ($paths) { // 解析剩余的URL参数 $var = array(); if (C('URL_PARAMS_BIND') && 1 == C('URL_PARAMS_BIND_TYPE')) { // URL参数按顺序绑定变量 $var = $paths; } else { - preg_replace_callback('/(\w+)\/([^\/]+)/', function ($match) use (&$var) {$var[$match[1]] = strip_tags($match[2]);}, implode('/', $paths)); + preg_replace_callback('/(\w+)\/([^\/]+)/', function ($match) use (&$var) { + $var[$match[1]] = strip_tags($match[2]); + }, implode('/', $paths)); } $_GET = array_merge($var, $_GET); } // 获取控制器的命名空间(路径) - define('CONTROLLER_PATH', self::getSpace($varAddon, $urlCase)); - // 获取控制器和操作名 - define('CONTROLLER_NAME', defined('BIND_CONTROLLER') ? BIND_CONTROLLER : self::getController($varController, $urlCase)); - define('ACTION_NAME', defined('BIND_ACTION') ? BIND_ACTION : self::getAction($varAction, $urlCase)); + define('CONTROLLER_PATH', self::getSpace($urlCase)); // 当前控制器的UR地址 $controllerName = defined('CONTROLLER_ALIAS') ? CONTROLLER_ALIAS : CONTROLLER_NAME; @@ -274,14 +241,17 @@ public static function dispatch() define('__ACTION__', __CONTROLLER__ . $depr . (defined('ACTION_ALIAS') ? ACTION_ALIAS : ACTION_NAME)); //保证$_REQUEST正常取值 - $_REQUEST = array_merge($_POST, $_GET, $_COOKIE); // -- 加了$_COOKIE. 保证哦.. + $_REQUEST = array_merge($_POST, $_GET); } /** * 获得控制器的命名空间路径 便于插件机制访问 + * @param boolean $urlCase 是否转换成小写 + * @return string */ - private static function getSpace($var, $urlCase) + private static function getSpace($urlCase) { + $var = C('VAR_ADDON'); $space = !empty($_GET[$var]) ? strip_tags($_GET[$var]) : ''; unset($_GET[$var]); return $space; @@ -289,11 +259,38 @@ private static function getSpace($var, $urlCase) /** * 获得实际的控制器名称 + * @param array $paths path_info数组 + * @param boolean $urlCase 是否转换成小写 + * @return string */ - private static function getController($var, $urlCase) + private static function getController(&$paths, $urlCase) { - $controller = (!empty($_GET[$var]) ? $_GET[$var] : C('DEFAULT_CONTROLLER')); - unset($_GET[$var]); + if (defined('BIND_CONTROLLER')) { + return BIND_CONTROLLER; + } else { + if ($paths && C('URL_ROUTER_ON') && Route::check($paths)) { + $depr = C('URL_PATHINFO_DEPR'); + $paths = explode($depr, trim($_SERVER['PATH_INFO'], $depr)); + } + if ($paths) { + // PATH_INFO检测标签位 + Hook::listen('path_info'); + if (C('CONTROLLER_LEVEL') > 1) {// 控制器层次 + $controller = implode('/', array_slice($paths, 0, C('CONTROLLER_LEVEL'))); + $paths = array_slice($paths, C('CONTROLLER_LEVEL')); + } else { + $controller = array_shift($paths); + } + } else { + $var = C('VAR_CONTROLLER'); + if (!empty($_GET[$var])) { + $controller = $_GET[$var]; + unset($_GET[$var]); + } else { + $controller = C('DEFAULT_CONTROLLER'); + } + } + } if ($maps = C('URL_CONTROLLER_MAP')) { if (isset($maps[strtolower($controller)])) { // 记录当前别名 @@ -315,13 +312,30 @@ private static function getController($var, $urlCase) /** * 获得实际的操作名称 + * @param array $paths path_info数组 + * @param boolean $urlCase 是否转换成小写 + * @return string */ - private static function getAction($var, $urlCase) + private static function getAction(&$paths, $urlCase) { - $action = !empty($_POST[$var]) ? - $_POST[$var] : - (!empty($_GET[$var]) ? $_GET[$var] : C('DEFAULT_ACTION')); - unset($_POST[$var], $_GET[$var]); + if (defined('BIND_ACTION')) { + return BIND_ACTION; + } else { + if ($paths) { + $action = array_shift($paths); + } else { + $var = C('VAR_ACTION'); + if (!empty($_GET[$var])) { + $action = $_GET[$var]; + unset($_GET[$var]); + } elseif (!empty($_POST[$var])) { + $action = $_POST[$var]; + unset($_POST[$var]); + } else { + $action = C('DEFAULT_ACTION'); + } + } + } if ($maps = C('URL_ACTION_MAP')) { if (isset($maps[strtolower(CONTROLLER_NAME)])) { $maps = $maps[strtolower(CONTROLLER_NAME)]; @@ -348,14 +362,34 @@ private static function getAction($var, $urlCase) /** * 获得实际的模块名称 + * @param array $paths path_info数组 + * @return string */ - private static function getModule($var) + private static function getModule(&$paths) { - $module = (!empty($_GET[$var]) ? $_GET[$var] : C('DEFAULT_MODULE')); - unset($_GET[$var]); - $allowList = C('MODULE_ALLOW_LIST'); // 允许的模块列表 - if (!empty($allowList) && is_array($allowList) && !in_array_case($module, $allowList)) { - E(L('_MODULE_NOT_EXIST_') . ':' . strip_tags(ucfirst($module))); + if (defined('BIND_MODULE')) { + return BIND_MODULE; + } else { + // 检查路由 + if ($paths && C('URL_ROUTER_ON') && Route::check($paths)) { + $paths = explode(MODULE_PATHINFO_DEPR, trim($_SERVER['PATH_INFO'], MODULE_PATHINFO_DEPR)); + } + if ($paths && C('MULTI_MODULE')) { // 获取模块名 + $allowList = C('MODULE_ALLOW_LIST'); // 允许的模块列表 + if (empty($allowList) || (is_array($allowList) && in_array_case($paths[0], $allowList))) { + $module = array_shift($paths); + $_SERVER['PATH_INFO'] = implode(MODULE_PATHINFO_DEPR, $paths); + } + } else { + $var = C('VAR_MODULE'); + if (!empty($_GET[$var])) { + $module = $_GET[$var]; + unset($_GET[$var]); + } + } + if (empty($module)) { + $module = C('DEFAULT_MODULE'); + } } if ($maps = C('URL_MODULE_MAP')) { if (isset($maps[strtolower($module)])) { @@ -363,7 +397,7 @@ private static function getModule($var) define('MODULE_ALIAS', strtolower($module)); // 获取实际的模块名 return ucfirst($maps[MODULE_ALIAS]); - } elseif (array_search(strtolower($module), $maps)) { + } elseif (array_search(strtolower($module), $maps) || in_array_case($module, C('MODULE_DENY_LIST'))) { // 禁止访问原始模块 return ''; } diff --git a/ThinkPHP/Library/Think/Route.class.php b/ThinkPHP/Library/Think/Route.class.php index 80bdec8cf..ef508e073 100644 --- a/ThinkPHP/Library/Think/Route.class.php +++ b/ThinkPHP/Library/Think/Route.class.php @@ -16,81 +16,76 @@ class Route { - // 路由检测 - public static function check() + /** + * 路由检测 + * @param array $paths path_info数组 + * @return boolean + */ + public static function check($paths = array()) { - $depr = C('URL_PATHINFO_DEPR'); - $regx = preg_replace('/\.' . __EXT__ . '$/i', '', trim($_SERVER['PATH_INFO'], $depr)); - // 分隔符替换 确保路由定义使用统一的分隔符 - if ('/' != $depr) { - $regx = str_replace($depr, '/', $regx); + $rules = self::ruleCache(); + if (!empty($paths)) { + $regx = implode('/', $paths); + } else { + $depr = C('URL_PATHINFO_DEPR'); + $regx = preg_replace('/\.' . __EXT__ . '$/i', '', trim($_SERVER['PATH_INFO'], $depr)); + if (!$regx) { + return false; + } + // 分隔符替换 确保路由定义使用统一的分隔符 + if ('/' != $depr) { + $regx = str_replace($depr, '/', $regx); + } } - // URL映射定义(静态路由) - $maps = C('URL_MAP_RULES'); - if (isset($maps[$regx])) { - $var = self::parseUrl($maps[$regx]); - $_GET = array_merge($var, $_GET); + // 静态路由检查 + if (isset($rules[0][$regx])) { + $route = $rules[0][$regx]; + $_SERVER['PATH_INFO'] = $route[0]; + $args = array_pop($route); + if (!empty($route[1])) { + $args = array_merge($args, $route[1]); + } + $_GET = array_merge($args, $_GET); return true; } - // 动态路由处理 - $routes = C('URL_ROUTE_RULES'); - if (!empty($routes)) { - foreach ($routes as $rule => $route) { - if (is_numeric($rule)) { - // 支持 array('rule','adddress',...) 定义路由 - $rule = array_shift($route); - } - if (is_array($route) && isset($route[2])) { - // 路由参数 - $options = $route[2]; - if (isset($options['ext']) && __EXT__ != $options['ext']) { - // URL后缀检测 - continue; - } - if (isset($options['method']) && REQUEST_METHOD != strtoupper($options['method'])) { - // 请求类型检测 + // 动态路由检查 + if (!empty($rules[1])) { + foreach ($rules[1] as $rule => $route) { + $args = array_pop($route); + if (isset($route[2])) { + // 路由参数检查 + if (!self::checkOption($route[2], __EXT__)) { continue; } - // 自定义检测 - if (!empty($options['callback']) && is_callable($options['callback'])) { - if (false === call_user_func($options['callback'])) { - continue; - } - } } - if (0 === strpos($rule, '/') && preg_match($rule, $regx, $matches)) { - // 正则路由 - if ($route instanceof \Closure) { + if ($matches = self::checkUrlMatch($rule, $args, $regx)) { + if ($route[0] instanceof \Closure) { // 执行闭包 - $result = self::invokeRegx($route, $matches); + $result = self::invoke($route[0], $matches); // 如果返回布尔值 则继续执行 return is_bool($result) ? $result : exit; } else { - return self::parseRegex($matches, $route, $regx); - } - } else { - // 规则路由 - $len1 = substr_count($regx, '/'); - $len2 = substr_count($rule, '/'); - if ($len1 >= $len2 || strpos($rule, '[')) { - if ('$' == substr($rule, -1, 1)) { - // 完整匹配 - if ($len1 != $len2) { - continue; - } else { - $rule = substr($rule, 0, -1); - } + // 存在动态变量 + if (strpos($route[0], ':')) { + $matches = array_values($matches); + $route[0] = preg_replace_callback('/:(\d+)/', function ($match) use (&$matches) { + return $matches[$match[1] - 1]; + }, $route[0]); } - $match = self::checkUrlMatch($regx, $rule); - if (false !== $match) { - if ($route instanceof \Closure) { - // 执行闭包 - $result = self::invokeRule($route, $match); - // 如果返回布尔值 则继续执行 - return is_bool($result) ? $result : exit; - } else { - return self::parseRule($rule, $route, $regx); + // 重定向 + if ('/' == substr($route[0], 0, 1)) { + header("Location: $route[0]", true, $route[1]); + exit; + } else { + $depr = C('URL_PATHINFO_DEPR'); + if ('/' != $depr) { + $route[0] = str_replace('/', $depr, $route[0]); + } + $_SERVER['PATH_INFO'] = $route[0]; + if (!empty($route[1])) { + $_GET = array_merge($route[1], $_GET); } + return true; } } } @@ -99,80 +94,112 @@ public static function check() return false; } - // 检测URL和规则路由是否匹配 - private static function checkUrlMatch($regx, $rule) + /** + * 路由反向解析 + * @param string $path 控制器/方法 + * @param array $vars url参数 + * @param string $depr 分隔符 + * @param string|true $suffix url后缀 + * @return string|false + */ + public static function reverse($path, &$vars, $depr, $suffix = true) { - $m1 = explode('/', $regx); - $m2 = explode('/', $rule); - $var = array(); - foreach ($m2 as $key => $val) { - if (0 === strpos($val, '[:')) { - $val = substr($val, 1, -1); + static $_rules; + if (is_null($_rules)) { + if ($rules = self::ruleCache()) { + foreach ($rules as $i => $rules2) { + foreach ($rules2 as $rule => $route) { + if (is_array($route) && is_string($route[0]) && '/' != substr($route[0], 0, 1)) { + $_rules[$i][$route[0]][$rule] = $route; + } + } + } } - - if (':' == substr($val, 0, 1)) { -// 动态变量 - if ($pos = strpos($val, '|')) { - // 使用函数过滤 - $val = substr($val, 1, $pos - 1); + } + // 静态路由 + if (isset($_rules[0][$path])) { + foreach ($_rules[0][$path] as $rule => $route) { + $args = array_pop($route); + if (count($vars) == count($args) && !empty($vars) && !array_diff($vars, $args)) { + return str_replace('/', $depr, $rule); + } + } + } + if (isset($_rules[1][$path])) { + foreach ($_rules[1][$path] as $rule => $route) { + $args = array_pop($route); + $array = array(); + if (isset($route[2])) { + // 路由参数检查 + if (!self::checkOption($route[2], $suffix)) { + continue; + } } - if (strpos($val, '\\')) { - $type = substr($val, -1); - if ('d' == $type) { - if (isset($m1[$key]) && !is_numeric($m1[$key])) { - return false; + if ('/' != substr($rule, 0, 1)) { + // 规则路由 + foreach ($args as $key => $val) { + $flag = false; + if ($val[0] == 0) { + // 静态变量值 + $array[$key] = $key; + continue; + } + if (isset($vars[$key])) { + // 是否有过滤条件 + if (!empty($val[2])) { + if ($val[2] == 'int') { + // 是否为数字 + if (!is_numeric($vars[$key]) || !is_int($vars[$key] + 0)) { + break; + } + } else { + // 排除的名称 + if (in_array($vars[$key], $val[2])) { + break; + } + } + } + $flag = true; + $array[$key] = $vars[$key]; + } elseif ($val[0] == 1) { + // 如果是必选项 + break; } - } - $name = substr($val, 1, -2); - } elseif ($pos = strpos($val, '^')) { - $array = explode('-', substr(strstr($val, '^'), 1)); - if (in_array($m1[$key], $array)) { - return false; + // 匹配成功 + if (!empty($flag)) { + foreach (array_keys($array) as $key) { + unset($vars[$key]); + } + return implode($depr, $array); } - $name = substr($val, 1, $pos - 1); } else { - $name = substr($val, 1); + // 正则路由 + $keys = !empty($args) ? array_keys($args) : array_keys($vars); + $str = preg_replace_callback('/\(.+\)/', function ($match) use (&$vars, &$keys) { + $k = array_shift($keys); + return isset($vars[$k]) ? $vars[$k] : ''; + }, $rule); + $str = substr($str, 1, -1); + $str = rtrim(ltrim($str, '^'), '$'); + $str = str_replace('\\', '', $str); + if (preg_match($rule, $str, $matches)) { + // 匹配成功 + if ($args) { + $keys = array_keys($args); + } + foreach ($keys as $key) { + unset($vars[$key]); + } + return str_replace('/', $depr, $str); + } } - $var[$name] = isset($m1[$key]) ? $m1[$key] : ''; - } elseif (0 !== strcasecmp($val, $m1[$key])) { - return false; } } - // 成功匹配后返回URL中的动态变量数组 - return $var; - } - - // 解析规范的路由地址 - // 地址格式 [控制器/操作?]参数1=值1&参数2=值2... - private static function parseUrl($url) - { - $var = array(); - if (false !== strpos($url, '?')) { - // [控制器/操作?]参数1=值1&参数2=值2... - $info = parse_url($url); - $path = explode('/', $info['path']); - parse_str($info['query'], $var); - } elseif (strpos($url, '/')) { - // [控制器/操作] - $path = explode('/', $url); - } else { - // 参数1=值1&参数2=值2... - parse_str($url, $var); - } - if (isset($path)) { - $var[C('VAR_ACTION')] = array_pop($path); - if (!empty($path)) { - $var[C('VAR_CONTROLLER')] = array_pop($path); - } - if (!empty($path)) { - $var[C('VAR_MODULE')] = array_pop($path); - } - } - return $var; + return false; } - // 解析规则路由 + // 规则路由定义方法: // '路由规则'=>'[控制器/操作]?额外参数1=值1&额外参数2=值2...' // '路由规则'=>array('[控制器/操作]','额外参数1=值1&额外参数2=值2...') // '路由规则'=>'外部地址' @@ -181,153 +208,257 @@ private static function parseUrl($url) // 外部地址中可以用动态变量 采用 :1 :2 的方式 // 'news/:month/:day/:id'=>array('News/read?cate=1','status=1'), // 'new/:id'=>array('/new.php?id=:1',301), 重定向 - private static function parseRule($rule, $route, $regx) + // 正则路由定义方法: + // '路由正则'=>'[控制器/操作]?参数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'), 重定向 + /** + * 读取规则缓存 + * @param boolean $update 是否更新 + * @return array + */ + public static function ruleCache($update = false) { - // 获取路由地址规则 - $url = is_array($route) ? $route[0] : $route; - // 获取URL地址中的参数 - $paths = explode('/', $regx); - // 解析路由规则 - $matches = array(); - $rule = explode('/', $rule); - foreach ($rule as $item) { - $fun = ''; - if (0 === strpos($item, '[:')) { - $item = substr($item, 1, -1); - } - if (0 === strpos($item, ':')) { - // 动态变量获取 - if ($pos = strpos($item, '|')) { - // 支持函数过滤 - $fun = substr($item, $pos + 1); - $item = substr($item, 0, $pos); + $result = array(); + $module = defined('MODULE_NAME') ? '_' . MODULE_NAME : ''; + if ($update || !$result = S('url_route_rules' . $module)) { + // 静态路由 + $result[0] = C('URL_MAP_RULES'); + if (!empty($result[0])) { + foreach ($result[0] as $rule => $route) { + if (!is_array($route)) { + $route = array($route); + } + if (strpos($route[0], '?')) { + // 分离参数 + list($route[0], $args) = explode('?', $route[0], 2); + parse_str($args, $args); + } else { + $args = array(); + } + if (!empty($route[1]) && is_string($route[1])) { + // 额外参数 + parse_str($route[1], $route[1]); + } + $route[] = $args; + $result[0][$rule] = $route; } - if ($pos = strpos($item, '^')) { - $var = substr($item, 1, $pos - 1); - } elseif (strpos($item, '\\')) { - $var = substr($item, 1, -2); - } else { - $var = substr($item, 1); + } + // 动态路由 + $result[1] = C('URL_ROUTE_RULES'); + if (!empty($result[1])) { + foreach ($result[1] as $rule => $route) { + if (!is_array($route)) { + $route = array($route); + } elseif (is_numeric($rule)) { + // 支持 array('rule','adddress',...) 定义路由 + $rule = array_shift($route); + } + if (!empty($route)) { + $args = array(); + if (is_string($route[0])) { + if (0 === strpos($route[0], '/') || 0 === strpos($route[0], 'http')) { + // 重定向 + if (!isset($route[1])) { + $route[1] = 301; + } + } else { + if (!empty($route[1]) && is_string($route[1])) { + // 额外参数 + parse_str($route[1], $route[1]); + } + if (strpos($route[0], '?')) { + // 分离参数 + list($route[0], $params) = explode('?', $route[0], 2); + if (!empty($params)) { + foreach (explode('&', $params) as $key => $val) { + if (0 === strpos($val, ':')) { + // 动态参数 + $val = substr($val, 1); + $args[$key] = strpos($val, '|') ? explode('|', $val, 2) : array($val); + } else { + $route[1][$key] = $val; + } + } + } + } + } + } + if ('/' != substr($rule, 0, 1)) { + // 规则路由 + foreach (explode('/', rtrim($rule, '$')) as $item) { + $filter = $fun = ''; + $type = 0; + if (0 === strpos($item, '[:')) { + // 可选变量 + $type = 2; + $item = substr($item, 1, -1); + } + if (0 === strpos($item, ':')) { + // 动态变量获取 + $type = $type ?: 1; + if ($pos = strpos($item, '|')) { + // 支持函数过滤 + $fun = substr($item, $pos + 1); + $item = substr($item, 1, $pos - 1); + } + if ($pos = strpos($item, '^')) { + // 排除项 + $filter = explode('-', substr($item, $pos + 1)); + $item = substr($item, 1, $pos - 1); + } elseif (strpos($item, '\\')) { + // \d表示限制为数字 + if ('d' == substr($item, -1)) { + $filter = 'int'; + } + $item = substr($item, 1, -2); + } else { + $item = substr($item, 1); + } + } + $args[$item] = array($type, $fun, $filter); + } + } + $route[] = $args; + $result[1][$rule] = $route; + } else { + unset($result[1][$rule]); + } } - $matches[$var] = !empty($fun) ? $fun(array_shift($paths)) : array_shift($paths); - } else { - // 过滤URL中的静态变量 - array_shift($paths); } + S('url_route_rules' . $module, $result); } + return $result; + } - if (0 === strpos($url, '/') || 0 === strpos($url, 'http')) { - // 路由重定向跳转 - if (strpos($url, ':')) { // 传递动态参数 - $values = array_values($matches); - $url = preg_replace_callback('/:(\d+)/', function ($match) use ($values) {return $values[$match[1] - 1];}, $url); - } - header("Location: $url", true, (is_array($route) && isset($route[1])) ? $route[1] : 301); - exit; - } else { - // 解析路由地址 - $var = self::parseUrl($url); - // 解析路由地址里面的动态参数 - $values = array_values($matches); - foreach ($var as $key => $val) { - if (0 === strpos($val, ':')) { - $var[$key] = $values[substr($val, 1) - 1]; + /** + * 路由参数检测 + * @param array $options 路由参数 + * @param string|true $suffix URL后缀 + * @return boolean + */ + private static function checkOption($options, $suffix = true) + { + // URL后缀检测 + if (isset($options['ext'])) { + if ($suffix) { + $suffix = $suffix === true ? C('URL_HTML_SUFFIX') : $suffix; + if ($pos = strpos($suffix, '|')) { + $suffix = substr($suffix, 0, $pos); } } - $var = array_merge($matches, $var); - // 解析剩余的URL参数 - if (!empty($paths)) { - preg_replace_callback('/(\w+)\/([^\/]+)/', function ($match) use (&$var) {$var[strtolower($match[1])] = strip_tags($match[2]);}, implode('/', $paths)); + if ($suffix != $options['ext']) { + return false; } - // 解析路由自动传入参数 - if (is_array($route) && isset($route[1])) { - if (is_array($route[1])) { - $params = $route[1]; - } else { - parse_str($route[1], $params); - } - $var = array_merge($var, $params); + } + if (isset($options['method']) && REQUEST_METHOD != strtoupper($options['method'])) { + // 请求类型检测 + return false; + } + // 自定义检测 + if (!empty($options['callback']) && is_callable($options['callback'])) { + if (false === call_user_func($options['callback'])) { + return false; } - $_GET = array_merge($var, $_GET); } return true; } - // 解析正则路由 - // '路由正则'=>'[控制器/操作]?参数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 static function parseRegex($matches, $route, $regx) + /** + * 检测URL和路由规则是否匹配 + * @param string $rule 路由规则 + * @param array $args 路由动态变量 + * @param string $regx URL地址 + * @return array|false + */ + private static function checkUrlMatch(&$rule, &$args, &$regx) { - // 获取路由地址规则 - $url = is_array($route) ? $route[0] : $route; - $url = preg_replace_callback('/:(\d+)/', function ($match) use ($matches) {return $matches[$match[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 = self::parseUrl($url); - // 处理函数 - foreach ($var as $key => $val) { - if (strpos($val, '|')) { - list($val, $fun) = explode('|', $val); - $var[$key] = $fun($val); + $params = array(); + if ('/' == substr($rule, 0, 1)) { + // 正则路由 + if (preg_match($rule, $regx, $matches)) { + if ($args) { // 存在动态变量 + foreach ($args as $key => $val) { + $params[$key] = isset($val[1]) ? $val[1]($matches[$val[0]]) : $matches[$val[0]]; + } + $regx = substr_replace($regx, '', 0, strlen($matches[0])); } + array_shift($matches); + } else { + return false; } - // 解析剩余的URL参数 - $regx = substr_replace($regx, '', 0, strlen($matches[0])); - if ($regx) { - preg_replace_callback('/(\w+)\/([^\/]+)/', function ($match) use (&$var) { - $var[strtolower($match[1])] = strip_tags($match[2]); - }, $regx); + } else { + $paths = explode('/', $regx); + // $结尾则要求完整匹配 + if ('$' == substr($rule, -1) && count($args) != count($paths)) { + return false; } - // 解析路由自动传入参数 - if (is_array($route) && isset($route[1])) { - if (is_array($route[1])) { - $params = $route[1]; + foreach ($args as $key => $val) { + $var = array_shift($paths) ?: ''; + if ($val[0] == 0) { + // 静态变量 + if (0 !== strcasecmp($key, $var)) { + return false; + } } else { - parse_str($route[1], $params); + if (isset($val[2])) { + // 设置了过滤条件 + if ($val[2] == 'int') { + // 如果值不为整数 + if (!is_int($var + 0)) { + return false; + } + } else { + // 如果值在排除的名单里 + if (in_array($var, $val[2])) { + return false; + } + } + } + if (!empty($var)) { + $params[$key] = !empty($val[1]) ? $val[1]($var) : $var; + } elseif ($val[0] == 1) { + // 不是可选的 + return false; + } } - $var = array_merge($var, $params); } - $_GET = array_merge($var, $_GET); + $matches = $params; + $regx = implode('/', $paths); } - return true; - } - - // 执行正则匹配下的闭包方法 支持参数调用 - private static function invokeRegx($closure, $var = array()) - { - $reflect = new \ReflectionFunction($closure); - $params = $reflect->getParameters(); - $args = array(); - array_shift($var); - foreach ($params as $param) { - if (!empty($var)) { - $args[] = array_shift($var); - } elseif ($param->isDefaultValueAvailable()) { - $args[] = $param->getDefaultValue(); - } + // 解析剩余的URL参数 + if ($regx) { + preg_replace_callback('/(\w+)\/([^\/]+)/', function ($match) use (&$params) { + $params[strtolower($match[1])] = strip_tags($match[2]); + }, $regx); } - return $reflect->invokeArgs($args); + $_GET = array_merge($params, $_GET); + + // 成功匹配后返回URL中的动态变量数组 + return $matches; } - // 执行规则匹配下的闭包方法 支持参数调用 - private static function invokeRule($closure, $var = array()) + /** + * 执行闭包方法 支持参数调用 + * @param function $closure 闭包函数 + * @param array $var 传给闭包的参数 + * @return boolean + */ + private static function invoke($closure, $var = array()) { $reflect = new \ReflectionFunction($closure); - $params = $reflect->getParameters(); - $args = array(); - foreach ($params as $param) { + $params = $reflect->getParameters(); + $args = array(); + foreach ($params as $i => $param) { $name = $param->getName(); if (isset($var[$name])) { $args[] = $var[$name]; + } elseif (isset($var[$i])) { + $args[] = $var[$i]; } elseif ($param->isDefaultValueAvailable()) { $args[] = $param->getDefaultValue(); } @@ -335,4 +466,4 @@ private static function invokeRule($closure, $var = array()) return $reflect->invokeArgs($args); } -} +} \ No newline at end of file From 467dd3bc8347f2681a756c43bc4d659052d819c8 Mon Sep 17 00:00:00 2001 From: oldrind <1401019000@qq.com> Date: Sat, 9 Jan 2016 20:14:19 +0800 Subject: [PATCH 131/166] =?UTF-8?q?=E6=94=B9[]=E4=B8=BAarray()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Common/functions.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ThinkPHP/Common/functions.php b/ThinkPHP/Common/functions.php index c81f9bddd..219f8f702 100644 --- a/ThinkPHP/Common/functions.php +++ b/ThinkPHP/Common/functions.php @@ -1014,7 +1014,7 @@ function U($url = '', $vars = '', $suffix = true, $domain = false) // aaa=1&bbb=2 转换成数组 parse_str($vars, $vars); } elseif (!is_array($vars)) { - $vars = []; + $vars = array(); } if (isset($info['query'])) { // 解析地址里面参数 合并到vars @@ -1041,7 +1041,7 @@ function U($url = '', $vars = '', $suffix = true, $domain = false) // 解析模块、控制器和操作 $url = trim($url, $depr); $path = explode($depr, $url); - $var = []; + $var = array(); $varModule = C('VAR_MODULE'); $varController = C('VAR_CONTROLLER'); $varAction = C('VAR_ACTION'); From 7be1aaf524f341c5591fab1aa3e106454958ab11 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Tue, 12 Jan 2016 09:21:36 +0800 Subject: [PATCH 132/166] =?UTF-8?q?=E8=A7=86=E5=9B=BE=E6=A8=A1=E5=9E=8B?= =?UTF-8?q?=E7=9A=84=E6=9F=A5=E8=AF=A2=E5=A2=9E=E5=BC=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Library/Think/Model/ViewModel.class.php | 81 ++++++++++++++++--- 1 file changed, 68 insertions(+), 13 deletions(-) diff --git a/ThinkPHP/Library/Think/Model/ViewModel.class.php b/ThinkPHP/Library/Think/Model/ViewModel.class.php index fb455740f..a91d27e40 100644 --- a/ThinkPHP/Library/Think/Model/ViewModel.class.php +++ b/ThinkPHP/Library/Think/Model/ViewModel.class.php @@ -111,32 +111,87 @@ private function _checkFields($name, $fields) /** * 检查条件中的视图字段 - * @access protected - * @param mixed $data 条件表达式 + * @param $where 条件表达式 * @return array */ protected function checkCondition($where) { if (is_array($where)) { - $view = array(); - // 检查视图字段 + $fields = $field_map_table = array(); foreach ($this->viewFields as $key => $val) { - $k = isset($val['_as']) ? $val['_as'] : $key; - $val = $this->_checkFields($key, $val); - foreach ($where as $name => $value) { - if (false !== $field = array_search($name, $val, true)) { - // 存在视图字段 - $_key = is_numeric($field) ? $k . '.' . $name : $k . '.' . $field; - $view[$_key] = $value; - unset($where[$name]); + $table_alias = isset($val['_as']) ? $val['_as'] : $key; + $val = $this->_checkFields($key, $val); + foreach ($val as $as_name => $v) { + if (is_numeric($as_name)) { + $fields[] = $v; //所有表字段集合 + $field_map_table[] = $table_alias; //所有表字段对应表名集合 + } else { + $fields[$as_name] = $v; + $field_map_table[$as_name] = $table_alias; } } } - $where = array_merge($view, array_diff_key(array_merge($where, $view), $view)); + $where = $this->_parseWhere($where, $fields, $field_map_table); } + return $where; } + /** + * 解析where表达式 + * @param $where + * @param $fields + * @param $field_map_table + * @return array + */ + private function _parseWhere($where, $fields, $field_map_table) + { + $view = array(); + foreach ($where as $name => $val) { + if ('_complex' == $name) { + //复合查询 + foreach ($val as $k => $v) { + if (false === strpos(substr($k, 0, 1), '_')) { + if (false !== $field = array_search($k, $fields, true)) { // 存在视图字段 + $k = is_numeric($field) ? $field_map_table[$field] . '.' . $k : $field_map_table[$field] . '.' . $field; //字段别名 + } + } else if (is_array($v)) { + //数组复合查询 + $v = $this->_parseWhere($val[$k], $fields, $field_map_table); + } + $view[$name][$k] = $v; + } + } else { + if (strpos($name, '|')) { + //name|title快捷查询 + $arr = explode('|', $name); + foreach ($arr as $k => $v) { + if (false !== $field = array_search($v, $fields, true)) { + $arr[$k] = is_numeric($field) ? $field_map_table[$field] . '.' . $v : $field_map_table[$field] . '.' . $field; + } + } + $view[implode('|', $arr)] = $val; + } else if (strpos($name, '&')) { + //name&title快捷查询 + $arr = explode('&', $name); + foreach ($arr as $k => $v) { + if (false !== $field = array_search($v, $fields, true)) { + $arr[$k] = is_numeric($field) ? $field_map_table[$field] . '.' . $v : $field_map_table[$field] . '.' . $field; + } + } + $view[implode('&', $arr)] = $val; + } else { + if (false !== $field = array_search($name, $fields, true)) { + $name = is_numeric($field) ? $field_map_table[$field] . '.' . $name : $field_map_table[$field] . '.' . $field; + } + $view[$name] = $val; + } + } + } + + return $view; + } + /** * 检查Order表达式中的视图字段 * @access protected From e470d875da07e77d722c6adde6582743d223581f Mon Sep 17 00:00:00 2001 From: xiaokun mu Date: Tue, 12 Jan 2016 15:11:41 +0800 Subject: [PATCH 133/166] =?UTF-8?q?Route.class.php=20=E5=88=A4=E6=96=AD?= =?UTF-8?q?=E6=98=AF=E5=90=A6=E6=98=AF=E6=95=B4=E6=95=B0=E7=9A=84=E5=88=A4?= =?UTF-8?q?=E6=96=ADBUG?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Route.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ThinkPHP/Library/Think/Route.class.php b/ThinkPHP/Library/Think/Route.class.php index ef508e073..3721c8190 100644 --- a/ThinkPHP/Library/Think/Route.class.php +++ b/ThinkPHP/Library/Think/Route.class.php @@ -149,7 +149,7 @@ public static function reverse($path, &$vars, $depr, $suffix = true) if (!empty($val[2])) { if ($val[2] == 'int') { // 是否为数字 - if (!is_numeric($vars[$key]) || !is_int($vars[$key] + 0)) { + if (!is_numeric($vars[$key]) || !is_int($vars[$key])) { break; } } else { @@ -409,7 +409,7 @@ private static function checkUrlMatch(&$rule, &$args, &$regx) // 设置了过滤条件 if ($val[2] == 'int') { // 如果值不为整数 - if (!is_int($var + 0)) { + if (!is_int($var)) { return false; } } else { From 07b88915909d4f4e2e933c977ff8e1c06083ab39 Mon Sep 17 00:00:00 2001 From: xiaokun mu Date: Tue, 12 Jan 2016 16:55:52 +0800 Subject: [PATCH 134/166] =?UTF-8?q?Route.class.php=20=E5=88=A4=E6=96=AD?= =?UTF-8?q?=E6=98=AF=E5=90=A6=E6=98=AF=E6=95=B4=E6=95=B0=E7=9A=84=E5=88=A4?= =?UTF-8?q?=E6=96=ADBUG?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Route.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ThinkPHP/Library/Think/Route.class.php b/ThinkPHP/Library/Think/Route.class.php index 3721c8190..ec8cd110f 100644 --- a/ThinkPHP/Library/Think/Route.class.php +++ b/ThinkPHP/Library/Think/Route.class.php @@ -149,7 +149,7 @@ public static function reverse($path, &$vars, $depr, $suffix = true) if (!empty($val[2])) { if ($val[2] == 'int') { // 是否为数字 - if (!is_numeric($vars[$key]) || !is_int($vars[$key])) { + if (!is_numeric($vars[$key]) || !preg_match('/^\d*$/',$vars[$key])) { break; } } else { @@ -409,7 +409,7 @@ private static function checkUrlMatch(&$rule, &$args, &$regx) // 设置了过滤条件 if ($val[2] == 'int') { // 如果值不为整数 - if (!is_int($var)) { + if (!preg_match('/^\d*$/',$var)) { return false; } } else { From 7dbe8c8217115e83a5eebc4acc977a90313ae6d5 Mon Sep 17 00:00:00 2001 From: oldrind <1401019000@qq.com> Date: Wed, 13 Jan 2016 11:13:00 +0800 Subject: [PATCH 135/166] =?UTF-8?q?=E4=BF=AE=E6=AD=A3$val[0]=E4=B8=8D?= =?UTF-8?q?=E5=AD=98=E6=97=B6=E5=9C=A8=E5=BC=95=E5=8F=91=E6=8A=A5=E9=94=99?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Db/Driver.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ThinkPHP/Library/Think/Db/Driver.class.php b/ThinkPHP/Library/Think/Db/Driver.class.php index 09b251fbd..185dc5e40 100644 --- a/ThinkPHP/Library/Think/Db/Driver.class.php +++ b/ThinkPHP/Library/Think/Db/Driver.class.php @@ -407,7 +407,7 @@ protected function parseLock($lock = false) protected function parseSet($data) { foreach ($data as $key => $val) { - if (is_array($val) && 'exp' == $val[0]) { + if (isset($val[0]) && 'exp' == $val[0]) { $set[] = $this->parseKey($key) . '=' . $val[1]; } elseif (is_null($val)) { $set[] = $this->parseKey($key) . '=NULL'; @@ -899,7 +899,7 @@ public function insert($data, $options = array(), $replace = false) $this->model = $options['model']; $this->parseBind(!empty($options['bind']) ? $options['bind'] : array()); foreach ($data as $key => $val) { - if (is_array($val) && 'exp' == $val[0]) { + if (isset($val[0]) && 'exp' == $val[0]) { $fields[] = $this->parseKey($key); $values[] = $val[1]; } elseif (is_null($val)) { From 72a78f1df9b81dfb52fb629b0610ae79073f482f Mon Sep 17 00:00:00 2001 From: xiaokun mu Date: Wed, 13 Jan 2016 12:20:51 +0800 Subject: [PATCH 136/166] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=20Route.class.php=20?= =?UTF-8?q?=E6=AD=A3=E5=88=99=E8=B7=AF=E7=94=B1=E8=A7=A3=E6=9E=90=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E6=97=B6BUG=EF=BC=88=E9=97=AE=E5=8F=B7=E5=B7=A6?= =?UTF-8?q?=E4=BE=A7=E5=8A=A8=E6=80=81=E5=8F=82=E6=95=B0=E5=8F=AF=E4=BB=A5?= =?UTF-8?q?=E8=A7=A3=E6=9E=90=EF=BC=8C=E5=8F=B3=E4=BE=A7=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E5=8A=A8=E6=80=81=E5=8F=82=E6=95=B0=E9=94=99=E8=AF=AF=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Route.class.php | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/ThinkPHP/Library/Think/Route.class.php b/ThinkPHP/Library/Think/Route.class.php index ec8cd110f..ad44f7893 100644 --- a/ThinkPHP/Library/Think/Route.class.php +++ b/ThinkPHP/Library/Think/Route.class.php @@ -72,6 +72,25 @@ public static function check($paths = array()) return $matches[$match[1] - 1]; }, $route[0]); } + // 路由参数关联$matches + if ('/' == substr($rule, 0, 1)) { + $rule_params = array(); + foreach($route[1] as $param_key => $param) + { + list($param_name,$param_value) = explode('=', $param,2); + if(!is_null($param_value)) + { + if(preg_match('/^:(\d*)$/',$param_value, $match_index)) + { + $match_index = $match_index[1]-1; + $param_value = $matches[$match_index]; + } + $rule_params[$param_name] = $param_value; + unset($route[1][$param_key]); + } + } + $route[1] = $rule_params; + } // 重定向 if ('/' == substr($route[0], 0, 1)) { header("Location: $route[0]", true, $route[1]); @@ -225,7 +244,7 @@ public static function ruleCache($update = false) { $result = array(); $module = defined('MODULE_NAME') ? '_' . MODULE_NAME : ''; - if ($update || !$result = S('url_route_rules' . $module)) { + if (APP_DEBUG || $update || !$result = S('url_route_rules' . $module)) { // 静态路由 $result[0] = C('URL_MAP_RULES'); if (!empty($result[0])) { @@ -325,6 +344,7 @@ public static function ruleCache($update = false) } $route[] = $args; $result[1][$rule] = $route; + //if($route[0] == 'Home/Article/article') } else { unset($result[1][$rule]); } @@ -388,6 +408,7 @@ private static function checkUrlMatch(&$rule, &$args, &$regx) $regx = substr_replace($regx, '', 0, strlen($matches[0])); } array_shift($matches); + return $matches; } else { return false; } From b85c8930ee6c8d50e264e3922e520c8b872f5490 Mon Sep 17 00:00:00 2001 From: xiaokun mu Date: Wed, 13 Jan 2016 12:27:53 +0800 Subject: [PATCH 137/166] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=20Route.class.php=20?= =?UTF-8?q?=E6=AD=A3=E5=88=99=E8=B7=AF=E7=94=B1=E8=A7=A3=E6=9E=90=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E6=97=B6BUG=EF=BC=88=E9=97=AE=E5=8F=B7=E5=B7=A6?= =?UTF-8?q?=E4=BE=A7=E5=8A=A8=E6=80=81=E5=8F=82=E6=95=B0=E5=8F=AF=E4=BB=A5?= =?UTF-8?q?=E8=A7=A3=E6=9E=90=EF=BC=8C=E5=8F=B3=E4=BE=A7=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E5=8A=A8=E6=80=81=E5=8F=82=E6=95=B0=E9=94=99=E8=AF=AF=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Route.class.php | 1 - 1 file changed, 1 deletion(-) diff --git a/ThinkPHP/Library/Think/Route.class.php b/ThinkPHP/Library/Think/Route.class.php index ad44f7893..4907b8335 100644 --- a/ThinkPHP/Library/Think/Route.class.php +++ b/ThinkPHP/Library/Think/Route.class.php @@ -344,7 +344,6 @@ public static function ruleCache($update = false) } $route[] = $args; $result[1][$rule] = $route; - //if($route[0] == 'Home/Article/article') } else { unset($result[1][$rule]); } From 2008b25ddc4202e97caf814d5488697083815e09 Mon Sep 17 00:00:00 2001 From: xiaokun mu Date: Wed, 13 Jan 2016 13:04:47 +0800 Subject: [PATCH 138/166] =?UTF-8?q?think=5Fexception.tpl=20=E5=88=A0?= =?UTF-8?q?=E9=99=A4NOLAYOUT?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Tpl/think_exception.tpl | 5 ----- 1 file changed, 5 deletions(-) diff --git a/ThinkPHP/Tpl/think_exception.tpl b/ThinkPHP/Tpl/think_exception.tpl index 61fd00717..e4afe4fae 100644 --- a/ThinkPHP/Tpl/think_exception.tpl +++ b/ThinkPHP/Tpl/think_exception.tpl @@ -1,8 +1,3 @@ - From c4b755d0a5e5232edaa61dae04bf3d93ef14e5e3 Mon Sep 17 00:00:00 2001 From: xiaokun mu Date: Thu, 14 Jan 2016 18:52:40 +0800 Subject: [PATCH 139/166] =?UTF-8?q?=E4=BF=AE=E6=AD=A3Route.class.php=201.?= =?UTF-8?q?=E8=A7=84=E5=88=99=E8=B7=AF=E7=94=B1=E5=8F=8D=E8=A7=A3=E6=9E=90?= =?UTF-8?q?=E6=97=B6=E8=BF=94=E5=9B=9E=E5=8F=82=E6=95=B0=E7=9A=84=E5=80=BC?= =?UTF-8?q?=E6=B2=A1=E6=9C=89=E4=BD=BF=E7=94=A8urlencode=202.=E6=AD=A3?= =?UTF-8?q?=E5=88=99=E8=B7=AF=E7=94=B1=E5=8F=8D=E8=A7=A3=E6=9E=90=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E6=97=B6=EF=BC=8C=E6=AD=A3=E5=88=99=E9=94=99=E8=AF=AF?= =?UTF-8?q?=203.=E6=AD=A3=E5=88=99=E8=B7=AF=E7=94=B1=E5=8F=8D=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=E6=97=B6=EF=BC=8C=E5=8F=82=E6=95=B0=E9=99=84=E5=8A=A0?= =?UTF-8?q?=E9=94=99=E8=AF=AF,=E6=9C=AA=E4=BD=BF=E7=94=A8urlencode=204.?= =?UTF-8?q?=E6=AD=A3=E5=88=99=E8=B7=AF=E7=94=B1=E7=94=B1=E4=BA=8E=E5=8C=B9?= =?UTF-8?q?=E9=85=8D=E6=97=B6=EF=BC=8C=E6=B2=A1=E6=9C=89=E9=94=AE=E5=80=BC?= =?UTF-8?q?=E5=AF=B9=E6=89=80=E4=BB=A5=E4=B8=8D=E7=B2=BE=E5=87=86=E6=85=8E?= =?UTF-8?q?=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Route.class.php | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/ThinkPHP/Library/Think/Route.class.php b/ThinkPHP/Library/Think/Route.class.php index 4907b8335..5349dbffd 100644 --- a/ThinkPHP/Library/Think/Route.class.php +++ b/ThinkPHP/Library/Think/Route.class.php @@ -188,6 +188,7 @@ public static function reverse($path, &$vars, $depr, $suffix = true) // 匹配成功 if (!empty($flag)) { foreach (array_keys($array) as $key) { + $array[$key] = urlencode($array[$key]); unset($vars[$key]); } return implode($depr, $array); @@ -195,21 +196,23 @@ public static function reverse($path, &$vars, $depr, $suffix = true) } else { // 正则路由 $keys = !empty($args) ? array_keys($args) : array_keys($vars); - $str = preg_replace_callback('/\(.+\)/', function ($match) use (&$vars, &$keys) { + $temp_vars = $vars; + $str = preg_replace_callback('/\(.*?\)/', function ($match) use (&$temp_vars, &$keys) { $k = array_shift($keys); - return isset($vars[$k]) ? $vars[$k] : ''; + $re_var = ''; + if(isset($temp_vars[$k])) + { + $re_var = $temp_vars[$k]; + unset($temp_vars[$k]); + } + return urlencode($re_var); }, $rule); $str = substr($str, 1, -1); $str = rtrim(ltrim($str, '^'), '$'); $str = str_replace('\\', '', $str); if (preg_match($rule, $str, $matches)) { // 匹配成功 - if ($args) { - $keys = array_keys($args); - } - foreach ($keys as $key) { - unset($vars[$key]); - } + $vars = $temp_vars; return str_replace('/', $depr, $str); } } From 38b185b65f62af4cad69f823fad49fb16ce1efcc Mon Sep 17 00:00:00 2001 From: thinkphp Date: Fri, 15 Jan 2016 13:46:16 +0800 Subject: [PATCH 140/166] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E8=AF=AD=E6=B3=95?= =?UTF-8?q?=E5=85=BC=E5=AE=B9=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Common/functions.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/ThinkPHP/Common/functions.php b/ThinkPHP/Common/functions.php index 219f8f702..b2bc163d6 100644 --- a/ThinkPHP/Common/functions.php +++ b/ThinkPHP/Common/functions.php @@ -332,16 +332,16 @@ function I($name, $default = '', $filter = null, $datas = null) break; case 'param': switch ($_SERVER['REQUEST_METHOD']) { - case 'POST': + case 'POST': $input = $_POST; break; - case 'PUT': + case 'PUT': if (is_null($_PUT)) { parse_str(file_get_contents('php://input'), $_PUT); } $input = $_PUT; break; - default: + default: $input = $_GET; } break; @@ -419,19 +419,19 @@ function I($name, $default = '', $filter = null, $datas = null) } if (!empty($type)) { switch (strtolower($type)) { - case 'a': // 数组 + case 'a': // 数组 $data = (array) $data; break; - case 'd': // 数字 + case 'd': // 数字 $data = (int) $data; break; - case 'f': // 浮点 + case 'f': // 浮点 $data = (float) $data; break; - case 'b': // 布尔 + case 'b': // 布尔 $data = (boolean) $data; break; - case 's': // 字符串 + case 's':// 字符串 default: $data = (string) $data; } @@ -1076,7 +1076,7 @@ function U($url = '', $vars = '', $suffix = true, $domain = false) $var[$varController] = MODULE_NAME; } - $vars = array_merge([$varAddon => CONTROLLER_PATH], $vars); + $vars = array_merge(array($varAddon => CONTROLLER_PATH), $vars); } elseif (C('MULTI_MODULE')) { if (MODULE_NAME != C('DEFAULT_MODULE') || !C('MODULE_ALLOW_LIST')) { From 5036e0b413f1dbf8f4235f88000f62008f7bd9a7 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Sun, 17 Jan 2016 22:20:49 +0800 Subject: [PATCH 141/166] =?UTF-8?q?=E6=94=B9=E8=BF=9BU=E5=87=BD=E6=95=B0?= =?UTF-8?q?=E5=AF=B9anchor=E7=9A=84=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Common/functions.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/ThinkPHP/Common/functions.php b/ThinkPHP/Common/functions.php index b2bc163d6..92a427fe1 100644 --- a/ThinkPHP/Common/functions.php +++ b/ThinkPHP/Common/functions.php @@ -332,16 +332,16 @@ function I($name, $default = '', $filter = null, $datas = null) break; case 'param': switch ($_SERVER['REQUEST_METHOD']) { - case 'POST': + case 'POST': $input = $_POST; break; - case 'PUT': + case 'PUT': if (is_null($_PUT)) { parse_str(file_get_contents('php://input'), $_PUT); } $input = $_PUT; break; - default: + default: $input = $_GET; } break; @@ -419,19 +419,19 @@ function I($name, $default = '', $filter = null, $datas = null) } if (!empty($type)) { switch (strtolower($type)) { - case 'a': // 数组 + case 'a': // 数组 $data = (array) $data; break; - case 'd': // 数字 + case 'd': // 数字 $data = (int) $data; break; - case 'f': // 浮点 + case 'f': // 浮点 $data = (float) $data; break; - case 'b': // 布尔 + case 'b': // 布尔 $data = (boolean) $data; break; - case 's':// 字符串 + case 's': // 字符串 default: $data = (string) $data; } @@ -1144,7 +1144,7 @@ function U($url = '', $vars = '', $suffix = true, $domain = false) } } } - if (isset($anchor)) { + if (!empty($anchor)) { $url .= '#' . $anchor; } if ($domain) { From 1dd05ed9b065834c0d763705c4a519dda1419195 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Wed, 20 Jan 2016 14:14:57 +0800 Subject: [PATCH 142/166] =?UTF-8?q?=E4=BF=AE=E6=94=B9View=E7=B1=BB?= =?UTF-8?q?=E7=9A=84PARSE=5FVAR=E8=BE=93=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/View.class.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ThinkPHP/Library/Think/View.class.php b/ThinkPHP/Library/Think/View.class.php index f6c5836c6..f4d13e175 100644 --- a/ThinkPHP/Library/Think/View.class.php +++ b/ThinkPHP/Library/Think/View.class.php @@ -146,9 +146,10 @@ public function fetch($templateFile = '', $content = '', $prefix = '') $content = ob_get_clean(); // 内容过滤标签 Hook::listen('view_filter', $content); - if(APP_DEBUG){ // debug模式时,将后台分配变量输出到浏览器控制台 + if (APP_DEBUG && C('PARSE_VAR')) { + // debug模式时,将后台分配变量输出到浏览器控制台 $parseVar = empty($this->tVar) ? json_encode(array()) : json_encode($this->tVar); - $content = $content.''; + $content = $content . ''; } // 输出模板文件 return $content; From 8d8e002384b51a79557d505c0637e61ad24ff606 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Wed, 20 Jan 2016 19:05:04 +0800 Subject: [PATCH 143/166] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=BA=93=E5=8F=82=E6=95=B0=E7=BB=91=E5=AE=9A=E4=B8=80=E5=A4=84?= =?UTF-8?q?BUG?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Db/Driver.class.php | 21 +++++++++---------- .../Library/Think/Db/Driver/Mysql.class.php | 6 +++--- .../Library/Think/Db/Driver/Sqlsrv.class.php | 2 +- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/ThinkPHP/Library/Think/Db/Driver.class.php b/ThinkPHP/Library/Think/Db/Driver.class.php index 185dc5e40..230021759 100644 --- a/ThinkPHP/Library/Think/Db/Driver.class.php +++ b/ThinkPHP/Library/Think/Db/Driver.class.php @@ -414,11 +414,11 @@ protected function parseSet($data) } elseif (is_scalar($val)) { // 过滤非标量数据 if (0 === strpos($val, ':') && in_array($val, array_keys($this->bind))) { - $set[] = $this->parseKey($key) . '=' . $this->escapeString($val); + $set[] = $this->parseKey($key) . '=' . $val; } else { $name = count($this->bind); - $set[] = $this->parseKey($key) . '=:' . $name; - $this->bindParam($name, $val); + $set[] = $this->parseKey($key) . '=:' . $key . '_' . $name; + $this->bindParam($key . '_' . $name, $val); } } } @@ -443,7 +443,7 @@ protected function bindParam($name, $value) * @param string $key * @return string */ - protected function parseKey(&$key) + protected function parseKey($key) { return $key; } @@ -522,8 +522,7 @@ protected function parseTable($tables) } $tables = $array; } elseif (is_string($tables)) { - $tables = explode(',', $tables); - array_walk($tables, array(&$this, 'parseKey')); + $tables = array_map(array($this, 'parseKey'), explode(',', $tables)); } return implode(',', $tables); } @@ -909,11 +908,11 @@ public function insert($data, $options = array(), $replace = false) // 过滤非标量数据 $fields[] = $this->parseKey($key); if (0 === strpos($val, ':') && in_array($val, array_keys($this->bind))) { - $values[] = $this->parseValue($val); + $values[] = $val; } else { $name = count($this->bind); - $values[] = ':' . $name; - $this->bindParam($name, $val); + $values[] = ':' . $key . '_' . $name; + $this->bindParam($key . '_' . $name, $val); } } } @@ -982,8 +981,8 @@ public function selectInsert($fields, $table, $options = array()) $fields = explode(',', $fields); } - array_walk($fields, array($this, 'parseKey')); - $sql = 'INSERT INTO ' . $this->parseTable($table) . ' (' . implode(',', $fields) . ') '; + $fields = array_map(array($this, 'parseKey'), $fields); + $sql = 'INSERT INTO ' . $this->parseTable($table) . ' (' . implode(',', $fields) . ') '; $sql .= $this->buildSelectSql($options); return $this->execute($sql, !empty($options['fetch_sql']) ? true : false); } diff --git a/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php b/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php index 975d6c933..afe9777c4 100644 --- a/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php +++ b/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php @@ -98,7 +98,7 @@ public function getTables($dbName = '') * @param string $key * @return string */ - protected function parseKey(&$key) + protected function parseKey($key) { $key = trim($key); if (!is_numeric($key) && !preg_match('/[,\'\"\*\(\)`.\s]/', $key)) { @@ -197,10 +197,10 @@ protected function parseDuplicate($duplicate) } switch ($val[0]) { - case 'exp': // 表达式 + case 'exp': // 表达式 $updates[] = $this->parseKey($key) . "=($val[1])"; break; - case 'value': // 值 + case 'value':// 值 default: $name = count($this->bind); $updates[] = $this->parseKey($key) . "=:" . $name; diff --git a/ThinkPHP/Library/Think/Db/Driver/Sqlsrv.class.php b/ThinkPHP/Library/Think/Db/Driver/Sqlsrv.class.php index fadf0a2c9..f7c7e407c 100644 --- a/ThinkPHP/Library/Think/Db/Driver/Sqlsrv.class.php +++ b/ThinkPHP/Library/Think/Db/Driver/Sqlsrv.class.php @@ -109,7 +109,7 @@ protected function parseOrder($order) * @param string $key * @return string */ - protected function parseKey(&$key) + protected function parseKey($key) { $key = trim($key); if (!is_numeric($key) && !preg_match('/[,\'\"\*\(\)\[.\s]/', $key)) { From b1638ecc7d067bdfb95f7551e320ec3653ef2020 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Thu, 21 Jan 2016 10:58:44 +0800 Subject: [PATCH 144/166] =?UTF-8?q?=E4=BF=AE=E6=AD=A3insertall=E6=96=B9?= =?UTF-8?q?=E6=B3=95=E7=9A=84=E5=8F=82=E6=95=B0=E7=BB=91=E5=AE=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Db/Driver.class.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ThinkPHP/Library/Think/Db/Driver.class.php b/ThinkPHP/Library/Think/Db/Driver.class.php index 230021759..d934e0db2 100644 --- a/ThinkPHP/Library/Think/Db/Driver.class.php +++ b/ThinkPHP/Library/Think/Db/Driver.class.php @@ -417,8 +417,8 @@ protected function parseSet($data) $set[] = $this->parseKey($key) . '=' . $val; } else { $name = count($this->bind); - $set[] = $this->parseKey($key) . '=:' . $key . '_' . $name; - $this->bindParam($key . '_' . $name, $val); + $set[] = $this->parseKey($key) . '=:' . 'bind_' . $name; + $this->bindParam('bind_' . $name, $val); } } } @@ -911,8 +911,8 @@ public function insert($data, $options = array(), $replace = false) $values[] = $val; } else { $name = count($this->bind); - $values[] = ':' . $key . '_' . $name; - $this->bindParam($key . '_' . $name, $val); + $values[] = ':' . 'bind_' . $name; + $this->bindParam('bind_' . $name, $val); } } } @@ -950,11 +950,11 @@ public function insertAll($dataSet, $options = array(), $replace = false) $value[] = 'NULL'; } elseif (is_scalar($val)) { if (0 === strpos($val, ':') && in_array($val, array_keys($this->bind))) { - $value[] = $this->parseValue($val); + $value[] = $val; } else { $name = count($this->bind); - $value[] = ':' . $name; - $this->bindParam($name, $val); + $value[] = ':' . 'bind_' . $name; + $this->bindParam('bind_' . $name, $val); } } } From 4f332b2e94a6482c7f6fd464d12034b7f845882a Mon Sep 17 00:00:00 2001 From: thinkphp Date: Thu, 21 Jan 2016 11:14:18 +0800 Subject: [PATCH 145/166] =?UTF-8?q?=E6=94=B9=E8=BF=9B=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E7=9A=84=E8=87=AA=E5=8A=A8=E7=BB=91=E5=AE=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Db/Driver.class.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ThinkPHP/Library/Think/Db/Driver.class.php b/ThinkPHP/Library/Think/Db/Driver.class.php index d934e0db2..cd8668be8 100644 --- a/ThinkPHP/Library/Think/Db/Driver.class.php +++ b/ThinkPHP/Library/Think/Db/Driver.class.php @@ -417,8 +417,8 @@ protected function parseSet($data) $set[] = $this->parseKey($key) . '=' . $val; } else { $name = count($this->bind); - $set[] = $this->parseKey($key) . '=:' . 'bind_' . $name; - $this->bindParam('bind_' . $name, $val); + $set[] = $this->parseKey($key) . '=:' . NOW_TIME.'_' . $name; + $this->bindParam(NOW_TIME.'_' . $name, $val); } } } @@ -911,8 +911,8 @@ public function insert($data, $options = array(), $replace = false) $values[] = $val; } else { $name = count($this->bind); - $values[] = ':' . 'bind_' . $name; - $this->bindParam('bind_' . $name, $val); + $values[] = ':' . NOW_TIME.'_' . $name; + $this->bindParam(NOW_TIME.'_' . $name, $val); } } } @@ -953,8 +953,8 @@ public function insertAll($dataSet, $options = array(), $replace = false) $value[] = $val; } else { $name = count($this->bind); - $value[] = ':' . 'bind_' . $name; - $this->bindParam('bind_' . $name, $val); + $value[] = ':' . NOW_TIME.'_' . $name; + $this->bindParam(NOW_TIME.'_' . $name, $val); } } } From e70056179f98b281d513841d156f178d6234ee26 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Thu, 21 Jan 2016 14:41:35 +0800 Subject: [PATCH 146/166] =?UTF-8?q?=E4=BF=AE=E6=AD=A3db=E7=B1=BB=E7=9A=84p?= =?UTF-8?q?arseDsn=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Db.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ThinkPHP/Library/Think/Db.class.php b/ThinkPHP/Library/Think/Db.class.php index 39f12b965..0a7117600 100644 --- a/ThinkPHP/Library/Think/Db.class.php +++ b/ThinkPHP/Library/Think/Db.class.php @@ -125,7 +125,7 @@ private static function parseDsn($dsnStr) '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) : '', + 'database' => isset($info['path']) ? ltrim($info['path'], '/') : '', 'charset' => isset($info['fragment']) ? $info['fragment'] : 'utf8', ); From 8928c459a49a47a1e91293d715368c7791e6aed3 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Sat, 23 Jan 2016 09:45:44 +0800 Subject: [PATCH 147/166] =?UTF-8?q?=E4=BF=AE=E6=AD=A3insertall=E6=96=B9?= =?UTF-8?q?=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Db/Driver.class.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ThinkPHP/Library/Think/Db/Driver.class.php b/ThinkPHP/Library/Think/Db/Driver.class.php index 230021759..761a08e77 100644 --- a/ThinkPHP/Library/Think/Db/Driver.class.php +++ b/ThinkPHP/Library/Think/Db/Driver.class.php @@ -950,11 +950,11 @@ public function insertAll($dataSet, $options = array(), $replace = false) $value[] = 'NULL'; } elseif (is_scalar($val)) { if (0 === strpos($val, ':') && in_array($val, array_keys($this->bind))) { - $value[] = $this->parseValue($val); + $value[] = $val; } else { $name = count($this->bind); - $value[] = ':' . $name; - $this->bindParam($name, $val); + $value[] = ':' . $key . '_' . $name; + $this->bindParam($key . '_' . $name, $val); } } } From 03145076a05f10af9c3dcc8cc91e273e5b782c9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E9=87=91=E7=84=95-qy?= Date: Thu, 28 Jan 2016 15:29:13 +0800 Subject: [PATCH 148/166] =?UTF-8?q?=E4=BF=AE=E6=94=B9BUILD=5FLITE=5FFILE?= =?UTF-8?q?=20=E7=9A=84true,false=E5=88=A4=E6=96=AD=EF=BC=9B=E4=BF=AE?= =?UTF-8?q?=E6=94=B9http=20download=E5=85=BC=E5=AE=B9=E4=B8=AD=E6=96=87?= =?UTF-8?q?=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Behavior/BuildLiteBehavior.class.php | 2 +- ThinkPHP/Library/Org/Net/Http.class.php | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/ThinkPHP/Library/Behavior/BuildLiteBehavior.class.php b/ThinkPHP/Library/Behavior/BuildLiteBehavior.class.php index 294c27d38..145b4f747 100644 --- a/ThinkPHP/Library/Behavior/BuildLiteBehavior.class.php +++ b/ThinkPHP/Library/Behavior/BuildLiteBehavior.class.php @@ -18,7 +18,7 @@ class BuildLiteBehavior { public function run(&$params) { - if (!defined('BUILD_LITE_FILE')) { + if (!defined('BUILD_LITE_FILE') || BUILD_LITE_FILE == false) { return; } diff --git a/ThinkPHP/Library/Org/Net/Http.class.php b/ThinkPHP/Library/Org/Net/Http.class.php index 94b509715..3e301071e 100644 --- a/ThinkPHP/Library/Org/Net/Http.class.php +++ b/ThinkPHP/Library/Org/Net/Http.class.php @@ -164,7 +164,7 @@ public static function download($filename, $showname = '', $content = '', $expir if (empty($showname)) { $showname = $filename; } - $showname = basename($showname); + $showname = self::get_basename($showname);; if (!empty($filename)) { $finfo = new \finfo(FILEINFO_MIME); $type = $finfo->file($filename); @@ -190,6 +190,14 @@ public static function download($filename, $showname = '', $content = '', $expir exit(); } + /** + * 获取文件的名称,兼容中文名 + * @return string + */ + static public function get_basename($filename){ + return preg_replace('/^.+[\\\\\\/]/', '', $filename); + } + /** * 显示HTTP Header 信息 * @return string From 2f464ada52246cc2d9b71828fcb66778a1e3da38 Mon Sep 17 00:00:00 2001 From: rural21st <397778701@qq.com> Date: Fri, 5 Feb 2016 03:50:25 +0800 Subject: [PATCH 149/166] Update RestController.class.php MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 当url未定义访问类型时,如:http://localhost/Home/Index/index 其HTTP_ACCEPT为:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 应该优先匹配 'html' => 'text/html,application/xhtml+xml,*/*', 而不是xml --- ThinkPHP/Library/Think/Controller/RestController.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ThinkPHP/Library/Think/Controller/RestController.class.php b/ThinkPHP/Library/Think/Controller/RestController.class.php index 63233ebc8..92f2e206f 100644 --- a/ThinkPHP/Library/Think/Controller/RestController.class.php +++ b/ThinkPHP/Library/Think/Controller/RestController.class.php @@ -104,6 +104,7 @@ public function __call($method, $args) protected function getAcceptType() { $type = array( + 'html' => 'text/html,application/xhtml+xml,*/*', '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', @@ -117,7 +118,6 @@ protected function getAcceptType() 'jpg' => 'image/jpg,image/jpeg,image/pjpeg', 'gif' => 'image/gif', 'csv' => 'text/csv', - 'html' => 'text/html,application/xhtml+xml,*/*', ); foreach ($type as $key => $val) { From 8794f9614afe51547e7a9a7d4c20c105d7410ed1 Mon Sep 17 00:00:00 2001 From: SmdCn Date: Fri, 19 Feb 2016 13:54:27 +0800 Subject: [PATCH 150/166] =?UTF-8?q?Memcached=20=E9=A9=B1=E5=8A=A8=E8=BF=87?= =?UTF-8?q?=E6=9C=9F=E6=97=B6=E9=97=B4=E8=AE=BE=E7=BD=AE=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Cache/Driver/Memcached.class.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ThinkPHP/Library/Think/Cache/Driver/Memcached.class.php b/ThinkPHP/Library/Think/Cache/Driver/Memcached.class.php index 5cf08faf1..82b38a5dd 100644 --- a/ThinkPHP/Library/Think/Cache/Driver/Memcached.class.php +++ b/ThinkPHP/Library/Think/Cache/Driver/Memcached.class.php @@ -72,7 +72,8 @@ public function set($name, $value, $expire = null) $expire = $this->options['expire']; } $name = $this->options['prefix'] . $name; - if ($this->handler->set($name, $value, time() + $expire)) { + $expire = $expire == 0 ? 0 : time() + $expire; + if ($this->handler->set($name, $value, $expire)) { if ($this->options['length'] > 0) { // 记录缓存队列 $this->queue($name); From 352a4e6284211d5390abe653e36de77a33ab4abb Mon Sep 17 00:00:00 2001 From: thinkphp Date: Sat, 20 Feb 2016 11:56:06 +0800 Subject: [PATCH 151/166] =?UTF-8?q?=E6=94=B9=E8=BF=9Bmodel=E7=B1=BB?= =?UTF-8?q?=E7=9A=84updateFields=E5=B1=9E=E6=80=A7=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Model.class.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ThinkPHP/Library/Think/Model.class.php b/ThinkPHP/Library/Think/Model.class.php index 897c72d7e..8f1fe61e7 100644 --- a/ThinkPHP/Library/Think/Model.class.php +++ b/ThinkPHP/Library/Think/Model.class.php @@ -1101,6 +1101,15 @@ public function create($data = '', $type = '') $fields = $this->insertFields; } elseif (self::MODEL_UPDATE == $type && isset($this->updateFields)) { $fields = $this->updateFields; + $pk = $this->getPk(); + if (is_string($pk)) { + array_push($fields, $pk); + } + if (is_array($pk)) { + foreach ($pk as $pkTemp) { + array_push($fields, $pkTemp); + } + } } if (isset($fields)) { if (is_string($fields)) { From 23c1ff48bf6d7ad901018e00ca238e6fe2c5cd36 Mon Sep 17 00:00:00 2001 From: He Lieting Date: Wed, 9 Mar 2016 16:43:31 +0800 Subject: [PATCH 152/166] Update Storage.class.php __callstatic => __callStatic --- ThinkPHP/Library/Think/Storage.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ThinkPHP/Library/Think/Storage.class.php b/ThinkPHP/Library/Think/Storage.class.php index df4bdabb5..7e5140066 100644 --- a/ThinkPHP/Library/Think/Storage.class.php +++ b/ThinkPHP/Library/Think/Storage.class.php @@ -34,7 +34,7 @@ public static function connect($type = 'File', $options = array()) self::$handler = new $class($options); } - public static function __callstatic($method, $args) + public static function __callStatic($method, $args) { //调用缓存驱动的方法 if (method_exists(self::$handler, $method)) { From eebad035886b71557f2f4fbb0f0e111d366daaa2 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Fri, 18 Mar 2016 14:21:40 +0800 Subject: [PATCH 153/166] =?UTF-8?q?=E4=BF=AE=E6=AD=A3U=E5=87=BD=E6=95=B0?= =?UTF-8?q?=E4=B8=80=E5=A4=84=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Common/functions.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/ThinkPHP/Common/functions.php b/ThinkPHP/Common/functions.php index 92a427fe1..b06dff8e7 100644 --- a/ThinkPHP/Common/functions.php +++ b/ThinkPHP/Common/functions.php @@ -332,16 +332,16 @@ function I($name, $default = '', $filter = null, $datas = null) break; case 'param': switch ($_SERVER['REQUEST_METHOD']) { - case 'POST': + case 'POST': $input = $_POST; break; - case 'PUT': + case 'PUT': if (is_null($_PUT)) { parse_str(file_get_contents('php://input'), $_PUT); } $input = $_PUT; break; - default: + default: $input = $_GET; } break; @@ -419,19 +419,19 @@ function I($name, $default = '', $filter = null, $datas = null) } if (!empty($type)) { switch (strtolower($type)) { - case 'a': // 数组 + case 'a': // 数组 $data = (array) $data; break; - case 'd': // 数字 + case 'd': // 数字 $data = (int) $data; break; - case 'f': // 浮点 + case 'f': // 浮点 $data = (float) $data; break; - case 'b': // 布尔 + case 'b': // 布尔 $data = (boolean) $data; break; - case 's': // 字符串 + case 's':// 字符串 default: $data = (string) $data; } @@ -1090,7 +1090,7 @@ function U($url = '', $vars = '', $suffix = true, $domain = false) } } if (isset($var[$varModule])) { - $module = defined('BIND_MODULE') && BIND_MODULE == $module ? '' : $var[$varModule]; + $module = defined('BIND_MODULE') && BIND_MODULE == $var[$varModule] ? '' : $var[$varModule]; unset($var[$varModule]); } From 59a9cb1527eea35be9501721debecaf3b17b2990 Mon Sep 17 00:00:00 2001 From: Terran Date: Tue, 22 Mar 2016 15:38:43 +0800 Subject: [PATCH 154/166] =?UTF-8?q?=E8=A7=A3=E5=86=B3ON=20DUPLICATE=20KEY?= =?UTF-8?q?=E6=97=B6=E5=80=BC=E4=B8=8D=E8=83=BD=E4=B8=BANULL=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Db/Driver/Mysql.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php b/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php index afe9777c4..4b847ea60 100644 --- a/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php +++ b/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php @@ -192,7 +192,7 @@ protected function parseDuplicate($duplicate) $val = array('value', $val); } - if (!isset($val[1])) { + if (!isset($val[1]) && !is_null($val[1])) { continue; } From facf7f1e1248de21645c3461aaaf0923e602bc18 Mon Sep 17 00:00:00 2001 From: DefineFC Date: Fri, 15 Apr 2016 10:52:46 +0800 Subject: [PATCH 155/166] =?UTF-8?q?=E8=A7=A3=E5=86=B3Json=E4=B8=AD?= =?UTF-8?q?=E6=96=87=E7=BC=96=E7=A0=81=E4=B8=BAunicode=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 解决Json中文编码为unicode的问题(mod RestController.class.php) PHP>=5.4, 使用JSON_UNESCAPED_UNICODE 在PHP<=5.3中,先将中文字段urlencode,json_encode后,再用urldecode,也可以保证中文不会被转成unicode ref:http://www.thinkphp.cn/topic/7857.html --- .../Think/Controller/RestController.class.php | 42 ++++++++++++++++++- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/ThinkPHP/Library/Think/Controller/RestController.class.php b/ThinkPHP/Library/Think/Controller/RestController.class.php index 92f2e206f..3146e66b2 100644 --- a/ThinkPHP/Library/Think/Controller/RestController.class.php +++ b/ThinkPHP/Library/Think/Controller/RestController.class.php @@ -203,9 +203,14 @@ protected function encodeData($data, $type = '') return ''; } - if ('json' == $type) { + if('json' == $type) { // 返回JSON数据格式到客户端 包含状态信息 - $data = json_encode($data); + if(version_compare(PHP_VERSION,'5.4.0','<')) { + $this->arrayRecursive($data, 'urlencode', true); + $data = urldecode(json_encode($data)); + } else { + $data = json_encode($data,JSON_UNESCAPED_UNICODE); + } } elseif ('xml' == $type) { // 返回xml格式数据 $data = xml_encode($data); @@ -217,6 +222,39 @@ protected function encodeData($data, $type = '') return $data; } + /************************************************************** + * + * 使用特定function对数组中所有元素做处理 + * @param string &$array 要处理的字符串 + * @param string $function 要执行的函数 + * @return boolean $apply_to_keys_also 是否也应用到key上 + * @access protected + * + *************************************************************/ + protected function arrayRecursive(&$array, $function, $apply_to_keys_also = false) + { + static $recursive_counter = 0; + if (++$recursive_counter > 1000) { + die('possible deep recursion attack'); + } + foreach ($array as $key => $value) { + if (is_array($value)) { + $this->arrayRecursive($array[$key], $function, $apply_to_keys_also); + } else { + $array[$key] = $function($value); + } + + if ($apply_to_keys_also && is_string($key)) { + $new_key = $function($key); + if ($new_key != $key) { + $array[$new_key] = $array[$key]; + unset($array[$key]); + } + } + } + $recursive_counter--; + } + /** * 设置页面输出的CONTENT_TYPE和编码 * @access public From f8597483d47b226234b7f8cd7ed6dd9a11b0470b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=87=91=E9=BB=8E=E6=98=8E?= Date: Fri, 15 Apr 2016 16:30:13 +0800 Subject: [PATCH 156/166] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BA=86IpLocation?= =?UTF-8?q?=E7=B1=BB=E7=9A=84=E6=9E=84=E9=80=A0=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修改了IpLocation类的构造函数,允许传入的参数是一个文件的绝对路径,如果不是绝对路径,再考虑使用原来的方法在类库的当前文件夹下寻找文件。 --- ThinkPHP/Library/Org/Net/IpLocation.class.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ThinkPHP/Library/Org/Net/IpLocation.class.php b/ThinkPHP/Library/Org/Net/IpLocation.class.php index bf7c70347..8d8562e63 100644 --- a/ThinkPHP/Library/Org/Net/IpLocation.class.php +++ b/ThinkPHP/Library/Org/Net/IpLocation.class.php @@ -54,7 +54,10 @@ class IpLocation public function __construct($filename = "UTFWry.dat") { $this->fp = 0; - if (($this->fp = fopen(dirname(__FILE__) . '/' . $filename, 'rb')) !== false) { + if(!is_file($filename)) { + $filename = dirname(__FILE__) . '/' . $filename; + } + if (($this->fp = fopen($filename, 'rb')) !== false) { $this->firstip = $this->getlong(); $this->lastip = $this->getlong(); $this->totalip = ($this->lastip - $this->firstip) / 7; From cb82feb775e9818fed0cdc19458c19ddf61a1865 Mon Sep 17 00:00:00 2001 From: Takuya Date: Mon, 18 Apr 2016 16:26:27 +0800 Subject: [PATCH 157/166] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=AB=98=E5=B9=B6?= =?UTF-8?q?=E5=8F=91=E4=B8=8BRuntime=E7=9A=84=E4=B8=80=E4=B8=AA=E6=AD=BB?= =?UTF-8?q?=E9=94=81Bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 这个Bug只有在并发量很大的时候才会产生。 我们在实际中遇到了这个Bug,通过Core dump跟踪系统调用定位到了这个Bug。 这里列举一个可能产生的情况: 线程A来访的时候,如果处于Debug开启或者找不到Runtime的状态,会进入编译Runtime的分支,但是编译分支的最开始首先就把老的Runtime删除了。然后进行后续操作。此时,如果刚好又出现了一个线程B,在线程A还在构建Runtime的过程中,访问到服务器,找不到Runtime文件,此时线程B正准备进入构建Runtime的分支,而此时如果恰巧线程A刚好已经执行完了构建Runtime的操作,保存Runtime到文件中,而此时线程B要恰巧开始执行删除文件指令了,这是刚创建好的文件就被删掉了,此时线程B又会会继续创建Runtime,假设此时来了一个线程C,又会进入这样的循环。 这个Bug需要来访特别密集,否则也不容易触发,修改方案就和我代码中呈现的一样,取消else后的第一个文件删除应该就可以了。 --- ThinkPHP/Library/Think/Think.class.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ThinkPHP/Library/Think/Think.class.php b/ThinkPHP/Library/Think/Think.class.php index 8ae9fca82..c63a9d2f7 100644 --- a/ThinkPHP/Library/Think/Think.class.php +++ b/ThinkPHP/Library/Think/Think.class.php @@ -44,9 +44,10 @@ public static function start() if (!APP_DEBUG && Storage::has($runtimefile)) { Storage::load($runtimefile); } else { - if (Storage::has($runtimefile)) { + //在高并发状态下,这里容易引起死锁,建议去掉这里的删除和重建,毕竟后面已经有一个删除和重建操作了 + /*if (Storage::has($runtimefile)) { Storage::unlink($runtimefile); - } + }*/ $content = ''; // 读取应用模式 From 787fc9af3927e0662c0a07b893b7779e3eb38354 Mon Sep 17 00:00:00 2001 From: Jake Date: Tue, 19 Apr 2016 09:42:43 +0800 Subject: [PATCH 158/166] =?UTF-8?q?=E5=AF=B9DefineFC=20=E7=9A=84=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E5=81=9A=E4=B8=80=E7=82=B9=E5=B0=8F=E5=B0=8F=E7=9A=84?= =?UTF-8?q?=E6=94=B9=E8=BF=9B=EF=BC=9A=E5=B8=83=E5=B0=94=E5=80=BC=E6=88=96?= =?UTF-8?q?=E8=80=85=E5=AF=B9=E8=B1=A1=E4=B8=8D=E5=BA=94=E8=AF=A5=E8=A2=AB?= =?UTF-8?q?=E5=BA=94=E7=94=A8=E5=88=B0$function=E4=B8=8A=EF=BC=8C=E5=90=A6?= =?UTF-8?q?=E5=88=99=E6=95=B0=E6=8D=AE=E5=8F=AF=E8=83=BD=E4=BC=9A=E4=BA=A7?= =?UTF-8?q?=E7=94=9F=E5=8F=98=E5=8C=96(=E6=AF=94=E5=A6=82=E5=B8=83?= =?UTF-8?q?=E5=B0=94=E5=80=BC=E4=BC=9A=E5=8F=98=E6=88=901)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Controller/RestController.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ThinkPHP/Library/Think/Controller/RestController.class.php b/ThinkPHP/Library/Think/Controller/RestController.class.php index 3146e66b2..3300455d4 100644 --- a/ThinkPHP/Library/Think/Controller/RestController.class.php +++ b/ThinkPHP/Library/Think/Controller/RestController.class.php @@ -225,7 +225,7 @@ protected function encodeData($data, $type = '') /************************************************************** * * 使用特定function对数组中所有元素做处理 - * @param string &$array 要处理的字符串 + * @param string|array &$array 要处理的字符串或者数组 * @param string $function 要执行的函数 * @return boolean $apply_to_keys_also 是否也应用到key上 * @access protected @@ -240,7 +240,7 @@ protected function arrayRecursive(&$array, $function, $apply_to_keys_also = fals foreach ($array as $key => $value) { if (is_array($value)) { $this->arrayRecursive($array[$key], $function, $apply_to_keys_also); - } else { + } elseif(is_string($value)) { $array[$key] = $function($value); } From 03ebce77aed95c01777d15121aae84804ae2a9a5 Mon Sep 17 00:00:00 2001 From: You Ming Date: Tue, 19 Apr 2016 16:22:30 +0800 Subject: [PATCH 159/166] =?UTF-8?q?=E8=AE=A9=E6=95=B0=E6=8D=AE=E5=BA=93?= =?UTF-8?q?=E4=BA=8B=E5=8A=A1=E6=93=8D=E4=BD=9C=E6=9B=B4=E5=87=86=E7=A1=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 使用事务时只选取一个数据库连接 2. 嵌套事务只在最外层提交 --- ThinkPHP/Library/Think/Db/Driver.class.php | 20 +++++++++++++++--- ThinkPHP/Library/Think/Db/Lite.class.php | 24 +++++++++++++++++----- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/ThinkPHP/Library/Think/Db/Driver.class.php b/ThinkPHP/Library/Think/Db/Driver.class.php index 761a08e77..dc45c1162 100644 --- a/ThinkPHP/Library/Think/Db/Driver.class.php +++ b/ThinkPHP/Library/Think/Db/Driver.class.php @@ -28,6 +28,8 @@ abstract class Driver protected $lastInsID = null; // 返回或者影响记录数 protected $numRows = 0; + // 事物操作PDO实例 + protected $transPDO = null; // 事务指令数 protected $transTimes = 0; // 错误信息 @@ -276,6 +278,8 @@ public function startTrans() //数据rollback 支持 if (0 == $this->transTimes) { + // 记录当前操作PDO + $this->transPdo = $this->_linkID; $this->_linkID->beginTransaction(); } $this->transTimes++; @@ -289,13 +293,17 @@ public function startTrans() */ public function commit() { - if ($this->transTimes > 0) { - $result = $this->_linkID->commit(); + if ($this->transTimes == 1) { + // 由嵌套事物的最外层进行提交 + $result = $this->_linkID->commit(); $this->transTimes = 0; + $this->transPdo = null; if (!$result) { $this->error(); return false; } + } else { + $this->transTimes--; } return true; } @@ -308,8 +316,9 @@ public function commit() public function rollback() { if ($this->transTimes > 0) { - $result = $this->_linkID->rollback(); + $result = $this->_linkID->rollback(); $this->transTimes = 0; + $this->transPdo = null; if (!$result) { $this->error(); return false; @@ -1188,6 +1197,11 @@ protected function debug($start) */ protected function initConnect($master = true) { + // 开启事物时用同一个连接进行操作 + if ($this->transPDO) { + return $this->transPDO; + } + if (!empty($this->config['deploy'])) // 采用分布式数据库 { diff --git a/ThinkPHP/Library/Think/Db/Lite.class.php b/ThinkPHP/Library/Think/Db/Lite.class.php index ad6ef16ed..8afc496c6 100644 --- a/ThinkPHP/Library/Think/Db/Lite.class.php +++ b/ThinkPHP/Library/Think/Db/Lite.class.php @@ -28,6 +28,8 @@ class Lite protected $lastInsID = null; // 返回或者影响记录数 protected $numRows = 0; + // 事物操作PDO实例 + protected $transPDO = null; // 事务指令数 protected $transTimes = 0; // 错误信息 @@ -248,6 +250,8 @@ public function startTrans() //数据rollback 支持 if (0 == $this->transTimes) { + // 记录当前操作PDO + $this->transPdo = $this->_linkID; $this->_linkID->beginTransaction(); } $this->transTimes++; @@ -261,13 +265,17 @@ public function startTrans() */ public function commit() { - if ($this->transTimes > 0) { - $result = $this->_linkID->commit(); + if ($this->transTimes == 1) { + // 由嵌套事物的最外层进行提交 + $result = $this->_linkID->commit(); $this->transTimes = 0; + $this->transPdo = null; if (!$result) { $this->error(); return false; } + } else { + $this->transTimes--; } return true; } @@ -280,8 +288,9 @@ public function commit() public function rollback() { if ($this->transTimes > 0) { - $result = $this->_linkID->rollback(); + $result = $this->_linkID->rollback(); $this->transTimes = 0; + $this->transPdo = null; if (!$result) { $this->error(); return false; @@ -353,7 +362,7 @@ public function error() // 记录错误日志 trace($this->error, '', 'ERR'); if ($this->config['debug']) { -// 开启数据库调试模式 + // 开启数据库调试模式 E($this->error); } else { return $this->error; @@ -421,7 +430,7 @@ public function setModel($model) protected function debug($start) { if ($this->config['debug']) { -// 开启数据库调试模式 + // 开启数据库调试模式 if ($start) { G('queryStartTime'); } else { @@ -442,6 +451,11 @@ protected function debug($start) */ protected function initConnect($master = true) { + // 开启事物时用同一个连接进行操作 + if ($this->transPDO) { + return $this->transPDO; + } + if (!empty($this->config['deploy'])) // 采用分布式数据库 { From 3a9fc49c63814d52f1eb158d46fe9ad2fa437457 Mon Sep 17 00:00:00 2001 From: "yangjingqzp@163.com" Date: Sat, 23 Apr 2016 16:11:12 +0800 Subject: [PATCH 160/166] =?UTF-8?q?=E5=A4=9A=E6=95=B0=E6=8D=AE=E5=BA=93?= =?UTF-8?q?=EF=BC=8C=E5=88=9D=E5=A7=8B=E5=8C=96Model=E6=97=B6=E5=AF=B9?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E8=A1=A8=E5=89=8D=E7=BC=80=E5=86=85=E5=AE=B9?= =?UTF-8?q?=E7=9A=84=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Model.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ThinkPHP/Library/Think/Model.class.php b/ThinkPHP/Library/Think/Model.class.php index 8f1fe61e7..140c18db6 100644 --- a/ThinkPHP/Library/Think/Model.class.php +++ b/ThinkPHP/Library/Think/Model.class.php @@ -93,7 +93,7 @@ public function __construct($name = '', $tablePrefix = '', $connection = '') } elseif ('' != $tablePrefix) { $this->tablePrefix = $tablePrefix; } elseif (!isset($this->tablePrefix)) { - $this->tablePrefix = C('DB_PREFIX'); + $this->tablePrefix = empty($this->connection) ? C('DB_PREFIX') : C($this->connection.'.DB_PREFIX'); } // 数据库初始化操作 From 6e273cca0a492967a61fadbccc7ebe6378d7f5e5 Mon Sep 17 00:00:00 2001 From: "yangjingqzp@163.com" Date: Tue, 26 Apr 2016 07:36:18 +0800 Subject: [PATCH 161/166] =?UTF-8?q?=E5=A4=9A=E6=95=B0=E6=8D=AE=E5=BA=93?= =?UTF-8?q?=E8=BF=9E=E6=8E=A5=E6=97=B6=EF=BC=8C=E5=A2=9E=E5=8A=A0=E5=AF=B9?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E8=A1=A8=E5=89=8D=E7=BC=80=E6=B2=A1=E6=9C=89?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E7=9A=84=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Model.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ThinkPHP/Library/Think/Model.class.php b/ThinkPHP/Library/Think/Model.class.php index 140c18db6..df50e0054 100644 --- a/ThinkPHP/Library/Think/Model.class.php +++ b/ThinkPHP/Library/Think/Model.class.php @@ -93,7 +93,7 @@ public function __construct($name = '', $tablePrefix = '', $connection = '') } elseif ('' != $tablePrefix) { $this->tablePrefix = $tablePrefix; } elseif (!isset($this->tablePrefix)) { - $this->tablePrefix = empty($this->connection) ? C('DB_PREFIX') : C($this->connection.'.DB_PREFIX'); + $this->tablePrefix = !empty($this->connection) && !is_null(C($this->connection.'.DB_PREFIX')) ? C($this->connection.'.DB_PREFIX') : C('DB_PREFIX'); } // 数据库初始化操作 From 9c243dd0925daffcc984b42bf16583ffebba3332 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Wed, 27 Apr 2016 11:47:28 +0800 Subject: [PATCH 162/166] =?UTF-8?q?=E6=94=B9=E8=BF=9BMongoDb=E9=A9=B1?= =?UTF-8?q?=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThinkPHP/Library/Think/Db/Driver/Mongo.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ThinkPHP/Library/Think/Db/Driver/Mongo.class.php b/ThinkPHP/Library/Think/Db/Driver/Mongo.class.php index 36e0c64b3..8fe879142 100644 --- a/ThinkPHP/Library/Think/Db/Driver/Mongo.class.php +++ b/ThinkPHP/Library/Think/Db/Driver/Mongo.class.php @@ -622,7 +622,7 @@ protected function parseSet($data) if (is_array($val)) { switch ($val[0]) { case 'inc': - $result['$inc'][$key] = (int) $val[1]; + $result['$inc'][$key] = (float) $val[1]; break; case 'set': case 'unset': From ac8dc2d3814e43d02a519169c8b893680386fd4e Mon Sep 17 00:00:00 2001 From: DefineFC Date: Wed, 27 Apr 2016 23:12:45 +0800 Subject: [PATCH 163/166] =?UTF-8?q?*=20RestController=E5=A4=84=E7=90=86?= =?UTF-8?q?=E6=B2=A1=E6=9C=89=E8=AF=B7=E6=B1=82=E5=A4=B4=E7=9A=84=E8=AF=B7?= =?UTF-8?q?=E6=B1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修改了RestController.class.php,检查_server数组,应对没有请求头的情况 --- ThinkPHP/Library/Think/Controller/RestController.class.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ThinkPHP/Library/Think/Controller/RestController.class.php b/ThinkPHP/Library/Think/Controller/RestController.class.php index 3300455d4..99298f2e5 100644 --- a/ThinkPHP/Library/Think/Controller/RestController.class.php +++ b/ThinkPHP/Library/Think/Controller/RestController.class.php @@ -123,9 +123,10 @@ protected function getAcceptType() foreach ($type as $key => $val) { $array = explode(',', $val); foreach ($array as $k => $v) { - if (stristr($_SERVER['HTTP_ACCEPT'], $v)) { - return $key; - } + if(array_key_exists('HTTP_ACCEPT',$_SERVER)) + if (stristr($_SERVER['HTTP_ACCEPT'], $v)) { + return $key; + } } } return false; From c2ed310598def5c3f73855a139f15b31e34a242d Mon Sep 17 00:00:00 2001 From: happylhb Date: Fri, 27 May 2016 18:17:04 +0800 Subject: [PATCH 164/166] Update Mongo.class.php MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复getMongoNextId时,不切换Collection错误 --- ThinkPHP/Library/Think/Db/Driver/Mongo.class.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ThinkPHP/Library/Think/Db/Driver/Mongo.class.php b/ThinkPHP/Library/Think/Db/Driver/Mongo.class.php index 8fe879142..299097111 100644 --- a/ThinkPHP/Library/Think/Db/Driver/Mongo.class.php +++ b/ThinkPHP/Library/Think/Db/Driver/Mongo.class.php @@ -270,8 +270,11 @@ public function insertAll($dataList, $options = array()) * @param string $pk 主键名 * @return integer */ - public function getMongoNextId($pk) + public function getMongoNextId($pk,$options=array()) { + if (isset($options['table'])) { + $this->switchCollection($options['table']); + } if ($this->config['debug']) { $this->queryStr = $this->_dbName . '.' . $this->_collectionName . '.find({},{' . $pk . ':1}).sort({' . $pk . ':-1}).limit(1)'; } From 312d6db1bbf1554609463f7265580f56545694da Mon Sep 17 00:00:00 2001 From: happylhb Date: Fri, 27 May 2016 18:19:45 +0800 Subject: [PATCH 165/166] Update MongoModel.class.php MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复getMongoNextId时,不切换Collection错误 --- ThinkPHP/Library/Think/Model/MongoModel.class.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ThinkPHP/Library/Think/Model/MongoModel.class.php b/ThinkPHP/Library/Think/Model/MongoModel.class.php index 67afdb481..1c3b3b4a9 100644 --- a/ThinkPHP/Library/Think/Model/MongoModel.class.php +++ b/ThinkPHP/Library/Think/Model/MongoModel.class.php @@ -148,7 +148,8 @@ public function getMongoNextId($pk = '') if (empty($pk)) { $pk = $this->getPk(); } - return $this->db->getMongoNextId($pk); + $options = $this->_parseOptions(); + return $this->db->getMongoNextId($pk,$options); } /** @@ -198,7 +199,7 @@ protected function _before_insert(&$data, $options) // 主键自动增长 $pk = $this->getPk(); if (!isset($data[$pk])) { - $data[$pk] = $this->db->getMongoNextId($pk); + $data[$pk] = $this->db->getMongoNextId($pk, $options); } } } From 11be5288a8a8937e5555fce6c35dec45c6f95623 Mon Sep 17 00:00:00 2001 From: happylhb Date: Mon, 30 May 2016 14:00:53 +0800 Subject: [PATCH 166/166] Update MongoModel.class.php MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit getMongoNextId使用参数 --- ThinkPHP/Library/Think/Model/MongoModel.class.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ThinkPHP/Library/Think/Model/MongoModel.class.php b/ThinkPHP/Library/Think/Model/MongoModel.class.php index 67afdb481..1c3b3b4a9 100644 --- a/ThinkPHP/Library/Think/Model/MongoModel.class.php +++ b/ThinkPHP/Library/Think/Model/MongoModel.class.php @@ -148,7 +148,8 @@ public function getMongoNextId($pk = '') if (empty($pk)) { $pk = $this->getPk(); } - return $this->db->getMongoNextId($pk); + $options = $this->_parseOptions(); + return $this->db->getMongoNextId($pk,$options); } /** @@ -198,7 +199,7 @@ protected function _before_insert(&$data, $options) // 主键自动增长 $pk = $this->getPk(); if (!isset($data[$pk])) { - $data[$pk] = $this->db->getMongoNextId($pk); + $data[$pk] = $this->db->getMongoNextId($pk, $options); } } }