更新tp5内核
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
namespace think\db;
|
||||
|
||||
use BadMethodCallException;
|
||||
use PDO;
|
||||
use think\Exception;
|
||||
|
||||
@@ -25,7 +26,7 @@ abstract class Builder
|
||||
protected $exp = ['eq' => '=', 'neq' => '<>', 'gt' => '>', 'egt' => '>=', 'lt' => '<', 'elt' => '<=', 'notlike' => 'NOT LIKE', 'not like' => 'NOT LIKE', 'like' => 'LIKE', 'in' => 'IN', 'exp' => 'EXP', 'notin' => 'NOT IN', 'not in' => 'NOT IN', 'between' => 'BETWEEN', 'not between' => 'NOT BETWEEN', 'notbetween' => 'NOT BETWEEN', 'exists' => 'EXISTS', 'notexists' => 'NOT EXISTS', 'not exists' => 'NOT EXISTS', 'null' => 'NULL', 'notnull' => 'NOT NULL', 'not null' => 'NOT NULL', '> time' => '> TIME', '< time' => '< TIME', '>= time' => '>= TIME', '<= time' => '<= TIME', 'between time' => 'BETWEEN TIME', 'not between time' => 'NOT BETWEEN TIME', 'notbetween time' => 'NOT BETWEEN TIME'];
|
||||
|
||||
// SQL表达式
|
||||
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%%UNION%%JOIN%%WHERE%%GROUP%%HAVING%%ORDER%%LIMIT%%LOCK%%COMMENT%';
|
||||
protected $insertSql = '%INSERT% INTO %TABLE% (%FIELD%) VALUES (%DATA%) %COMMENT%';
|
||||
protected $insertAllSql = '%INSERT% INTO %TABLE% (%FIELD%) %DATA% %COMMENT%';
|
||||
protected $updateSql = 'UPDATE %TABLE% SET %SET% %JOIN% %WHERE% %ORDER%%LIMIT% %LOCK%%COMMENT%';
|
||||
@@ -46,7 +47,7 @@ abstract class Builder
|
||||
/**
|
||||
* 获取当前的连接对象实例
|
||||
* @access public
|
||||
* @return void
|
||||
* @return Connection
|
||||
*/
|
||||
public function getConnection()
|
||||
{
|
||||
@@ -56,7 +57,7 @@ abstract class Builder
|
||||
/**
|
||||
* 获取当前的Query对象实例
|
||||
* @access public
|
||||
* @return void
|
||||
* @return Query
|
||||
*/
|
||||
public function getQuery()
|
||||
{
|
||||
@@ -80,6 +81,7 @@ abstract class Builder
|
||||
* @param array $data 数据
|
||||
* @param array $options 查询参数
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function parseData($data, $options)
|
||||
{
|
||||
@@ -108,16 +110,26 @@ abstract class Builder
|
||||
}
|
||||
} elseif (is_null($val)) {
|
||||
$result[$item] = 'NULL';
|
||||
} elseif (isset($val[0]) && 'exp' == $val[0]) {
|
||||
$result[$item] = $val[1];
|
||||
} elseif (is_array($val) && !empty($val)) {
|
||||
switch ($val[0]) {
|
||||
case 'exp':
|
||||
$result[$item] = $val[1];
|
||||
break;
|
||||
case 'inc':
|
||||
$result[$item] = $this->parseKey($val[1]) . '+' . floatval($val[2]);
|
||||
break;
|
||||
case 'dec':
|
||||
$result[$item] = $this->parseKey($val[1]) . '-' . floatval($val[2]);
|
||||
break;
|
||||
}
|
||||
} elseif (is_scalar($val)) {
|
||||
// 过滤非标量数据
|
||||
if (0 === strpos($val, ':') && $this->query->isBind(substr($val, 1))) {
|
||||
$result[$item] = $val;
|
||||
} else {
|
||||
$key = str_replace('.', '_', $key);
|
||||
$this->query->bind('__data__' . $key, $val, isset($bind[$key]) ? $bind[$key] : PDO::PARAM_STR);
|
||||
$result[$item] = ':__data__' . $key;
|
||||
$this->query->bind('data__' . $key, $val, isset($bind[$key]) ? $bind[$key] : PDO::PARAM_STR);
|
||||
$result[$item] = ':data__' . $key;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -300,7 +312,7 @@ abstract class Builder
|
||||
|
||||
// 查询规则和条件
|
||||
if (!is_array($val)) {
|
||||
$val = ['=', $val];
|
||||
$val = is_null($val) ? ['null', ''] : ['=', $val];
|
||||
}
|
||||
list($exp, $value) = $val;
|
||||
|
||||
@@ -335,6 +347,11 @@ abstract class Builder
|
||||
$bindName = md5($bindName);
|
||||
}
|
||||
|
||||
if (is_object($value) && method_exists($value, '__toString')) {
|
||||
// 对象数据写入
|
||||
$value = $value->__toString();
|
||||
}
|
||||
|
||||
$bindType = isset($binds[$field]) ? $binds[$field] : PDO::PARAM_STR;
|
||||
if (is_scalar($value) && array_key_exists($field, $binds) && !in_array($exp, ['EXP', 'NOT NULL', 'NULL', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN']) && strpos($exp, 'TIME') === false) {
|
||||
if (strpos($value, ':') !== 0 || !$this->query->isBind(substr($value, 1))) {
|
||||
@@ -492,7 +509,7 @@ abstract class Builder
|
||||
/**
|
||||
* limit分析
|
||||
* @access protected
|
||||
* @param mixed $lmit
|
||||
* @param mixed $limit
|
||||
* @return string
|
||||
*/
|
||||
protected function parseLimit($limit)
|
||||
@@ -544,7 +561,11 @@ abstract class Builder
|
||||
foreach ($order as $key => $val) {
|
||||
if (is_numeric($key)) {
|
||||
if ('[rand]' == $val) {
|
||||
$array[] = $this->parseRand();
|
||||
if (method_exists($this, 'parseRand')) {
|
||||
$array[] = $this->parseRand();
|
||||
} else {
|
||||
throw new BadMethodCallException('method not exists:' . get_class($this) . '-> parseRand');
|
||||
}
|
||||
} elseif (false === strpos($val, '(')) {
|
||||
$array[] = $this->parseKey($val, $options);
|
||||
} else {
|
||||
@@ -568,7 +589,7 @@ abstract class Builder
|
||||
*/
|
||||
protected function parseGroup($group)
|
||||
{
|
||||
return !empty($group) ? ' GROUP BY ' . $group : '';
|
||||
return !empty($group) ? ' GROUP BY ' . $this->parseKey($group) : '';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -619,12 +640,12 @@ abstract class Builder
|
||||
unset($union['type']);
|
||||
foreach ($union as $u) {
|
||||
if ($u instanceof \Closure) {
|
||||
$sql[] = $type . ' ' . $this->parseClosure($u, false);
|
||||
$sql[] = $type . ' ' . $this->parseClosure($u);
|
||||
} elseif (is_string($u)) {
|
||||
$sql[] = $type . ' ' . $this->parseSqlTable($u);
|
||||
$sql[] = $type . ' ( ' . $this->parseSqlTable($u) . ' )';
|
||||
}
|
||||
}
|
||||
return implode(' ', $sql);
|
||||
return ' ' . implode(' ', $sql);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -649,12 +670,16 @@ abstract class Builder
|
||||
/**
|
||||
* 设置锁机制
|
||||
* @access protected
|
||||
* @param bool $locl
|
||||
* @param bool|string $lock
|
||||
* @return string
|
||||
*/
|
||||
protected function parseLock($lock = false)
|
||||
{
|
||||
return $lock ? ' FOR UPDATE ' : '';
|
||||
if (is_bool($lock)) {
|
||||
return $lock ? ' FOR UPDATE ' : '';
|
||||
} elseif (is_string($lock)) {
|
||||
return ' ' . trim($lock) . ' ';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -723,8 +748,9 @@ abstract class Builder
|
||||
* @param array $options 表达式
|
||||
* @param bool $replace 是否replace
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
public function insertAll($dataSet, $options, $replace = false)
|
||||
public function insertAll($dataSet, $options = [], $replace = false)
|
||||
{
|
||||
// 获取合法的字段
|
||||
if ('*' == $options['field']) {
|
||||
@@ -733,7 +759,7 @@ abstract class Builder
|
||||
$fields = $options['field'];
|
||||
}
|
||||
|
||||
foreach ($dataSet as &$data) {
|
||||
foreach ($dataSet as $data) {
|
||||
foreach ($data as $key => $val) {
|
||||
if (!in_array($key, $fields, true)) {
|
||||
if ($options['strict']) {
|
||||
@@ -754,23 +780,25 @@ abstract class Builder
|
||||
}
|
||||
$value = array_values($data);
|
||||
$values[] = 'SELECT ' . implode(',', $value);
|
||||
|
||||
if (!isset($insertFields)) {
|
||||
$insertFields = array_map([$this, 'parseKey'], array_keys($data));
|
||||
}
|
||||
}
|
||||
$fields = array_map([$this, 'parseKey'], array_keys(reset($dataSet)));
|
||||
$sql = str_replace(
|
||||
|
||||
return str_replace(
|
||||
['%INSERT%', '%TABLE%', '%FIELD%', '%DATA%', '%COMMENT%'],
|
||||
[
|
||||
$replace ? 'REPLACE' : 'INSERT',
|
||||
$this->parseTable($options['table'], $options),
|
||||
implode(' , ', $fields),
|
||||
implode(' , ', $insertFields),
|
||||
implode(' UNION ALL ', $values),
|
||||
$this->parseComment($options['comment']),
|
||||
], $this->insertAllSql);
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成slectinsert SQL
|
||||
* 生成select insert SQL
|
||||
* @access public
|
||||
* @param array $fields 数据
|
||||
* @param string $table 数据表
|
||||
@@ -791,7 +819,7 @@ abstract class Builder
|
||||
/**
|
||||
* 生成update SQL
|
||||
* @access public
|
||||
* @param array $fields 数据
|
||||
* @param array $data 数据
|
||||
* @param array $options 表达式
|
||||
* @return string
|
||||
*/
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
@@ -338,8 +338,8 @@ abstract class Connection
|
||||
* @param bool $master 是否在主服务器读操作
|
||||
* @param bool $pdo 是否返回PDO对象
|
||||
* @return mixed
|
||||
* @throws BindParamException
|
||||
* @throws PDOException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function query($sql, $bind = [], $master = false, $pdo = false)
|
||||
{
|
||||
@@ -354,15 +354,15 @@ abstract class Connection
|
||||
$this->bind = $bind;
|
||||
}
|
||||
|
||||
// 释放前次的查询结果
|
||||
if (!empty($this->PDOStatement)) {
|
||||
$this->free();
|
||||
}
|
||||
|
||||
Db::$queryTimes++;
|
||||
try {
|
||||
// 调试开始
|
||||
$this->debug(true);
|
||||
|
||||
// 释放前次的查询结果
|
||||
if (!empty($this->PDOStatement)) {
|
||||
$this->free();
|
||||
}
|
||||
// 预处理
|
||||
if (empty($this->PDOStatement)) {
|
||||
$this->PDOStatement = $this->linkID->prepare($sql);
|
||||
@@ -386,6 +386,11 @@ abstract class Connection
|
||||
return $this->close()->query($sql, $bind, $master, $pdo);
|
||||
}
|
||||
throw new PDOException($e, $this->config, $this->getLastsql());
|
||||
} catch (\Throwable $e) {
|
||||
if ($this->isBreak($e)) {
|
||||
return $this->close()->query($sql, $bind, $master, $pdo);
|
||||
}
|
||||
throw $e;
|
||||
} catch (\Exception $e) {
|
||||
if ($this->isBreak($e)) {
|
||||
return $this->close()->query($sql, $bind, $master, $pdo);
|
||||
@@ -400,8 +405,8 @@ abstract class Connection
|
||||
* @param string $sql sql指令
|
||||
* @param array $bind 参数绑定
|
||||
* @return int
|
||||
* @throws BindParamException
|
||||
* @throws PDOException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function execute($sql, $bind = [])
|
||||
{
|
||||
@@ -416,15 +421,15 @@ abstract class Connection
|
||||
$this->bind = $bind;
|
||||
}
|
||||
|
||||
//释放前次的查询结果
|
||||
if (!empty($this->PDOStatement) && $this->PDOStatement->queryString != $sql) {
|
||||
$this->free();
|
||||
}
|
||||
|
||||
Db::$executeTimes++;
|
||||
try {
|
||||
// 调试开始
|
||||
$this->debug(true);
|
||||
|
||||
//释放前次的查询结果
|
||||
if (!empty($this->PDOStatement) && $this->PDOStatement->queryString != $sql) {
|
||||
$this->free();
|
||||
}
|
||||
// 预处理
|
||||
if (empty($this->PDOStatement)) {
|
||||
$this->PDOStatement = $this->linkID->prepare($sql);
|
||||
@@ -449,6 +454,11 @@ abstract class Connection
|
||||
return $this->close()->execute($sql, $bind);
|
||||
}
|
||||
throw new PDOException($e, $this->config, $this->getLastsql());
|
||||
} catch (\Throwable $e) {
|
||||
if ($this->isBreak($e)) {
|
||||
return $this->close()->execute($sql, $bind);
|
||||
}
|
||||
throw $e;
|
||||
} catch (\Exception $e) {
|
||||
if ($this->isBreak($e)) {
|
||||
return $this->close()->execute($sql, $bind);
|
||||
@@ -466,6 +476,10 @@ abstract class Connection
|
||||
*/
|
||||
public function getRealSql($sql, array $bind = [])
|
||||
{
|
||||
if (is_array($sql)) {
|
||||
$sql = implode(';', $sql);
|
||||
}
|
||||
|
||||
foreach ($bind as $key => $val) {
|
||||
$value = is_array($val) ? $val[0] : $val;
|
||||
$type = is_array($val) ? $val[1] : PDO::PARAM_STR;
|
||||
@@ -478,8 +492,8 @@ abstract class Connection
|
||||
$sql = is_numeric($key) ?
|
||||
substr_replace($sql, $value, strpos($sql, '?'), 1) :
|
||||
str_replace(
|
||||
[':' . $key . ')', ':' . $key . ',', ':' . $key . ' '],
|
||||
[$value . ')', $value . ',', $value . ' '],
|
||||
[':' . $key . ')', ':' . $key . ',', ':' . $key . ' ', ':' . $key . PHP_EOL],
|
||||
[$value . ')', $value . ',', $value . ' ', $value . PHP_EOL],
|
||||
$sql . ' ');
|
||||
}
|
||||
return rtrim($sql);
|
||||
@@ -552,7 +566,7 @@ abstract class Connection
|
||||
* @access protected
|
||||
* @param bool $pdo 是否返回PDOStatement
|
||||
* @param bool $procedure 是否存储过程
|
||||
* @return array
|
||||
* @return PDOStatement|array
|
||||
*/
|
||||
protected function getResult($pdo = false, $procedure = false)
|
||||
{
|
||||
@@ -618,7 +632,8 @@ abstract class Connection
|
||||
/**
|
||||
* 启动事务
|
||||
* @access public
|
||||
* @return void
|
||||
* @return bool|mixed
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function startTrans()
|
||||
{
|
||||
@@ -642,7 +657,12 @@ abstract class Connection
|
||||
return $this->close()->startTrans();
|
||||
}
|
||||
throw $e;
|
||||
} catch (\ErrorException $e) {
|
||||
} catch (\Exception $e) {
|
||||
if ($this->isBreak($e)) {
|
||||
return $this->close()->startTrans();
|
||||
}
|
||||
throw $e;
|
||||
} catch (\Error $e) {
|
||||
if ($this->isBreak($e)) {
|
||||
return $this->close()->startTrans();
|
||||
}
|
||||
@@ -724,7 +744,7 @@ abstract class Connection
|
||||
* @param array $sqlArray SQL批处理指令
|
||||
* @return boolean
|
||||
*/
|
||||
public function batchQuery($sqlArray = [])
|
||||
public function batchQuery($sqlArray = [], $bind = [])
|
||||
{
|
||||
if (!is_array($sqlArray)) {
|
||||
return false;
|
||||
@@ -733,7 +753,7 @@ abstract class Connection
|
||||
$this->startTrans();
|
||||
try {
|
||||
foreach ($sqlArray as $sql) {
|
||||
$this->execute($sql);
|
||||
$this->execute($sql, $bind);
|
||||
}
|
||||
// 提交事务
|
||||
$this->commit();
|
||||
@@ -741,6 +761,7 @@ abstract class Connection
|
||||
$this->rollback();
|
||||
throw $e;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -782,7 +803,7 @@ abstract class Connection
|
||||
/**
|
||||
* 是否断线
|
||||
* @access protected
|
||||
* @param \PDOException $e 异常对象
|
||||
* @param \PDOException|\Exception $e 异常对象
|
||||
* @return bool
|
||||
*/
|
||||
protected function isBreak($e)
|
||||
|
||||
+144
-95
@@ -2,7 +2,7 @@
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
@@ -12,6 +12,7 @@
|
||||
namespace think\db;
|
||||
|
||||
use PDO;
|
||||
use think\App;
|
||||
use think\Cache;
|
||||
use think\Collection;
|
||||
use think\Config;
|
||||
@@ -114,6 +115,7 @@ class Query
|
||||
{
|
||||
$this->connection = Db::connect($config);
|
||||
$this->setBuilder();
|
||||
$this->prefix = $this->connection->getConfig('prefix');
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -310,9 +312,9 @@ class Query
|
||||
* @param array $sql SQL批处理指令
|
||||
* @return boolean
|
||||
*/
|
||||
public function batchQuery($sql = [])
|
||||
public function batchQuery($sql = [], $bind = [])
|
||||
{
|
||||
return $this->connection->batchQuery($sql);
|
||||
return $this->connection->batchQuery($sql, $bind);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -415,8 +417,9 @@ class Query
|
||||
}
|
||||
$result = $pdo->fetchColumn();
|
||||
if ($force) {
|
||||
$result = is_numeric($result) ? $result + 0 : $result;
|
||||
$result += 0;
|
||||
}
|
||||
|
||||
if (isset($cache)) {
|
||||
// 缓存数据
|
||||
$this->cacheData($key, $result, $cache);
|
||||
@@ -531,22 +534,24 @@ class Query
|
||||
* MIN查询
|
||||
* @access public
|
||||
* @param string $field 字段名
|
||||
* @param bool $force 强制转为数字类型
|
||||
* @return mixed
|
||||
*/
|
||||
public function min($field)
|
||||
public function min($field, $force = true)
|
||||
{
|
||||
return $this->value('MIN(' . $field . ') AS tp_min', 0, true);
|
||||
return $this->value('MIN(' . $field . ') AS tp_min', 0, $force);
|
||||
}
|
||||
|
||||
/**
|
||||
* MAX查询
|
||||
* @access public
|
||||
* @param string $field 字段名
|
||||
* @param bool $force 强制转为数字类型
|
||||
* @return mixed
|
||||
*/
|
||||
public function max($field)
|
||||
public function max($field, $force = true)
|
||||
{
|
||||
return $this->value('MAX(' . $field . ') AS tp_max', 0, true);
|
||||
return $this->value('MAX(' . $field . ') AS tp_max', 0, $force);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -604,7 +609,7 @@ class Query
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return $this->setField($field, ['exp', $field . '+' . $step]);
|
||||
return $this->setField($field, ['inc', $field, $step]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -632,8 +637,9 @@ class Query
|
||||
$this->options = [];
|
||||
return true;
|
||||
}
|
||||
return $this->setField($field, ['inc', $field, $step]);
|
||||
}
|
||||
return $this->setField($field, ['exp', $field . '-' . $step]);
|
||||
return $this->setField($field, ['dec', $field, $step]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -701,7 +707,8 @@ class Query
|
||||
{
|
||||
// 传入的表名为数组
|
||||
if (is_array($join)) {
|
||||
list($table, $alias) = each($join);
|
||||
$table = key($join);
|
||||
$alias = current($join);
|
||||
} else {
|
||||
$join = trim($join);
|
||||
if (false !== strpos($join, '(')) {
|
||||
@@ -723,10 +730,13 @@ class Query
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isset($alias)) {
|
||||
if (isset($alias) && $table != $alias) {
|
||||
if (isset($this->options['alias'][$table])) {
|
||||
$table = $table . '@think' . uniqid();
|
||||
} elseif ($this->gettable() == $table) {
|
||||
$table = $table . '@think' . uniqid();
|
||||
}
|
||||
|
||||
$table = [$table => $alias];
|
||||
$this->alias($table);
|
||||
}
|
||||
@@ -825,7 +835,7 @@ class Query
|
||||
{
|
||||
$fields = is_string($field) ? explode(',', $field) : $field;
|
||||
foreach ($fields as $field) {
|
||||
$this->data($field, ['exp', $field . '+' . $step]);
|
||||
$this->data($field, ['inc', $field, $step]);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
@@ -841,7 +851,7 @@ class Query
|
||||
{
|
||||
$fields = is_string($field) ? explode(',', $field) : $field;
|
||||
foreach ($fields as $field) {
|
||||
$this->data($field, ['exp', $field . '-' . $step]);
|
||||
$this->data($field, ['dec', $field, $step]);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
@@ -1184,10 +1194,8 @@ class Query
|
||||
$this->options['multi'][$logic][$field][] = $where[$field];
|
||||
} elseif (is_null($condition)) {
|
||||
// 字段相等查询
|
||||
$where[$field] = ['eq', $op];
|
||||
if ('AND' != $logic) {
|
||||
$this->options['multi'][$logic][$field][] = $where[$field];
|
||||
}
|
||||
$where[$field] = ['eq', $op];
|
||||
$this->options['multi'][$logic][$field][] = $where[$field];
|
||||
} else {
|
||||
$where[$field] = [$op, $condition, isset($param[2]) ? $param[2] : null];
|
||||
if ('exp' == strtolower($op) && isset($param[2]) && is_array($param[2])) {
|
||||
@@ -1238,6 +1246,7 @@ class Query
|
||||
$logic = strtoupper($logic);
|
||||
if (isset($this->options['where'][$logic][$field])) {
|
||||
unset($this->options['where'][$logic][$field]);
|
||||
unset($this->options['multi'][$logic][$field]);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
@@ -1444,18 +1453,19 @@ class Query
|
||||
/**
|
||||
* 查询缓存
|
||||
* @access public
|
||||
* @param mixed $key 缓存key
|
||||
* @param integer $expire 缓存有效期
|
||||
* @param string $tag 缓存标签
|
||||
* @param mixed $key 缓存key
|
||||
* @param integer|\DateTime $expire 缓存有效期
|
||||
* @param string $tag 缓存标签
|
||||
* @return $this
|
||||
*/
|
||||
public function cache($key = true, $expire = null, $tag = null)
|
||||
{
|
||||
// 增加快捷调用方式 cache(10) 等同于 cache(true, 10)
|
||||
if (is_numeric($key) && is_null($expire)) {
|
||||
if ($key instanceof \DateTime || (is_numeric($key) && is_null($expire))) {
|
||||
$expire = $key;
|
||||
$key = true;
|
||||
}
|
||||
|
||||
if (false !== $key) {
|
||||
$this->options['cache'] = ['key' => $key, 'expire' => $expire, 'tag' => $tag];
|
||||
}
|
||||
@@ -1489,7 +1499,7 @@ class Query
|
||||
/**
|
||||
* 指定查询lock
|
||||
* @access public
|
||||
* @param boolean $lock 是否lock
|
||||
* @param bool|string $lock 是否lock
|
||||
* @return $this
|
||||
*/
|
||||
public function lock($lock = false)
|
||||
@@ -1521,7 +1531,12 @@ class Query
|
||||
{
|
||||
if (is_array($alias)) {
|
||||
foreach ($alias as $key => $val) {
|
||||
$this->options['alias'][$key] = $val;
|
||||
if (false !== strpos($key, '__')) {
|
||||
$table = $this->parseSqlTable($key);
|
||||
} else {
|
||||
$table = $key;
|
||||
}
|
||||
$this->options['alias'][$table] = $val;
|
||||
}
|
||||
} else {
|
||||
if (isset($this->options['table'])) {
|
||||
@@ -1649,46 +1664,49 @@ class Query
|
||||
* 查询日期或者时间
|
||||
* @access public
|
||||
* @param string $field 日期字段名
|
||||
* @param string $op 比较运算符或者表达式
|
||||
* @param string|array $op 比较运算符或者表达式
|
||||
* @param string|array $range 比较范围
|
||||
* @return $this
|
||||
*/
|
||||
public function whereTime($field, $op, $range = null)
|
||||
{
|
||||
if (is_null($range)) {
|
||||
// 使用日期表达式
|
||||
$date = getdate();
|
||||
switch (strtolower($op)) {
|
||||
case 'today':
|
||||
case 'd':
|
||||
$range = ['today', 'tomorrow'];
|
||||
break;
|
||||
case 'week':
|
||||
case 'w':
|
||||
$range = 'this week 00:00:00';
|
||||
break;
|
||||
case 'month':
|
||||
case 'm':
|
||||
$range = mktime(0, 0, 0, $date['mon'], 1, $date['year']);
|
||||
break;
|
||||
case 'year':
|
||||
case 'y':
|
||||
$range = mktime(0, 0, 0, 1, 1, $date['year']);
|
||||
break;
|
||||
case 'yesterday':
|
||||
$range = ['yesterday', 'today'];
|
||||
break;
|
||||
case 'last week':
|
||||
$range = ['last week 00:00:00', 'this week 00:00:00'];
|
||||
break;
|
||||
case 'last month':
|
||||
$range = [date('y-m-01', strtotime('-1 month')), mktime(0, 0, 0, $date['mon'], 1, $date['year'])];
|
||||
break;
|
||||
case 'last year':
|
||||
$range = [mktime(0, 0, 0, 1, 1, $date['year'] - 1), mktime(0, 0, 0, 1, 1, $date['year'])];
|
||||
break;
|
||||
default:
|
||||
$range = $op;
|
||||
if (is_array($op)) {
|
||||
$range = $op;
|
||||
} else {
|
||||
// 使用日期表达式
|
||||
switch (strtolower($op)) {
|
||||
case 'today':
|
||||
case 'd':
|
||||
$range = ['today', 'tomorrow'];
|
||||
break;
|
||||
case 'week':
|
||||
case 'w':
|
||||
$range = ['this week 00:00:00', 'next week 00:00:00'];
|
||||
break;
|
||||
case 'month':
|
||||
case 'm':
|
||||
$range = ['first Day of this month 00:00:00', 'first Day of next month 00:00:00'];
|
||||
break;
|
||||
case 'year':
|
||||
case 'y':
|
||||
$range = ['this year 1/1', 'next year 1/1'];
|
||||
break;
|
||||
case 'yesterday':
|
||||
$range = ['yesterday', 'today'];
|
||||
break;
|
||||
case 'last week':
|
||||
$range = ['last week 00:00:00', 'this week 00:00:00'];
|
||||
break;
|
||||
case 'last month':
|
||||
$range = ['first Day of last month 00:00:00', 'first Day of this month 00:00:00'];
|
||||
break;
|
||||
case 'last year':
|
||||
$range = ['last year 1/1', 'this year 1/1'];
|
||||
break;
|
||||
default:
|
||||
$range = $op;
|
||||
}
|
||||
}
|
||||
$op = is_array($range) ? 'between' : '>';
|
||||
}
|
||||
@@ -1733,7 +1751,7 @@ class Query
|
||||
$schema = $guid;
|
||||
}
|
||||
// 读取缓存
|
||||
if (is_file(RUNTIME_PATH . 'schema/' . $schema . '.php')) {
|
||||
if (!App::$debug && is_file(RUNTIME_PATH . 'schema/' . $schema . '.php')) {
|
||||
$info = include RUNTIME_PATH . 'schema/' . $schema . '.php';
|
||||
} else {
|
||||
$info = $this->connection->getFields($guid);
|
||||
@@ -1808,7 +1826,9 @@ class Query
|
||||
*/
|
||||
protected function getFieldBindType($type)
|
||||
{
|
||||
if (preg_match('/(int|double|float|decimal|real|numeric|serial|bit)/is', $type)) {
|
||||
if (0 === strpos($type, 'set') || 0 === strpos($type, 'enum')) {
|
||||
$bind = PDO::PARAM_STR;
|
||||
} elseif (preg_match('/(int|double|float|decimal|real|numeric|serial|bit)/is', $type)) {
|
||||
$bind = PDO::PARAM_INT;
|
||||
} elseif (preg_match('/bool/is', $type)) {
|
||||
$bind = PDO::PARAM_BOOL;
|
||||
@@ -2080,7 +2100,7 @@ class Query
|
||||
}
|
||||
|
||||
// 执行操作
|
||||
$result = $this->execute($sql, $bind);
|
||||
$result = 0 === $sql ? 0 : $this->execute($sql, $bind);
|
||||
if ($result) {
|
||||
$sequence = $sequence ?: (isset($options['sequence']) ? $options['sequence'] : null);
|
||||
$lastInsId = $this->getLastInsID($sequence);
|
||||
@@ -2116,24 +2136,37 @@ class Query
|
||||
/**
|
||||
* 批量插入记录
|
||||
* @access public
|
||||
* @param mixed $dataSet 数据集
|
||||
* @param boolean $replace 是否replace
|
||||
* @param mixed $dataSet 数据集
|
||||
* @param boolean $replace 是否replace
|
||||
* @param integer $limit 每次写入数据限制
|
||||
* @return integer|string
|
||||
*/
|
||||
public function insertAll(array $dataSet, $replace = false)
|
||||
public function insertAll(array $dataSet, $replace = false, $limit = null)
|
||||
{
|
||||
// 分析查询表达式
|
||||
$options = $this->parseExpress();
|
||||
if (!is_array(reset($dataSet))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 生成SQL语句
|
||||
$sql = $this->builder->insertAll($dataSet, $options, $replace);
|
||||
if (is_null($limit)) {
|
||||
$sql = $this->builder->insertAll($dataSet, $options, $replace);
|
||||
} else {
|
||||
$array = array_chunk($dataSet, $limit, true);
|
||||
foreach ($array as $item) {
|
||||
$sql[] = $this->builder->insertAll($item, $options, $replace);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取参数绑定
|
||||
$bind = $this->getBind();
|
||||
if ($options['fetch_sql']) {
|
||||
// 获取实际执行的SQL语句
|
||||
return $this->connection->getRealSql($sql, $bind);
|
||||
} elseif (is_array($sql)) {
|
||||
// 执行操作
|
||||
return $this->batchQuery($sql, $bind);
|
||||
} else {
|
||||
// 执行操作
|
||||
return $this->execute($sql, $bind);
|
||||
@@ -2335,7 +2368,7 @@ class Query
|
||||
$modelName = $this->model;
|
||||
if (count($resultSet) > 0) {
|
||||
foreach ($resultSet as $key => $result) {
|
||||
/** @var Model $result */
|
||||
/** @var Model $model */
|
||||
$model = new $modelName($result);
|
||||
$model->isUpdate(true);
|
||||
|
||||
@@ -2391,12 +2424,13 @@ class Query
|
||||
* @param mixed $value 缓存数据
|
||||
* @param array $options 缓存参数
|
||||
* @param array $bind 绑定参数
|
||||
* @return string
|
||||
*/
|
||||
protected function getCacheKey($value, $options, $bind = [])
|
||||
{
|
||||
if (is_scalar($value)) {
|
||||
$data = $value;
|
||||
} elseif (is_array($value) && 'eq' == strtolower($value[0])) {
|
||||
} elseif (is_array($value) && is_string($value[0]) && 'eq' == strtolower($value[0])) {
|
||||
$data = $value[1];
|
||||
}
|
||||
if (isset($data)) {
|
||||
@@ -2564,44 +2598,59 @@ class Query
|
||||
* @param integer $count 每次处理的数据数量
|
||||
* @param callable $callback 处理回调方法
|
||||
* @param string $column 分批处理的字段名
|
||||
* @param string $order 排序规则
|
||||
* @return boolean
|
||||
* @throws \LogicException
|
||||
*/
|
||||
public function chunk($count, $callback, $column = null)
|
||||
public function chunk($count, $callback, $column = null, $order = 'asc')
|
||||
{
|
||||
$options = $this->getOptions();
|
||||
if (isset($options['table'])) {
|
||||
$table = is_array($options['table']) ? key($options['table']) : $options['table'];
|
||||
} else {
|
||||
$table = '';
|
||||
}
|
||||
$column = $column ?: $this->getPk($table);
|
||||
$bind = $this->bind;
|
||||
$resultSet = $this->limit($count)->order($column, 'asc')->select();
|
||||
if (strpos($column, '.')) {
|
||||
list($alias, $key) = explode('.', $column);
|
||||
} else {
|
||||
$key = $column;
|
||||
}
|
||||
if ($resultSet instanceof Collection) {
|
||||
$resultSet = $resultSet->all();
|
||||
}
|
||||
|
||||
while (!empty($resultSet)) {
|
||||
if (false === call_user_func($callback, $resultSet)) {
|
||||
return false;
|
||||
$column = $column ?: $this->getPk($options);
|
||||
|
||||
if (isset($options['order'])) {
|
||||
if (App::$debug) {
|
||||
throw new \LogicException('chunk not support call order');
|
||||
}
|
||||
$end = end($resultSet);
|
||||
$lastId = is_array($end) ? $end[$key] : $end->$key;
|
||||
$resultSet = $this->options($options)
|
||||
->limit($count)
|
||||
->bind($bind)
|
||||
->where($column, '>', $lastId)
|
||||
->order($column, 'asc')
|
||||
->select();
|
||||
unset($options['order']);
|
||||
}
|
||||
$bind = $this->bind;
|
||||
if (is_array($column)) {
|
||||
$times = 1;
|
||||
$query = $this->options($options)->page($times, $count);
|
||||
} else {
|
||||
if (strpos($column, '.')) {
|
||||
list($alias, $key) = explode('.', $column);
|
||||
} else {
|
||||
$key = $column;
|
||||
}
|
||||
$query = $this->options($options)->limit($count);
|
||||
}
|
||||
$resultSet = $query->order($column, $order)->select();
|
||||
|
||||
while (count($resultSet) > 0) {
|
||||
if ($resultSet instanceof Collection) {
|
||||
$resultSet = $resultSet->all();
|
||||
}
|
||||
|
||||
if (false === call_user_func($callback, $resultSet)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_array($column)) {
|
||||
$times++;
|
||||
$query = $this->options($options)->page($times, $count);
|
||||
} else {
|
||||
$end = end($resultSet);
|
||||
$lastId = is_array($end) ? $end[$key] : $end->getData($key);
|
||||
$query = $this->options($options)
|
||||
->limit($count)
|
||||
->where($column, 'asc' == strtolower($order) ? '>' : '<', $lastId);
|
||||
}
|
||||
|
||||
$resultSet = $query->bind($bind)->order($column, $order)->select();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
@@ -12,13 +12,72 @@
|
||||
namespace think\db\builder;
|
||||
|
||||
use think\db\Builder;
|
||||
use think\Exception;
|
||||
|
||||
/**
|
||||
* mysql数据库驱动
|
||||
*/
|
||||
class Mysql extends Builder
|
||||
{
|
||||
protected $updateSql = 'UPDATE %TABLE% %JOIN% SET %SET% %WHERE% %ORDER%%LIMIT% %LOCK%%COMMENT%';
|
||||
|
||||
protected $insertAllSql = '%INSERT% INTO %TABLE% (%FIELD%) VALUES %DATA% %COMMENT%';
|
||||
protected $updateSql = 'UPDATE %TABLE% %JOIN% SET %SET% %WHERE% %ORDER%%LIMIT% %LOCK%%COMMENT%';
|
||||
|
||||
/**
|
||||
* 生成insertall SQL
|
||||
* @access public
|
||||
* @param array $dataSet 数据集
|
||||
* @param array $options 表达式
|
||||
* @param bool $replace 是否replace
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
public function insertAll($dataSet, $options = [], $replace = false)
|
||||
{
|
||||
// 获取合法的字段
|
||||
if ('*' == $options['field']) {
|
||||
$fields = array_keys($this->query->getFieldsType($options['table']));
|
||||
} else {
|
||||
$fields = $options['field'];
|
||||
}
|
||||
|
||||
foreach ($dataSet as $data) {
|
||||
foreach ($data as $key => $val) {
|
||||
if (!in_array($key, $fields, true)) {
|
||||
if ($options['strict']) {
|
||||
throw new Exception('fields not exists:[' . $key . ']');
|
||||
}
|
||||
unset($data[$key]);
|
||||
} elseif (is_null($val)) {
|
||||
$data[$key] = 'NULL';
|
||||
} elseif (is_scalar($val)) {
|
||||
$data[$key] = $this->parseValue($val, $key);
|
||||
} elseif (is_object($val) && method_exists($val, '__toString')) {
|
||||
// 对象数据写入
|
||||
$data[$key] = $val->__toString();
|
||||
} else {
|
||||
// 过滤掉非标量数据
|
||||
unset($data[$key]);
|
||||
}
|
||||
}
|
||||
$value = array_values($data);
|
||||
$values[] = '( ' . implode(',', $value) . ' )';
|
||||
|
||||
if (!isset($insertFields)) {
|
||||
$insertFields = array_map([$this, 'parseKey'], array_keys($data));
|
||||
}
|
||||
}
|
||||
|
||||
return str_replace(
|
||||
['%INSERT%', '%TABLE%', '%FIELD%', '%DATA%', '%COMMENT%'],
|
||||
[
|
||||
$replace ? 'REPLACE' : 'INSERT',
|
||||
$this->parseTable($options['table'], $options),
|
||||
implode(' , ', $insertFields),
|
||||
implode(' , ', $values),
|
||||
$this->parseComment($options['comment']),
|
||||
], $this->insertAllSql);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段和表名处理
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
@@ -18,6 +18,8 @@ use think\db\Builder;
|
||||
*/
|
||||
class Pgsql extends Builder
|
||||
{
|
||||
protected $insertSql = 'INSERT INTO %TABLE% (%FIELD%) VALUES (%DATA%) %COMMENT%';
|
||||
protected $insertAllSql = 'INSERT INTO %TABLE% (%FIELD%) %DATA% %COMMENT%';
|
||||
|
||||
/**
|
||||
* limit分析
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
@@ -22,6 +22,7 @@ class Sqlite extends Builder
|
||||
/**
|
||||
* limit
|
||||
* @access public
|
||||
* @param string $limit
|
||||
* @return string
|
||||
*/
|
||||
public function parseLimit($limit)
|
||||
|
||||
@@ -22,6 +22,8 @@ class Sqlsrv extends Builder
|
||||
protected $selectInsertSql = 'SELECT %DISTINCT% %FIELD% FROM %TABLE%%JOIN%%WHERE%%GROUP%%HAVING%';
|
||||
protected $updateSql = 'UPDATE %TABLE% SET %SET% FROM %TABLE% %JOIN% %WHERE% %LIMIT% %LOCK%%COMMENT%';
|
||||
protected $deleteSql = 'DELETE FROM %TABLE% %USING% FROM %TABLE% %JOIN% %WHERE% %LIMIT% %LOCK%%COMMENT%';
|
||||
protected $insertSql = 'INSERT INTO %TABLE% (%FIELD%) VALUES (%DATA%) %COMMENT%';
|
||||
protected $insertAllSql = 'INSERT INTO %TABLE% (%FIELD%) %DATA% %COMMENT%';
|
||||
|
||||
/**
|
||||
* order分析
|
||||
@@ -40,6 +42,8 @@ class Sqlsrv extends Builder
|
||||
$array[] = $this->parseKey($val, $options);
|
||||
} elseif ('[rand]' == $val) {
|
||||
$array[] = $this->parseRand();
|
||||
} else {
|
||||
$array[] = $val;
|
||||
}
|
||||
} else {
|
||||
$sort = in_array(strtolower(trim($val)), ['asc', 'desc']) ? ' ' . $val : '';
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
@@ -31,12 +31,15 @@ class Mysql extends Connection
|
||||
*/
|
||||
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['socket'])) {
|
||||
$dsn = 'mysql:unix_socket=' . $config['socket'];
|
||||
} elseif (!empty($config['hostport'])) {
|
||||
$dsn = 'mysql:host=' . $config['hostname'] . ';port=' . $config['hostport'];
|
||||
} else {
|
||||
$dsn = 'mysql:host=' . $config['hostname'];
|
||||
}
|
||||
$dsn .= ';dbname=' . $config['database'];
|
||||
|
||||
if (!empty($config['charset'])) {
|
||||
$dsn .= ';charset=' . $config['charset'];
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user