modified ThinkPHP核心版本升级

This commit is contained in:
zhaoxiang 2018-04-09 09:38:10 +08:00
parent 784ed0d5cd
commit 06709ae5cc
164 changed files with 213 additions and 93 deletions

View File

@ -20,6 +20,7 @@ class RequestFilter {
/** /**
* 默认行为函数 * 默认行为函数
* @throws \think\Exception
* @throws \think\exception\DbException * @throws \think\exception\DbException
* @author zhaoxiang <zhaoxiang051405@gmail.com> * @author zhaoxiang <zhaoxiang051405@gmail.com>
*/ */

0
thinkphp/CONTRIBUTING.md Normal file → Executable file
View File

0
thinkphp/LICENSE.txt Normal file → Executable file
View File

2
thinkphp/README.md Normal file → Executable file
View File

@ -92,7 +92,7 @@ www WEB部署目录或者子目录
## 命名规范 ## 命名规范
ThinkPHP5的命名规范遵循PSR-2规范以及PSR-4自动加载规范。 ThinkPHP5的命名规范遵循`PSR-2`规范以及`PSR-4`自动加载规范。
## 参与开发 ## 参与开发
注册并登录 Github 帐号, fork 本项目并进行改动。 注册并登录 Github 帐号, fork 本项目并进行改动。

2
thinkphp/base.php Normal file → Executable file
View File

@ -9,7 +9,7 @@
// | Author: liu21st <liu21st@gmail.com> // | Author: liu21st <liu21st@gmail.com>
// +---------------------------------------------------------------------- // +----------------------------------------------------------------------
define('THINK_VERSION', '5.0.15'); define('THINK_VERSION', '5.0.16');
define('THINK_START_TIME', microtime(true)); define('THINK_START_TIME', microtime(true));
define('THINK_START_MEM', memory_get_usage()); define('THINK_START_MEM', memory_get_usage());
define('EXT', '.php'); define('EXT', '.php');

0
thinkphp/codecov.yml Normal file → Executable file
View File

0
thinkphp/composer.json Normal file → Executable file
View File

0
thinkphp/console.php Normal file → Executable file
View File

7
thinkphp/convention.php Normal file → Executable file
View File

@ -286,4 +286,11 @@ return [
'list_rows' => 15, 'list_rows' => 15,
], ],
//控制台配置
'console' => [
'name' => 'Think Console',
'version' => '0.1',
'user' => null,
],
]; ];

6
thinkphp/helper.php Normal file → Executable file
View File

@ -443,6 +443,12 @@ if (!function_exists('view')) {
*/ */
function view($template = '', $vars = [], $replace = [], $code = 200) function view($template = '', $vars = [], $replace = [], $code = 200)
{ {
if ('' === $template) {
$trace = debug_backtrace(false, 2);
$suffix = Config::get('action_suffix');
$action = $suffix ? substr($trace[1]['function'], 0, -strlen($suffix)) : $trace[1]['function'];
$template = Loader::parseName($action);
}
return Response::create($template, 'view', $code)->replace($replace)->assign($vars); return Response::create($template, 'view', $code)->replace($replace)->assign($vars);
} }
} }

0
thinkphp/lang/zh-cn.php Normal file → Executable file
View File

0
thinkphp/library/think/App.php Normal file → Executable file
View File

0
thinkphp/library/think/Build.php Normal file → Executable file
View File

0
thinkphp/library/think/Cache.php Normal file → Executable file
View File

0
thinkphp/library/think/Collection.php Normal file → Executable file
View File

0
thinkphp/library/think/Config.php Normal file → Executable file
View File

39
thinkphp/library/think/Console.php Normal file → Executable file
View File

@ -79,14 +79,19 @@ class Console
/** /**
* Console constructor. * Console constructor.
* @access public * @access public
* @param string $name 名称 * @param string $name 名称
* @param string $version 版本 * @param string $version 版本
* @param null|string $user 执行用户
*/ */
public function __construct($name = 'UNKNOWN', $version = 'UNKNOWN') public function __construct($name = 'UNKNOWN', $version = 'UNKNOWN', $user = null)
{ {
$this->name = $name; $this->name = $name;
$this->version = $version; $this->version = $version;
if ($user) {
$this->setUser($user);
}
$this->defaultCommand = 'list'; $this->defaultCommand = 'list';
$this->definition = $this->getDefaultInputDefinition(); $this->definition = $this->getDefaultInputDefinition();
@ -95,6 +100,19 @@ class Console
} }
} }
/**
* 设置执行用户
* @param $user
*/
public function setUser($user)
{
$user = posix_getpwnam($user);
if ($user) {
posix_setuid($user['uid']);
posix_setgid($user['gid']);
}
}
/** /**
* 初始化 Console * 初始化 Console
* @access public * @access public
@ -106,8 +124,9 @@ class Console
static $console; static $console;
if (!$console) { if (!$console) {
$config = Config::get('console');
// 实例化 console // 实例化 console
$console = new self('Think Console', '0.1'); $console = new self($config['name'], $config['version'], $config['user']);
// 读取指令集 // 读取指令集
if (is_file(CONF_PATH . 'command' . EXT)) { if (is_file(CONF_PATH . 'command' . EXT)) {
@ -479,7 +498,7 @@ class Console
}, $namespace); }, $namespace);
$allNamespaces = $this->getNamespaces(); $allNamespaces = $this->getNamespaces();
$namespaces = preg_grep('{^' . $expr . '}', $allNamespaces); $namespaces = preg_grep('{^' . $expr . '}', $allNamespaces);
if (empty($namespaces)) { if (empty($namespaces)) {
$message = sprintf( $message = sprintf(
@ -527,7 +546,7 @@ class Console
}, $name); }, $name);
$allCommands = array_keys($this->commands); $allCommands = array_keys($this->commands);
$commands = preg_grep('{^' . $expr . '}', $allCommands); $commands = preg_grep('{^' . $expr . '}', $allCommands);
if (empty($commands) || count(preg_grep('{^' . $expr . '$}', $commands)) < 1) { if (empty($commands) || count(preg_grep('{^' . $expr . '$}', $commands)) < 1) {
if (false !== ($pos = strrpos($name, ':'))) { if (false !== ($pos = strrpos($name, ':'))) {
@ -550,7 +569,7 @@ class Console
if (count($commands) > 1) { if (count($commands) > 1) {
$commandList = $this->commands; $commandList = $this->commands;
$commands = array_filter($commands, function ($nameOrAlias) use ($commandList, $commands) { $commands = array_filter($commands, function ($nameOrAlias) use ($commandList, $commands) {
$commandName = $commandList[$nameOrAlias]->getName(); $commandName = $commandList[$nameOrAlias]->getName();
return $commandName === $nameOrAlias || !in_array($commandName, $commands); return $commandName === $nameOrAlias || !in_array($commandName, $commands);
@ -601,7 +620,7 @@ class Console
$abbrevs = []; $abbrevs = [];
foreach ($names as $name) { foreach ($names as $name) {
for ($len = strlen($name); $len > 0; --$len) { for ($len = strlen($name); $len > 0; --$len) {
$abbrev = substr($name, 0, $len); $abbrev = substr($name, 0, $len);
$abbrevs[$abbrev][] = $name; $abbrevs[$abbrev][] = $name;
} }
} }
@ -754,8 +773,8 @@ class Console
*/ */
private function findAlternatives($name, $collection) private function findAlternatives($name, $collection)
{ {
$threshold = 1e3; $threshold = 1e3;
$alternatives = []; $alternatives = [];
$collectionParts = []; $collectionParts = [];
foreach ($collection as $item) { foreach ($collection as $item) {

19
thinkphp/library/think/Controller.php Normal file → Executable file
View File

@ -52,7 +52,7 @@ class Controller
*/ */
public function __construct(Request $request = null) public function __construct(Request $request = null)
{ {
$this->view = View::instance(Config::get('template'), Config::get('view_replace_str')); $this->view = View::instance(Config::get('template'), Config::get('view_replace_str'));
$this->request = is_null($request) ? Request::instance() : $request; $this->request = is_null($request) ? Request::instance() : $request;
// 控制器初始化 // 控制器初始化
@ -117,6 +117,13 @@ class Controller
*/ */
protected function fetch($template = '', $vars = [], $replace = [], $config = []) protected function fetch($template = '', $vars = [], $replace = [], $config = [])
{ {
if ('' === $template) {
$trace = debug_backtrace(false, 2);
$suffix = Config::get('action_suffix');
$action = $suffix ? substr($trace[1]['function'], 0, -strlen($suffix)) : $trace[1]['function'];
$template = Loader::parseName($action);
}
return $this->view->fetch($template, $vars, $replace, $config); return $this->view->fetch($template, $vars, $replace, $config);
} }
@ -202,9 +209,15 @@ class Controller
} }
// 批量验证 // 批量验证
if ($batch || $this->batchValidate) $v->batch(true); if ($batch || $this->batchValidate) {
$v->batch(true);
}
// 设置错误信息 // 设置错误信息
if (is_array($message)) $v->message($message); if (is_array($message)) {
$v->message($message);
}
// 使用回调验证 // 使用回调验证
if ($callback && is_callable($callback)) { if ($callback && is_callable($callback)) {
call_user_func_array($callback, [$v, &$data]); call_user_func_array($callback, [$v, &$data]);

0
thinkphp/library/think/Cookie.php Normal file → Executable file
View File

0
thinkphp/library/think/Db.php Normal file → Executable file
View File

0
thinkphp/library/think/Debug.php Normal file → Executable file
View File

0
thinkphp/library/think/Env.php Normal file → Executable file
View File

0
thinkphp/library/think/Error.php Normal file → Executable file
View File

0
thinkphp/library/think/Exception.php Normal file → Executable file
View File

0
thinkphp/library/think/File.php Normal file → Executable file
View File

0
thinkphp/library/think/Hook.php Normal file → Executable file
View File

0
thinkphp/library/think/Lang.php Normal file → Executable file
View File

29
thinkphp/library/think/Loader.php Normal file → Executable file
View File

@ -284,6 +284,25 @@ class Loader
// 注册系统自动加载 // 注册系统自动加载
spl_autoload_register($autoload ?: 'think\\Loader::autoload', true, true); spl_autoload_register($autoload ?: 'think\\Loader::autoload', true, true);
// Composer 自动加载支持
if (is_dir(VENDOR_PATH . 'composer')) {
if (PHP_VERSION_ID >= 50600 && is_file(VENDOR_PATH . 'composer' . DS . 'autoload_static.php')) {
require VENDOR_PATH . 'composer' . DS . 'autoload_static.php';
$declaredClass = get_declared_classes();
$composerClass = array_pop($declaredClass);
self::$prefixLengthsPsr4 = $composerClass::$prefixLengthsPsr4;
self::$prefixDirsPsr4 = property_exists($composerClass, 'prefixDirsPsr4') ? $composerClass::$prefixDirsPsr4 : [];
self::$prefixesPsr0 = property_exists($composerClass, 'prefixesPsr0') ? $composerClass::$prefixesPsr0 : [];
self::$map = property_exists($composerClass, 'classMap') ? $composerClass::$classMap : [];
} else {
self::registerComposerLoader();
}
}
// 注册命名空间定义 // 注册命名空间定义
self::addNamespace([ self::addNamespace([
'think' => LIB_PATH . 'think' . DS, 'think' => LIB_PATH . 'think' . DS,
@ -296,10 +315,7 @@ class Loader
self::addClassMap(__include_file(RUNTIME_PATH . 'classmap' . EXT)); self::addClassMap(__include_file(RUNTIME_PATH . 'classmap' . EXT));
} }
// Composer 自动加载支持 self::loadComposerAutoloadFiles();
if (is_dir(VENDOR_PATH . 'composer')) {
self::registerComposerLoader();
}
// 自动加载 extend 目录 // 自动加载 extend 目录
self::$fallbackDirsPsr4[] = rtrim(EXTEND_PATH, DS); self::$fallbackDirsPsr4[] = rtrim(EXTEND_PATH, DS);
@ -331,9 +347,12 @@ class Loader
if ($classMap) { if ($classMap) {
self::addClassMap($classMap); self::addClassMap($classMap);
} }
} }
}
// 加载composer autofile文件
public static function loadComposerAutoloadFiles()
{
if (is_file(VENDOR_PATH . 'composer/autoload_files.php')) { if (is_file(VENDOR_PATH . 'composer/autoload_files.php')) {
$includeFiles = require VENDOR_PATH . 'composer/autoload_files.php'; $includeFiles = require VENDOR_PATH . 'composer/autoload_files.php';
foreach ($includeFiles as $fileIdentifier => $file) { foreach ($includeFiles as $fileIdentifier => $file) {

0
thinkphp/library/think/Log.php Normal file → Executable file
View File

6
thinkphp/library/think/Model.php Normal file → Executable file
View File

@ -679,7 +679,11 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
$value = empty($value) ? new \stdClass() : json_decode($value); $value = empty($value) ? new \stdClass() : json_decode($value);
break; break;
case 'serialize': case 'serialize':
$value = unserialize($value); try {
$value = unserialize($value);
} catch (\Exception $e) {
$value = null;
}
break; break;
default: default:
if (false !== strpos($type, '\\')) { if (false !== strpos($type, '\\')) {

2
thinkphp/library/think/Paginator.php Normal file → Executable file
View File

@ -128,7 +128,7 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J
} }
$url = $path; $url = $path;
if (!empty($parameters)) { if (!empty($parameters)) {
$url .= '?' . urldecode(http_build_query($parameters, null, '&')); $url .= '?' . http_build_query($parameters, null, '&');
} }
return $url . $this->buildFragment(); return $url . $this->buildFragment();
} }

0
thinkphp/library/think/Process.php Normal file → Executable file
View File

0
thinkphp/library/think/Request.php Normal file → Executable file
View File

0
thinkphp/library/think/Response.php Normal file → Executable file
View File

0
thinkphp/library/think/Route.php Normal file → Executable file
View File

0
thinkphp/library/think/Session.php Normal file → Executable file
View File

28
thinkphp/library/think/Template.php Normal file → Executable file
View File

@ -64,14 +64,16 @@ class Template
*/ */
public function __construct(array $config = []) public function __construct(array $config = [])
{ {
$this->config['cache_path'] = TEMP_PATH; $this->config['cache_path'] = TEMP_PATH;
$this->config = array_merge($this->config, $config); $this->config = array_merge($this->config, $config);
$this->config['taglib_begin_origin'] = $this->config['taglib_begin']; $this->config['taglib_begin_origin'] = $this->config['taglib_begin'];
$this->config['taglib_end_origin'] = $this->config['taglib_end']; $this->config['taglib_end_origin'] = $this->config['taglib_end'];
$this->config['taglib_begin'] = $this->stripPreg($this->config['taglib_begin']);
$this->config['taglib_end'] = $this->stripPreg($this->config['taglib_end']); $this->config['taglib_begin'] = preg_quote($this->config['taglib_begin'], '/');
$this->config['tpl_begin'] = $this->stripPreg($this->config['tpl_begin']); $this->config['taglib_end'] = preg_quote($this->config['taglib_end'], '/');
$this->config['tpl_end'] = $this->stripPreg($this->config['tpl_end']); $this->config['tpl_begin'] = preg_quote($this->config['tpl_begin'], '/');
$this->config['tpl_end'] = preg_quote($this->config['tpl_end'], '/');
// 初始化模板编译存储器 // 初始化模板编译存储器
$type = $this->config['compile_type'] ? $this->config['compile_type'] : 'File'; $type = $this->config['compile_type'] ? $this->config['compile_type'] : 'File';
@ -79,20 +81,6 @@ class Template
$this->storage = new $class(); $this->storage = new $class();
} }
/**
* 字符串替换 避免正则混淆
* @access private
* @param string $str
* @return string
*/
private function stripPreg($str)
{
return str_replace(
['{', '}', '(', ')', '|', '[', ']', '-', '+', '*', '.', '^', '?'],
['\{', '\}', '\(', '\)', '\|', '\[', '\]', '\-', '\+', '\*', '\.', '\^', '\?'],
$str);
}
/** /**
* 模板变量赋值 * 模板变量赋值
* @access public * @access public

2
thinkphp/library/think/Url.php Normal file → Executable file
View File

@ -302,7 +302,7 @@ class Url
foreach ($rule as $item) { foreach ($rule as $item) {
list($url, $pattern, $domain, $suffix) = $item; list($url, $pattern, $domain, $suffix) = $item;
if (empty($pattern)) { if (empty($pattern)) {
return [$url, $domain, $suffix]; return [rtrim($url, '$'), $domain, $suffix];
} }
$type = Config::get('url_common_param'); $type = Config::get('url_common_param');
foreach ($pattern as $key => $val) { foreach ($pattern as $key => $val) {

3
thinkphp/library/think/Validate.php Normal file → Executable file
View File

@ -42,7 +42,6 @@ class Validate
'float' => ':attribute must be float', 'float' => ':attribute must be float',
'boolean' => ':attribute must be bool', 'boolean' => ':attribute must be bool',
'email' => ':attribute not a valid email address', 'email' => ':attribute not a valid email address',
'mobile' => ':attribute not a valid mobile',
'array' => ':attribute must be a array', 'array' => ':attribute must be a array',
'accepted' => ':attribute must be yes,on or 1', 'accepted' => ':attribute must be yes,on or 1',
'date' => ':attribute not a valid datetime', 'date' => ':attribute not a valid datetime',
@ -1196,7 +1195,7 @@ class Validate
// 不是正则表达式则两端补上/ // 不是正则表达式则两端补上/
$rule = '/^' . $rule . '$/'; $rule = '/^' . $rule . '$/';
} }
return 1 === preg_match($rule, (string) $value); return is_scalar($value) && 1 === preg_match($rule, (string) $value);
} }
/** /**

0
thinkphp/library/think/View.php Normal file → Executable file
View File

0
thinkphp/library/think/cache/Driver.php vendored Normal file → Executable file
View File

5
thinkphp/library/think/cache/driver/File.php vendored Normal file → Executable file
View File

@ -215,7 +215,10 @@ class File extends Driver
public function rm($name) public function rm($name)
{ {
$filename = $this->getCacheKey($name); $filename = $this->getCacheKey($name);
return $this->unlink($filename); try {
return $this->unlink($filename);
} catch (\Exception $e) {
}
} }
/** /**

0
thinkphp/library/think/cache/driver/Lite.php vendored Normal file → Executable file
View File

0
thinkphp/library/think/cache/driver/Memcache.php vendored Normal file → Executable file
View File

0
thinkphp/library/think/cache/driver/Memcached.php vendored Normal file → Executable file
View File

0
thinkphp/library/think/cache/driver/Redis.php vendored Normal file → Executable file
View File

0
thinkphp/library/think/cache/driver/Sqlite.php vendored Normal file → Executable file
View File

0
thinkphp/library/think/cache/driver/Wincache.php vendored Normal file → Executable file
View File

0
thinkphp/library/think/cache/driver/Xcache.php vendored Normal file → Executable file
View File

0
thinkphp/library/think/config/driver/Ini.php Normal file → Executable file
View File

0
thinkphp/library/think/config/driver/Json.php Normal file → Executable file
View File

0
thinkphp/library/think/config/driver/Xml.php Normal file → Executable file
View File

0
thinkphp/library/think/console/Command.php Normal file → Executable file
View File

0
thinkphp/library/think/console/Input.php Normal file → Executable file
View File

0
thinkphp/library/think/console/LICENSE Normal file → Executable file
View File

0
thinkphp/library/think/console/Output.php Normal file → Executable file
View File

0
thinkphp/library/think/console/bin/README.md Normal file → Executable file
View File

0
thinkphp/library/think/console/bin/hiddeninput.exe Normal file → Executable file
View File

0
thinkphp/library/think/console/command/Build.php Normal file → Executable file
View File

0
thinkphp/library/think/console/command/Clear.php Normal file → Executable file
View File

0
thinkphp/library/think/console/command/Help.php Normal file → Executable file
View File

0
thinkphp/library/think/console/command/Lists.php Normal file → Executable file
View File

0
thinkphp/library/think/console/command/Make.php Normal file → Executable file
View File

View File

0
thinkphp/library/think/console/command/make/Model.php Normal file → Executable file
View File

View File

View File

View File

View File

View File

View File

0
thinkphp/library/think/console/input/Argument.php Normal file → Executable file
View File

0
thinkphp/library/think/console/input/Definition.php Normal file → Executable file
View File

0
thinkphp/library/think/console/input/Option.php Normal file → Executable file
View File

0
thinkphp/library/think/console/output/Ask.php Normal file → Executable file
View File

0
thinkphp/library/think/console/output/Descriptor.php Normal file → Executable file
View File

0
thinkphp/library/think/console/output/Formatter.php Normal file → Executable file
View File

0
thinkphp/library/think/console/output/Question.php Normal file → Executable file
View File

View File

View File

View File

View File

View File

View File

View File

View File

0
thinkphp/library/think/controller/Rest.php Normal file → Executable file
View File

0
thinkphp/library/think/controller/Yar.php Normal file → Executable file
View File

10
thinkphp/library/think/db/Builder.php Normal file → Executable file
View File

@ -116,10 +116,14 @@ abstract class Builder
$result[$item] = $val[1]; $result[$item] = $val[1];
break; break;
case 'inc': case 'inc':
$result[$item] = $this->parseKey($val[1]) . '+' . floatval($val[2]); if ($key == $val[1]) {
$result[$item] = $this->parseKey($val[1]) . '+' . floatval($val[2]);
}
break; break;
case 'dec': case 'dec':
$result[$item] = $this->parseKey($val[1]) . '-' . floatval($val[2]); if ($key == $val[1]) {
$result[$item] = $this->parseKey($val[1]) . '-' . floatval($val[2]);
}
break; break;
} }
} elseif (is_scalar($val)) { } elseif (is_scalar($val)) {
@ -338,7 +342,7 @@ abstract class Builder
throw new Exception('where express error:' . $exp); throw new Exception('where express error:' . $exp);
} }
} }
$bindName = $bindName ?: 'where_' . str_replace(['.', '-'], '_', $field); $bindName = $bindName ?: 'where_' . $rule . '_' . str_replace(['.', '-'], '_', $field);
if (preg_match('/\W/', $bindName)) { if (preg_match('/\W/', $bindName)) {
// 处理带非单词字符的字段名 // 处理带非单词字符的字段名
$bindName = md5($bindName); $bindName = md5($bindName);

1
thinkphp/library/think/db/Connection.php Normal file → Executable file
View File

@ -823,6 +823,7 @@ abstract class Connection
'SSL connection has been closed unexpectedly', 'SSL connection has been closed unexpectedly',
'Error writing data to the connection', 'Error writing data to the connection',
'Resource deadlock avoided', 'Resource deadlock avoided',
'failed with errno',
]; ];
$error = $e->getMessage(); $error = $e->getMessage();

55
thinkphp/library/think/db/Query.php Normal file → Executable file
View File

@ -131,7 +131,7 @@ class Query
} }
/** /**
* 获取当前的模型对象 * 获取当前的模型对象实例
* @access public * @access public
* @return Model|null * @return Model|null
*/ */
@ -403,7 +403,7 @@ class Query
if (empty($this->options['table'])) { if (empty($this->options['table'])) {
$this->options['table'] = $this->getTable(); $this->options['table'] = $this->getTable();
} }
$key = is_string($cache['key']) ? $cache['key'] : md5($field . serialize($this->options) . serialize($this->bind)); $key = is_string($cache['key']) ? $cache['key'] : md5($this->connection->getConfig('database') . '.' . $field . serialize($this->options) . serialize($this->bind));
$result = Cache::get($key); $result = Cache::get($key);
} }
if (false === $result) { if (false === $result) {
@ -447,7 +447,7 @@ class Query
if (empty($this->options['table'])) { if (empty($this->options['table'])) {
$this->options['table'] = $this->getTable(); $this->options['table'] = $this->getTable();
} }
$guid = is_string($cache['key']) ? $cache['key'] : md5($field . serialize($this->options) . serialize($this->bind)); $guid = is_string($cache['key']) ? $cache['key'] : md5($this->connection->getConfig('database') . '.' . $field . serialize($this->options) . serialize($this->bind));
$result = Cache::get($guid); $result = Cache::get($guid);
} }
if (false === $result) { if (false === $result) {
@ -708,6 +708,7 @@ class Query
// 传入的表名为数组 // 传入的表名为数组
if (is_array($join)) { if (is_array($join)) {
$table = $join; $table = $join;
$alias = array_shift($join);
} else { } else {
$join = trim($join); $join = trim($join);
if (false !== strpos($join, '(')) { if (false !== strpos($join, '(')) {
@ -793,7 +794,7 @@ class Query
} }
if (isset($this->options['field'])) { if (isset($this->options['field'])) {
$field = array_merge($this->options['field'], $field); $field = array_merge((array) $this->options['field'], $field);
} }
$this->options['field'] = array_unique($field); $this->options['field'] = array_unique($field);
return $this; return $this;
@ -873,9 +874,9 @@ class Query
public function view($join, $field = true, $on = null, $type = 'INNER') public function view($join, $field = true, $on = null, $type = 'INNER')
{ {
$this->options['view'] = true; $this->options['view'] = true;
if (is_array($join) && key($join) !== 0) { if (is_array($join) && key($join) === 0) {
foreach ($join as $key => $val) { foreach ($join as $key => $val) {
$this->view($key, $val[0], isset($val[1]) ? $val[1] : null, isset($val[2]) ? $val[2] : 'INNER'); $this->view($val[0], $val[1], isset($val[2]) ? $val[2] : null, isset($val[3]) ? $val[3] : 'INNER');
} }
} else { } else {
$fields = []; $fields = [];
@ -983,7 +984,7 @@ class Query
*/ */
public function whereNull($field, $logic = 'AND') public function whereNull($field, $logic = 'AND')
{ {
$this->parseWhereExp($logic, $field, 'null', null); $this->parseWhereExp($logic, $field, 'null', null, [], true);
return $this; return $this;
} }
@ -996,7 +997,7 @@ class Query
*/ */
public function whereNotNull($field, $logic = 'AND') public function whereNotNull($field, $logic = 'AND')
{ {
$this->parseWhereExp($logic, $field, 'notnull', null); $this->parseWhereExp($logic, $field, 'notnull', null, [], true);
return $this; return $this;
} }
@ -1036,7 +1037,7 @@ class Query
*/ */
public function whereIn($field, $condition, $logic = 'AND') public function whereIn($field, $condition, $logic = 'AND')
{ {
$this->parseWhereExp($logic, $field, 'in', $condition); $this->parseWhereExp($logic, $field, 'in', $condition, [], true);
return $this; return $this;
} }
@ -1050,7 +1051,7 @@ class Query
*/ */
public function whereNotIn($field, $condition, $logic = 'AND') public function whereNotIn($field, $condition, $logic = 'AND')
{ {
$this->parseWhereExp($logic, $field, 'not in', $condition); $this->parseWhereExp($logic, $field, 'not in', $condition, [], true);
return $this; return $this;
} }
@ -1064,7 +1065,7 @@ class Query
*/ */
public function whereLike($field, $condition, $logic = 'AND') public function whereLike($field, $condition, $logic = 'AND')
{ {
$this->parseWhereExp($logic, $field, 'like', $condition); $this->parseWhereExp($logic, $field, 'like', $condition, [], true);
return $this; return $this;
} }
@ -1078,7 +1079,7 @@ class Query
*/ */
public function whereNotLike($field, $condition, $logic = 'AND') public function whereNotLike($field, $condition, $logic = 'AND')
{ {
$this->parseWhereExp($logic, $field, 'not like', $condition); $this->parseWhereExp($logic, $field, 'not like', $condition, [], true);
return $this; return $this;
} }
@ -1092,7 +1093,7 @@ class Query
*/ */
public function whereBetween($field, $condition, $logic = 'AND') public function whereBetween($field, $condition, $logic = 'AND')
{ {
$this->parseWhereExp($logic, $field, 'between', $condition); $this->parseWhereExp($logic, $field, 'between', $condition, [], true);
return $this; return $this;
} }
@ -1106,7 +1107,7 @@ class Query
*/ */
public function whereNotBetween($field, $condition, $logic = 'AND') public function whereNotBetween($field, $condition, $logic = 'AND')
{ {
$this->parseWhereExp($logic, $field, 'not between', $condition); $this->parseWhereExp($logic, $field, 'not between', $condition, [], true);
return $this; return $this;
} }
@ -1120,7 +1121,7 @@ class Query
*/ */
public function whereExp($field, $condition, $logic = 'AND') public function whereExp($field, $condition, $logic = 'AND')
{ {
$this->parseWhereExp($logic, $field, 'exp', $condition); $this->parseWhereExp($logic, $field, 'exp', $condition, [], true);
return $this; return $this;
} }
@ -1147,9 +1148,10 @@ class Query
* @param mixed $op 查询表达式 * @param mixed $op 查询表达式
* @param mixed $condition 查询条件 * @param mixed $condition 查询条件
* @param array $param 查询参数 * @param array $param 查询参数
* @param bool $strict 严格模式
* @return void * @return void
*/ */
protected function parseWhereExp($logic, $field, $op, $condition, $param = []) protected function parseWhereExp($logic, $field, $op, $condition, $param = [], $strict = false)
{ {
$logic = strtoupper($logic); $logic = strtoupper($logic);
if ($field instanceof \Closure) { if ($field instanceof \Closure) {
@ -1160,7 +1162,14 @@ class Query
if (is_string($field) && !empty($this->options['via']) && !strpos($field, '.')) { if (is_string($field) && !empty($this->options['via']) && !strpos($field, '.')) {
$field = $this->options['via'] . '.' . $field; $field = $this->options['via'] . '.' . $field;
} }
if (is_string($field) && preg_match('/[,=\>\<\'\"\(\s]/', $field)) {
if ($strict) {
// 使用严格模式查询
$where[$field] = [$op, $condition];
// 记录一个字段多次查询条件
$this->options['multi'][$logic][$field][] = $where[$field];
} elseif (is_string($field) && preg_match('/[,=\>\<\'\"\(\s]/', $field)) {
$where[] = ['exp', $field]; $where[] = ['exp', $field];
if (is_array($op)) { if (is_array($op)) {
// 参数绑定 // 参数绑定
@ -2322,7 +2331,7 @@ class Query
// 判断查询缓存 // 判断查询缓存
$cache = $options['cache']; $cache = $options['cache'];
unset($options['cache']); unset($options['cache']);
$key = is_string($cache['key']) ? $cache['key'] : md5(serialize($options) . serialize($this->bind)); $key = is_string($cache['key']) ? $cache['key'] : md5($this->connection->getConfig('database') . '.' . serialize($options) . serialize($this->bind));
$resultSet = Cache::get($key); $resultSet = Cache::get($key);
} }
if (false === $resultSet) { if (false === $resultSet) {
@ -2423,10 +2432,12 @@ class Query
} elseif (is_array($value) && is_string($value[0]) && 'eq' == strtolower($value[0])) { } elseif (is_array($value) && is_string($value[0]) && 'eq' == strtolower($value[0])) {
$data = $value[1]; $data = $value[1];
} }
$prefix = $this->connection->getConfig('database') . '.';
if (isset($data)) { if (isset($data)) {
return 'think:' . (is_array($options['table']) ? key($options['table']) : $options['table']) . '|' . $data; return 'think:' . $prefix . (is_array($options['table']) ? key($options['table']) : $options['table']) . '|' . $data;
} else { } else {
return md5(serialize($options) . serialize($bind)); return md5($prefix . serialize($options) . serialize($bind));
} }
} }
@ -2463,11 +2474,11 @@ class Query
// 判断查询缓存 // 判断查询缓存
$cache = $options['cache']; $cache = $options['cache'];
if (true === $cache['key'] && !is_null($data) && !is_array($data)) { if (true === $cache['key'] && !is_null($data) && !is_array($data)) {
$key = 'think:' . (is_array($options['table']) ? key($options['table']) : $options['table']) . '|' . $data; $key = 'think:' . $this->connection->getConfig('database') . '.' . (is_array($options['table']) ? key($options['table']) : $options['table']) . '|' . $data;
} elseif (is_string($cache['key'])) { } elseif (is_string($cache['key'])) {
$key = $cache['key']; $key = $cache['key'];
} elseif (!isset($key)) { } elseif (!isset($key)) {
$key = md5(serialize($options) . serialize($this->bind)); $key = md5($this->connection->getConfig('database') . '.' . serialize($options) . serialize($this->bind));
} }
$result = Cache::get($key); $result = Cache::get($key);
} }

0
thinkphp/library/think/db/builder/Mysql.php Normal file → Executable file
View File

0
thinkphp/library/think/db/builder/Pgsql.php Normal file → Executable file
View File

0
thinkphp/library/think/db/builder/Sqlite.php Normal file → Executable file
View File

0
thinkphp/library/think/db/builder/Sqlsrv.php Normal file → Executable file
View File

0
thinkphp/library/think/db/connector/Mysql.php Normal file → Executable file
View File

0
thinkphp/library/think/db/connector/Pgsql.php Normal file → Executable file
View File

0
thinkphp/library/think/db/connector/Sqlite.php Normal file → Executable file
View File

0
thinkphp/library/think/db/connector/Sqlsrv.php Normal file → Executable file
View File

Some files were not shown because too many files have changed in this diff Show More