升级ThinkPHP版本

This commit is contained in:
Anyon 2021-01-11 11:55:23 +08:00
parent 988532dc3f
commit dd56cd470e
26 changed files with 191 additions and 95 deletions

View File

@ -536,17 +536,17 @@
},
{
"name": "topthink/framework",
"version": "v6.0.5",
"version_normalized": "6.0.5.0",
"version": "v6.0.6",
"version_normalized": "6.0.6.0",
"source": {
"type": "git",
"url": "https://github.com/top-think/framework.git",
"reference": "85625d984f5c96699dc27d384869f206c3aec1cc"
"reference": "dd265d9e962da2c033a45190b839d5538770a760"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/top-think/framework/zipball/85625d984f5c96699dc27d384869f206c3aec1cc",
"reference": "85625d984f5c96699dc27d384869f206c3aec1cc",
"url": "https://api.github.com/repos/top-think/framework/zipball/dd265d9e962da2c033a45190b839d5538770a760",
"reference": "dd265d9e962da2c033a45190b839d5538770a760",
"shasum": "",
"mirrors": [
{
@ -572,7 +572,7 @@
"mockery/mockery": "^1.2",
"phpunit/phpunit": "^7.0"
},
"time": "2020-10-26T07:18:00+00:00",
"time": "2021-01-10T15:35:54+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
@ -601,11 +601,7 @@
"framework",
"orm",
"thinkphp"
],
"support": {
"issues": "https://github.com/top-think/framework/issues",
"source": "https://github.com/top-think/framework/tree/v6.0.5"
}
]
},
{
"name": "topthink/think-helper",
@ -660,17 +656,17 @@
},
{
"name": "topthink/think-orm",
"version": "v2.0.34",
"version_normalized": "2.0.34.0",
"version": "v2.0.35",
"version_normalized": "2.0.35.0",
"source": {
"type": "git",
"url": "https://github.com/top-think/think-orm.git",
"reference": "57f9b98895b0ff4ae7b7b75e51456fd8cb8fb629"
"reference": "f0bba0b15610d4015655ff6f07ea3d639212076f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/top-think/think-orm/zipball/57f9b98895b0ff4ae7b7b75e51456fd8cb8fb629",
"reference": "57f9b98895b0ff4ae7b7b75e51456fd8cb8fb629",
"url": "https://api.github.com/repos/top-think/think-orm/zipball/f0bba0b15610d4015655ff6f07ea3d639212076f",
"reference": "f0bba0b15610d4015655ff6f07ea3d639212076f",
"shasum": "",
"mirrors": [
{
@ -686,7 +682,7 @@
"psr/simple-cache": "^1.0",
"topthink/think-helper": "^3.1"
},
"time": "2020-09-28T08:24:57+00:00",
"time": "2021-01-06T12:55:12+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
@ -709,11 +705,7 @@
"keywords": [
"database",
"orm"
],
"support": {
"issues": "https://github.com/top-think/think-orm/issues",
"source": "https://github.com/top-think/think-orm/tree/v2.0.34"
}
]
},
{
"name": "topthink/think-template",

2
vendor/services.php vendored
View File

@ -1,5 +1,5 @@
<?php
// This file is automatically generated at:2021-01-09 18:42:18
// This file is automatically generated at:2021-01-11 11:55:05
declare (strict_types = 1);
return array (
0 => 'think\\admin\\Library',

View File

@ -19,6 +19,7 @@ services:
before_install:
- echo "extension = memcached.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
- echo 'xdebug.mode = coverage' >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini
- printf "\n" | pecl install -f redis
- travis_retry composer self-update
- mysql -e 'CREATE DATABASE test;'

View File

@ -13,7 +13,7 @@ ThinkPHP 6.0
ThinkPHP6.0底层架构采用PHP7.1改写和进一步优化。
[官方应用服务市场](https://market.topthink.com) | [`ThinkPHP`开发者扶持计划](https://sites.thinkphp.cn/1782366)
[官方应用服务市场](https://market.topthink.com) | [`ThinkAPI`——官方统一API服务](https://docs.topthink.com/think-api/)
## 主要新特性
@ -35,7 +35,7 @@ ThinkPHP6.0底层架构采用PHP7.1改写和进一步优化。
* 统一和精简大量用法
> ThinkPHP6.0的运行环境要求PHP7.1+。
> ThinkPHP6.0的运行环境要求PHP7.1+兼容PHP8.0
## 安装
@ -79,7 +79,7 @@ ThinkPHP遵循Apache2开源协议发布并提供免费使用。
本项目包含的第三方源码和二进制文件之版权信息另行标注。
版权所有Copyright © 2006-2020 by ThinkPHP (http://thinkphp.cn) All rights reserved。
版权所有Copyright © 2006-2021 by ThinkPHP (http://thinkphp.cn) All rights reserved。
ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。

View File

@ -39,7 +39,7 @@ use think\initializer\RegisterService;
*/
class App extends Container
{
const VERSION = '6.0.5';
const VERSION = '6.0.6';
/**
* 应用调试模式

View File

@ -380,8 +380,10 @@ class Container implements ContainerInterface, ArrayAccess, IteratorAggregate, C
if ($reflect->hasMethod('__make')) {
$method = $reflect->getMethod('__make');
if ($method->isPublic() && $method->isStatic()) {
$args = $this->bindParams($method, $vars);
return $method->invokeArgs(null, $args);
$args = $this->bindParams($method, $vars);
$object = $method->invokeArgs(null, $args);
$this->invokeAfter($class, $object);
return $object;
}
}
@ -440,10 +442,10 @@ class Container implements ContainerInterface, ArrayAccess, IteratorAggregate, C
foreach ($params as $param) {
$name = $param->getName();
$lowerName = Str::snake($name);
$class = $param->getClass();
$reflectionType = $param->getType();
if ($class) {
$args[] = $this->getObjectParam($class->getName(), $vars);
if ($reflectionType && $reflectionType->isBuiltin() === false) {
$args[] = $this->getObjectParam($reflectionType->getName(), $vars);
} elseif (1 == $type && !empty($vars)) {
$args[] = array_shift($vars);
} elseif (0 == $type && array_key_exists($name, $vars)) {

View File

@ -1659,7 +1659,7 @@ class Request implements ArrayAccess
$flag = FILTER_FLAG_IPV6;
break;
default:
$flag = null;
$flag = 0;
break;
}

View File

@ -126,10 +126,10 @@ class Validate
'alpha' => '/^[A-Za-z]+$/',
'alphaNum' => '/^[A-Za-z0-9]+$/',
'alphaDash' => '/^[A-Za-z0-9\-\_]+$/',
'chs' => '/^[\x{4e00}-\x{9fa5}]+$/u',
'chsAlpha' => '/^[\x{4e00}-\x{9fa5}a-zA-Z]+$/u',
'chsAlphaNum' => '/^[\x{4e00}-\x{9fa5}a-zA-Z0-9]+$/u',
'chsDash' => '/^[\x{4e00}-\x{9fa5}a-zA-Z0-9\_\-]+$/u',
'chs' => '/^[\x{4e00}-\x{9fa5}\x{9fa6}-\x{9fef}\x{3400}-\x{4db5}\x{20000}-\x{2ebe0}]+$/u',
'chsAlpha' => '/^[\x{4e00}-\x{9fa5}\x{9fa6}-\x{9fef}\x{3400}-\x{4db5}\x{20000}-\x{2ebe0}a-zA-Z]+$/u',
'chsAlphaNum' => '/^[\x{4e00}-\x{9fa5}\x{9fa6}-\x{9fef}\x{3400}-\x{4db5}\x{20000}-\x{2ebe0}a-zA-Z0-9]+$/u',
'chsDash' => '/^[\x{4e00}-\x{9fa5}\x{9fa6}-\x{9fef}\x{3400}-\x{4db5}\x{20000}-\x{2ebe0}a-zA-Z0-9\_\-]+$/u',
'mobile' => '/^1[3-9]\d{9}$/',
'idCard' => '/(^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$)|(^[1-9]\d{5}\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}$)/',
'zip' => '/\d{6}/',
@ -1605,6 +1605,11 @@ class Validate
return $this->errorMsgIsArray($msg, $rule, $title);
}
// rule若是数组则转为字符串
if (is_array($rule)) {
$rule = implode(',', $rule);
}
if (is_scalar($rule) && false !== strpos($msg, ':')) {
// 变量替换
if (is_string($rule) && strpos($rule, ',')) {

View File

@ -115,7 +115,11 @@ class View extends Manager
{
// 页面缓存
ob_start();
ob_implicit_flush(0);
if (PHP_VERSION > 8.0) {
ob_implicit_flush(false);
} else {
ob_implicit_flush(0);
}
// 渲染输出
try {

View File

@ -31,7 +31,10 @@ class VendorPublish extends Command
if (is_file($path = $this->app->getRootPath() . 'vendor/composer/installed.json')) {
$packages = json_decode(@file_get_contents($path), true);
// Compatibility with Composer 2.0
if (isset($packages['packages'])) {
$packages = $packages['packages'];
}
foreach ($packages as $package) {
//配置
$configDir = $this->app->getConfigPath();

View File

@ -31,6 +31,6 @@ class Middleware extends Make
protected function getNamespace(string $app): string
{
return 'app\\middleware';
return parent::getNamespace($app) . '\\middleware';
}
}

View File

@ -10,6 +10,7 @@
// +----------------------------------------------------------------------
namespace think\console\command\optimize;
use Exception;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
@ -78,13 +79,17 @@ class Schema extends Command
{
$reflect = new \ReflectionClass($class);
if (!$reflect->isAbstract() && $reflect->isSubclassOf('\think\Model')) {
/** @var \think\Model $model */
$model = new $class;
$connection = $model->db()->getConnection();
if ($connection instanceof PDOConnection) {
$table = $model->getTable();
//预读字段信息
$connection->getSchemaInfo($table, true);
try {
/** @var \think\Model $model */
$model = new $class;
$connection = $model->db()->getConnection();
if ($connection instanceof PDOConnection) {
$table = $model->getTable();
//预读字段信息
$connection->getSchemaInfo($table, true);
}
} catch (Exception $e) {
}
}
}

View File

@ -41,6 +41,11 @@ class Socket implements LogHandlerInterface
'expand_level' => ['debug'],
// 日志头渲染回调
'format_head' => null,
// curl opt
'curl_opt' => [
CURLOPT_CONNECTTIMEOUT => 1,
CURLOPT_TIMEOUT => 10,
],
];
protected $css = [
@ -292,8 +297,8 @@ class Socket implements LogHandlerInterface
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $message);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->config['curl_opt'][CURLOPT_CONNECTTIMEOUT] ?? 1);
curl_setopt($ch, CURLOPT_TIMEOUT, $this->config['curl_opt'][CURLOPT_TIMEOUT] ?? 10);
$headers = [
"Content-Type: application/json;charset=UTF-8",

View File

@ -162,7 +162,7 @@ class CheckRequestCache
foreach ($param as $item => $val) {
if (is_string($val) && false !== strpos($key, ':' . $item)) {
$key = str_replace(':' . $item, $val, $key);
$key = str_replace(':' . $item, (string) $val, $key);
}
}
} elseif (strpos($key, ']')) {

View File

@ -44,7 +44,9 @@ class File extends Response
throw new Exception('file not exists:' . $data);
}
ob_end_clean();
while (ob_get_level() > 0) {
ob_end_clean();
}
if (!empty($this->name)) {
$name = $this->name;

View File

@ -132,7 +132,7 @@ class Resource extends RuleGroup
$ruleItem = $this->addRule(trim($prefix . $val[1], '/'), $this->route . '/' . $val[2], $val[0]);
foreach (['model', 'validate', 'middleware'] as $name) {
foreach (['model', 'validate', 'middleware', 'pattern'] as $name) {
if (isset($this->$name[$key])) {
call_user_func_array([$ruleItem, $name], (array) $this->$name[$key]);
}

View File

@ -806,7 +806,8 @@ abstract class Rule
}
$regex = str_replace(array_unique($match), array_unique($replace), $rule);
$regex = str_replace([')?/', ')/', ')?-', ')-', '\\\\/'], [')\/', ')\/', ')\-', ')\-', '\/'], $regex);
$regex = str_replace('/', '\/', $regex);
$regex = str_replace([')?\/', ')?-', ')-', '\\\\/'], [')\/', ')\-', ')\-', '\/'], $regex);
if (isset($hasSlash)) {
$regex .= '\/';

View File

@ -328,7 +328,7 @@ class Url
foreach ($pattern as $key => $val) {
if (isset($vars[$key])) {
$url = str_replace(['[:' . $key . ']', '<' . $key . '?>', ':' . $key, '<' . $key . '>'], $type ? $vars[$key] : urlencode((string) $vars[$key]), $url);
$url = str_replace(['[:' . $key . ']', '<' . $key . '?>', ':' . $key, '<' . $key . '>'], $type ? (string) $vars[$key] : urlencode((string) $vars[$key]), $url);
$keys[] = $key;
$url = str_replace(['/?', '-?'], ['/', '-'], $url);
$result = [rtrim($url, '?/-'), $domain, $suffix];
@ -353,6 +353,11 @@ class Url
return [];
}
/**
* 生成URL地址
* @access public
* @return string
*/
public function build()
{
// 解析URL

View File

@ -266,6 +266,8 @@ abstract class Model implements JsonSerializable, ArrayAccess, Arrayable, Jsonab
*/
public function newInstance(array $data = [], $where = null): Model
{
$this->readDataType($data);
$model = new static($data);
if ($this->connection) {
@ -609,9 +611,11 @@ abstract class Model implements JsonSerializable, ArrayAccess, Arrayable, Jsonab
return true;
}
if ($this->autoWriteTimestamp && $this->updateTime && !isset($data[$this->updateTime])) {
$this->writeDataType($data);
if ($this->autoWriteTimestamp && $this->updateTime) {
// 自动写入更新时间
$data[$this->updateTime] = $this->autoWriteTimestamp($this->updateTime);
$data[$this->updateTime] = $this->autoWriteTimestamp();
$this->data[$this->updateTime] = $data[$this->updateTime];
}
@ -669,11 +673,11 @@ abstract class Model implements JsonSerializable, ArrayAccess, Arrayable, Jsonab
// 时间戳自动写入
if ($this->autoWriteTimestamp) {
if ($this->createTime && !isset($this->data[$this->createTime])) {
$this->data[$this->createTime] = $this->autoWriteTimestamp($this->createTime);
$this->data[$this->createTime] = $this->autoWriteTimestamp();
}
if ($this->updateTime && !isset($this->data[$this->updateTime])) {
$this->data[$this->updateTime] = $this->autoWriteTimestamp($this->updateTime);
$this->data[$this->updateTime] = $this->autoWriteTimestamp();
}
}
@ -682,6 +686,7 @@ abstract class Model implements JsonSerializable, ArrayAccess, Arrayable, Jsonab
}
$this->checkData();
$this->writeDataType($this->data);
// 检查允许字段
$allowFields = $this->checkAllowFields();

View File

@ -1191,7 +1191,7 @@ abstract class PDOConnection extends Connection
$key = null;
}
if (strpos($column, ',')) {
if ('*' == $column || strpos($column, ',')) {
$column = null;
} elseif (strpos($column, ' ')) {
$column = substr(strrchr(trim($column), ' '), 1);
@ -1236,8 +1236,8 @@ abstract class PDOConnection extends Connection
// 判断占位符
$sql = is_numeric($key) ?
substr_replace($sql, $value, strpos($sql, '?'), 1) :
substr_replace($sql, $value, strpos($sql, ':' . $key), strlen(':' . $key));
substr_replace($sql, (string) $value, strpos($sql, '?'), 1) :
substr_replace($sql, (string) $value, strpos($sql, ':' . $key), strlen(':' . $key));
}
return rtrim($sql);

View File

@ -313,10 +313,15 @@ class Mysql extends Builder
$key = trim($key);
if (strpos($key, '->') && false === strpos($key, '(')) {
if (strpos($key, '->>') && false === strpos($key, '(')) {
// JSON字段支持
[$field, $name] = explode('->>', $key, 2);
return $this->parseKey($query, $field, true) . '->>\'$' . (strpos($name, '[') === 0 ? '' : '.') . str_replace('->>', '.', $name) . '\'';
} elseif (strpos($key, '->') && false === strpos($key, '(')) {
// JSON字段支持
[$field, $name] = explode('->', $key, 2);
return 'json_extract(' . $this->parseKey($query, $field) . ', \'$' . (strpos($name, '[') === 0 ? '' : '.') . str_replace('->', '.', $name) . '\')';
return 'json_extract(' . $this->parseKey($query, $field, true) . ', \'$' . (strpos($name, '[') === 0 ? '' : '.') . str_replace('->', '.', $name) . '\')';
} elseif (strpos($key, '.') && !preg_match('/[,\'\"\(\)`\s]/', $key)) {
[$table, $key] = explode('.', $key, 2);

View File

@ -514,9 +514,17 @@ trait WhereQuery
}
if ($condition) {
$this->where($query);
if ($query instanceof Closure) {
$query($this, $condition);
} elseif (is_array($query)) {
$this->where($query);
}
} elseif ($otherwise) {
$this->where($otherwise);
if ($otherwise instanceof Closure) {
$otherwise($this, $condition);
} elseif (is_array($otherwise)) {
$this->where($otherwise);
}
}
return $this;

View File

@ -56,7 +56,7 @@ class Sqlsrv extends PDOConnection
public function getFields(string $tableName): array
{
[$tableName] = explode(' ', $tableName);
strpos($tableName,'.') && $tableName = substr($tableName,strpos($tableName,'.') + 1);
$sql = "SELECT column_name, data_type, column_default, is_nullable
FROM information_schema.tables AS t
JOIN information_schema.columns AS c

View File

@ -28,14 +28,17 @@ class PDOException extends DbException
*/
public function __construct(\PDOException $exception, array $config = [], string $sql = '', int $code = 10501)
{
$error = $exception->errorInfo;
$error = $exception->errorInfo;
$message = $exception->getMessage();
$this->setData('PDO Error Info', [
'SQLSTATE' => $error[0],
'Driver Error Code' => isset($error[1]) ? $error[1] : 0,
'Driver Error Message' => isset($error[2]) ? $error[2] : '',
]);
if (!empty($error)) {
$this->setData('PDO Error Info', [
'SQLSTATE' => $error[0],
'Driver Error Code' => isset($error[1]) ? $error[1] : 0,
'Driver Error Message' => isset($error[2]) ? $error[2] : '',
]);
}
parent::__construct($exception->getMessage(), $config, $sql, $code);
parent::__construct($message, $config, $sql, $code);
}
}

View File

@ -358,25 +358,17 @@ trait Attribute
return;
}
if (is_null($value) && $this->autoWriteTimestamp && in_array($name, [$this->createTime, $this->updateTime])) {
// 自动写入的时间戳字段
$value = $this->autoWriteTimestamp();
} else {
// 检测修改器
$method = 'set' . Str::studly($name) . 'Attr';
// 检测修改器
$method = 'set' . Str::studly($name) . 'Attr';
if (method_exists($this, $method)) {
$array = $this->data;
if (method_exists($this, $method)) {
$array = $this->data;
$value = $this->$method($value, array_merge($this->data, $data));
$value = $this->$method($value, array_merge($this->data, $data));
$this->set[$name] = true;
if (is_null($value) && $array !== $this->data) {
return;
}
} elseif (isset($this->type[$name])) {
// 类型转换
$value = $this->writeTransform($value, $this->type[$name]);
$this->set[$name] = true;
if (is_null($value) && $array !== $this->data) {
return;
}
}
@ -506,11 +498,6 @@ trait Attribute
}
$value = $this->$method($value, $this->data);
} elseif (isset($this->type[$fieldName])) {
// 类型转换
$value = $this->readTransform($value, $this->type[$fieldName]);
} elseif ($this->autoWriteTimestamp && in_array($fieldName, [$this->createTime, $this->updateTime])) {
$value = $this->getTimestampValue($value);
} elseif ($relation) {
$value = $this->getRelationValue($relation);
// 保存关联对象值
@ -520,6 +507,43 @@ trait Attribute
return $value;
}
/**
* 读取数据类型处理
* @access protected
* @param array $data 数据
* @return void
*/
protected function readDataType(array &$data): void
{
foreach ($data as $name => &$value) {
if (isset($this->type[$name])) {
// 类型转换
$value = $this->readTransform($value, $this->type[$name]);
} elseif ($this->autoWriteTimestamp && in_array($name, [$this->createTime, $this->updateTime])) {
$value = $this->getTimestampValue($value);
}
}
}
/**
* 写入数据类型处理
* @access protected
* @param array $data 数据
* @return void
*/
protected function writeDataType(array &$data): void
{
foreach ($data as $name => &$value) {
if (isset($this->type[$name])) {
// 类型转换
$value = $this->writeTransform($value, $this->type[$name]);
} elseif (is_null($value) && $this->autoWriteTimestamp && in_array($name, [$this->createTime, $this->updateTime])) {
// 自动写入的时间戳字段
$value = $this->autoWriteTimestamp();
}
}
}
/**
* 获取JSON字段属性值
* @access protected

View File

@ -42,6 +42,12 @@ trait Conversion
*/
protected $append = [];
/**
* 数据输出字段映射
* @var array
*/
protected $mapping = [];
/**
* 数据集对象名
* @var string
@ -137,6 +143,19 @@ trait Conversion
return $this;
}
/**
* 设置属性的映射输出
* @access public
* @param array $map
* @return $this
*/
public function mapping(array $map)
{
$this->mapping = $map;
return $this;
}
/**
* 转换当前模型对象为数组
* @access public
@ -192,6 +211,13 @@ trait Conversion
} elseif (!isset($this->hidden[$key]) && !$hasVisible) {
$item[$key] = $this->getAttr($key);
}
if (isset($this->mapping[$key])) {
// 检查字段映射
$mapName = $this->mapping[$key];
$item[$mapName] = $item[$key];
unset($item[$key]);
}
}
// 追加属性(必须定义获取器)