diff --git a/README.md b/README.md index 00a1fa42b..5cd6d1597 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -**3.2版本已经过了维护生命周期,官方已经不再维护,请及时更新至5.0版本** +**3.2版本已经过了维护生命周期,官方已经不再维护,请及时更新至5.0或者5.1版本** ## 简介 diff --git a/ThinkPHP/Library/Think/Db/Driver.class.php b/ThinkPHP/Library/Think/Db/Driver.class.php index 66361ffc1..a5048fe8f 100644 --- a/ThinkPHP/Library/Think/Db/Driver.class.php +++ b/ThinkPHP/Library/Think/Db/Driver.class.php @@ -448,12 +448,12 @@ protected function bindParam($name, $value) /** * 字段和表名处理 - * @access protected + * @access public * @param string $key * @param bool $strict * @return string */ - protected function parseKey($key, $strict = false) + public function parseKey($key, $strict = false) { return $key; } @@ -758,29 +758,34 @@ protected function parseOrder($order) return ''; } $array = array(); + if (is_string($order) && '[RAND]' != $order) { + $order = array_map('trim', explode(',', $order)); + } + if (is_array($order)) { foreach ($order as $key => $val) { if (is_numeric($key)) { - if (false === strpos($val, '(')) { - $array[] = $this->parseKey($val); + list($key, $sort) = explode(' ', strpos($val, ' ') ? $val : $val . ' '); + } else { + $sort = $val; + } + + if (preg_match('/^[\w\.]+$/', $key)) { + $sort = strtoupper($sort); + $sort = in_array($sort, ['ASC', 'DESC'], true) ? ' ' . $sort : ''; + if (strpos($key, '.')) { + list($alias, $key) = explode('.', $key); + $array[] = $this->parseKey($alias, true) . '.' . $this->parseKey($key, true) . $sort; + } else { + $array[] = $this->parseKey($key, true) . $sort; } - } elseif (false === strpos($key, ')') && false === strpos($key, '#')) { - $sort = in_array(strtolower($val), array('asc', 'desc')) ? ' ' . $val : ''; - $array[] = $this->parseKey($key, true) . $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)) { - $array[] = $this->parseKey(ltrim(substr($val, 0, $match[0][1]))) . ' ' . $match[1][0]; - } elseif (false === strpos($val, '(')) { - $array[] = $this->parseKey($val); - } - } } + $order = implode(',', $array); return !empty($order) ? ' ORDER BY ' . $order : ''; } diff --git a/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php b/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php index dbece8879..e67575385 100644 --- a/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php +++ b/ThinkPHP/Library/Think/Db/Driver/Mysql.class.php @@ -94,15 +94,24 @@ public function getTables($dbName = '') /** * 字段和表名处理 - * @access protected + * @access public * @param string $key * @param bool $strict * @return string */ - protected function parseKey($key, $strict = false) + public function parseKey($key, $strict = false) { + if (is_int($key)) { + return $key; + } + $key = trim($key); - if ($strict || (!is_numeric($key) && !preg_match('/[,\'\"\*\(\)`.\s]/', $key))) { + + if ($strict && !preg_match('/^[\w\.\*]+$/', $key)) { + E('not support data:' . $key); + } + + if ('*' != $key && !preg_match('/[,\'\"\*\(\)`.\s]/', $key)) { $key = '`' . $key . '`'; } return $key; diff --git a/ThinkPHP/Library/Think/Db/Driver/Sqlsrv.class.php b/ThinkPHP/Library/Think/Db/Driver/Sqlsrv.class.php index cff986ddb..5d4e52cdc 100644 --- a/ThinkPHP/Library/Think/Db/Driver/Sqlsrv.class.php +++ b/ThinkPHP/Library/Think/Db/Driver/Sqlsrv.class.php @@ -105,14 +105,19 @@ protected function parseOrder($order) /** * 字段和表名处理 - * @access protected + * @access public * @param string $key * @param bool $strict * @return string */ - protected function parseKey($key, $strict = false) + public function parseKey($key, $strict = false) { $key = trim($key); + + if ($strict && !preg_match('/^[\w\.\*]+$/', $key)) { + E('not support data:' . $key); + } + if ($strict || (!is_numeric($key) && !preg_match('/[,\'\"\*\(\)\[.\s]/', $key))) { $key = '[' . $key . ']'; } diff --git a/ThinkPHP/Library/Think/Dispatcher.class.php b/ThinkPHP/Library/Think/Dispatcher.class.php index 8d8376b63..9ef34c342 100644 --- a/ThinkPHP/Library/Think/Dispatcher.class.php +++ b/ThinkPHP/Library/Think/Dispatcher.class.php @@ -76,7 +76,7 @@ public static function dispatch() $array = explode('/', $rule); // 模块绑定 define('BIND_MODULE', array_shift($array)); - // 控制器绑定 + // 控制器绑定 if (!empty($array)) { $controller = array_shift($array); if ($controller) { @@ -268,10 +268,6 @@ private static function getController(&$paths, $urlCase) 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'); diff --git a/ThinkPHP/Library/Think/Model.class.php b/ThinkPHP/Library/Think/Model.class.php index 275b00d8b..c1c6ebbd6 100644 --- a/ThinkPHP/Library/Think/Model.class.php +++ b/ThinkPHP/Library/Think/Model.class.php @@ -239,7 +239,7 @@ public function __call($method, $args) } 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); + return $this->getField(strtoupper($method) . '(' . $this->db->parseKey($field, true) . ') AS tp_' . $method); } elseif (strtolower(substr($method, 0, 5)) == 'getby') { // 根据某个字段获取记录 $field = parse_name(substr($method, 5)); diff --git a/ThinkPHP/Library/Think/Route.class.php b/ThinkPHP/Library/Think/Route.class.php index 5349dbffd..19b76213f 100644 --- a/ThinkPHP/Library/Think/Route.class.php +++ b/ThinkPHP/Library/Think/Route.class.php @@ -51,6 +51,10 @@ public static function check($paths = array()) // 动态路由检查 if (!empty($rules[1])) { foreach ($rules[1] as $rule => $route) { + if (is_numeric($rule)) { + $rule = array_shift($route); + } + $args = array_pop($route); if (isset($route[2])) { // 路由参数检查 @@ -58,7 +62,8 @@ public static function check($paths = array()) continue; } } - if ($matches = self::checkUrlMatch($rule, $args, $regx)) { + $matches = self::checkUrlMatch($rule, $args, $regx); + if ($matches !== false) { if ($route[0] instanceof \Closure) { // 执行闭包 $result = self::invoke($route[0], $matches); @@ -146,6 +151,10 @@ public static function reverse($path, &$vars, $depr, $suffix = true) } if (isset($_rules[1][$path])) { foreach ($_rules[1][$path] as $rule => $route) { + if (is_numeric($rule)) { + $rule = array_shift($route); + } + $args = array_pop($route); $array = array(); if (isset($route[2])) { @@ -271,9 +280,13 @@ public static function ruleCache($update = false) } } // 动态路由 - $result[1] = C('URL_ROUTE_RULES'); - if (!empty($result[1])) { - foreach ($result[1] as $rule => $route) { + $result[1] = []; + $dynamicRoutes = C('URL_ROUTE_RULES'); + if (!empty($dynamicRoutes)) { + foreach ($dynamicRoutes as $key => $value) { + $rule = $key; + $route = $value; + if (!is_array($route)) { $route = array($route); } elseif (is_numeric($rule)) { @@ -346,9 +359,14 @@ public static function ruleCache($update = false) } } $route[] = $args; + + // 保持配置中路由定义的键的类型,以支持多个路由的路由表达式相同而路由参数不同的情况 + if (is_numeric($key)) { + array_unshift($route, $rule); + $rule = $key; + } + $result[1][$rule] = $route; - } else { - unset($result[1][$rule]); } } } @@ -437,7 +455,7 @@ private static function checkUrlMatch(&$rule, &$args, &$regx) } } else { // 如果值在排除的名单里 - if (in_array($var, $val[2])) { + if (is_array($val[2]) && in_array($var, $val[2])) { return false; } } diff --git a/ThinkPHP/ThinkPHP.php b/ThinkPHP/ThinkPHP.php index 9825594f4..6e165683a 100644 --- a/ThinkPHP/ThinkPHP.php +++ b/ThinkPHP/ThinkPHP.php @@ -22,7 +22,7 @@ } // 版本信息 -const THINK_VERSION = '3.2.4'; +const THINK_VERSION = '3.2.5'; // URL 模式定义 const URL_COMMON = 0; //普通模式