mirror of
https://gitee.com/zoujingli/ThinkAdmin.git
synced 2025-04-06 03:58:04 +08:00
ComposerUpdate
This commit is contained in:
parent
a6f0eeb0ed
commit
8b8c7806e9
38
composer.lock
generated
38
composer.lock
generated
@ -578,16 +578,16 @@
|
||||
},
|
||||
{
|
||||
"name": "topthink/framework",
|
||||
"version": "v6.0.2",
|
||||
"version": "v6.0.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/top-think/framework.git",
|
||||
"reference": "1444cce94b40a836958380b160a5fb7bfc165daf"
|
||||
"reference": "b4046fb21e6163ba23a792b694162693dbe71b4b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/top-think/framework/zipball/1444cce94b40a836958380b160a5fb7bfc165daf",
|
||||
"reference": "1444cce94b40a836958380b160a5fb7bfc165daf",
|
||||
"url": "https://api.github.com/repos/top-think/framework/zipball/b4046fb21e6163ba23a792b694162693dbe71b4b",
|
||||
"reference": "b4046fb21e6163ba23a792b694162693dbe71b4b",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
@ -642,7 +642,7 @@
|
||||
"orm",
|
||||
"thinkphp"
|
||||
],
|
||||
"time": "2020-01-13T05:48:05+00:00"
|
||||
"time": "2020-06-26T16:03:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "topthink/think-helper",
|
||||
@ -691,16 +691,16 @@
|
||||
},
|
||||
{
|
||||
"name": "topthink/think-multi-app",
|
||||
"version": "v1.0.12",
|
||||
"version": "v1.0.13",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/top-think/think-multi-app.git",
|
||||
"reference": "3c1914d2adc08c8753c7f67228885ca47fb9b3bf"
|
||||
"reference": "21ac02a99bd69e29444963841e09c5d39b2bcecb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/top-think/think-multi-app/zipball/3c1914d2adc08c8753c7f67228885ca47fb9b3bf",
|
||||
"reference": "3c1914d2adc08c8753c7f67228885ca47fb9b3bf",
|
||||
"url": "https://api.github.com/repos/top-think/think-multi-app/zipball/21ac02a99bd69e29444963841e09c5d39b2bcecb",
|
||||
"reference": "21ac02a99bd69e29444963841e09c5d39b2bcecb",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
@ -737,20 +737,20 @@
|
||||
}
|
||||
],
|
||||
"description": "thinkphp6 multi app support",
|
||||
"time": "2020-03-01T13:29:35+00:00"
|
||||
"time": "2020-04-24T08:53:21+00:00"
|
||||
},
|
||||
{
|
||||
"name": "topthink/think-orm",
|
||||
"version": "v2.0.32",
|
||||
"version": "v2.0.33",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/top-think/think-orm.git",
|
||||
"reference": "03aaaa4d8c4475115b3acaa5aa2498bf5792e017"
|
||||
"reference": "35ca511a1e4d671b39f7afb4c887703c16ef6957"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/top-think/think-orm/zipball/03aaaa4d8c4475115b3acaa5aa2498bf5792e017",
|
||||
"reference": "03aaaa4d8c4475115b3acaa5aa2498bf5792e017",
|
||||
"url": "https://api.github.com/repos/top-think/think-orm/zipball/35ca511a1e4d671b39f7afb4c887703c16ef6957",
|
||||
"reference": "35ca511a1e4d671b39f7afb4c887703c16ef6957",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
@ -788,7 +788,7 @@
|
||||
"database",
|
||||
"orm"
|
||||
],
|
||||
"time": "2020-04-26T13:54:48+00:00"
|
||||
"time": "2020-06-22T14:57:28+00:00"
|
||||
},
|
||||
{
|
||||
"name": "topthink/think-template",
|
||||
@ -929,12 +929,12 @@
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/zoujingli/ThinkLibrary.git",
|
||||
"reference": "c72947dcdfe84b488dd5721f65266a7c00e082c6"
|
||||
"reference": "327c1f1e995bc6344dc938e71c07f33f134c3dd5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/zoujingli/ThinkLibrary/zipball/c72947dcdfe84b488dd5721f65266a7c00e082c6",
|
||||
"reference": "c72947dcdfe84b488dd5721f65266a7c00e082c6",
|
||||
"url": "https://api.github.com/repos/zoujingli/ThinkLibrary/zipball/327c1f1e995bc6344dc938e71c07f33f134c3dd5",
|
||||
"reference": "327c1f1e995bc6344dc938e71c07f33f134c3dd5",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
@ -978,7 +978,7 @@
|
||||
],
|
||||
"description": "ThinkPHP v6.0 Development Library",
|
||||
"homepage": "http://framework.thinkadmin.top",
|
||||
"time": "2020-06-22T10:03:12+00:00"
|
||||
"time": "2020-06-24T09:42:59+00:00"
|
||||
},
|
||||
{
|
||||
"name": "zoujingli/wechat-developer",
|
||||
|
5
vendor/composer/autoload_classmap.php
vendored
5
vendor/composer/autoload_classmap.php
vendored
@ -252,6 +252,7 @@ return array(
|
||||
'think\\admin\\Exception' => $vendorDir . '/zoujingli/think-library/src/Exception.php',
|
||||
'think\\admin\\Helper' => $vendorDir . '/zoujingli/think-library/src/Helper.php',
|
||||
'think\\admin\\Library' => $vendorDir . '/zoujingli/think-library/src/Library.php',
|
||||
'think\\admin\\Module' => $vendorDir . '/zoujingli/think-library/src/Module.php',
|
||||
'think\\admin\\Queue' => $vendorDir . '/zoujingli/think-library/src/Queue.php',
|
||||
'think\\admin\\Service' => $vendorDir . '/zoujingli/think-library/src/Service.php',
|
||||
'think\\admin\\Storage' => $vendorDir . '/zoujingli/think-library/src/Storage.php',
|
||||
@ -278,7 +279,6 @@ return array(
|
||||
'think\\admin\\service\\InstallService' => $vendorDir . '/zoujingli/think-library/src/service/InstallService.php',
|
||||
'think\\admin\\service\\MenuService' => $vendorDir . '/zoujingli/think-library/src/service/MenuService.php',
|
||||
'think\\admin\\service\\MessageService' => $vendorDir . '/zoujingli/think-library/src/service/MessageService.php',
|
||||
'think\\admin\\service\\ModuleService' => $vendorDir . '/zoujingli/think-library/src/service/ModuleService.php',
|
||||
'think\\admin\\service\\NodeService' => $vendorDir . '/zoujingli/think-library/src/service/NodeService.php',
|
||||
'think\\admin\\service\\OpenService' => $vendorDir . '/zoujingli/think-library/src/service/OpenService.php',
|
||||
'think\\admin\\service\\ProcessService' => $vendorDir . '/zoujingli/think-library/src/service/ProcessService.php',
|
||||
@ -476,10 +476,7 @@ return array(
|
||||
'think\\route\\Url' => $vendorDir . '/topthink/framework/src/think/route/Url.php',
|
||||
'think\\route\\dispatch\\Callback' => $vendorDir . '/topthink/framework/src/think/route/dispatch/Callback.php',
|
||||
'think\\route\\dispatch\\Controller' => $vendorDir . '/topthink/framework/src/think/route/dispatch/Controller.php',
|
||||
'think\\route\\dispatch\\Redirect' => $vendorDir . '/topthink/framework/src/think/route/dispatch/Redirect.php',
|
||||
'think\\route\\dispatch\\Response' => $vendorDir . '/topthink/framework/src/think/route/dispatch/Response.php',
|
||||
'think\\route\\dispatch\\Url' => $vendorDir . '/topthink/framework/src/think/route/dispatch/Url.php',
|
||||
'think\\route\\dispatch\\View' => $vendorDir . '/topthink/framework/src/think/route/dispatch/View.php',
|
||||
'think\\service\\ModelService' => $vendorDir . '/topthink/framework/src/think/service/ModelService.php',
|
||||
'think\\service\\PaginatorService' => $vendorDir . '/topthink/framework/src/think/service/PaginatorService.php',
|
||||
'think\\service\\ValidateService' => $vendorDir . '/topthink/framework/src/think/service/ValidateService.php',
|
||||
|
5
vendor/composer/autoload_static.php
vendored
5
vendor/composer/autoload_static.php
vendored
@ -385,6 +385,7 @@ class ComposerStaticInitb911c14a0826c73d9f097343fd33a252
|
||||
'think\\admin\\Exception' => __DIR__ . '/..' . '/zoujingli/think-library/src/Exception.php',
|
||||
'think\\admin\\Helper' => __DIR__ . '/..' . '/zoujingli/think-library/src/Helper.php',
|
||||
'think\\admin\\Library' => __DIR__ . '/..' . '/zoujingli/think-library/src/Library.php',
|
||||
'think\\admin\\Module' => __DIR__ . '/..' . '/zoujingli/think-library/src/Module.php',
|
||||
'think\\admin\\Queue' => __DIR__ . '/..' . '/zoujingli/think-library/src/Queue.php',
|
||||
'think\\admin\\Service' => __DIR__ . '/..' . '/zoujingli/think-library/src/Service.php',
|
||||
'think\\admin\\Storage' => __DIR__ . '/..' . '/zoujingli/think-library/src/Storage.php',
|
||||
@ -411,7 +412,6 @@ class ComposerStaticInitb911c14a0826c73d9f097343fd33a252
|
||||
'think\\admin\\service\\InstallService' => __DIR__ . '/..' . '/zoujingli/think-library/src/service/InstallService.php',
|
||||
'think\\admin\\service\\MenuService' => __DIR__ . '/..' . '/zoujingli/think-library/src/service/MenuService.php',
|
||||
'think\\admin\\service\\MessageService' => __DIR__ . '/..' . '/zoujingli/think-library/src/service/MessageService.php',
|
||||
'think\\admin\\service\\ModuleService' => __DIR__ . '/..' . '/zoujingli/think-library/src/service/ModuleService.php',
|
||||
'think\\admin\\service\\NodeService' => __DIR__ . '/..' . '/zoujingli/think-library/src/service/NodeService.php',
|
||||
'think\\admin\\service\\OpenService' => __DIR__ . '/..' . '/zoujingli/think-library/src/service/OpenService.php',
|
||||
'think\\admin\\service\\ProcessService' => __DIR__ . '/..' . '/zoujingli/think-library/src/service/ProcessService.php',
|
||||
@ -609,10 +609,7 @@ class ComposerStaticInitb911c14a0826c73d9f097343fd33a252
|
||||
'think\\route\\Url' => __DIR__ . '/..' . '/topthink/framework/src/think/route/Url.php',
|
||||
'think\\route\\dispatch\\Callback' => __DIR__ . '/..' . '/topthink/framework/src/think/route/dispatch/Callback.php',
|
||||
'think\\route\\dispatch\\Controller' => __DIR__ . '/..' . '/topthink/framework/src/think/route/dispatch/Controller.php',
|
||||
'think\\route\\dispatch\\Redirect' => __DIR__ . '/..' . '/topthink/framework/src/think/route/dispatch/Redirect.php',
|
||||
'think\\route\\dispatch\\Response' => __DIR__ . '/..' . '/topthink/framework/src/think/route/dispatch/Response.php',
|
||||
'think\\route\\dispatch\\Url' => __DIR__ . '/..' . '/topthink/framework/src/think/route/dispatch/Url.php',
|
||||
'think\\route\\dispatch\\View' => __DIR__ . '/..' . '/topthink/framework/src/think/route/dispatch/View.php',
|
||||
'think\\service\\ModelService' => __DIR__ . '/..' . '/topthink/framework/src/think/service/ModelService.php',
|
||||
'think\\service\\PaginatorService' => __DIR__ . '/..' . '/topthink/framework/src/think/service/PaginatorService.php',
|
||||
'think\\service\\ValidateService' => __DIR__ . '/..' . '/topthink/framework/src/think/service/ValidateService.php',
|
||||
|
44
vendor/composer/installed.json
vendored
44
vendor/composer/installed.json
vendored
@ -589,17 +589,17 @@
|
||||
},
|
||||
{
|
||||
"name": "topthink/framework",
|
||||
"version": "v6.0.2",
|
||||
"version_normalized": "6.0.2.0",
|
||||
"version": "v6.0.3",
|
||||
"version_normalized": "6.0.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/top-think/framework.git",
|
||||
"reference": "1444cce94b40a836958380b160a5fb7bfc165daf"
|
||||
"reference": "b4046fb21e6163ba23a792b694162693dbe71b4b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/top-think/framework/zipball/1444cce94b40a836958380b160a5fb7bfc165daf",
|
||||
"reference": "1444cce94b40a836958380b160a5fb7bfc165daf",
|
||||
"url": "https://api.github.com/repos/top-think/framework/zipball/b4046fb21e6163ba23a792b694162693dbe71b4b",
|
||||
"reference": "b4046fb21e6163ba23a792b694162693dbe71b4b",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
@ -626,7 +626,7 @@
|
||||
"mockery/mockery": "^1.2",
|
||||
"phpunit/phpunit": "^7.0"
|
||||
},
|
||||
"time": "2020-01-13T05:48:05+00:00",
|
||||
"time": "2020-06-26T16:03:10+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
@ -706,17 +706,17 @@
|
||||
},
|
||||
{
|
||||
"name": "topthink/think-multi-app",
|
||||
"version": "v1.0.12",
|
||||
"version_normalized": "1.0.12.0",
|
||||
"version": "v1.0.13",
|
||||
"version_normalized": "1.0.13.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/top-think/think-multi-app.git",
|
||||
"reference": "3c1914d2adc08c8753c7f67228885ca47fb9b3bf"
|
||||
"reference": "21ac02a99bd69e29444963841e09c5d39b2bcecb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/top-think/think-multi-app/zipball/3c1914d2adc08c8753c7f67228885ca47fb9b3bf",
|
||||
"reference": "3c1914d2adc08c8753c7f67228885ca47fb9b3bf",
|
||||
"url": "https://api.github.com/repos/top-think/think-multi-app/zipball/21ac02a99bd69e29444963841e09c5d39b2bcecb",
|
||||
"reference": "21ac02a99bd69e29444963841e09c5d39b2bcecb",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
@ -729,7 +729,7 @@
|
||||
"php": ">=7.1.0",
|
||||
"topthink/framework": "^6.0.0"
|
||||
},
|
||||
"time": "2020-03-01T13:29:35+00:00",
|
||||
"time": "2020-04-24T08:53:21+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"think": {
|
||||
@ -758,17 +758,17 @@
|
||||
},
|
||||
{
|
||||
"name": "topthink/think-orm",
|
||||
"version": "v2.0.32",
|
||||
"version_normalized": "2.0.32.0",
|
||||
"version": "v2.0.33",
|
||||
"version_normalized": "2.0.33.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/top-think/think-orm.git",
|
||||
"reference": "03aaaa4d8c4475115b3acaa5aa2498bf5792e017"
|
||||
"reference": "35ca511a1e4d671b39f7afb4c887703c16ef6957"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/top-think/think-orm/zipball/03aaaa4d8c4475115b3acaa5aa2498bf5792e017",
|
||||
"reference": "03aaaa4d8c4475115b3acaa5aa2498bf5792e017",
|
||||
"url": "https://api.github.com/repos/top-think/think-orm/zipball/35ca511a1e4d671b39f7afb4c887703c16ef6957",
|
||||
"reference": "35ca511a1e4d671b39f7afb4c887703c16ef6957",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
@ -784,7 +784,7 @@
|
||||
"psr/simple-cache": "^1.0",
|
||||
"topthink/think-helper": "^3.1"
|
||||
},
|
||||
"time": "2020-04-26T13:54:48+00:00",
|
||||
"time": "2020-06-22T14:57:28+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
@ -955,12 +955,12 @@
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/zoujingli/ThinkLibrary.git",
|
||||
"reference": "c72947dcdfe84b488dd5721f65266a7c00e082c6"
|
||||
"reference": "327c1f1e995bc6344dc938e71c07f33f134c3dd5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/zoujingli/ThinkLibrary/zipball/c72947dcdfe84b488dd5721f65266a7c00e082c6",
|
||||
"reference": "c72947dcdfe84b488dd5721f65266a7c00e082c6",
|
||||
"url": "https://api.github.com/repos/zoujingli/ThinkLibrary/zipball/327c1f1e995bc6344dc938e71c07f33f134c3dd5",
|
||||
"reference": "327c1f1e995bc6344dc938e71c07f33f134c3dd5",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
@ -976,7 +976,7 @@
|
||||
"ext-json": "*",
|
||||
"topthink/framework": "^6.0"
|
||||
},
|
||||
"time": "2020-06-22T10:03:12+00:00",
|
||||
"time": "2020-06-24T09:42:59+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"think": {
|
||||
|
2
vendor/services.php
vendored
2
vendor/services.php
vendored
@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// This file is automatically generated at:2020-06-23 10:13:28
|
||||
// This file is automatically generated at:2020-07-03 17:42:19
|
||||
declare (strict_types = 1);
|
||||
return array (
|
||||
0 => 'think\\app\\Service',
|
||||
|
8
vendor/topthink/framework/README.md
vendored
8
vendor/topthink/framework/README.md
vendored
@ -13,6 +13,8 @@ ThinkPHP 6.0
|
||||
|
||||
ThinkPHP6.0底层架构采用PHP7.1改写和进一步优化。
|
||||
|
||||
[官方应用服务市场](https://www.thinkphp.cn/service) | [`ThinkPHP`开发者扶持计划](https://sites.thinkphp.cn/1782366)
|
||||
|
||||
## 主要新特性
|
||||
|
||||
* 采用`PHP7`强类型(严格模式)
|
||||
@ -69,7 +71,7 @@ composer update topthink/framework
|
||||
|
||||
## 参与开发
|
||||
|
||||
请参阅 [ThinkPHP核心框架包](https://github.com/top-think/framework)。
|
||||
直接提交PR或者Issue即可
|
||||
|
||||
## 版权信息
|
||||
|
||||
@ -77,9 +79,7 @@ ThinkPHP遵循Apache2开源协议发布,并提供免费使用。
|
||||
|
||||
本项目包含的第三方源码和二进制文件之版权信息另行标注。
|
||||
|
||||
版权所有Copyright © 2006-2019 by ThinkPHP (http://thinkphp.cn)
|
||||
|
||||
All rights reserved。
|
||||
版权所有Copyright © 2006-2020 by ThinkPHP (http://thinkphp.cn) All rights reserved。
|
||||
|
||||
ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。
|
||||
|
||||
|
2
vendor/topthink/framework/composer.json
vendored
2
vendor/topthink/framework/composer.json
vendored
@ -44,7 +44,7 @@
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"think\\tests\\": "src/tests/"
|
||||
"think\\tests\\": "tests/"
|
||||
}
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
|
4
vendor/topthink/framework/src/helper.php
vendored
4
vendor/topthink/framework/src/helper.php
vendored
@ -359,7 +359,7 @@ if (!function_exists('parse_name')) {
|
||||
return $ucfirst ? ucfirst($name) : lcfirst($name);
|
||||
}
|
||||
|
||||
return strtolower(trim(preg_replace("/[A-Z]/", "_\\0", $name), "_"));
|
||||
return strtolower(trim(preg_replace('/[A-Z]/', '_\\0', $name), '_'));
|
||||
}
|
||||
}
|
||||
|
||||
@ -632,7 +632,7 @@ if (!function_exists('public_path')) {
|
||||
*/
|
||||
function public_path($path = '')
|
||||
{
|
||||
return app()->getRootPath() . ($path ? ltrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR : $path);
|
||||
return app()->getRootPath() . 'public' . DIRECTORY_SEPARATOR . ($path ? ltrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR : $path);
|
||||
}
|
||||
}
|
||||
|
||||
|
6
vendor/topthink/framework/src/think/App.php
vendored
6
vendor/topthink/framework/src/think/App.php
vendored
@ -39,7 +39,7 @@ use think\initializer\RegisterService;
|
||||
*/
|
||||
class App extends Container
|
||||
{
|
||||
const VERSION = '6.0.2';
|
||||
const VERSION = '6.0.3';
|
||||
|
||||
/**
|
||||
* 应用调试模式
|
||||
@ -602,9 +602,7 @@ class App extends Container
|
||||
*/
|
||||
protected function getDefaultRootPath(): string
|
||||
{
|
||||
$path = dirname(dirname(dirname(dirname($this->thinkPath))));
|
||||
|
||||
return $path . DIRECTORY_SEPARATOR;
|
||||
return dirname($this->thinkPath, 4) . DIRECTORY_SEPARATOR;
|
||||
}
|
||||
|
||||
}
|
||||
|
5
vendor/topthink/framework/src/think/Db.php
vendored
5
vendor/topthink/framework/src/think/Db.php
vendored
@ -15,6 +15,7 @@ namespace think;
|
||||
/**
|
||||
* 数据库管理类
|
||||
* @package think
|
||||
* @property Config $config
|
||||
*/
|
||||
class Db extends DbManager
|
||||
{
|
||||
@ -32,7 +33,9 @@ class Db extends DbManager
|
||||
$db->setConfig($config);
|
||||
$db->setEvent($event);
|
||||
$db->setLog($log);
|
||||
$db->setCache($cache);
|
||||
|
||||
$store = $db->getConfig('cache_store');
|
||||
$db->setCache($cache->store($store));
|
||||
$db->triggerSql();
|
||||
|
||||
return $db;
|
||||
|
38
vendor/topthink/framework/src/think/Event.php
vendored
38
vendor/topthink/framework/src/think/Event.php
vendored
@ -39,12 +39,6 @@ class Event
|
||||
'LogWrite' => event\LogWrite::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* 是否需要事件响应
|
||||
* @var bool
|
||||
*/
|
||||
protected $withEvent = true;
|
||||
|
||||
/**
|
||||
* 应用对象
|
||||
* @var App
|
||||
@ -56,18 +50,6 @@ class Event
|
||||
$this->app = $app;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置是否开启事件响应
|
||||
* @access protected
|
||||
* @param bool $event 是否需要事件响应
|
||||
* @return $this
|
||||
*/
|
||||
public function withEvent(bool $event)
|
||||
{
|
||||
$this->withEvent = $event;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量注册事件监听
|
||||
* @access public
|
||||
@ -76,10 +58,6 @@ class Event
|
||||
*/
|
||||
public function listenEvents(array $events)
|
||||
{
|
||||
if (!$this->withEvent) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
foreach ($events as $event => $listeners) {
|
||||
if (isset($this->bind[$event])) {
|
||||
$event = $this->bind[$event];
|
||||
@ -101,10 +79,6 @@ class Event
|
||||
*/
|
||||
public function listen(string $event, $listener, bool $first = false)
|
||||
{
|
||||
if (!$this->withEvent) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
if (isset($this->bind[$event])) {
|
||||
$event = $this->bind[$event];
|
||||
}
|
||||
@ -169,10 +143,6 @@ class Event
|
||||
*/
|
||||
public function subscribe($subscriber)
|
||||
{
|
||||
if (!$this->withEvent) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$subscribers = (array) $subscriber;
|
||||
|
||||
foreach ($subscribers as $subscriber) {
|
||||
@ -201,10 +171,6 @@ class Event
|
||||
*/
|
||||
public function observe($observer, string $prefix = '')
|
||||
{
|
||||
if (!$this->withEvent) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
if (is_string($observer)) {
|
||||
$observer = $this->app->make($observer);
|
||||
}
|
||||
@ -238,10 +204,6 @@ class Event
|
||||
*/
|
||||
public function trigger($event, $params = null, bool $once = false)
|
||||
{
|
||||
if (!$this->withEvent) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_object($event)) {
|
||||
$params = $event;
|
||||
$event = get_class($event);
|
||||
|
4
vendor/topthink/framework/src/think/File.php
vendored
4
vendor/topthink/framework/src/think/File.php
vendored
@ -157,11 +157,11 @@ class File extends SplFileInfo
|
||||
|
||||
/**
|
||||
* 自动生成文件名
|
||||
* @access protected
|
||||
* @access public
|
||||
* @param string|\Closure $rule
|
||||
* @return string
|
||||
*/
|
||||
public function hashName($rule = 'date'): string
|
||||
public function hashName($rule = ''): string
|
||||
{
|
||||
if (!$this->hashName) {
|
||||
if ($rule instanceof \Closure) {
|
||||
|
3
vendor/topthink/framework/src/think/Http.php
vendored
3
vendor/topthink/framework/src/think/Http.php
vendored
@ -191,9 +191,6 @@ class Http
|
||||
// 加载全局中间件
|
||||
$this->loadMiddleware();
|
||||
|
||||
// 设置开启事件机制
|
||||
$this->app->event->withEvent($this->app->config->get('app.with_event', true));
|
||||
|
||||
// 监听HttpRun
|
||||
$this->app->event->trigger(HttpRun::class);
|
||||
|
||||
|
11
vendor/topthink/framework/src/think/Lang.php
vendored
11
vendor/topthink/framework/src/think/Lang.php
vendored
@ -33,6 +33,8 @@ class Lang
|
||||
'extend_list' => [],
|
||||
// 多语言cookie变量
|
||||
'cookie_var' => 'think_lang',
|
||||
// 多语言header变量
|
||||
'header_var' => 'think-lang',
|
||||
// 多语言自动侦测变量名
|
||||
'detect_var' => 'lang',
|
||||
// Accept-Language转义为对应语言包名称
|
||||
@ -118,9 +120,9 @@ class Lang
|
||||
|
||||
$lang = [];
|
||||
|
||||
foreach ((array) $file as $_file) {
|
||||
if (is_file($_file)) {
|
||||
$result = $this->parse($_file);
|
||||
foreach ((array) $file as $name) {
|
||||
if (is_file($name)) {
|
||||
$result = $this->parse($name);
|
||||
$lang = array_change_key_case($result) + $lang;
|
||||
}
|
||||
}
|
||||
@ -239,6 +241,9 @@ class Lang
|
||||
if ($request->get($this->config['detect_var'])) {
|
||||
// url中设置了语言变量
|
||||
$langSet = strtolower($request->get($this->config['detect_var']));
|
||||
} elseif ($request->header($this->config['header_var'])) {
|
||||
// Header中设置了语言变量
|
||||
$langSet = strtolower($request->header($this->config['header_var']));
|
||||
} elseif ($request->cookie($this->config['cookie_var'])) {
|
||||
// Cookie中设置了语言变量
|
||||
$langSet = strtolower($request->cookie($this->config['cookie_var']));
|
||||
|
30
vendor/topthink/framework/src/think/Request.php
vendored
30
vendor/topthink/framework/src/think/Request.php
vendored
@ -12,6 +12,7 @@ declare (strict_types = 1);
|
||||
|
||||
namespace think;
|
||||
|
||||
use ArrayAccess;
|
||||
use think\file\UploadedFile;
|
||||
use think\route\Rule;
|
||||
|
||||
@ -19,7 +20,7 @@ use think\route\Rule;
|
||||
* 请求管理类
|
||||
* @package think
|
||||
*/
|
||||
class Request
|
||||
class Request implements ArrayAccess
|
||||
{
|
||||
/**
|
||||
* 兼容PATH_INFO获取
|
||||
@ -898,7 +899,8 @@ class Request
|
||||
*/
|
||||
public function setRoute(array $route)
|
||||
{
|
||||
$this->route = array_merge($this->route, $route);
|
||||
$this->route = array_merge($this->route, $route);
|
||||
$this->mergeParam = false;
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -985,7 +987,7 @@ class Request
|
||||
protected function getInputData($content): array
|
||||
{
|
||||
$contentType = $this->contentType();
|
||||
if ($contentType == 'application/x-www-form-urlencoded') {
|
||||
if ('application/x-www-form-urlencoded' == $contentType) {
|
||||
parse_str($content, $data);
|
||||
return $data;
|
||||
} elseif (false !== strpos($contentType, 'json')) {
|
||||
@ -1754,7 +1756,7 @@ class Request
|
||||
if ($this->host) {
|
||||
$host = $this->host;
|
||||
} else {
|
||||
$host = strval($this->server('HTTP_X_REAL_HOST') ?: $this->server('HTTP_HOST'));
|
||||
$host = strval($this->server('HTTP_X_FORWARDED_HOST') ?: $this->server('HTTP_HOST'));
|
||||
}
|
||||
|
||||
return true === $strict && strpos($host, ':') ? strstr($host, ':', true) : $host;
|
||||
@ -1767,7 +1769,7 @@ class Request
|
||||
*/
|
||||
public function port(): int
|
||||
{
|
||||
return (int) $this->server('SERVER_PORT', '');
|
||||
return (int) ($this->server('HTTP_X_FORWARDED_PORT') ?: $this->server('SERVER_PORT', ''));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2126,4 +2128,22 @@ class Request
|
||||
{
|
||||
return isset($this->middleware[$name]);
|
||||
}
|
||||
|
||||
// ArrayAccess
|
||||
public function offsetExists($name): bool
|
||||
{
|
||||
return $this->has($name);
|
||||
}
|
||||
|
||||
public function offsetGet($name)
|
||||
{
|
||||
return $this->param($name);
|
||||
}
|
||||
|
||||
public function offsetSet($name, $value)
|
||||
{}
|
||||
|
||||
public function offsetUnset($name)
|
||||
{}
|
||||
|
||||
}
|
||||
|
42
vendor/topthink/framework/src/think/Route.php
vendored
42
vendor/topthink/framework/src/think/Route.php
vendored
@ -15,6 +15,7 @@ namespace think;
|
||||
use Closure;
|
||||
use think\exception\RouteNotFoundException;
|
||||
use think\route\Dispatch;
|
||||
use think\route\dispatch\Callback;
|
||||
use think\route\dispatch\Url as UrlDispatch;
|
||||
use think\route\Domain;
|
||||
use think\route\Resource;
|
||||
@ -120,7 +121,7 @@ class Route
|
||||
|
||||
/**
|
||||
* 域名对象
|
||||
* @var array
|
||||
* @var Domain[]
|
||||
*/
|
||||
protected $domains = [];
|
||||
|
||||
@ -134,7 +135,7 @@ class Route
|
||||
* 路由是否延迟解析
|
||||
* @var bool
|
||||
*/
|
||||
protected $lazy = true;
|
||||
protected $lazy = false;
|
||||
|
||||
/**
|
||||
* 路由是否测试模式
|
||||
@ -433,7 +434,7 @@ class Route
|
||||
* 批量导入路由标识
|
||||
* @access public
|
||||
* @param array $name 路由标识
|
||||
* @return $this
|
||||
* @return void
|
||||
*/
|
||||
public function import(array $name): void
|
||||
{
|
||||
@ -510,6 +511,12 @@ class Route
|
||||
*/
|
||||
public function rule(string $rule, $route = null, string $method = '*'): RuleItem
|
||||
{
|
||||
if ($route instanceof Response) {
|
||||
// 兼容之前的路由到响应对象,感觉不需要,使用场景很少,闭包就能实现
|
||||
$route = function () use ($route) {
|
||||
return $route;
|
||||
};
|
||||
}
|
||||
return $this->group->addRule($rule, $route, $method);
|
||||
}
|
||||
|
||||
@ -658,7 +665,9 @@ class Route
|
||||
*/
|
||||
public function view(string $rule, string $template = '', array $vars = []): RuleItem
|
||||
{
|
||||
return $this->rule($rule, $template, 'GET')->view($vars);
|
||||
return $this->rule($rule, function () use ($vars, $template) {
|
||||
return Response::create($template, 'view')->assign($vars);
|
||||
}, 'GET');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -671,7 +680,9 @@ class Route
|
||||
*/
|
||||
public function redirect(string $rule, string $route = '', int $status = 301): RuleItem
|
||||
{
|
||||
return $this->rule($rule, $route, '*')->redirect()->status($status);
|
||||
return $this->rule($rule, function () use ($status, $route) {
|
||||
return Response::create($route, 'redirect')->code($status);
|
||||
}, '*');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -722,10 +733,10 @@ class Route
|
||||
/**
|
||||
* 路由调度
|
||||
* @param Request $request
|
||||
* @param Closure $withRoute
|
||||
* @param Closure|bool $withRoute
|
||||
* @return Response
|
||||
*/
|
||||
public function dispatch(Request $request, $withRoute = null)
|
||||
public function dispatch(Request $request, $withRoute = true)
|
||||
{
|
||||
$this->request = $request;
|
||||
$this->host = $this->request->host(true);
|
||||
@ -733,7 +744,9 @@ class Route
|
||||
|
||||
if ($withRoute) {
|
||||
//加载路由
|
||||
$withRoute();
|
||||
if ($withRoute instanceof Closure) {
|
||||
$withRoute();
|
||||
}
|
||||
$dispatch = $this->check();
|
||||
} else {
|
||||
$dispatch = $this->url($this->path());
|
||||
@ -751,10 +764,10 @@ class Route
|
||||
/**
|
||||
* 检测URL路由
|
||||
* @access public
|
||||
* @return Dispatch
|
||||
* @return Dispatch|false
|
||||
* @throws RouteNotFoundException
|
||||
*/
|
||||
public function check(): Dispatch
|
||||
public function check()
|
||||
{
|
||||
// 自动检测域名路由
|
||||
$url = str_replace($this->config['pathinfo_depr'], '|', $this->path());
|
||||
@ -807,8 +820,15 @@ class Route
|
||||
* @param string $url URL地址
|
||||
* @return Dispatch
|
||||
*/
|
||||
public function url(string $url): UrlDispatch
|
||||
public function url(string $url): Dispatch
|
||||
{
|
||||
if ($this->request->method() == 'OPTIONS') {
|
||||
// 自动响应options请求
|
||||
return new Callback($this->request, $this->group, function () {
|
||||
return Response::create('', 'html', 204)->header(['Allow' => 'GET, POST, PUT, DELETE']);
|
||||
});
|
||||
}
|
||||
|
||||
return new UrlDispatch($this->request, $this->group, $url);
|
||||
}
|
||||
|
||||
|
16
vendor/topthink/framework/src/think/Validate.php
vendored
16
vendor/topthink/framework/src/think/Validate.php
vendored
@ -472,15 +472,15 @@ class Validate
|
||||
{
|
||||
$this->error = [];
|
||||
|
||||
if ($this->currentScene) {
|
||||
$this->getScene($this->currentScene);
|
||||
}
|
||||
|
||||
if (empty($rules)) {
|
||||
// 读取验证规则
|
||||
$rules = $this->rule;
|
||||
}
|
||||
|
||||
if ($this->currentScene) {
|
||||
$this->getScene($this->currentScene);
|
||||
}
|
||||
|
||||
foreach ($this->append as $key => $rule) {
|
||||
if (!isset($rules[$key])) {
|
||||
$rules[$key] = $rule;
|
||||
@ -607,6 +607,10 @@ class Validate
|
||||
$rules = array_unique(array_merge($rules, $this->append[$field]), SORT_REGULAR);
|
||||
}
|
||||
|
||||
if (empty($rules)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$i = 0;
|
||||
foreach ($rules as $key => $rule) {
|
||||
if ($rule instanceof Closure) {
|
||||
@ -617,7 +621,6 @@ class Validate
|
||||
[$type, $rule, $info] = $this->getValidateType($key, $rule);
|
||||
|
||||
if (isset($this->append[$field]) && in_array($info, $this->append[$field])) {
|
||||
|
||||
} elseif (isset($this->remove[$field]) && in_array($info, $this->remove[$field])) {
|
||||
// 规则已经移除
|
||||
$i++;
|
||||
@ -1611,7 +1614,8 @@ class Validate
|
||||
$msg = str_replace(
|
||||
[':attribute', ':1', ':2', ':3'],
|
||||
[$title, $array[0], $array[1], $array[2]],
|
||||
$msg);
|
||||
$msg
|
||||
);
|
||||
|
||||
if (strpos($msg, ':rule')) {
|
||||
$msg = str_replace(':rule', (string) $rule, $msg);
|
||||
|
@ -2,7 +2,7 @@
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.
|
||||
// | Copyright (c) 2006~2020 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
@ -42,16 +42,22 @@ use Throwable;
|
||||
*/
|
||||
class Output
|
||||
{
|
||||
// 不显示信息(静默)
|
||||
const VERBOSITY_QUIET = 0;
|
||||
// 正常信息
|
||||
const VERBOSITY_NORMAL = 1;
|
||||
// 详细信息
|
||||
const VERBOSITY_VERBOSE = 2;
|
||||
// 非常详细的信息
|
||||
const VERBOSITY_VERY_VERBOSE = 3;
|
||||
// 调试信息
|
||||
const VERBOSITY_DEBUG = 4;
|
||||
|
||||
const OUTPUT_NORMAL = 0;
|
||||
const OUTPUT_RAW = 1;
|
||||
const OUTPUT_PLAIN = 2;
|
||||
|
||||
// 输出信息级别
|
||||
private $verbosity = self::VERBOSITY_NORMAL;
|
||||
|
||||
/** @var Buffer|Console|Nothing */
|
||||
@ -162,7 +168,8 @@ class Output
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* 设置输出信息级别
|
||||
* @param int $level 输出信息级别
|
||||
*/
|
||||
public function setVerbosity(int $level)
|
||||
{
|
||||
@ -170,7 +177,8 @@ class Output
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* 获取输出信息级别
|
||||
* @return int
|
||||
*/
|
||||
public function getVerbosity(): int
|
||||
{
|
||||
@ -220,5 +228,4 @@ class Output
|
||||
throw new Exception('method not exists:' . __CLASS__ . '->' . $method);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ class Clear extends Command
|
||||
->addOption('cache', 'c', Option::VALUE_NONE, 'clear cache file')
|
||||
->addOption('log', 'l', Option::VALUE_NONE, 'clear log file')
|
||||
->addOption('dir', 'r', Option::VALUE_NONE, 'clear empty dir')
|
||||
->addOption('expire', 'e', Option::VALUE_NONE, 'clear cache file if cache has expired')
|
||||
->setDescription('Clear runtime file');
|
||||
}
|
||||
|
||||
@ -41,24 +42,44 @@ class Clear extends Command
|
||||
}
|
||||
|
||||
$rmdir = $input->getOption('dir') ? true : false;
|
||||
$this->clear(rtrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR, $rmdir);
|
||||
// --expire 仅当 --cache 时生效
|
||||
$cache_expire = $input->getOption('expire') && $input->getOption('cache') ? true : false;
|
||||
$this->clear(rtrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR, $rmdir, $cache_expire);
|
||||
|
||||
$output->writeln("<info>Clear Successed</info>");
|
||||
}
|
||||
|
||||
protected function clear(string $path, bool $rmdir): void
|
||||
protected function clear(string $path, bool $rmdir, bool $cache_expire): void
|
||||
{
|
||||
$files = is_dir($path) ? scandir($path) : [];
|
||||
|
||||
foreach ($files as $file) {
|
||||
if ('.' != $file && '..' != $file && is_dir($path . $file)) {
|
||||
array_map('unlink', glob($path . $file . DIRECTORY_SEPARATOR . '*.*'));
|
||||
$this->clear($path . $file . DIRECTORY_SEPARATOR, $rmdir, $cache_expire);
|
||||
if ($rmdir) {
|
||||
rmdir($path . $file);
|
||||
@rmdir($path . $file);
|
||||
}
|
||||
} elseif ('.gitignore' != $file && is_file($path . $file)) {
|
||||
unlink($path . $file);
|
||||
if ($cache_expire) {
|
||||
if ($this->cacheHasExpired($path . $file)) {
|
||||
unlink($path . $file);
|
||||
}
|
||||
} else {
|
||||
unlink($path . $file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 缓存文件是否已过期
|
||||
* @param $filename string 文件路径
|
||||
* @return bool
|
||||
*/
|
||||
protected function cacheHasExpired($filename) {
|
||||
$content = file_get_contents($filename);
|
||||
$expire = (int) substr($content, 8, 12);
|
||||
return 0 != $expire && time() - $expire > filemtime($filename);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ namespace {%namespace%};
|
||||
use think\Model;
|
||||
|
||||
/**
|
||||
* @mixin think\Model
|
||||
* @mixin \think\Model
|
||||
*/
|
||||
class {%className%} extends Model
|
||||
{
|
||||
|
@ -15,6 +15,7 @@ use think\console\Input;
|
||||
use think\console\input\Argument;
|
||||
use think\console\input\Option;
|
||||
use think\console\Output;
|
||||
use think\db\PDOConnection;
|
||||
|
||||
class Schema extends Command
|
||||
{
|
||||
@ -22,7 +23,7 @@ class Schema extends Command
|
||||
{
|
||||
$this->setName('optimize:schema')
|
||||
->addArgument('dir', Argument::OPTIONAL, 'dir name .')
|
||||
->addOption('db', null, Option::VALUE_REQUIRED, 'db name .')
|
||||
->addOption('connection', null, Option::VALUE_REQUIRED, 'connection name .')
|
||||
->addOption('table', null, Option::VALUE_REQUIRED, 'table name .')
|
||||
->setDescription('Build database schema cache.');
|
||||
}
|
||||
@ -31,22 +32,24 @@ class Schema extends Command
|
||||
{
|
||||
$dir = $input->getArgument('dir') ?: '';
|
||||
|
||||
$schemaPath = $this->app->db->getConnection()->getConfig('schema_cache_path');
|
||||
|
||||
if (!is_dir($schemaPath)) {
|
||||
mkdir($schemaPath, 0755, true);
|
||||
}
|
||||
|
||||
if ($input->hasOption('table')) {
|
||||
$connection = $this->app->db->connect($input->getOption('connection'));
|
||||
if (!$connection instanceof PDOConnection) {
|
||||
$output->error("only PDO connection support schema cache!");
|
||||
return;
|
||||
}
|
||||
$table = $input->getOption('table');
|
||||
if (false === strpos($table, '.')) {
|
||||
$dbName = $this->app->db->getConnection()->getConfig('database');
|
||||
$dbName = $connection->getConfig('database');
|
||||
} else {
|
||||
[$dbName, $table] = explode('.', $table);
|
||||
}
|
||||
|
||||
$tables[] = $table;
|
||||
} elseif ($input->hasOption('db')) {
|
||||
$dbName = $input->getOption('db');
|
||||
$tables = $this->app->db->getConnection()->getTables($dbName);
|
||||
if ($table == '*') {
|
||||
$table = $connection->getTables($dbName);
|
||||
}
|
||||
|
||||
$this->buildDataBaseSchema($connection, (array) $table, $dbName);
|
||||
} else {
|
||||
if ($dir) {
|
||||
$appPath = $this->app->getBasePath() . $dir . DIRECTORY_SEPARATOR;
|
||||
@ -66,14 +69,8 @@ class Schema extends Command
|
||||
$class = '\\' . $namespace . '\\model\\' . pathinfo($file, PATHINFO_FILENAME);
|
||||
$this->buildModelSchema($class);
|
||||
}
|
||||
|
||||
$output->writeln('<info>Succeed!</info>');
|
||||
return;
|
||||
}
|
||||
|
||||
$db = isset($dbName) ? $dbName . '.' : '';
|
||||
$this->buildDataBaseSchema($schemaPath, $tables, $db);
|
||||
|
||||
$output->writeln('<info>Succeed!</info>');
|
||||
}
|
||||
|
||||
@ -82,35 +79,21 @@ class Schema extends Command
|
||||
$reflect = new \ReflectionClass($class);
|
||||
if (!$reflect->isAbstract() && $reflect->isSubclassOf('\think\Model')) {
|
||||
/** @var \think\Model $model */
|
||||
$model = new $class;
|
||||
|
||||
$table = $model->getTable();
|
||||
$dbName = $model->db()->getConnection()->getConfig('database');
|
||||
$path = $model->db()->getConnection()->getConfig('schema_cache_path');
|
||||
if (!is_dir($path)) {
|
||||
mkdir($path, 0755, true);
|
||||
$model = new $class;
|
||||
$connection = $model->db()->getConnection();
|
||||
if ($connection instanceof PDOConnection) {
|
||||
$table = $model->getTable();
|
||||
//预读字段信息
|
||||
$connection->getSchemaInfo($table, true);
|
||||
}
|
||||
$content = '<?php ' . PHP_EOL . 'return ';
|
||||
$info = $model->db()->getConnection()->getTableFieldsInfo($table);
|
||||
$content .= var_export($info, true) . ';';
|
||||
|
||||
file_put_contents($path . $dbName . '.' . $table . '.php', $content);
|
||||
}
|
||||
}
|
||||
|
||||
protected function buildDataBaseSchema(string $path, array $tables, string $db): void
|
||||
protected function buildDataBaseSchema(PDOConnection $connection, array $tables, string $dbName): void
|
||||
{
|
||||
if ('' == $db) {
|
||||
$dbName = $this->app->db->getConnection()->getConfig('database') . '.';
|
||||
} else {
|
||||
$dbName = $db;
|
||||
}
|
||||
|
||||
foreach ($tables as $table) {
|
||||
$content = '<?php ' . PHP_EOL . 'return ';
|
||||
$info = $this->app->db->getConnection()->getTableFieldsInfo($db . $table);
|
||||
$content .= var_export($info, true) . ';';
|
||||
file_put_contents($path . $dbName . $table . '.php', $content);
|
||||
//预读字段信息
|
||||
$connection->getSchemaInfo("{$dbName}.{$table}", true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -216,7 +216,7 @@ class Descriptor
|
||||
$description = new ConsoleDescription($console, $describedNamespace);
|
||||
|
||||
if (isset($options['raw_text']) && $options['raw_text']) {
|
||||
$width = $this->getColumnWidth($description->getCommands());
|
||||
$width = $this->getColumnWidth($description->getNamespaces());
|
||||
|
||||
foreach ($description->getCommands() as $command) {
|
||||
$this->writeText(sprintf("%-${width}s %s", $command->getName(), $command->getDescription()), $options);
|
||||
@ -235,7 +235,7 @@ class Descriptor
|
||||
$this->writeText("\n");
|
||||
$this->writeText("\n");
|
||||
|
||||
$width = $this->getColumnWidth($description->getCommands());
|
||||
$width = $this->getColumnWidth($description->getNamespaces());
|
||||
|
||||
if ($describedNamespace) {
|
||||
$this->writeText(sprintf('<comment>Available commands for the "%s" namespace:</comment>', $describedNamespace), $options);
|
||||
@ -282,14 +282,18 @@ class Descriptor
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Command[] $commands
|
||||
* @param Namespaces[] $namespaces
|
||||
* @return int
|
||||
*/
|
||||
private function getColumnWidth(array $commands)
|
||||
private function getColumnWidth(array $namespaces)
|
||||
{
|
||||
$width = 0;
|
||||
foreach ($commands as $command) {
|
||||
$width = strlen($command->getName()) > $width ? strlen($command->getName()) : $width;
|
||||
foreach ($namespaces as $namespace) {
|
||||
foreach ($namespace['commands'] as $name) {
|
||||
if (strlen($name) > $width) {
|
||||
$width = strlen($name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $width + 2;
|
||||
|
@ -77,7 +77,7 @@ class Handle
|
||||
|
||||
try {
|
||||
$this->app->log->record($log, 'error');
|
||||
} catch (Exception $e){}
|
||||
} catch (Exception $e) {}
|
||||
}
|
||||
}
|
||||
|
||||
@ -152,7 +152,7 @@ class Handle
|
||||
{
|
||||
if ($this->app->isDebug()) {
|
||||
// 调试模式,获取详细的错误信息
|
||||
$traces = [];
|
||||
$traces = [];
|
||||
$nextException = $exception;
|
||||
do {
|
||||
$traces[] = [
|
||||
@ -171,14 +171,12 @@ class Handle
|
||||
'traces' => $traces,
|
||||
'datas' => $this->getExtendData($exception),
|
||||
'tables' => [
|
||||
'GET Data' => $this->app->request->get(),
|
||||
'POST Data' => $this->app->request->post(),
|
||||
'Files' => $this->app->request->file(),
|
||||
'Cookies' => $this->app->request->cookie(),
|
||||
'Session' => $this->app->session->all(),
|
||||
'Server/Request Data' => $this->app->request->server(),
|
||||
'Environment Variables' => $this->app->request->env(),
|
||||
'ThinkPHP Constants' => $this->getConst(),
|
||||
'GET Data' => $this->app->request->get(),
|
||||
'POST Data' => $this->app->request->post(),
|
||||
'Files' => $this->app->request->file(),
|
||||
'Cookies' => $this->app->request->cookie(),
|
||||
'Session' => $this->app->exists('session') ? $this->app->session->all() : [],
|
||||
'Server/Request Data' => $this->app->request->server(),
|
||||
],
|
||||
];
|
||||
} else {
|
||||
|
@ -18,6 +18,32 @@ use think\Facade;
|
||||
* @see \think\App
|
||||
* @package think\facade
|
||||
* @mixin \think\App
|
||||
* @method static \think\Service|null register(\think\Service|string $service, bool $force = false) 注册服务
|
||||
* @method static mixed bootService(\think\Service $service) 执行服务
|
||||
* @method static \think\Service|null getService(string|\think\Service $service) 获取服务
|
||||
* @method static \think\App debug(bool $debug = true) 开启应用调试模式
|
||||
* @method static bool isDebug() 是否为调试模式
|
||||
* @method static \think\App setNamespace(string $namespace) 设置应用命名空间
|
||||
* @method static string getNamespace() 获取应用类库命名空间
|
||||
* @method static string version() 获取框架版本
|
||||
* @method static string getRootPath() 获取应用根目录
|
||||
* @method static string getBasePath() 获取应用基础目录
|
||||
* @method static string getAppPath() 获取当前应用目录
|
||||
* @method static mixed setAppPath(string $path) 设置应用目录
|
||||
* @method static string getRuntimePath() 获取应用运行时目录
|
||||
* @method static void setRuntimePath(string $path) 设置runtime目录
|
||||
* @method static string getThinkPath() 获取核心框架目录
|
||||
* @method static string getConfigPath() 获取应用配置目录
|
||||
* @method static string getConfigExt() 获取配置后缀
|
||||
* @method static float getBeginTime() 获取应用开启时间
|
||||
* @method static integer getBeginMem() 获取应用初始内存占用
|
||||
* @method static \think\App initialize() 初始化应用
|
||||
* @method static bool initialized() 是否初始化过
|
||||
* @method static void loadLangPack(string $langset) 加载语言包
|
||||
* @method static void boot() 引导应用
|
||||
* @method static void loadEvent(array $event) 注册应用事件
|
||||
* @method static string parseClass(string $layer, string $name) 解析应用类的类名
|
||||
* @method static bool runningInConsole() 是否运行在命令行下
|
||||
*/
|
||||
class App extends Facade
|
||||
{
|
||||
|
@ -13,11 +13,26 @@ declare (strict_types = 1);
|
||||
namespace think\facade;
|
||||
|
||||
use think\Facade;
|
||||
use think\cache\Driver;
|
||||
use think\cache\TagSet;
|
||||
|
||||
/**
|
||||
* @see \think\Cache
|
||||
* @package think\facade
|
||||
* @mixin \think\Cache
|
||||
* @method static string|null getDefaultDriver() 默认驱动
|
||||
* @method static mixed getConfig(null|string $name = null, mixed $default = null) 获取缓存配置
|
||||
* @method static array getStoreConfig(string $store, string $name = null, null $default = null) 获取驱动配置
|
||||
* @method static Driver store(string $name = null) 连接或者切换缓存
|
||||
* @method static bool clear() 清空缓冲池
|
||||
* @method static mixed get(string $key, mixed $default = null) 读取缓存
|
||||
* @method static bool set(string $key, mixed $value, int|\DateTime $ttl = null) 写入缓存
|
||||
* @method static bool delete(string $key) 删除缓存
|
||||
* @method static iterable getMultiple(iterable $keys, mixed $default = null) 读取缓存
|
||||
* @method static bool setMultiple(iterable $values, null|int|\DateInterval $ttl = null) 写入缓存
|
||||
* @method static bool deleteMultiple(iterable $keys) 删除缓存
|
||||
* @method static bool has(string $key) 判断缓存是否存在
|
||||
* @method static TagSet tag(string|array $name) 缓存标签
|
||||
*/
|
||||
class Cache extends Facade
|
||||
{
|
||||
|
@ -18,6 +18,10 @@ use think\Facade;
|
||||
* @see \think\Config
|
||||
* @package think\facade
|
||||
* @mixin \think\Config
|
||||
* @method static array load(string $file, string $name = '') 加载配置文件(多种格式)
|
||||
* @method static bool has(string $name) 检测配置是否存在
|
||||
* @method static mixed get(string $name = null, mixed $default = null) 获取配置参数 为空则获取所有配置
|
||||
* @method static array set(array $config, string $name = null) 设置配置参数 name为数组则为批量设置
|
||||
*/
|
||||
class Config extends Facade
|
||||
{
|
||||
|
@ -13,11 +13,34 @@ declare (strict_types = 1);
|
||||
namespace think\facade;
|
||||
|
||||
use think\Facade;
|
||||
use think\console\Command;
|
||||
use think\console\Input;
|
||||
use think\console\input\Definition as InputDefinition;
|
||||
use think\console\Output;
|
||||
use think\console\output\driver\Buffer;
|
||||
|
||||
/**
|
||||
* Class Console
|
||||
* @package think\facade
|
||||
* @mixin \think\Console
|
||||
* @method static Output|Buffer call(string $command, array $parameters = [], string $driver = 'buffer')
|
||||
* @method static int run() 执行当前的指令
|
||||
* @method static int doRun(Input $input, Output $output) 执行指令
|
||||
* @method static void setDefinition(InputDefinition $definition) 设置输入参数定义
|
||||
* @method static InputDefinition The InputDefinition instance getDefinition() 获取输入参数定义
|
||||
* @method static string A help message. getHelp() Gets the help message.
|
||||
* @method static void setCatchExceptions(bool $boolean) 是否捕获异常
|
||||
* @method static void setAutoExit(bool $boolean) 是否自动退出
|
||||
* @method static string getLongVersion() 获取完整的版本号
|
||||
* @method static void addCommands(array $commands) 添加指令集
|
||||
* @method static Command|void addCommand(string|Command $command, string $name = '') 添加一个指令
|
||||
* @method static Command getCommand(string $name) 获取指令
|
||||
* @method static bool hasCommand(string $name) 某个指令是否存在
|
||||
* @method static array getNamespaces() 获取所有的命名空间
|
||||
* @method static string findNamespace(string $namespace) 查找注册命名空间中的名称或缩写。
|
||||
* @method static Command find(string $name) 查找指令
|
||||
* @method static Command[] all(string $namespace = null) 获取所有的指令
|
||||
* @method static string extractNamespace(string $name, int $limit = 0) 返回命名空间部分
|
||||
*/
|
||||
class Console extends Facade
|
||||
{
|
||||
|
@ -18,6 +18,13 @@ use think\Facade;
|
||||
* @see \think\Cookie
|
||||
* @package think\facade
|
||||
* @mixin \think\Cookie
|
||||
* @method static mixed get(mixed $name = '', string $default = null) 获取cookie
|
||||
* @method static bool has(string $name) 是否存在Cookie参数
|
||||
* @method static void set(string $name, string $value, mixed $option = null) Cookie 设置
|
||||
* @method static void forever(string $name, string $value = '', mixed $option = null) 永久保存Cookie数据
|
||||
* @method static void delete(string $name) Cookie删除
|
||||
* @method static array getCookie() 获取cookie保存数据
|
||||
* @method static void save() 保存Cookie
|
||||
*/
|
||||
class Cookie extends Facade
|
||||
{
|
||||
|
@ -18,6 +18,17 @@ use think\Facade;
|
||||
* @see \think\Env
|
||||
* @package think\facade
|
||||
* @mixin \think\Env
|
||||
* @method static void load(string $file) 读取环境变量定义文件
|
||||
* @method static mixed get(string $name = null, mixed $default = null) 获取环境变量值
|
||||
* @method static void set(string|array $env, mixed $value = null) 设置环境变量值
|
||||
* @method static bool has(string $name) 检测是否存在环境变量
|
||||
* @method static void __set(string $name, mixed $value) 设置环境变量
|
||||
* @method static mixed __get(string $name) 获取环境变量
|
||||
* @method static bool __isset(string $name) 检测是否存在环境变量
|
||||
* @method static void offsetSet($name, $value)
|
||||
* @method static bool offsetExists($name)
|
||||
* @method static mixed offsetUnset($name)
|
||||
* @method static mixed offsetGet($name)
|
||||
*/
|
||||
class Env extends Facade
|
||||
{
|
||||
|
@ -18,6 +18,15 @@ use think\Facade;
|
||||
* @see \think\Event
|
||||
* @package think\facade
|
||||
* @mixin \think\Event
|
||||
* @method static \think\Event listenEvents(array $events) 批量注册事件监听
|
||||
* @method static \think\Event listen(string $event, mixed $listener, bool $first = false) 注册事件监听
|
||||
* @method static bool hasListener(string $event) 是否存在事件监听
|
||||
* @method static void remove(string $event) 移除事件监听
|
||||
* @method static \think\Event bind(array $events) 指定事件别名标识 便于调用
|
||||
* @method static \think\Event subscribe(mixed $subscriber) 注册事件订阅者
|
||||
* @method static \think\Event observe(string|object $observer, null|string $prefix = '') 自动注册事件观察者
|
||||
* @method static mixed trigger(string|object $event, mixed $params = null, bool $once = false) 触发事件
|
||||
* @method static mixed until($event, $params = null) 触发事件(只获取一个有效返回值)
|
||||
*/
|
||||
class Event extends Facade
|
||||
{
|
||||
|
@ -13,11 +13,16 @@ declare (strict_types = 1);
|
||||
namespace think\facade;
|
||||
|
||||
use think\Facade;
|
||||
use think\filesystem\Driver;
|
||||
|
||||
/**
|
||||
* Class Filesystem
|
||||
* @package think\facade
|
||||
* @mixin \think\Filesystem
|
||||
* @method static Driver disk(string $name = null) ,null|string
|
||||
* @method static mixed getConfig(null|string $name = null, mixed $default = null) 获取缓存配置
|
||||
* @method static array getDiskConfig(string $disk, null $name = null, null $default = null) 获取磁盘配置
|
||||
* @method static string|null getDefaultDriver() 默认驱动
|
||||
*/
|
||||
class Filesystem extends Facade
|
||||
{
|
||||
|
@ -18,6 +18,14 @@ use think\Facade;
|
||||
* @see \think\Lang
|
||||
* @package think\facade
|
||||
* @mixin \think\Lang
|
||||
* @method static void setLangSet(string $lang) 设置当前语言
|
||||
* @method static string getLangSet() 获取当前语言
|
||||
* @method static string defaultLangSet() 获取默认语言
|
||||
* @method static array load(string|array $file, string $range = '') 加载语言定义(不区分大小写)
|
||||
* @method static bool has(string|null $name, string $range = '') 判断是否存在语言定义(不区分大小写)
|
||||
* @method static mixed get(string|null $name = null, array $vars = [], string $range = '') 获取语言定义(不区分大小写)
|
||||
* @method static string detect(\think\Request $request) 自动侦测设置获取语言选择
|
||||
* @method static void saveToCookie(\think\Cookie $cookie) 保存当前语言到Cookie
|
||||
*/
|
||||
class Lang extends Facade
|
||||
{
|
||||
|
@ -13,11 +13,36 @@ declare (strict_types = 1);
|
||||
namespace think\facade;
|
||||
|
||||
use think\Facade;
|
||||
use think\log\Channel;
|
||||
use think\log\ChannelSet;
|
||||
|
||||
/**
|
||||
* @see \think\Log
|
||||
* @package think\facade
|
||||
* @mixin \think\Log
|
||||
* @method static string|null getDefaultDriver() 默认驱动
|
||||
* @method static mixed getConfig(null|string $name = null, mixed $default = null) 获取日志配置
|
||||
* @method static array getChannelConfig(string $channel, null $name = null, null $default = null) 获取渠道配置
|
||||
* @method static Channel|ChannelSet channel(string|array $name = null) driver() 的别名
|
||||
* @method static mixed createDriver(string $name)
|
||||
* @method static \think\Log clear(string|array $channel = '*') 清空日志信息
|
||||
* @method static \think\Log close(string|array $channel = '*') 关闭本次请求日志写入
|
||||
* @method static array getLog(string $channel = null) 获取日志信息
|
||||
* @method static bool save() 保存日志信息
|
||||
* @method static \think\Log record(mixed $msg, string $type = 'info', array $context = [], bool $lazy = true) 记录日志信息
|
||||
* @method static \think\Log write(mixed $msg, string $type = 'info', array $context = []) 实时写入日志信息
|
||||
* @method static Event listen($listener) 注册日志写入事件监听
|
||||
* @method static void log(string $level, mixed $message, array $context = []) 记录日志信息
|
||||
* @method static void emergency(mixed $message, array $context = []) 记录emergency信息
|
||||
* @method static void alert(mixed $message, array $context = []) 记录警报信息
|
||||
* @method static void critical(mixed $message, array $context = []) 记录紧急情况
|
||||
* @method static void error(mixed $message, array $context = []) 记录错误信息
|
||||
* @method static void warning(mixed $message, array $context = []) 记录warning信息
|
||||
* @method static void notice(mixed $message, array $context = []) 记录notice信息
|
||||
* @method static void info(mixed $message, array $context = []) 记录一般信息
|
||||
* @method static void debug(mixed $message, array $context = []) 记录调试信息
|
||||
* @method static void sql(mixed $message, array $context = []) 记录sql信息
|
||||
* @method static mixed __call($method, $parameters)
|
||||
*/
|
||||
class Log extends Facade
|
||||
{
|
||||
|
@ -18,6 +18,15 @@ use think\Facade;
|
||||
* @see \think\Middleware
|
||||
* @package think\facade
|
||||
* @mixin \think\Middleware
|
||||
* @method static void import(array $middlewares = [], string $type = 'global') 导入中间件
|
||||
* @method static void add(mixed $middleware, string $type = 'global') 注册中间件
|
||||
* @method static void route(mixed $middleware) 注册路由中间件
|
||||
* @method static void controller(mixed $middleware) 注册控制器中间件
|
||||
* @method static mixed unshift(mixed $middleware, string $type = 'global') 注册中间件到开始位置
|
||||
* @method static array all(string $type = 'global') 获取注册的中间件
|
||||
* @method static Pipeline pipeline(string $type = 'global') 调度管道
|
||||
* @method static mixed end(\think\Response $response) 结束调度
|
||||
* @method static \think\Response handleException(\think\Request $passable, \Throwable $e) 异常处理
|
||||
*/
|
||||
class Middleware extends Facade
|
||||
{
|
||||
|
@ -13,11 +13,112 @@ declare (strict_types = 1);
|
||||
namespace think\facade;
|
||||
|
||||
use think\Facade;
|
||||
use think\file\UploadedFile;
|
||||
use think\route\Rule;
|
||||
|
||||
/**
|
||||
* @see \think\Request
|
||||
* @package think\facade
|
||||
* @mixin \think\Request
|
||||
* @method static \think\Request setDomain(string $domain) 设置当前包含协议的域名
|
||||
* @method static string domain(bool $port = false) 获取当前包含协议的域名
|
||||
* @method static string rootDomain() 获取当前根域名
|
||||
* @method static \think\Request setSubDomain(string $domain) 设置当前泛域名的值
|
||||
* @method static string subDomain() 获取当前子域名
|
||||
* @method static \think\Request setPanDomain(string $domain) 设置当前泛域名的值
|
||||
* @method static string panDomain() 获取当前泛域名的值
|
||||
* @method static \think\Request setUrl(string $url) 设置当前完整URL 包括QUERY_STRING
|
||||
* @method static string url(bool $complete = false) 获取当前完整URL 包括QUERY_STRING
|
||||
* @method static \think\Request setBaseUrl(string $url) 设置当前URL 不含QUERY_STRING
|
||||
* @method static string baseUrl(bool $complete = false) 获取当前URL 不含QUERY_STRING
|
||||
* @method static string baseFile(bool $complete = false) 获取当前执行的文件 SCRIPT_NAME
|
||||
* @method static \think\Request setRoot(string $url) 设置URL访问根地址
|
||||
* @method static string root(bool $complete = false) 获取URL访问根地址
|
||||
* @method static string rootUrl() 获取URL访问根目录
|
||||
* @method static \think\Request setPathinfo(string $pathinfo) 设置当前请求的pathinfo
|
||||
* @method static string pathinfo() 获取当前请求URL的pathinfo信息(含URL后缀)
|
||||
* @method static string ext() 当前URL的访问后缀
|
||||
* @method static integer|float time(bool $float = false) 获取当前请求的时间
|
||||
* @method static string type() 当前请求的资源类型
|
||||
* @method static void mimeType(string|array $type, string $val = '') 设置资源类型
|
||||
* @method static \think\Request setMethod(string $method) 设置请求类型
|
||||
* @method static string method(bool $origin = false) 当前的请求类型
|
||||
* @method static bool isGet() 是否为GET请求
|
||||
* @method static bool isPost() 是否为POST请求
|
||||
* @method static bool isPut() 是否为PUT请求
|
||||
* @method static bool isDelete() 是否为DELTE请求
|
||||
* @method static bool isHead() 是否为HEAD请求
|
||||
* @method static bool isPatch() 是否为PATCH请求
|
||||
* @method static bool isOptions() 是否为OPTIONS请求
|
||||
* @method static bool isCli() 是否为cli
|
||||
* @method static bool isCgi() 是否为cgi
|
||||
* @method static mixed param(string|array $name = '', mixed $default = null, string|array $filter = '') 获取当前请求的参数
|
||||
* @method static \think\Request setRule(Rule $rule) 设置路由变量
|
||||
* @method static Rule|null rule() 获取当前路由对象
|
||||
* @method static \think\Request setRoute(array $route) 设置路由变量
|
||||
* @method static mixed route(string|array $name = '', mixed $default = null, string|array $filter = '') 获取路由参数
|
||||
* @method static mixed get(string|array $name = '', mixed $default = null, string|array $filter = '') 获取GET参数
|
||||
* @method static mixed middleware(mixed $name, mixed $default = null) 获取中间件传递的参数
|
||||
* @method static mixed post(string|array $name = '', mixed $default = null, string|array $filter = '') 获取POST参数
|
||||
* @method static mixed put(string|array $name = '', mixed $default = null, string|array $filter = '') 获取PUT参数
|
||||
* @method static mixed delete(mixed $name = '', mixed $default = null, string|array $filter = '') 设置获取DELETE参数
|
||||
* @method static mixed patch(mixed $name = '', mixed $default = null, string|array $filter = '') 设置获取PATCH参数
|
||||
* @method static mixed request(string|array $name = '', mixed $default = null, string|array $filter = '') 获取request变量
|
||||
* @method static mixed env(string $name = '', string $default = null) 获取环境变量
|
||||
* @method static mixed session(string $name = '', string $default = null) 获取session数据
|
||||
* @method static mixed cookie(mixed $name = '', string $default = null, string|array $filter = '') 获取cookie参数
|
||||
* @method static mixed server(string $name = '', string $default = '') 获取server参数
|
||||
* @method static null|array|UploadedFile file(string $name = '') 获取上传的文件信息
|
||||
* @method static string|array header(string $name = '', string $default = null) 设置或者获取当前的Header
|
||||
* @method static mixed input(array $data = [], string|false $name = '', mixed $default = null, string|array $filter = '') 获取变量 支持过滤和默认值
|
||||
* @method static mixed filter(mixed $filter = null) 设置或获取当前的过滤规则
|
||||
* @method static mixed filterValue(mixed &$value, mixed $key, array $filters) 递归过滤给定的值
|
||||
* @method static bool has(string $name, string $type = 'param', bool $checkEmpty = false) 是否存在某个请求参数
|
||||
* @method static array only(array $name, mixed $data = 'param', string|array $filter = '') 获取指定的参数
|
||||
* @method static mixed except(array $name, string $type = 'param') 排除指定参数获取
|
||||
* @method static bool isSsl() 当前是否ssl
|
||||
* @method static bool isJson() 当前是否JSON请求
|
||||
* @method static bool isAjax(bool $ajax = false) 当前是否Ajax请求
|
||||
* @method static bool isPjax(bool $pjax = false) 当前是否Pjax请求
|
||||
* @method static string ip() 获取客户端IP地址
|
||||
* @method static boolean isValidIP(string $ip, string $type = '') 检测是否是合法的IP地址
|
||||
* @method static string ip2bin(string $ip) 将IP地址转换为二进制字符串
|
||||
* @method static bool isMobile() 检测是否使用手机访问
|
||||
* @method static string scheme() 当前URL地址中的scheme参数
|
||||
* @method static string query() 当前请求URL地址中的query参数
|
||||
* @method static \think\Request setHost(string $host) 设置当前请求的host(包含端口)
|
||||
* @method static string host(bool $strict = false) 当前请求的host
|
||||
* @method static int port() 当前请求URL地址中的port参数
|
||||
* @method static string protocol() 当前请求 SERVER_PROTOCOL
|
||||
* @method static int remotePort() 当前请求 REMOTE_PORT
|
||||
* @method static string contentType() 当前请求 HTTP_CONTENT_TYPE
|
||||
* @method static string secureKey() 获取当前请求的安全Key
|
||||
* @method static \think\Request setController(string $controller) 设置当前的控制器名
|
||||
* @method static \think\Request setAction(string $action) 设置当前的操作名
|
||||
* @method static string controller(bool $convert = false) 获取当前的控制器名
|
||||
* @method static string action(bool $convert = false) 获取当前的操作名
|
||||
* @method static string getContent() 设置或者获取当前请求的content
|
||||
* @method static string getInput() 获取当前请求的php://input
|
||||
* @method static string buildToken(string $name = '__token__', mixed $type = 'md5') 生成请求令牌
|
||||
* @method static bool checkToken(string $token = '__token__', array $data = []) 检查请求令牌
|
||||
* @method static \think\Request withMiddleware(array $middleware) 设置在中间件传递的数据
|
||||
* @method static \think\Request withGet(array $get) 设置GET数据
|
||||
* @method static \think\Request withPost(array $post) 设置POST数据
|
||||
* @method static \think\Request withCookie(array $cookie) 设置COOKIE数据
|
||||
* @method static \think\Request withSession(Session $session) 设置SESSION数据
|
||||
* @method static \think\Request withServer(array $server) 设置SERVER数据
|
||||
* @method static \think\Request withHeader(array $header) 设置HEADER数据
|
||||
* @method static \think\Request withEnv(Env $env) 设置ENV数据
|
||||
* @method static \think\Request withInput(string $input) 设置php://input数据
|
||||
* @method static \think\Request withFiles(array $files) 设置文件上传数据
|
||||
* @method static \think\Request withRoute(array $route) 设置ROUTE变量
|
||||
* @method static mixed __set(string $name, mixed $value) 设置中间传递数据
|
||||
* @method static mixed __get(string $name) 获取中间传递数据的值
|
||||
* @method static boolean __isset(string $name) 检测中间传递数据的值
|
||||
* @method static bool offsetExists($name)
|
||||
* @method static mixed offsetGet($name)
|
||||
* @method static mixed offsetSet($name, $value)
|
||||
* @method static mixed offsetUnset($name)
|
||||
*/
|
||||
class Request extends Facade
|
||||
{
|
||||
|
@ -13,11 +13,61 @@ declare (strict_types = 1);
|
||||
namespace think\facade;
|
||||
|
||||
use think\Facade;
|
||||
use think\route\Dispatch;
|
||||
use think\route\Domain;
|
||||
use think\route\Rule;
|
||||
use think\route\RuleGroup;
|
||||
use think\route\RuleItem;
|
||||
use think\route\RuleName;
|
||||
use think\route\Url as UrlBuild;
|
||||
|
||||
/**
|
||||
* @see \think\Route
|
||||
* @package think\facade
|
||||
* @mixin \think\Route
|
||||
* @method static mixed config(string $name = null)
|
||||
* @method static \think\Route lazy(bool $lazy = true) 设置路由域名及分组(包括资源路由)是否延迟解析
|
||||
* @method static void setTestMode(bool $test) 设置路由为测试模式
|
||||
* @method static bool isTest() 检查路由是否为测试模式
|
||||
* @method static \think\Route mergeRuleRegex(bool $merge = true) 设置路由域名及分组(包括资源路由)是否合并解析
|
||||
* @method static void setGroup(RuleGroup $group) 设置当前分组
|
||||
* @method static RuleGroup getGroup(string $name = null) 获取指定标识的路由分组 不指定则获取当前分组
|
||||
* @method static \think\Route pattern(array $pattern) 注册变量规则
|
||||
* @method static \think\Route option(array $option) 注册路由参数
|
||||
* @method static Domain domain(string|array $name, mixed $rule = null) 注册域名路由
|
||||
* @method static array getDomains() 获取域名
|
||||
* @method static RuleName getRuleName() 获取RuleName对象
|
||||
* @method static \think\Route bind(string $bind, string $domain = null) 设置路由绑定
|
||||
* @method static array getBind() 读取路由绑定信息
|
||||
* @method static string|null getDomainBind(string $domain = null) 读取路由绑定
|
||||
* @method static RuleItem[] getName(string $name = null, string $domain = null, string $method = '*') 读取路由标识
|
||||
* @method static void import(array $name) 批量导入路由标识
|
||||
* @method static void setName(string $name, RuleItem $ruleItem, bool $first = false) 注册路由标识
|
||||
* @method static void setRule(string $rule, RuleItem $ruleItem = null) 保存路由规则
|
||||
* @method static RuleItem[] getRule(string $rule) 读取路由
|
||||
* @method static array getRuleList() 读取路由列表
|
||||
* @method static void clear() 清空路由规则
|
||||
* @method static RuleItem rule(string $rule, mixed $route = null, string $method = '*') 注册路由规则
|
||||
* @method static \think\Route setCrossDomainRule(Rule $rule, string $method = '*') 设置跨域有效路由规则
|
||||
* @method static RuleGroup group(string|\Closure $name, mixed $route = null) 注册路由分组
|
||||
* @method static RuleItem any(string $rule, mixed $route) 注册路由
|
||||
* @method static RuleItem get(string $rule, mixed $route) 注册GET路由
|
||||
* @method static RuleItem post(string $rule, mixed $route) 注册POST路由
|
||||
* @method static RuleItem put(string $rule, mixed $route) 注册PUT路由
|
||||
* @method static RuleItem delete(string $rule, mixed $route) 注册DELETE路由
|
||||
* @method static RuleItem patch(string $rule, mixed $route) 注册PATCH路由
|
||||
* @method static RuleItem options(string $rule, mixed $route) 注册OPTIONS路由
|
||||
* @method static Resource resource(string $rule, string $route) 注册资源路由
|
||||
* @method static RuleItem view(string $rule, string $template = '', array $vars = []) 注册视图路由
|
||||
* @method static RuleItem redirect(string $rule, string $route = '', int $status = 301) 注册重定向路由
|
||||
* @method static \think\Route rest(string|array $name, array|bool $resource = []) rest方法定义和修改
|
||||
* @method static array|null getRest(string $name = null) 获取rest方法定义的参数
|
||||
* @method static RuleItem miss(string|Closure $route, string $method = '*') 注册未匹配路由规则后的处理
|
||||
* @method static Response dispatch(\think\Request $request, Closure|bool $withRoute = true) 路由调度
|
||||
* @method static Dispatch|false check() 检测URL路由
|
||||
* @method static Dispatch url(string $url) 默认URL解析
|
||||
* @method static UrlBuild buildUrl(string $url = '', array $vars = []) URL生成 支持路由反射
|
||||
* @method static RuleGroup __call(string $method, array $args) 设置全局的路由分组参数
|
||||
*/
|
||||
class Route extends Facade
|
||||
{
|
||||
|
@ -18,6 +18,8 @@ use think\Facade;
|
||||
* @see \think\Session
|
||||
* @package think\facade
|
||||
* @mixin \think\Session
|
||||
* @method static mixed getConfig(null|string $name = null, mixed $default = null) 获取Session配置
|
||||
* @method static string|null getDefaultDriver() 默认驱动
|
||||
*/
|
||||
class Session extends Facade
|
||||
{
|
||||
|
@ -18,6 +18,62 @@ use think\Facade;
|
||||
* @see \think\Validate
|
||||
* @package think\facade
|
||||
* @mixin \think\Validate
|
||||
* @method static void setLang(\think\Lang $lang) 设置Lang对象
|
||||
* @method static void setDb(\think\Db $db) 设置Db对象
|
||||
* @method static void setRequest(\think\Request $request) 设置Request对象
|
||||
* @method static \think\Validate rule(string|array $name, mixed $rule = '') 添加字段验证规则
|
||||
* @method static \think\Validate extend(string $type, callable $callback = null, string $message = null) 注册验证(类型)规则
|
||||
* @method static void setTypeMsg(string|array $type, string $msg = null) 设置验证规则的默认提示信息
|
||||
* @method static Validate message(array $message) 设置提示信息
|
||||
* @method static \think\Validate scene(string $name) 设置验证场景
|
||||
* @method static bool hasScene(string $name) 判断是否存在某个验证场景
|
||||
* @method static \think\Validate batch(bool $batch = true) 设置批量验证
|
||||
* @method static \think\Validate failException(bool $fail = true) 设置验证失败后是否抛出异常
|
||||
* @method static \think\Validate only(array $fields) 指定需要验证的字段列表
|
||||
* @method static \think\Validate remove(string|array $field, mixed $rule = null) 移除某个字段的验证规则
|
||||
* @method static \think\Validate append(string|array $field, mixed $rule = null) 追加某个字段的验证规则
|
||||
* @method static bool check(array $data, array $rules = []) 数据自动验证
|
||||
* @method static bool checkRule(mixed $value, mixed $rules) 根据验证规则验证数据
|
||||
* @method static bool confirm(mixed $value, mixed $rule, array $data = [], string $field = '') 验证是否和某个字段的值一致
|
||||
* @method static bool different(mixed $value, mixed $rule, array $data = []) 验证是否和某个字段的值是否不同
|
||||
* @method static bool egt(mixed $value, mixed $rule, array $data = []) 验证是否大于等于某个值
|
||||
* @method static bool gt(mixed $value, mixed $rule, array $data = []) 验证是否大于某个值
|
||||
* @method static bool elt(mixed $value, mixed $rule, array $data = []) 验证是否小于等于某个值
|
||||
* @method static bool lt(mixed $value, mixed $rule, array $data = []) 验证是否小于某个值
|
||||
* @method static bool eq(mixed $value, mixed $rule) 验证是否等于某个值
|
||||
* @method static bool must(mixed $value, mixed $rule = null) 必须验证
|
||||
* @method static bool is(mixed $value, string $rule, array $data = []) 验证字段值是否为有效格式
|
||||
* @method static bool token(mixed $value, mixed $rule, array $data) 验证表单令牌
|
||||
* @method static bool activeUrl(mixed $value, mixed $rule = 'MX') 验证是否为合格的域名或者IP 支持A,MX,NS,SOA,PTR,CNAME,AAAA,A6, SRV,NAPTR,TXT 或者 ANY类型
|
||||
* @method static bool ip(mixed $value, mixed $rule = 'ipv4') 验证是否有效IP
|
||||
* @method static bool fileExt(mixed $file, mixed $rule) 验证上传文件后缀
|
||||
* @method static bool fileMime(mixed $file, mixed $rule) 验证上传文件类型
|
||||
* @method static bool fileSize(mixed $file, mixed $rule) 验证上传文件大小
|
||||
* @method static bool image(mixed $file, mixed $rule) 验证图片的宽高及类型
|
||||
* @method static bool dateFormat(mixed $value, mixed $rule) 验证时间和日期是否符合指定格式
|
||||
* @method static bool unique(mixed $value, mixed $rule, array $data = [], string $field = '') 验证是否唯一
|
||||
* @method static bool filter(mixed $value, mixed $rule) 使用filter_var方式验证
|
||||
* @method static bool requireIf(mixed $value, mixed $rule, array $data = []) 验证某个字段等于某个值的时候必须
|
||||
* @method static bool requireCallback(mixed $value, mixed $rule, array $data = []) 通过回调方法验证某个字段是否必须
|
||||
* @method static bool requireWith(mixed $value, mixed $rule, array $data = []) 验证某个字段有值的情况下必须
|
||||
* @method static bool requireWithout(mixed $value, mixed $rule, array $data = []) 验证某个字段没有值的情况下必须
|
||||
* @method static bool in(mixed $value, mixed $rule) 验证是否在范围内
|
||||
* @method static bool notIn(mixed $value, mixed $rule) 验证是否不在某个范围
|
||||
* @method static bool between(mixed $value, mixed $rule) between验证数据
|
||||
* @method static bool notBetween(mixed $value, mixed $rule) 使用notbetween验证数据
|
||||
* @method static bool length(mixed $value, mixed $rule) 验证数据长度
|
||||
* @method static bool max(mixed $value, mixed $rule) 验证数据最大长度
|
||||
* @method static bool min(mixed $value, mixed $rule) 验证数据最小长度
|
||||
* @method static bool after(mixed $value, mixed $rule, array $data = []) 验证日期
|
||||
* @method static bool before(mixed $value, mixed $rule, array $data = []) 验证日期
|
||||
* @method static bool afterWith(mixed $value, mixed $rule, array $data = []) 验证日期
|
||||
* @method static bool beforeWith(mixed $value, mixed $rule, array $data = []) 验证日期
|
||||
* @method static bool expire(mixed $value, mixed $rule) 验证有效期
|
||||
* @method static bool allowIp(mixed $value, mixed $rule) 验证IP许可
|
||||
* @method static bool denyIp(mixed $value, mixed $rule) 验证IP禁用
|
||||
* @method static bool regex(mixed $value, mixed $rule) 使用正则验证数据
|
||||
* @method static array|string getError() 获取错误信息
|
||||
* @method static bool __call(string $method, array $args) 动态方法 直接调用is方法进行验证
|
||||
*/
|
||||
class Validate extends Facade
|
||||
{
|
||||
|
@ -18,6 +18,15 @@ use think\Facade;
|
||||
* @see \think\View
|
||||
* @package think\facade
|
||||
* @mixin \think\View
|
||||
* @method static \think\View engine(string $type = null) 获取模板引擎
|
||||
* @method static \think\View assign(string|array $name, mixed $value = null) 模板变量赋值
|
||||
* @method static \think\View filter(\think\Callable $filter = null) 视图过滤
|
||||
* @method static string fetch(string $template = '', array $vars = []) 解析和获取模板内容 用于输出
|
||||
* @method static string display(string $content, array $vars = []) 渲染内容输出
|
||||
* @method static mixed __set(string $name, mixed $value) 模板变量赋值
|
||||
* @method static mixed __get(string $name) 取得模板显示变量的值
|
||||
* @method static bool __isset(string $name) 检测模板变量是否设置
|
||||
* @method static string|null getDefaultDriver() 默认驱动
|
||||
*/
|
||||
class View extends Facade
|
||||
{
|
||||
|
@ -60,13 +60,13 @@ class UploadedFile extends File
|
||||
$error = $msg;
|
||||
});
|
||||
|
||||
$moved = move_uploaded_file($this->getPathname(), $target);
|
||||
$moved = move_uploaded_file($this->getPathname(), (string) $target);
|
||||
restore_error_handler();
|
||||
if (!$moved) {
|
||||
throw new FileException(sprintf('Could not move the file "%s" to "%s" (%s)', $this->getPathname(), $target, strip_tags($error)));
|
||||
}
|
||||
|
||||
@chmod($target, 0666 & ~umask());
|
||||
@chmod((string) $target, 0666 & ~umask());
|
||||
|
||||
return $target;
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ class File implements LogHandlerInterface
|
||||
$info = [];
|
||||
|
||||
// 日志信息封装
|
||||
$time = date($this->config['time_format']);
|
||||
$time = \DateTime::createFromFormat('0.u00 U', microtime())->setTimezone(new \DateTimeZone(date_default_timezone_get()))->format($this->config['time_format']);
|
||||
|
||||
foreach ($log as $type => $val) {
|
||||
$message = [];
|
||||
|
@ -90,14 +90,14 @@ class Socket implements LogHandlerInterface
|
||||
|
||||
if ($this->config['debug']) {
|
||||
if ($this->app->exists('request')) {
|
||||
$current_uri = $this->app->request->url(true);
|
||||
$currentUri = $this->app->request->url(true);
|
||||
} else {
|
||||
$current_uri = 'cmd:' . implode(' ', $_SERVER['argv'] ?? []);
|
||||
$currentUri = 'cmd:' . implode(' ', $_SERVER['argv'] ?? []);
|
||||
}
|
||||
|
||||
if (!empty($this->config['format_head'])) {
|
||||
try {
|
||||
$current_uri = $this->app->invoke($this->config['format_head'], [$current_uri]);
|
||||
$currentUri = $this->app->invoke($this->config['format_head'], [$currentUri]);
|
||||
} catch (NotFoundExceptionInterface $notFoundException) {
|
||||
// Ignore exception
|
||||
}
|
||||
@ -106,16 +106,16 @@ class Socket implements LogHandlerInterface
|
||||
// 基本信息
|
||||
$trace[] = [
|
||||
'type' => 'group',
|
||||
'msg' => $current_uri,
|
||||
'msg' => $currentUri,
|
||||
'css' => $this->css['page'],
|
||||
];
|
||||
}
|
||||
|
||||
$expand_level = array_flip($this->config['expand_level']);
|
||||
$expandLevel = array_flip($this->config['expand_level']);
|
||||
|
||||
foreach ($log as $type => $val) {
|
||||
$trace[] = [
|
||||
'type' => isset($expand_level[$type]) ? 'group' : 'groupCollapsed',
|
||||
'type' => isset($expandLevel[$type]) ? 'group' : 'groupCollapsed',
|
||||
'msg' => '[ ' . $type . ' ]',
|
||||
'css' => $this->css[$type] ?? '',
|
||||
];
|
||||
@ -166,18 +166,18 @@ class Socket implements LogHandlerInterface
|
||||
|
||||
$tabid = $this->getClientArg('tabid');
|
||||
|
||||
if (!$client_id = $this->getClientArg('client_id')) {
|
||||
$client_id = '';
|
||||
if (!$clientId = $this->getClientArg('client_id')) {
|
||||
$clientId = '';
|
||||
}
|
||||
|
||||
if (!empty($this->allowForceClientIds)) {
|
||||
//强制推送到多个client_id
|
||||
foreach ($this->allowForceClientIds as $force_client_id) {
|
||||
$client_id = $force_client_id;
|
||||
$this->sendToClient($tabid, $client_id, $trace, $force_client_id);
|
||||
foreach ($this->allowForceClientIds as $forceClientId) {
|
||||
$clientId = $forceClientId;
|
||||
$this->sendToClient($tabid, $clientId, $trace, $forceClientId);
|
||||
}
|
||||
} else {
|
||||
$this->sendToClient($tabid, $client_id, $trace, '');
|
||||
$this->sendToClient($tabid, $clientId, $trace, '');
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -188,21 +188,21 @@ class Socket implements LogHandlerInterface
|
||||
* @access protected
|
||||
* @author Zjmainstay
|
||||
* @param $tabid
|
||||
* @param $client_id
|
||||
* @param $clientId
|
||||
* @param $logs
|
||||
* @param $force_client_id
|
||||
* @param $forceClientId
|
||||
*/
|
||||
protected function sendToClient($tabid, $client_id, $logs, $force_client_id)
|
||||
protected function sendToClient($tabid, $clientId, $logs, $forceClientId)
|
||||
{
|
||||
$logs = [
|
||||
'tabid' => $tabid,
|
||||
'client_id' => $client_id,
|
||||
'client_id' => $clientId,
|
||||
'logs' => $logs,
|
||||
'force_client_id' => $force_client_id,
|
||||
'force_client_id' => $forceClientId,
|
||||
];
|
||||
|
||||
$msg = json_encode($logs, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PARTIAL_OUTPUT_ON_ERROR);
|
||||
$address = '/' . $client_id; //将client_id作为地址, server端通过地址判断将日志发布给谁
|
||||
$address = '/' . $clientId; //将client_id作为地址, server端通过地址判断将日志发布给谁
|
||||
|
||||
$this->send($this->config['host'], $this->config['port'], $msg, $address);
|
||||
}
|
||||
@ -222,17 +222,17 @@ class Socket implements LogHandlerInterface
|
||||
}
|
||||
|
||||
//用户认证
|
||||
$allow_client_ids = $this->config['allow_client_ids'];
|
||||
$allowClientIds = $this->config['allow_client_ids'];
|
||||
|
||||
if (!empty($allow_client_ids)) {
|
||||
if (!empty($allowClientIds)) {
|
||||
//通过数组交集得出授权强制推送的client_id
|
||||
$this->allowForceClientIds = array_intersect($allow_client_ids, $this->config['force_client_ids']);
|
||||
$this->allowForceClientIds = array_intersect($allowClientIds, $this->config['force_client_ids']);
|
||||
if (!$tabid && count($this->allowForceClientIds)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$client_id = $this->getClientArg('client_id');
|
||||
if (!in_array($client_id, $allow_client_ids)) {
|
||||
$clientId = $this->getClientArg('client_id');
|
||||
if (!in_array($clientId, $allowClientIds)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
|
@ -26,6 +26,7 @@ class AllowCrossDomain
|
||||
|
||||
protected $header = [
|
||||
'Access-Control-Allow-Credentials' => 'true',
|
||||
'Access-Control-Max-Age' => 1800,
|
||||
'Access-Control-Allow-Methods' => 'GET, POST, PATCH, PUT, DELETE, OPTIONS',
|
||||
'Access-Control-Allow-Headers' => 'Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-CSRF-TOKEN, X-Requested-With',
|
||||
];
|
||||
@ -57,10 +58,6 @@ class AllowCrossDomain
|
||||
}
|
||||
}
|
||||
|
||||
if ($request->method(true) == 'OPTIONS') {
|
||||
return Response::create()->code(204)->header($header);
|
||||
}
|
||||
|
||||
return $next($request)->header($header);
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ class File extends Response
|
||||
protected $name;
|
||||
protected $mimeType;
|
||||
protected $isContent = false;
|
||||
protected $force = true;
|
||||
|
||||
public function __construct($data = '', int $code = 200)
|
||||
{
|
||||
@ -62,7 +63,7 @@ class File extends Response
|
||||
$this->header['Pragma'] = 'public';
|
||||
$this->header['Content-Type'] = $mimeType ?: 'application/octet-stream';
|
||||
$this->header['Cache-control'] = 'max-age=' . $this->expire;
|
||||
$this->header['Content-Disposition'] = 'attachment; filename="' . $name . '"';
|
||||
$this->header['Content-Disposition'] = ($this->force ? 'attachment; ' : '') . 'filename="' . $name . '"';
|
||||
$this->header['Content-Length'] = $size;
|
||||
$this->header['Content-Transfer-Encoding'] = 'binary';
|
||||
$this->header['Expires'] = gmdate("D, d M Y H:i:s", time() + $this->expire) . ' GMT';
|
||||
@ -108,6 +109,18 @@ class File extends Response
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置文件强制下载
|
||||
* @access public
|
||||
* @param bool $force 强制浏览器下载
|
||||
* @return $this
|
||||
*/
|
||||
public function force(bool $force)
|
||||
{
|
||||
$this->force = $force;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件类型信息
|
||||
* @access public
|
||||
|
@ -51,8 +51,8 @@ class Jsonp extends Response
|
||||
{
|
||||
try {
|
||||
// 返回JSON数据格式到客户端 包含状态信息 [当url_common_param为false时是无法获取到$_GET的数据的,故使用Request来获取<xiaobo.sun@qq.com>]
|
||||
$var_jsonp_handler = $this->request->param($this->options['var_jsonp_handler'], "");
|
||||
$handler = !empty($var_jsonp_handler) ? $var_jsonp_handler : $this->options['default_jsonp_handler'];
|
||||
$varJsonpHandler = $this->request->param($this->options['var_jsonp_handler'], "");
|
||||
$handler = !empty($varJsonpHandler) ? $varJsonpHandler : $this->options['default_jsonp_handler'];
|
||||
|
||||
$data = json_encode($data, $this->options['json_encode_param']);
|
||||
|
||||
|
@ -53,19 +53,12 @@ abstract class Dispatch
|
||||
*/
|
||||
protected $param;
|
||||
|
||||
/**
|
||||
* 状态码
|
||||
* @var int
|
||||
*/
|
||||
protected $code;
|
||||
|
||||
public function __construct(Request $request, Rule $rule, $dispatch, array $param = [], int $code = null)
|
||||
public function __construct(Request $request, Rule $rule, $dispatch, array $param = [])
|
||||
{
|
||||
$this->request = $request;
|
||||
$this->rule = $rule;
|
||||
$this->dispatch = $dispatch;
|
||||
$this->param = $param;
|
||||
$this->code = $code;
|
||||
}
|
||||
|
||||
public function init(App $app)
|
||||
@ -244,7 +237,7 @@ abstract class Dispatch
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
return ['rule', 'dispatch', 'param', 'code', 'controller', 'actionName'];
|
||||
return ['rule', 'dispatch', 'param', 'controller', 'actionName'];
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
@ -258,7 +251,6 @@ abstract class Dispatch
|
||||
return [
|
||||
'dispatch' => $this->dispatch,
|
||||
'param' => $this->param,
|
||||
'code' => $this->code,
|
||||
'rule' => $this->rule,
|
||||
];
|
||||
}
|
||||
|
@ -18,13 +18,9 @@ use think\middleware\AllowCrossDomain;
|
||||
use think\middleware\CheckRequestCache;
|
||||
use think\middleware\FormTokenCheck;
|
||||
use think\Request;
|
||||
use think\Response;
|
||||
use think\Route;
|
||||
use think\route\dispatch\Callback as CallbackDispatch;
|
||||
use think\route\dispatch\Controller as ControllerDispatch;
|
||||
use think\route\dispatch\Redirect as RedirectDispatch;
|
||||
use think\route\dispatch\Response as ResponseDispatch;
|
||||
use think\route\dispatch\View as ViewDispatch;
|
||||
|
||||
/**
|
||||
* 路由规则基础类
|
||||
@ -505,38 +501,16 @@ abstract class Rule
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前路由到一个模板地址 当使用数组的时候可以传入模板变量
|
||||
* 路由到一个模板地址 需要额外传入的模板变量
|
||||
* @access public
|
||||
* @param bool|array $view 视图
|
||||
* @param array $view 视图
|
||||
* @return $this
|
||||
*/
|
||||
public function view($view = true)
|
||||
public function view(array $view = [])
|
||||
{
|
||||
return $this->setOption('view', $view);
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前路由为重定向
|
||||
* @access public
|
||||
* @param bool $redirect 是否为重定向
|
||||
* @return $this
|
||||
*/
|
||||
public function redirect(bool $redirect = true)
|
||||
{
|
||||
return $this->setOption('redirect', $redirect);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置status
|
||||
* @access public
|
||||
* @param int $status 状态码
|
||||
* @return $this
|
||||
*/
|
||||
public function status(int $status)
|
||||
{
|
||||
return $this->setOption('status', $status);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置路由完整匹配
|
||||
* @access public
|
||||
@ -651,20 +625,14 @@ abstract class Rule
|
||||
*/
|
||||
protected function dispatch(Request $request, $route, array $option): Dispatch
|
||||
{
|
||||
if ($route instanceof Dispatch) {
|
||||
$result = $route;
|
||||
if (is_subclass_of($route, Dispatch::class)) {
|
||||
$result = new $route($request, $this, $route, $this->vars);
|
||||
} elseif ($route instanceof Closure) {
|
||||
// 执行闭包
|
||||
$result = new CallbackDispatch($request, $this, $route, $this->vars);
|
||||
} elseif ($route instanceof Response) {
|
||||
$result = new ResponseDispatch($request, $this, $route);
|
||||
} elseif (isset($option['view']) && false !== $option['view']) {
|
||||
$result = new ViewDispatch($request, $this, $route, is_array($option['view']) ? $option['view'] : $this->vars);
|
||||
} elseif (!empty($option['redirect'])) {
|
||||
// 路由到重定向地址
|
||||
$result = new RedirectDispatch($request, $this, $route, $this->vars, $option['status'] ?? 301);
|
||||
} elseif (false !== strpos($route, '\\')) {
|
||||
} elseif (false !== strpos($route, '@') || false !== strpos($route, '::')) {
|
||||
// 路由到类的方法
|
||||
$route = str_replace('::', '@', $route);
|
||||
$result = $this->dispatchMethod($request, $route);
|
||||
} else {
|
||||
// 路由到控制器/操作
|
||||
|
@ -16,9 +16,7 @@ use Closure;
|
||||
use think\Container;
|
||||
use think\Exception;
|
||||
use think\Request;
|
||||
use think\Response;
|
||||
use think\Route;
|
||||
use think\route\dispatch\Response as ResponseDispatch;
|
||||
|
||||
/**
|
||||
* 路由分组类
|
||||
@ -29,16 +27,7 @@ class RuleGroup extends Rule
|
||||
* 分组路由(包括子分组)
|
||||
* @var array
|
||||
*/
|
||||
protected $rules = [
|
||||
'*' => [],
|
||||
'get' => [],
|
||||
'post' => [],
|
||||
'put' => [],
|
||||
'patch' => [],
|
||||
'delete' => [],
|
||||
'head' => [],
|
||||
'options' => [],
|
||||
];
|
||||
protected $rules = [];
|
||||
|
||||
/**
|
||||
* 分组路由规则
|
||||
@ -151,15 +140,13 @@ class RuleGroup extends Rule
|
||||
// 解析分组路由
|
||||
if ($this instanceof Resource) {
|
||||
$this->buildResourceRule();
|
||||
} elseif ($this->rule instanceof Response) {
|
||||
return new ResponseDispatch($request, $this, $this->rule);
|
||||
} else {
|
||||
$this->parseGroupRule($this->rule);
|
||||
}
|
||||
|
||||
// 获取当前路由规则
|
||||
$method = strtolower($request->method());
|
||||
$rules = $this->getMethodRules($method);
|
||||
$rules = $this->getRules($method);
|
||||
|
||||
if ($this->parent) {
|
||||
// 合并分组参数
|
||||
@ -183,7 +170,7 @@ class RuleGroup extends Rule
|
||||
|
||||
// 检查分组路由
|
||||
foreach ($rules as $key => $item) {
|
||||
$result = $item->check($request, $url, $completeMatch);
|
||||
$result = $item[1]->check($request, $url, $completeMatch);
|
||||
|
||||
if (false !== $result) {
|
||||
return $result;
|
||||
@ -200,17 +187,6 @@ class RuleGroup extends Rule
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前请求的路由规则(包括子分组、资源路由)
|
||||
* @access protected
|
||||
* @param string $method 请求类型
|
||||
* @return array
|
||||
*/
|
||||
protected function getMethodRules(string $method): array
|
||||
{
|
||||
return array_merge($this->rules[$method], $this->rules['*']);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分组URL匹配检查
|
||||
* @access protected
|
||||
@ -302,7 +278,8 @@ class RuleGroup extends Rule
|
||||
$regex = [];
|
||||
$items = [];
|
||||
|
||||
foreach ($rules as $key => $item) {
|
||||
foreach ($rules as $key => $val) {
|
||||
$item = $val[1];
|
||||
if ($item instanceof RuleItem) {
|
||||
$rule = $depr . str_replace('/', $depr, $item->getRule());
|
||||
if ($depr == $rule && $depr != $url) {
|
||||
@ -460,10 +437,10 @@ class RuleGroup extends Rule
|
||||
$method = '*';
|
||||
}
|
||||
|
||||
$this->rules[$method][] = $rule;
|
||||
$this->rules[] = [$method, $rule];
|
||||
|
||||
if ($rule instanceof RuleItem && 'options' != $method) {
|
||||
$this->rules['options'][] = $rule->setAutoOptions();
|
||||
$this->rules[] = ['options', $rule->setAutoOptions()];
|
||||
}
|
||||
|
||||
return $this;
|
||||
@ -517,7 +494,9 @@ class RuleGroup extends Rule
|
||||
return $this->rules;
|
||||
}
|
||||
|
||||
return $this->rules[strtolower($method)] ?? [];
|
||||
return array_filter($this->rules, function ($item) use ($method) {
|
||||
return $method == $item[0] || $item[0] == '*';
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -527,15 +506,6 @@ class RuleGroup extends Rule
|
||||
*/
|
||||
public function clear(): void
|
||||
{
|
||||
$this->rules = [
|
||||
'*' => [],
|
||||
'get' => [],
|
||||
'post' => [],
|
||||
'put' => [],
|
||||
'patch' => [],
|
||||
'delete' => [],
|
||||
'head' => [],
|
||||
'options' => [],
|
||||
];
|
||||
$this->rules = [];
|
||||
}
|
||||
}
|
||||
|
@ -164,9 +164,9 @@ class Url
|
||||
$domains = $this->route->getDomains();
|
||||
|
||||
if (!empty($domains)) {
|
||||
$route_domain = array_keys($domains);
|
||||
foreach ($route_domain as $domain_prefix) {
|
||||
if (0 === strpos($domain_prefix, '*.') && strpos($domain, ltrim($domain_prefix, '*.')) !== false) {
|
||||
$routeDomain = array_keys($domains);
|
||||
foreach ($routeDomain as $domainPrefix) {
|
||||
if (0 === strpos($domainPrefix, '*.') && strpos($domain, ltrim($domainPrefix, '*.')) !== false) {
|
||||
foreach ($domains as $key => $rule) {
|
||||
$rule = is_array($rule) ? $rule[0] : $rule;
|
||||
if (is_string($rule) && false === strpos($key, '*') && 0 === strpos($url, $rule)) {
|
||||
|
@ -145,7 +145,10 @@ class Controller extends Dispatch
|
||||
}
|
||||
|
||||
if (is_string($val) && strpos($val, ':')) {
|
||||
$val = explode(':', $val, 2);
|
||||
$val = explode(':', $val);
|
||||
if (count($val) > 1) {
|
||||
$val = [$val[0], array_slice($val, 1)];
|
||||
}
|
||||
}
|
||||
|
||||
$this->app->middleware->controller($val);
|
||||
|
@ -1,27 +0,0 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2019 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace think\route\dispatch;
|
||||
|
||||
use think\Response;
|
||||
use think\route\Dispatch;
|
||||
|
||||
/**
|
||||
* Redirect Dispatcher
|
||||
*/
|
||||
class Redirect extends Dispatch
|
||||
{
|
||||
public function exec()
|
||||
{
|
||||
return Response::create($this->dispatch, 'redirect')->code($this->code);
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2019 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace think\route\dispatch;
|
||||
|
||||
use think\route\Dispatch;
|
||||
|
||||
/**
|
||||
* Response Dispatcher
|
||||
*/
|
||||
class Response extends Dispatch
|
||||
{
|
||||
public function exec()
|
||||
{
|
||||
return $this->dispatch;
|
||||
}
|
||||
|
||||
}
|
@ -23,14 +23,14 @@ use think\route\Rule;
|
||||
class Url extends Controller
|
||||
{
|
||||
|
||||
public function __construct(Request $request, Rule $rule, $dispatch, array $param = [], int $code = null)
|
||||
public function __construct(Request $request, Rule $rule, $dispatch)
|
||||
{
|
||||
$this->request = $request;
|
||||
$this->rule = $rule;
|
||||
// 解析默认的URL规则
|
||||
$dispatch = $this->parseUrl($dispatch);
|
||||
|
||||
parent::__construct($request, $rule, $dispatch, $this->param, $code);
|
||||
parent::__construct($request, $rule, $dispatch, $this->param);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,28 +0,0 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2019 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace think\route\dispatch;
|
||||
|
||||
use think\Response;
|
||||
use think\route\Dispatch;
|
||||
|
||||
/**
|
||||
* View Dispatcher
|
||||
*/
|
||||
class View extends Dispatch
|
||||
{
|
||||
public function exec()
|
||||
{
|
||||
// 渲染模板输出
|
||||
return Response::create($this->dispatch, 'view')->assign($this->param);
|
||||
}
|
||||
}
|
5
vendor/topthink/framework/tests/DbTest.php
vendored
5
vendor/topthink/framework/tests/DbTest.php
vendored
@ -5,6 +5,7 @@ namespace think\tests;
|
||||
use Mockery as m;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use think\Cache;
|
||||
use think\cache\Driver;
|
||||
use think\Config;
|
||||
use think\Db;
|
||||
use think\Event;
|
||||
@ -23,6 +24,10 @@ class DbTest extends TestCase
|
||||
$config = m::mock(Config::class);
|
||||
$log = m::mock(Log::class);
|
||||
$cache = m::mock(Cache::class);
|
||||
$store = m::mock(Driver::class);
|
||||
|
||||
$config->shouldReceive('get')->with('database.cache_store', null)->andReturn(null);
|
||||
$cache->shouldReceive('store')->with(null)->andReturn($store);
|
||||
|
||||
$db = Db::__make($event, $config, $log, $cache);
|
||||
|
||||
|
@ -108,15 +108,6 @@ class EventTest extends TestCase
|
||||
$this->event->trigger('bar');
|
||||
}
|
||||
|
||||
public function testWithoutEvent()
|
||||
{
|
||||
$this->event->withEvent(false);
|
||||
|
||||
$this->event->listen('SomeListener', TestListener::class);
|
||||
|
||||
$this->assertFalse($this->event->hasListener('SomeListener'));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class TestListener
|
||||
|
30
vendor/topthink/framework/tests/InteractsWithApp.php
vendored
Normal file
30
vendor/topthink/framework/tests/InteractsWithApp.php
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace think\tests;
|
||||
|
||||
use Mockery as m;
|
||||
use Mockery\MockInterface;
|
||||
use think\App;
|
||||
use think\Config;
|
||||
use think\Container;
|
||||
|
||||
trait InteractsWithApp
|
||||
{
|
||||
/** @var App|MockInterface */
|
||||
protected $app;
|
||||
|
||||
/** @var Config|MockInterface */
|
||||
protected $config;
|
||||
|
||||
protected function prepareApp()
|
||||
{
|
||||
$this->app = m::mock(App::class)->makePartial();
|
||||
Container::setInstance($this->app);
|
||||
$this->app->shouldReceive('make')->with(App::class)->andReturn($this->app);
|
||||
$this->app->shouldReceive('isDebug')->andReturnTrue();
|
||||
$this->config = m::mock(Config::class)->makePartial();
|
||||
$this->config->shouldReceive('get')->with('app.show_error_msg')->andReturnTrue();
|
||||
$this->app->shouldReceive('get')->with('config')->andReturn($this->config);
|
||||
$this->app->shouldReceive('runningInConsole')->andReturn(false);
|
||||
}
|
||||
}
|
17
vendor/topthink/framework/tests/LogTest.php
vendored
17
vendor/topthink/framework/tests/LogTest.php
vendored
@ -7,23 +7,16 @@ use Mockery as m;
|
||||
use Mockery\MockInterface;
|
||||
use org\bovigo\vfs\vfsStream;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use think\App;
|
||||
use think\Config;
|
||||
use think\Container;
|
||||
use think\Log;
|
||||
use think\log\ChannelSet;
|
||||
|
||||
class LogTest extends TestCase
|
||||
{
|
||||
/** @var App|MockInterface */
|
||||
protected $app;
|
||||
use InteractsWithApp;
|
||||
|
||||
/** @var Log|MockInterface */
|
||||
protected $log;
|
||||
|
||||
/** @var Config|MockInterface */
|
||||
protected $config;
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
m::close();
|
||||
@ -31,13 +24,7 @@ class LogTest extends TestCase
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->app = m::mock(App::class)->makePartial();
|
||||
Container::setInstance($this->app);
|
||||
|
||||
$this->app->shouldReceive('make')->with(App::class)->andReturn($this->app);
|
||||
$this->config = m::mock(Config::class)->makePartial();
|
||||
$this->app->shouldReceive('get')->with('config')->andReturn($this->config);
|
||||
$this->app->shouldReceive('runningInConsole')->andReturn(false);
|
||||
$this->prepareApp();
|
||||
|
||||
$this->log = new Log($this->app);
|
||||
}
|
||||
|
@ -5,9 +5,6 @@ namespace think\tests;
|
||||
use Mockery as m;
|
||||
use Mockery\MockInterface;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use think\App;
|
||||
use think\Config;
|
||||
use think\Container;
|
||||
use think\Exception;
|
||||
use think\exception\Handle;
|
||||
use think\Middleware;
|
||||
@ -17,15 +14,11 @@ use think\Response;
|
||||
|
||||
class MiddlewareTest extends TestCase
|
||||
{
|
||||
/** @var App|MockInterface */
|
||||
protected $app;
|
||||
use InteractsWithApp;
|
||||
|
||||
/** @var Middleware|MockInterface */
|
||||
protected $middleware;
|
||||
|
||||
/** @var Config|MockInterface */
|
||||
protected $config;
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
m::close();
|
||||
@ -33,13 +26,7 @@ class MiddlewareTest extends TestCase
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->app = m::mock(App::class)->makePartial();
|
||||
Container::setInstance($this->app);
|
||||
|
||||
$this->app->shouldReceive('make')->with(App::class)->andReturn($this->app);
|
||||
$this->config = m::mock(Config::class)->makePartial();
|
||||
$this->app->shouldReceive('get')->with('config')->andReturn($this->config);
|
||||
$this->app->shouldReceive('runningInConsole')->andReturn(false);
|
||||
$this->prepareApp();
|
||||
|
||||
$this->middleware = new Middleware($this->app);
|
||||
}
|
||||
|
285
vendor/topthink/framework/tests/RouteTest.php
vendored
Normal file
285
vendor/topthink/framework/tests/RouteTest.php
vendored
Normal file
@ -0,0 +1,285 @@
|
||||
<?php
|
||||
|
||||
namespace think\tests;
|
||||
|
||||
use Closure;
|
||||
use Mockery as m;
|
||||
use Mockery\MockInterface;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use think\helper\Str;
|
||||
use think\Request;
|
||||
use think\response\Redirect;
|
||||
use think\response\View;
|
||||
use think\Route;
|
||||
|
||||
class RouteTest extends TestCase
|
||||
{
|
||||
use InteractsWithApp;
|
||||
|
||||
/** @var Route|MockInterface */
|
||||
protected $route;
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
m::close();
|
||||
}
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->prepareApp();
|
||||
$this->route = new Route($this->app);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $path
|
||||
* @param string $method
|
||||
* @param string $host
|
||||
* @return m\Mock|Request
|
||||
*/
|
||||
protected function makeRequest($path, $method = 'GET', $host = 'localhost')
|
||||
{
|
||||
$request = m::mock(Request::class)->makePartial();
|
||||
$request->shouldReceive('host')->andReturn($host);
|
||||
$request->shouldReceive('pathinfo')->andReturn($path);
|
||||
$request->shouldReceive('url')->andReturn('/' . $path);
|
||||
$request->shouldReceive('method')->andReturn(strtoupper($method));
|
||||
return $request;
|
||||
}
|
||||
|
||||
public function testSimpleRequest()
|
||||
{
|
||||
$this->route->get('foo', function () {
|
||||
return 'get-foo';
|
||||
});
|
||||
|
||||
$this->route->put('foo', function () {
|
||||
return 'put-foo';
|
||||
});
|
||||
|
||||
$this->route->group(function () {
|
||||
$this->route->post('foo', function () {
|
||||
return 'post-foo';
|
||||
});
|
||||
});
|
||||
|
||||
$request = $this->makeRequest('foo', 'post');
|
||||
$response = $this->route->dispatch($request);
|
||||
$this->assertEquals(200, $response->getCode());
|
||||
$this->assertEquals('post-foo', $response->getContent());
|
||||
|
||||
$request = $this->makeRequest('foo', 'get');
|
||||
$response = $this->route->dispatch($request);
|
||||
$this->assertEquals(200, $response->getCode());
|
||||
$this->assertEquals('get-foo', $response->getContent());
|
||||
}
|
||||
|
||||
public function testOptionsRequest()
|
||||
{
|
||||
$this->route->get('foo', function () {
|
||||
return 'get-foo';
|
||||
});
|
||||
|
||||
$this->route->put('foo', function () {
|
||||
return 'put-foo';
|
||||
});
|
||||
|
||||
$this->route->group(function () {
|
||||
$this->route->post('foo', function () {
|
||||
return 'post-foo';
|
||||
});
|
||||
});
|
||||
$this->route->group('abc', function () {
|
||||
$this->route->post('foo/:id', function () {
|
||||
return 'post-abc-foo';
|
||||
});
|
||||
});
|
||||
|
||||
$this->route->post('foo/:id', function () {
|
||||
return 'post-abc-foo';
|
||||
});
|
||||
|
||||
$this->route->resource('bar', 'SomeClass');
|
||||
|
||||
$request = $this->makeRequest('foo', 'options');
|
||||
$response = $this->route->dispatch($request);
|
||||
$this->assertEquals(204, $response->getCode());
|
||||
$this->assertEquals('GET, PUT, POST', $response->getHeader('Allow'));
|
||||
|
||||
$request = $this->makeRequest('bar', 'options');
|
||||
$response = $this->route->dispatch($request);
|
||||
$this->assertEquals(204, $response->getCode());
|
||||
$this->assertEquals('GET, POST', $response->getHeader('Allow'));
|
||||
|
||||
$request = $this->makeRequest('bar/1', 'options');
|
||||
$response = $this->route->dispatch($request);
|
||||
$this->assertEquals(204, $response->getCode());
|
||||
$this->assertEquals('GET, PUT, DELETE', $response->getHeader('Allow'));
|
||||
|
||||
$request = $this->makeRequest('xxxx', 'options');
|
||||
$response = $this->route->dispatch($request);
|
||||
$this->assertEquals(204, $response->getCode());
|
||||
$this->assertEquals('GET, POST, PUT, DELETE', $response->getHeader('Allow'));
|
||||
}
|
||||
|
||||
public function testAllowCrossDomain()
|
||||
{
|
||||
$this->route->get('foo', function () {
|
||||
return 'get-foo';
|
||||
})->allowCrossDomain(['some' => 'bar']);
|
||||
|
||||
$request = $this->makeRequest('foo', 'get');
|
||||
$response = $this->route->dispatch($request);
|
||||
|
||||
$this->assertEquals('bar', $response->getHeader('some'));
|
||||
$this->assertArrayHasKey('Access-Control-Allow-Credentials', $response->getHeader());
|
||||
|
||||
$request = $this->makeRequest('foo2', 'options');
|
||||
$response = $this->route->dispatch($request);
|
||||
|
||||
$this->assertEquals(204, $response->getCode());
|
||||
$this->assertArrayHasKey('Access-Control-Allow-Credentials', $response->getHeader());
|
||||
$this->assertEquals('GET, POST, PUT, DELETE', $response->getHeader('Allow'));
|
||||
}
|
||||
|
||||
public function testControllerDispatch()
|
||||
{
|
||||
$this->route->get('foo', 'foo/bar');
|
||||
|
||||
$controller = m::Mock(\stdClass::class);
|
||||
|
||||
$this->app->shouldReceive('parseClass')->with('controller', 'Foo')->andReturn($controller->mockery_getName());
|
||||
$this->app->shouldReceive('make')->with($controller->mockery_getName(), [], true)->andReturn($controller);
|
||||
|
||||
$controller->shouldReceive('bar')->andReturn('bar');
|
||||
|
||||
$request = $this->makeRequest('foo');
|
||||
$response = $this->route->dispatch($request);
|
||||
$this->assertEquals('bar', $response->getContent());
|
||||
}
|
||||
|
||||
public function testEmptyControllerDispatch()
|
||||
{
|
||||
$this->route->get('foo', 'foo/bar');
|
||||
|
||||
$controller = m::Mock(\stdClass::class);
|
||||
|
||||
$this->app->shouldReceive('parseClass')->with('controller', 'Error')->andReturn($controller->mockery_getName());
|
||||
$this->app->shouldReceive('make')->with($controller->mockery_getName(), [], true)->andReturn($controller);
|
||||
|
||||
$controller->shouldReceive('bar')->andReturn('bar');
|
||||
|
||||
$request = $this->makeRequest('foo');
|
||||
$response = $this->route->dispatch($request);
|
||||
$this->assertEquals('bar', $response->getContent());
|
||||
}
|
||||
|
||||
protected function createMiddleware($times = 1)
|
||||
{
|
||||
$middleware = m::mock(Str::random(5));
|
||||
$middleware->shouldReceive('handle')->times($times)->andReturnUsing(function ($request, Closure $next) {
|
||||
return $next($request);
|
||||
});
|
||||
$this->app->shouldReceive('make')->with($middleware->mockery_getName())->andReturn($middleware);
|
||||
|
||||
return $middleware;
|
||||
}
|
||||
|
||||
public function testControllerWithMiddleware()
|
||||
{
|
||||
$this->route->get('foo', 'foo/bar');
|
||||
|
||||
$controller = m::mock(FooClass::class);
|
||||
|
||||
$controller->middleware = [
|
||||
$this->createMiddleware()->mockery_getName() . ":params1:params2",
|
||||
$this->createMiddleware(0)->mockery_getName() => ['except' => 'bar'],
|
||||
$this->createMiddleware()->mockery_getName() => ['only' => 'bar'],
|
||||
];
|
||||
|
||||
$this->app->shouldReceive('parseClass')->with('controller', 'Foo')->andReturn($controller->mockery_getName());
|
||||
$this->app->shouldReceive('make')->with($controller->mockery_getName(), [], true)->andReturn($controller);
|
||||
|
||||
$controller->shouldReceive('bar')->once()->andReturn('bar');
|
||||
|
||||
$request = $this->makeRequest('foo');
|
||||
$response = $this->route->dispatch($request);
|
||||
$this->assertEquals('bar', $response->getContent());
|
||||
}
|
||||
|
||||
public function testUrlDispatch()
|
||||
{
|
||||
$controller = m::mock(FooClass::class);
|
||||
$controller->shouldReceive('index')->andReturn('bar');
|
||||
|
||||
$this->app->shouldReceive('parseClass')->once()->with('controller', 'Foo')->andReturn($controller->mockery_getName());
|
||||
$this->app->shouldReceive('make')->with($controller->mockery_getName(), [], true)->andReturn($controller);
|
||||
|
||||
$request = $this->makeRequest('foo');
|
||||
$response = $this->route->dispatch($request);
|
||||
$this->assertEquals('bar', $response->getContent());
|
||||
}
|
||||
|
||||
public function testRedirectDispatch()
|
||||
{
|
||||
$this->route->redirect('foo', 'http://localhost', 302);
|
||||
|
||||
$request = $this->makeRequest('foo');
|
||||
$response = $this->route->dispatch($request);
|
||||
|
||||
$this->assertInstanceOf(Redirect::class, $response);
|
||||
$this->assertEquals(302, $response->getCode());
|
||||
$this->assertEquals('http://localhost', $response->getData());
|
||||
}
|
||||
|
||||
public function testViewDispatch()
|
||||
{
|
||||
$this->route->view('foo', 'index/hello', ['city' => 'shanghai']);
|
||||
|
||||
$request = $this->makeRequest('foo');
|
||||
$response = $this->route->dispatch($request);
|
||||
|
||||
$this->assertInstanceOf(View::class, $response);
|
||||
$this->assertEquals(['city' => 'shanghai'], $response->getVars());
|
||||
$this->assertEquals('index/hello', $response->getData());
|
||||
}
|
||||
|
||||
public function testResponseDispatch()
|
||||
{
|
||||
$this->route->get('hello/:name', response()
|
||||
->data('Hello,ThinkPHP')
|
||||
->code(200)
|
||||
->contentType('text/plain'));
|
||||
|
||||
$request = $this->makeRequest('hello/some');
|
||||
$response = $this->route->dispatch($request);
|
||||
|
||||
$this->assertEquals('Hello,ThinkPHP', $response->getContent());
|
||||
$this->assertEquals(200, $response->getCode());
|
||||
}
|
||||
|
||||
public function testDomainBindResponse()
|
||||
{
|
||||
$this->route->domain('test', function () {
|
||||
$this->route->get('/', function () {
|
||||
return 'Hello,ThinkPHP';
|
||||
});
|
||||
});
|
||||
|
||||
$request = $this->makeRequest('', 'get', 'test.domain.com');
|
||||
$response = $this->route->dispatch($request);
|
||||
|
||||
$this->assertEquals('Hello,ThinkPHP', $response->getContent());
|
||||
$this->assertEquals(200, $response->getCode());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class FooClass
|
||||
{
|
||||
public $middleware = [];
|
||||
|
||||
public function bar()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
<?php
|
||||
|
||||
require __DIR__.'/../vendor/autoload.php';
|
||||
include __DIR__.'/../src/helper.php';
|
||||
|
64
vendor/topthink/think-multi-app/src/Service.php
vendored
64
vendor/topthink/think-multi-app/src/Service.php
vendored
@ -1,32 +1,32 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace think\app;
|
||||
|
||||
use think\Service as BaseService;
|
||||
|
||||
class Service extends BaseService
|
||||
{
|
||||
public function boot()
|
||||
{
|
||||
$this->app->event->listen('HttpRun', function () {
|
||||
$this->app->middleware->add(MultiApp::class);
|
||||
});
|
||||
|
||||
$this->commands([
|
||||
'build' => command\Build::class,
|
||||
'clear' => command\Clear::class,
|
||||
]);
|
||||
|
||||
$this->app->bind([
|
||||
'think\route\Url' => Url::class,
|
||||
]);
|
||||
}
|
||||
}
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace think\app;
|
||||
|
||||
use think\Service as BaseService;
|
||||
|
||||
class Service extends BaseService
|
||||
{
|
||||
public function boot()
|
||||
{
|
||||
$this->app->event->listen('HttpRun', function () {
|
||||
$this->app->middleware->add(MultiApp::class);
|
||||
});
|
||||
|
||||
$this->commands([
|
||||
'build' => command\Build::class,
|
||||
'clear' => command\Clear::class,
|
||||
]);
|
||||
|
||||
$this->app->bind([
|
||||
'think\route\Url' => Url::class,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
1
vendor/topthink/think-multi-app/src/Url.php
vendored
1
vendor/topthink/think-multi-app/src/Url.php
vendored
@ -59,6 +59,7 @@ class Url extends UrlBuild
|
||||
$bind = $this->app->config->get('app.domain_bind', []);
|
||||
|
||||
if ($key = array_search($app, $bind)) {
|
||||
isset($bind[$_SERVER['SERVER_NAME']]) && $domain = $_SERVER['SERVER_NAME'];
|
||||
$domain = is_bool($domain) ? $key : $domain;
|
||||
} else {
|
||||
$map = $this->app->config->get('app.app_map', []);
|
||||
|
16
vendor/topthink/think-orm/src/DbManager.php
vendored
16
vendor/topthink/think-orm/src/DbManager.php
vendored
@ -229,21 +229,11 @@ class DbManager
|
||||
* @access public
|
||||
* @param string|null $name 连接配置标识
|
||||
* @param bool $force 强制重新连接
|
||||
* @return BaseQuery
|
||||
* @return ConnectionInterface
|
||||
*/
|
||||
public function connect(string $name = null, bool $force = false): BaseQuery
|
||||
public function connect(string $name = null, bool $force = false)
|
||||
{
|
||||
$connection = $this->instance($name, $force);
|
||||
|
||||
$class = $connection->getQueryClass();
|
||||
$query = new $class($connection);
|
||||
|
||||
$timeRule = $this->getConfig('time_query_rule');
|
||||
if (!empty($timeRule)) {
|
||||
$query->timeRule($timeRule);
|
||||
}
|
||||
|
||||
return $query;
|
||||
return $this->instance($name, $force);
|
||||
}
|
||||
|
||||
/**
|
||||
|
67
vendor/topthink/think-orm/src/Model.php
vendored
67
vendor/topthink/think-orm/src/Model.php
vendored
@ -632,9 +632,8 @@ abstract class Model implements JsonSerializable, ArrayAccess, Arrayable, Jsonab
|
||||
|
||||
// 模型更新
|
||||
$db = $this->db();
|
||||
$db->startTrans();
|
||||
|
||||
try {
|
||||
$db->transaction(function () use ($data, $allowFields, $db) {
|
||||
$this->key = null;
|
||||
$where = $this->getWhere();
|
||||
|
||||
@ -651,17 +650,12 @@ abstract class Model implements JsonSerializable, ArrayAccess, Arrayable, Jsonab
|
||||
if (!empty($this->relationWrite)) {
|
||||
$this->autoRelationUpdate();
|
||||
}
|
||||
});
|
||||
|
||||
$db->commit();
|
||||
// 更新回调
|
||||
$this->trigger('AfterUpdate');
|
||||
|
||||
// 更新回调
|
||||
$this->trigger('AfterUpdate');
|
||||
|
||||
return true;
|
||||
} catch (\Exception $e) {
|
||||
$db->rollback();
|
||||
throw $e;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -693,9 +687,8 @@ abstract class Model implements JsonSerializable, ArrayAccess, Arrayable, Jsonab
|
||||
$allowFields = $this->checkAllowFields();
|
||||
|
||||
$db = $this->db();
|
||||
$db->startTrans();
|
||||
|
||||
try {
|
||||
$db->transaction(function () use ($sequence, $allowFields, $db) {
|
||||
$result = $db->strict(false)
|
||||
->field($allowFields)
|
||||
->replace($this->replace)
|
||||
@ -715,20 +708,15 @@ abstract class Model implements JsonSerializable, ArrayAccess, Arrayable, Jsonab
|
||||
if (!empty($this->relationWrite)) {
|
||||
$this->autoRelationInsert();
|
||||
}
|
||||
});
|
||||
|
||||
$db->commit();
|
||||
// 标记数据已经存在
|
||||
$this->exists = true;
|
||||
|
||||
// 标记数据已经存在
|
||||
$this->exists = true;
|
||||
// 新增回调
|
||||
$this->trigger('AfterInsert');
|
||||
|
||||
// 新增回调
|
||||
$this->trigger('AfterInsert');
|
||||
|
||||
return true;
|
||||
} catch (\Exception $e) {
|
||||
$db->rollback();
|
||||
throw $e;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -769,9 +757,9 @@ abstract class Model implements JsonSerializable, ArrayAccess, Arrayable, Jsonab
|
||||
public function saveAll(iterable $dataSet, bool $replace = true): Collection
|
||||
{
|
||||
$db = $this->db();
|
||||
$db->startTrans();
|
||||
|
||||
try {
|
||||
$result = $db->transaction(function () use ($replace, $dataSet) {
|
||||
|
||||
$pk = $this->getPk();
|
||||
|
||||
if (is_string($pk) && $replace) {
|
||||
@ -790,13 +778,10 @@ abstract class Model implements JsonSerializable, ArrayAccess, Arrayable, Jsonab
|
||||
}
|
||||
}
|
||||
|
||||
$db->commit();
|
||||
return $result;
|
||||
});
|
||||
|
||||
return $this->toCollection($result);
|
||||
} catch (\Exception $e) {
|
||||
$db->rollback();
|
||||
throw $e;
|
||||
}
|
||||
return $this->toCollection($result);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -814,9 +799,8 @@ abstract class Model implements JsonSerializable, ArrayAccess, Arrayable, Jsonab
|
||||
$where = $this->getWhere();
|
||||
|
||||
$db = $this->db();
|
||||
$db->startTrans();
|
||||
|
||||
try {
|
||||
$db->transaction(function () use ($where, $db) {
|
||||
// 删除当前模型数据
|
||||
$db->where($where)->delete();
|
||||
|
||||
@ -824,19 +808,14 @@ abstract class Model implements JsonSerializable, ArrayAccess, Arrayable, Jsonab
|
||||
if (!empty($this->relationWrite)) {
|
||||
$this->autoRelationDelete();
|
||||
}
|
||||
});
|
||||
|
||||
$db->commit();
|
||||
$this->trigger('AfterDelete');
|
||||
|
||||
$this->trigger('AfterDelete');
|
||||
$this->exists = false;
|
||||
$this->lazySave = false;
|
||||
|
||||
$this->exists = false;
|
||||
$this->lazySave = false;
|
||||
|
||||
return true;
|
||||
} catch (\Exception $e) {
|
||||
$db->rollback();
|
||||
throw $e;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
23
vendor/topthink/think-orm/src/Paginator.php
vendored
23
vendor/topthink/think-orm/src/Paginator.php
vendored
@ -239,6 +239,10 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J
|
||||
static::$currentPathResolver = $resolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取数据总条数
|
||||
* @return int
|
||||
*/
|
||||
public function total(): int
|
||||
{
|
||||
if ($this->simple) {
|
||||
@ -248,16 +252,28 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J
|
||||
return $this->total;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取每页数量
|
||||
* @return int
|
||||
*/
|
||||
public function listRows(): int
|
||||
{
|
||||
return $this->listRows;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前页页码
|
||||
* @return int
|
||||
*/
|
||||
public function currentPage(): int
|
||||
{
|
||||
return $this->currentPage;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取最后一页页码
|
||||
* @return int
|
||||
*/
|
||||
public function lastPage(): int
|
||||
{
|
||||
if ($this->simple) {
|
||||
@ -445,7 +461,8 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J
|
||||
}
|
||||
|
||||
/**
|
||||
* Count elements of an object
|
||||
* 统计数据集条数
|
||||
* @return int
|
||||
*/
|
||||
public function count(): int
|
||||
{
|
||||
@ -457,6 +474,10 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J
|
||||
return (string) $this->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为数组
|
||||
* @return array
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
try {
|
||||
|
39
vendor/topthink/think-orm/src/db/Builder.php
vendored
39
vendor/topthink/think-orm/src/db/Builder.php
vendored
@ -149,7 +149,7 @@ abstract class Builder
|
||||
$item = $this->parseKey($query, $key, true);
|
||||
|
||||
if ($val instanceof Raw) {
|
||||
$result[$item] = $val->getValue();
|
||||
$result[$item] = $this->parseRaw($query, $val);
|
||||
continue;
|
||||
} elseif (!is_scalar($val) && (in_array($key, (array) $query->getOptions('json')) || 'json' == $query->getFieldType($key))) {
|
||||
$val = json_encode($val);
|
||||
@ -165,7 +165,7 @@ abstract class Builder
|
||||
}
|
||||
} elseif (is_null($val)) {
|
||||
$result[$item] = 'NULL';
|
||||
} elseif (is_array($val) && !empty($val)) {
|
||||
} elseif (is_array($val) && !empty($val) && is_string($val[0])) {
|
||||
switch (strtoupper($val[0])) {
|
||||
case 'INC':
|
||||
$result[$item] = $item . ' + ' . floatval($val[1]);
|
||||
@ -195,7 +195,7 @@ abstract class Builder
|
||||
protected function parseDataBind(Query $query, string $key, $data, array $bind = []): string
|
||||
{
|
||||
if ($data instanceof Raw) {
|
||||
return $data->getValue();
|
||||
return $this->parseRaw($query, $data);
|
||||
}
|
||||
|
||||
$name = $query->bindValue($data, $bind[$key] ?? PDO::PARAM_STR);
|
||||
@ -243,7 +243,7 @@ abstract class Builder
|
||||
|
||||
foreach ($fields as $key => $field) {
|
||||
if ($field instanceof Raw) {
|
||||
$array[] = $field->getValue();
|
||||
$array[] = $this->parseRaw($query, $field);
|
||||
} elseif (!is_numeric($key)) {
|
||||
$array[] = $this->parseKey($query, $key) . ' AS ' . $this->parseKey($query, $field, true);
|
||||
} else {
|
||||
@ -273,7 +273,7 @@ abstract class Builder
|
||||
|
||||
foreach ((array) $tables as $key => $table) {
|
||||
if ($table instanceof Raw) {
|
||||
$item[] = $table->getValue();
|
||||
$item[] = $this->parseRaw($query, $table);
|
||||
} elseif (!is_numeric($key)) {
|
||||
$item[] = $this->parseKey($query, $key) . ' ' . $this->parseKey($query, $table);
|
||||
} elseif (isset($options['alias'][$table])) {
|
||||
@ -350,7 +350,7 @@ abstract class Builder
|
||||
$where = [];
|
||||
foreach ($val as $value) {
|
||||
if ($value instanceof Raw) {
|
||||
$where[] = ' ' . $logic . ' ( ' . $value->getValue() . ' )';
|
||||
$where[] = ' ' . $logic . ' ( ' . $this->parseRaw($query, $value) . ' )';
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -577,7 +577,7 @@ abstract class Builder
|
||||
protected function parseExp(Query $query, string $key, string $exp, Raw $value, string $field, int $bindType): string
|
||||
{
|
||||
// 表达式查询
|
||||
return '( ' . $key . ' ' . $value->getValue() . ' )';
|
||||
return '( ' . $key . ' ' . $this->parseRaw($query, $value) . ' )';
|
||||
}
|
||||
|
||||
/**
|
||||
@ -659,7 +659,7 @@ abstract class Builder
|
||||
if ($value instanceof Closure) {
|
||||
$value = $this->parseClosure($query, $value, false);
|
||||
} elseif ($value instanceof Raw) {
|
||||
$value = $value->getValue();
|
||||
$value = $this->parseRaw($query, $value);
|
||||
} else {
|
||||
throw new Exception('where express error:' . $value);
|
||||
}
|
||||
@ -753,7 +753,7 @@ abstract class Builder
|
||||
if ($value instanceof Closure) {
|
||||
$value = $this->parseClosure($query, $value, false);
|
||||
} elseif ($value instanceof Raw) {
|
||||
$value = $value->getValue();
|
||||
$value = $this->parseRaw($query, $value);
|
||||
} else {
|
||||
$value = array_unique(is_array($value) ? $value : explode(',', $value));
|
||||
$array = [];
|
||||
@ -891,7 +891,7 @@ abstract class Builder
|
||||
$array = [];
|
||||
foreach ($order as $key => $val) {
|
||||
if ($val instanceof Raw) {
|
||||
$array[] = $val->getValue();
|
||||
$array[] = $this->parseRaw($query, $val);
|
||||
} elseif (is_array($val) && preg_match('/^[\w\.]+$/', $key)) {
|
||||
$array[] = $this->parseOrderField($query, $key, $val);
|
||||
} elseif ('[rand]' == $val) {
|
||||
@ -916,6 +916,25 @@ abstract class Builder
|
||||
return empty($array) ? '' : ' ORDER BY ' . implode(',', $array);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分析Raw对象
|
||||
* @access protected
|
||||
* @param Query $query 查询对象
|
||||
* @param Raw $raw Raw对象
|
||||
* @return string
|
||||
*/
|
||||
protected function parseRaw(Query $query, Raw $raw): string
|
||||
{
|
||||
$sql = $raw->getValue();
|
||||
$bind = $raw->getBind();
|
||||
|
||||
if ($bind) {
|
||||
$query->bindParams($sql, $bind);
|
||||
}
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* 随机排序
|
||||
* @access protected
|
||||
|
67
vendor/topthink/think-orm/src/db/Connection.php
vendored
67
vendor/topthink/think-orm/src/db/Connection.php
vendored
@ -14,12 +14,11 @@ namespace think\db;
|
||||
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
use think\DbManager;
|
||||
use think\db\CacheItem;
|
||||
|
||||
/**
|
||||
* 数据库连接基础类
|
||||
*/
|
||||
abstract class Connection
|
||||
abstract class Connection implements ConnectionInterface
|
||||
{
|
||||
|
||||
/**
|
||||
@ -90,7 +89,7 @@ abstract class Connection
|
||||
|
||||
/**
|
||||
* Db对象
|
||||
* @var Db
|
||||
* @var DbManager
|
||||
*/
|
||||
protected $db;
|
||||
|
||||
@ -108,10 +107,27 @@ abstract class Connection
|
||||
|
||||
/**
|
||||
* 缓存对象
|
||||
* @var Cache
|
||||
* @var CacheInterface
|
||||
*/
|
||||
protected $cache;
|
||||
|
||||
/**
|
||||
* 架构函数 读取数据库配置信息
|
||||
* @access public
|
||||
* @param array $config 数据库配置数组
|
||||
*/
|
||||
public function __construct(array $config = [])
|
||||
{
|
||||
if (!empty($config)) {
|
||||
$this->config = array_merge($this->config, $config);
|
||||
}
|
||||
|
||||
// 创建Builder对象
|
||||
$class = $this->getBuilderClass();
|
||||
|
||||
$this->builder = new $class($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前的builder实例对象
|
||||
* @access public
|
||||
@ -122,6 +138,45 @@ abstract class Connection
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 创建查询对象
|
||||
*/
|
||||
public function newQuery()
|
||||
{
|
||||
$class = $this->getQueryClass();
|
||||
|
||||
/** @var BaseQuery $query */
|
||||
$query = new $class($this);
|
||||
|
||||
$timeRule = $this->db->getConfig('time_query_rule');
|
||||
if (!empty($timeRule)) {
|
||||
$query->timeRule($timeRule);
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定表名开始查询
|
||||
* @param $table
|
||||
* @return BaseQuery
|
||||
*/
|
||||
public function table($table)
|
||||
{
|
||||
return $this->newQuery()->table($table);
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定表名开始查询(不带前缀)
|
||||
* @param $name
|
||||
* @return BaseQuery
|
||||
*/
|
||||
public function name($name)
|
||||
{
|
||||
return $this->newQuery()->name($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前的数据库Db对象
|
||||
* @access public
|
||||
@ -214,7 +269,7 @@ abstract class Connection
|
||||
* 分析缓存Key
|
||||
* @access protected
|
||||
* @param BaseQuery $query 查询对象
|
||||
* @param string $method查询方法
|
||||
* @param string $method 查询方法
|
||||
* @return string
|
||||
*/
|
||||
protected function getCacheKey(BaseQuery $query, string $method = ''): string
|
||||
@ -233,7 +288,7 @@ abstract class Connection
|
||||
* @access protected
|
||||
* @param BaseQuery $query 查询对象
|
||||
* @param array $cache 缓存信息
|
||||
* @param string $method查询方法
|
||||
* @param string $method 查询方法
|
||||
* @return CacheItem
|
||||
*/
|
||||
protected function parseCache(BaseQuery $query, array $cache, string $method = ''): CacheItem
|
||||
|
@ -27,6 +27,20 @@ interface ConnectionInterface
|
||||
*/
|
||||
public function getQueryClass(): string;
|
||||
|
||||
/**
|
||||
* 指定表名开始查询
|
||||
* @param $table
|
||||
* @return BaseQuery
|
||||
*/
|
||||
public function table($table);
|
||||
|
||||
/**
|
||||
* 指定表名开始查询(不带前缀)
|
||||
* @param $name
|
||||
* @return BaseQuery
|
||||
*/
|
||||
public function name($name);
|
||||
|
||||
/**
|
||||
* 连接数据库方法
|
||||
* @access public
|
||||
@ -72,9 +86,6 @@ interface ConnectionInterface
|
||||
* @access public
|
||||
* @param BaseQuery $query 查询对象
|
||||
* @return array
|
||||
* @throws DbException
|
||||
* @throws ModelNotFoundException
|
||||
* @throws DataNotFoundException
|
||||
*/
|
||||
public function find(BaseQuery $query): array;
|
||||
|
||||
@ -83,9 +94,6 @@ interface ConnectionInterface
|
||||
* @access public
|
||||
* @param BaseQuery $query 查询对象
|
||||
* @return array
|
||||
* @throws DbException
|
||||
* @throws ModelNotFoundException
|
||||
* @throws DataNotFoundException
|
||||
*/
|
||||
public function select(BaseQuery $query): array;
|
||||
|
||||
@ -104,8 +112,6 @@ interface ConnectionInterface
|
||||
* @param BaseQuery $query 查询对象
|
||||
* @param mixed $dataSet 数据集
|
||||
* @return integer
|
||||
* @throws \Exception
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function insertAll(BaseQuery $query, array $dataSet = []): int;
|
||||
|
||||
@ -114,8 +120,6 @@ interface ConnectionInterface
|
||||
* @access public
|
||||
* @param BaseQuery $query 查询对象
|
||||
* @return integer
|
||||
* @throws Exception
|
||||
* @throws PDOException
|
||||
*/
|
||||
public function update(BaseQuery $query): int;
|
||||
|
||||
@ -124,8 +128,6 @@ interface ConnectionInterface
|
||||
* @access public
|
||||
* @param BaseQuery $query 查询对象
|
||||
* @return int
|
||||
* @throws Exception
|
||||
* @throws PDOException
|
||||
*/
|
||||
public function delete(BaseQuery $query): int;
|
||||
|
||||
@ -135,7 +137,6 @@ interface ConnectionInterface
|
||||
* @param BaseQuery $query 查询对象
|
||||
* @param string $field 字段名
|
||||
* @param mixed $default 默认值
|
||||
* @param bool $one 返回一个值
|
||||
* @return mixed
|
||||
*/
|
||||
public function value(BaseQuery $query, string $field, $default = null);
|
||||
@ -155,9 +156,6 @@ interface ConnectionInterface
|
||||
* @access public
|
||||
* @param callable $callback 数据操作方法回调
|
||||
* @return mixed
|
||||
* @throws PDOException
|
||||
* @throws \Exception
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function transaction(callable $callback);
|
||||
|
||||
@ -165,8 +163,6 @@ interface ConnectionInterface
|
||||
* 启动事务
|
||||
* @access public
|
||||
* @return void
|
||||
* @throws \PDOException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function startTrans();
|
||||
|
||||
@ -174,7 +170,6 @@ interface ConnectionInterface
|
||||
* 用于非自动提交状态下面的查询提交
|
||||
* @access public
|
||||
* @return void
|
||||
* @throws PDOException
|
||||
*/
|
||||
public function commit();
|
||||
|
||||
@ -182,7 +177,6 @@ interface ConnectionInterface
|
||||
* 事务回滚
|
||||
* @access public
|
||||
* @return void
|
||||
* @throws PDOException
|
||||
*/
|
||||
public function rollback();
|
||||
|
||||
|
5
vendor/topthink/think-orm/src/db/Fetch.php
vendored
5
vendor/topthink/think-orm/src/db/Fetch.php
vendored
@ -69,8 +69,9 @@ class Fetch
|
||||
/**
|
||||
* 得到某个字段的值
|
||||
* @access public
|
||||
* @param string $field 字段名
|
||||
* @param mixed $default 默认值
|
||||
* @param string $field 字段名
|
||||
* @param mixed $default 默认值
|
||||
* @param bool $one
|
||||
* @return string
|
||||
*/
|
||||
public function value(string $field, $default = null, bool $one = true): string
|
||||
|
49
vendor/topthink/think-orm/src/db/Mongo.php
vendored
49
vendor/topthink/think-orm/src/db/Mongo.php
vendored
@ -9,38 +9,24 @@
|
||||
declare (strict_types = 1);
|
||||
namespace think\db;
|
||||
|
||||
use MongoDB\Driver\BulkWrite;
|
||||
use MongoDB\Driver\Command;
|
||||
use MongoDB\Driver\Cursor;
|
||||
use MongoDB\Driver\Exception\AuthenticationException;
|
||||
use MongoDB\Driver\Exception\BulkWriteException;
|
||||
use MongoDB\Driver\Exception\ConnectionException;
|
||||
use MongoDB\Driver\Exception\InvalidArgumentException;
|
||||
use MongoDB\Driver\Exception\RuntimeException;
|
||||
use MongoDB\Driver\Query as MongoQuery;
|
||||
use MongoDB\Driver\ReadPreference;
|
||||
use MongoDB\Driver\WriteConcern;
|
||||
use think\Collection;
|
||||
use think\db\connector\Mongo as Connection;
|
||||
use think\db\exception\DbException as Exception;
|
||||
use think\Paginator;
|
||||
|
||||
class Mongo extends BaseQuery
|
||||
{
|
||||
/**
|
||||
* 执行查询 返回数据集
|
||||
* @access public
|
||||
* @param MongoQuery $query 查询对象
|
||||
* @return mixed
|
||||
* @throws AuthenticationException
|
||||
* @throws InvalidArgumentException
|
||||
* @throws ConnectionException
|
||||
* @throws RuntimeException
|
||||
* 当前数据库连接对象
|
||||
* @var \think\db\connector\Mongo
|
||||
*/
|
||||
public function query(MongoQuery $query)
|
||||
{
|
||||
return $this->connection->query($this, $query);
|
||||
}
|
||||
protected $connection;
|
||||
|
||||
/**
|
||||
* 执行指令 返回数据集
|
||||
@ -60,22 +46,6 @@ class Mongo extends BaseQuery
|
||||
return $this->connection->command($command, $dbName, $readPreference, $typeMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行语句
|
||||
* @access public
|
||||
* @param BulkWrite $bulk
|
||||
* @return int
|
||||
* @throws AuthenticationException
|
||||
* @throws InvalidArgumentException
|
||||
* @throws ConnectionException
|
||||
* @throws RuntimeException
|
||||
* @throws BulkWriteException
|
||||
*/
|
||||
public function execute(BulkWrite $bulk)
|
||||
{
|
||||
return $this->connection->execute($this, $bulk);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行command
|
||||
* @access public
|
||||
@ -699,12 +669,13 @@ class Mongo extends BaseQuery
|
||||
|
||||
if (isset($options['page'])) {
|
||||
// 根据页数计算limit
|
||||
list($page, $listRows) = $options['page'];
|
||||
$page = $page > 0 ? $page : 1;
|
||||
$listRows = $listRows > 0 ? $listRows : (is_numeric($options['limit']) ? $options['limit'] : 20);
|
||||
$offset = $listRows * ($page - 1);
|
||||
$options['skip'] = intval($offset);
|
||||
$options['limit'] = intval($listRows);
|
||||
[$page, $listRows] = $options['page'];
|
||||
|
||||
$page = $page > 0 ? $page : 1;
|
||||
$listRows = $listRows > 0 ? $listRows : (is_numeric($options['limit']) ? $options['limit'] : 20);
|
||||
$offset = $listRows * ($page - 1);
|
||||
$options['skip'] = intval($offset);
|
||||
$options['limit'] = intval($listRows);
|
||||
}
|
||||
|
||||
$this->options = $options;
|
||||
|
229
vendor/topthink/think-orm/src/db/PDOConnection.php
vendored
229
vendor/topthink/think-orm/src/db/PDOConnection.php
vendored
@ -16,14 +16,13 @@ use Closure;
|
||||
use PDO;
|
||||
use PDOStatement;
|
||||
use think\db\exception\BindParamException;
|
||||
use think\db\exception\DataNotFoundException;
|
||||
use think\db\exception\ModelNotFoundException;
|
||||
use think\db\exception\DbException;
|
||||
use think\db\exception\PDOException;
|
||||
|
||||
/**
|
||||
* 数据库连接基础类
|
||||
*/
|
||||
abstract class PDOConnection extends Connection implements ConnectionInterface
|
||||
abstract class PDOConnection extends Connection
|
||||
{
|
||||
const PARAM_FLOAT = 21;
|
||||
|
||||
@ -33,51 +32,49 @@ abstract class PDOConnection extends Connection implements ConnectionInterface
|
||||
*/
|
||||
protected $config = [
|
||||
// 数据库类型
|
||||
'type' => '',
|
||||
'type' => '',
|
||||
// 服务器地址
|
||||
'hostname' => '',
|
||||
'hostname' => '',
|
||||
// 数据库名
|
||||
'database' => '',
|
||||
'database' => '',
|
||||
// 用户名
|
||||
'username' => '',
|
||||
'username' => '',
|
||||
// 密码
|
||||
'password' => '',
|
||||
'password' => '',
|
||||
// 端口
|
||||
'hostport' => '',
|
||||
'hostport' => '',
|
||||
// 连接dsn
|
||||
'dsn' => '',
|
||||
'dsn' => '',
|
||||
// 数据库连接参数
|
||||
'params' => [],
|
||||
'params' => [],
|
||||
// 数据库编码默认采用utf8
|
||||
'charset' => 'utf8',
|
||||
'charset' => 'utf8',
|
||||
// 数据库表前缀
|
||||
'prefix' => '',
|
||||
'prefix' => '',
|
||||
// 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
|
||||
'deploy' => 0,
|
||||
'deploy' => 0,
|
||||
// 数据库读写是否分离 主从式有效
|
||||
'rw_separate' => false,
|
||||
'rw_separate' => false,
|
||||
// 读写分离后 主服务器数量
|
||||
'master_num' => 1,
|
||||
'master_num' => 1,
|
||||
// 指定从服务器序号
|
||||
'slave_no' => '',
|
||||
'slave_no' => '',
|
||||
// 模型写入后自动读取主服务器
|
||||
'read_master' => false,
|
||||
'read_master' => false,
|
||||
// 是否严格检查字段是否存在
|
||||
'fields_strict' => true,
|
||||
'fields_strict' => true,
|
||||
// 开启字段缓存
|
||||
'fields_cache' => false,
|
||||
'fields_cache' => false,
|
||||
// 监听SQL
|
||||
'trigger_sql' => true,
|
||||
'trigger_sql' => true,
|
||||
// Builder类
|
||||
'builder' => '',
|
||||
'builder' => '',
|
||||
// Query类
|
||||
'query' => '',
|
||||
'query' => '',
|
||||
// 是否需要断线重连
|
||||
'break_reconnect' => false,
|
||||
'break_reconnect' => false,
|
||||
// 断线标识字符串
|
||||
'break_match_str' => [],
|
||||
// 字段缓存路径
|
||||
'schema_cache_path' => '',
|
||||
'break_match_str' => [],
|
||||
];
|
||||
|
||||
/**
|
||||
@ -180,23 +177,6 @@ abstract class PDOConnection extends Connection implements ConnectionInterface
|
||||
*/
|
||||
protected $bind = [];
|
||||
|
||||
/**
|
||||
* 架构函数 读取数据库配置信息
|
||||
* @access public
|
||||
* @param array $config 数据库配置数组
|
||||
*/
|
||||
public function __construct(array $config = [])
|
||||
{
|
||||
if (!empty($config)) {
|
||||
$this->config = array_merge($this->config, $config);
|
||||
}
|
||||
|
||||
// 创建Builder对象
|
||||
$class = $this->getBuilderClass();
|
||||
|
||||
$this->builder = new $class($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前连接器类对应的Query类
|
||||
* @access public
|
||||
@ -285,6 +265,8 @@ abstract class PDOConnection extends Connection implements ConnectionInterface
|
||||
$result = 'timestamp';
|
||||
} elseif (0 === strpos($type, 'datetime')) {
|
||||
$result = 'datetime';
|
||||
} elseif (0 === strpos($type, 'date')) {
|
||||
$result = 'date';
|
||||
} else {
|
||||
$result = 'string';
|
||||
}
|
||||
@ -318,46 +300,42 @@ abstract class PDOConnection extends Connection implements ConnectionInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取数据表信息
|
||||
* @access public
|
||||
* @param mixed $tableName 数据表名 留空自动获取
|
||||
* @param string $fetch 获取信息类型 包括 fields type bind pk
|
||||
* @return mixed
|
||||
* 获取数据表信息缓存key
|
||||
* @access protected
|
||||
* @param string $schema 数据表名称
|
||||
* @return string
|
||||
*/
|
||||
public function getTableInfo($tableName, string $fetch = '')
|
||||
protected function getSchemaCacheKey(string $schema): string
|
||||
{
|
||||
if (is_array($tableName)) {
|
||||
$tableName = key($tableName) ?: current($tableName);
|
||||
}
|
||||
|
||||
if (strpos($tableName, ',') || strpos($tableName, ')')) {
|
||||
// 多表不获取字段信息
|
||||
return [];
|
||||
}
|
||||
|
||||
[$tableName] = explode(' ', $tableName);
|
||||
return $this->getConfig('hostname') . ':' . $this->getConfig('hostport') . '@' . $schema;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $tableName 数据表名称
|
||||
* @param bool $force 强制从数据库获取
|
||||
* @return array
|
||||
*/
|
||||
public function getSchemaInfo(string $tableName, $force = false)
|
||||
{
|
||||
if (!strpos($tableName, '.')) {
|
||||
$schema = $this->getConfig('database') . '.' . $tableName;
|
||||
} else {
|
||||
$schema = $tableName;
|
||||
}
|
||||
|
||||
if (!isset($this->info[$schema])) {
|
||||
if (!isset($this->info[$schema]) || $force) {
|
||||
// 读取字段缓存
|
||||
$cacheFile = $this->config['schema_cache_path'] . $schema . '.php';
|
||||
$cacheKey = $this->getSchemaCacheKey($schema);
|
||||
$cacheField = $this->config['fields_cache'] && !empty($this->cache);
|
||||
|
||||
if ($this->config['fields_cache'] && is_file($cacheFile)) {
|
||||
$info = include $cacheFile;
|
||||
} else {
|
||||
if ($cacheField && !$force) {
|
||||
$info = $this->cache->get($cacheKey);
|
||||
}
|
||||
|
||||
if (empty($info)) {
|
||||
$info = $this->getTableFieldsInfo($tableName);
|
||||
if ($this->config['fields_cache']) {
|
||||
if (!is_dir($this->config['schema_cache_path'])) {
|
||||
mkdir($this->config['schema_cache_path'], 0755, true);
|
||||
}
|
||||
|
||||
$content = '<?php ' . PHP_EOL . 'return ' . var_export($info, true) . ';';
|
||||
file_put_contents($cacheFile, $content);
|
||||
if ($cacheField) {
|
||||
$this->cache->set($cacheKey, $info);
|
||||
}
|
||||
}
|
||||
|
||||
@ -379,7 +357,32 @@ abstract class PDOConnection extends Connection implements ConnectionInterface
|
||||
];
|
||||
}
|
||||
|
||||
return $fetch ? $this->info[$schema][$fetch] : $this->info[$schema];
|
||||
return $this->info[$schema];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取数据表信息
|
||||
* @access public
|
||||
* @param mixed $tableName 数据表名 留空自动获取
|
||||
* @param string $fetch 获取信息类型 包括 fields type bind pk
|
||||
* @return mixed
|
||||
*/
|
||||
public function getTableInfo($tableName, string $fetch = '')
|
||||
{
|
||||
if (is_array($tableName)) {
|
||||
$tableName = key($tableName) ?: current($tableName);
|
||||
}
|
||||
|
||||
if (strpos($tableName, ',') || strpos($tableName, ')')) {
|
||||
// 多表不获取字段信息
|
||||
return [];
|
||||
}
|
||||
|
||||
[$tableName] = explode(' ', $tableName);
|
||||
|
||||
$info = $this->getSchemaInfo($tableName);
|
||||
|
||||
return $fetch ? $info[$fetch] : $info;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -541,6 +544,17 @@ abstract class PDOConnection extends Connection implements ConnectionInterface
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 视图查询
|
||||
* @access public
|
||||
* @param array $args
|
||||
* @return BaseQuery
|
||||
*/
|
||||
public function view(...$args)
|
||||
{
|
||||
return $this->newQuery()->view(...$args);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建PDO实例
|
||||
* @param $dsn
|
||||
@ -604,16 +618,46 @@ abstract class PDOConnection extends Connection implements ConnectionInterface
|
||||
/**
|
||||
* 执行查询 返回数据集
|
||||
* @access public
|
||||
* @param string $sql sql指令
|
||||
* @param array $bind 参数绑定
|
||||
* @param bool $master 主库读取
|
||||
* @return array
|
||||
* @throws BindParamException
|
||||
* @throws \PDOException
|
||||
*/
|
||||
public function query(string $sql, array $bind = [], bool $master = false): array
|
||||
{
|
||||
return $this->pdoQuery($this->newQuery(), $sql, $bind, $master);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行语句
|
||||
* @access public
|
||||
* @param string $sql sql指令
|
||||
* @param array $bind 参数绑定
|
||||
* @return int
|
||||
* @throws BindParamException
|
||||
* @throws \PDOException
|
||||
*/
|
||||
public function execute(string $sql, array $bind = []): int
|
||||
{
|
||||
return $this->pdoExecute($this->newQuery(), $sql, $bind, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行查询 返回数据集
|
||||
* @access protected
|
||||
* @param BaseQuery $query 查询对象
|
||||
* @param mixed $sql sql指令
|
||||
* @param array $bind 参数绑定
|
||||
* @param bool $master 主库读取
|
||||
* @return array
|
||||
* @throws BindParamException
|
||||
* @throws \PDOException
|
||||
* @throws \Exception
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function query(BaseQuery $query, $sql, array $bind = []): array
|
||||
protected function pdoQuery(BaseQuery $query, $sql, array $bind = [], bool $master = null): array
|
||||
{
|
||||
// 分析查询表达式
|
||||
$query->parseOptions();
|
||||
@ -623,8 +667,10 @@ abstract class PDOConnection extends Connection implements ConnectionInterface
|
||||
$cacheItem = $this->parseCache($query, $query->getOptions('cache'));
|
||||
$key = $cacheItem->getKey();
|
||||
|
||||
if ($this->cache->has($key)) {
|
||||
return $this->cache->get($key);
|
||||
$data = $this->cache->get($key);
|
||||
|
||||
if (null !== $data) {
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
@ -633,7 +679,10 @@ abstract class PDOConnection extends Connection implements ConnectionInterface
|
||||
$bind = $query->getBind();
|
||||
}
|
||||
|
||||
$master = $query->getOptions('master') ? true : false;
|
||||
if (!isset($master)) {
|
||||
$master = $query->getOptions('master') ? true : false;
|
||||
}
|
||||
|
||||
$procedure = $query->getOptions('procedure') ? true : in_array(strtolower(substr(trim($sql), 0, 4)), ['call', 'exec']);
|
||||
|
||||
$this->getPDOStatement($sql, $bind, $master, $procedure);
|
||||
@ -728,7 +777,7 @@ abstract class PDOConnection extends Connection implements ConnectionInterface
|
||||
|
||||
/**
|
||||
* 执行语句
|
||||
* @access public
|
||||
* @access protected
|
||||
* @param BaseQuery $query 查询对象
|
||||
* @param string $sql sql指令
|
||||
* @param array $bind 参数绑定
|
||||
@ -739,7 +788,7 @@ abstract class PDOConnection extends Connection implements ConnectionInterface
|
||||
* @throws \Exception
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function execute(BaseQuery $query, string $sql, array $bind = [], bool $origin = false): int
|
||||
protected function pdoExecute(BaseQuery $query, string $sql, array $bind = [], bool $origin = false): int
|
||||
{
|
||||
if ($origin) {
|
||||
$query->parseOptions();
|
||||
@ -784,8 +833,6 @@ abstract class PDOConnection extends Connection implements ConnectionInterface
|
||||
* @param BaseQuery $query 查询对象
|
||||
* @return array
|
||||
* @throws DbException
|
||||
* @throws ModelNotFoundException
|
||||
* @throws DataNotFoundException
|
||||
*/
|
||||
public function find(BaseQuery $query): array
|
||||
{
|
||||
@ -794,7 +841,7 @@ abstract class PDOConnection extends Connection implements ConnectionInterface
|
||||
|
||||
if (!$result) {
|
||||
// 执行查询
|
||||
$resultSet = $this->query($query, function ($query) {
|
||||
$resultSet = $this->pdoQuery($query, function ($query) {
|
||||
return $this->builder->select($query, true);
|
||||
});
|
||||
|
||||
@ -830,8 +877,6 @@ abstract class PDOConnection extends Connection implements ConnectionInterface
|
||||
* @param BaseQuery $query 查询对象
|
||||
* @return array
|
||||
* @throws DbException
|
||||
* @throws ModelNotFoundException
|
||||
* @throws DataNotFoundException
|
||||
*/
|
||||
public function select(BaseQuery $query): array
|
||||
{
|
||||
@ -839,7 +884,7 @@ abstract class PDOConnection extends Connection implements ConnectionInterface
|
||||
|
||||
if (!$resultSet) {
|
||||
// 执行查询操作
|
||||
$resultSet = $this->query($query, function ($query) {
|
||||
$resultSet = $this->pdoQuery($query, function ($query) {
|
||||
return $this->builder->select($query);
|
||||
});
|
||||
}
|
||||
@ -863,7 +908,7 @@ abstract class PDOConnection extends Connection implements ConnectionInterface
|
||||
$sql = $this->builder->insert($query);
|
||||
|
||||
// 执行操作
|
||||
$result = '' == $sql ? 0 : $this->execute($query, $sql, $query->getBind());
|
||||
$result = '' == $sql ? 0 : $this->pdoExecute($query, $sql, $query->getBind());
|
||||
|
||||
if ($result) {
|
||||
$sequence = $options['sequence'] ?? null;
|
||||
@ -923,7 +968,7 @@ abstract class PDOConnection extends Connection implements ConnectionInterface
|
||||
|
||||
foreach ($array as $item) {
|
||||
$sql = $this->builder->insertAll($query, $item, $replace);
|
||||
$count += $this->execute($query, $sql, $query->getBind());
|
||||
$count += $this->pdoExecute($query, $sql, $query->getBind());
|
||||
}
|
||||
|
||||
// 提交事务
|
||||
@ -938,7 +983,7 @@ abstract class PDOConnection extends Connection implements ConnectionInterface
|
||||
|
||||
$sql = $this->builder->insertAll($query, $dataSet, $replace);
|
||||
|
||||
return $this->execute($query, $sql, $query->getBind());
|
||||
return $this->pdoExecute($query, $sql, $query->getBind());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -957,7 +1002,7 @@ abstract class PDOConnection extends Connection implements ConnectionInterface
|
||||
|
||||
$sql = $this->builder->selectInsert($query, $fields, $table);
|
||||
|
||||
return $this->execute($query, $sql, $query->getBind());
|
||||
return $this->pdoExecute($query, $sql, $query->getBind());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -975,7 +1020,7 @@ abstract class PDOConnection extends Connection implements ConnectionInterface
|
||||
$sql = $this->builder->update($query);
|
||||
|
||||
// 执行操作
|
||||
$result = '' == $sql ? 0 : $this->execute($query, $sql, $query->getBind());
|
||||
$result = '' == $sql ? 0 : $this->pdoExecute($query, $sql, $query->getBind());
|
||||
|
||||
if ($result) {
|
||||
$this->db->trigger('after_update', $query);
|
||||
@ -1000,7 +1045,7 @@ abstract class PDOConnection extends Connection implements ConnectionInterface
|
||||
$sql = $this->builder->delete($query);
|
||||
|
||||
// 执行操作
|
||||
$result = $this->execute($query, $sql, $query->getBind());
|
||||
$result = $this->pdoExecute($query, $sql, $query->getBind());
|
||||
|
||||
if ($result) {
|
||||
$this->db->trigger('after_delete', $query);
|
||||
@ -1457,7 +1502,7 @@ abstract class PDOConnection extends Connection implements ConnectionInterface
|
||||
|
||||
try {
|
||||
foreach ($sqlArray as $sql) {
|
||||
$this->execute($query, $sql, $bind);
|
||||
$this->pdoExecute($query, $sql, $bind);
|
||||
}
|
||||
// 提交事务
|
||||
$this->commit();
|
||||
|
34
vendor/topthink/think-orm/src/db/Query.php
vendored
34
vendor/topthink/think-orm/src/db/Query.php
vendored
@ -33,11 +33,7 @@ class Query extends BaseQuery
|
||||
*/
|
||||
public function orderRaw(string $field, array $bind = [])
|
||||
{
|
||||
if (!empty($bind)) {
|
||||
$this->bindParams($field, $bind);
|
||||
}
|
||||
|
||||
$this->options['order'][] = new Raw($field);
|
||||
$this->options['order'][] = new Raw($field, $bind);
|
||||
|
||||
return $this;
|
||||
}
|
||||
@ -111,34 +107,6 @@ class Query extends BaseQuery
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行查询 返回数据集
|
||||
* @access public
|
||||
* @param string $sql sql指令
|
||||
* @param array $bind 参数绑定
|
||||
* @return array
|
||||
* @throws BindParamException
|
||||
* @throws PDOException
|
||||
*/
|
||||
public function query(string $sql, array $bind = []): array
|
||||
{
|
||||
return $this->connection->query($this, $sql, $bind);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行语句
|
||||
* @access public
|
||||
* @param string $sql sql指令
|
||||
* @param array $bind 参数绑定
|
||||
* @return int
|
||||
* @throws BindParamException
|
||||
* @throws PDOException
|
||||
*/
|
||||
public function execute(string $sql, array $bind = []): int
|
||||
{
|
||||
return $this->connection->execute($this, $sql, $bind, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取执行的SQL语句而不进行实际的查询
|
||||
* @access public
|
||||
|
21
vendor/topthink/think-orm/src/db/Raw.php
vendored
21
vendor/topthink/think-orm/src/db/Raw.php
vendored
@ -24,15 +24,24 @@ class Raw
|
||||
*/
|
||||
protected $value;
|
||||
|
||||
/**
|
||||
* 参数绑定
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $bind = [];
|
||||
|
||||
/**
|
||||
* 创建一个查询表达式
|
||||
*
|
||||
* @param string $value
|
||||
* @param array $bind
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(string $value)
|
||||
public function __construct(string $value, array $bind = [])
|
||||
{
|
||||
$this->value = $value;
|
||||
$this->bind = $bind;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -45,6 +54,16 @@ class Raw
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取参数绑定
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getBind(): array
|
||||
{
|
||||
return $this->bind;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return (string) $this->value;
|
||||
|
@ -270,7 +270,7 @@ class Mysql extends Builder
|
||||
protected function parseRegexp(Query $query, string $key, string $exp, $value, string $field): string
|
||||
{
|
||||
if ($value instanceof Raw) {
|
||||
$value = $value->getValue();
|
||||
$value = $this->parseRaw($query, $value);
|
||||
}
|
||||
|
||||
return $key . ' ' . $exp . ' ' . $value;
|
||||
@ -289,7 +289,7 @@ class Mysql extends Builder
|
||||
protected function parseFindInSet(Query $query, string $key, string $exp, $value, string $field): string
|
||||
{
|
||||
if ($value instanceof Raw) {
|
||||
$value = $value->getValue();
|
||||
$value = $this->parseRaw($query, $value);
|
||||
}
|
||||
|
||||
return 'FIND_IN_SET(' . $value . ', ' . $key . ')';
|
||||
@ -308,7 +308,7 @@ class Mysql extends Builder
|
||||
if (is_int($key)) {
|
||||
return (string) $key;
|
||||
} elseif ($key instanceof Raw) {
|
||||
return $key->getValue();
|
||||
return $this->parseRaw($query, $key);
|
||||
}
|
||||
|
||||
$key = trim($key);
|
||||
@ -396,7 +396,7 @@ class Mysql extends Builder
|
||||
}
|
||||
|
||||
if ($duplicate instanceof Raw) {
|
||||
return ' ON DUPLICATE KEY UPDATE ' . $duplicate->getValue() . ' ';
|
||||
return ' ON DUPLICATE KEY UPDATE ' . $this->parseRaw($query, $duplicate) . ' ';
|
||||
}
|
||||
|
||||
if (is_string($duplicate)) {
|
||||
@ -409,7 +409,7 @@ class Mysql extends Builder
|
||||
$val = $this->parseKey($query, $val);
|
||||
$updates[] = $val . ' = VALUES(' . $val . ')';
|
||||
} elseif ($val instanceof Raw) {
|
||||
$updates[] = $this->parseKey($query, $key) . " = " . $val->getValue();
|
||||
$updates[] = $this->parseKey($query, $key) . " = " . $this->parseRaw($query, $val);
|
||||
} else {
|
||||
$name = $query->bindValue($val, $query->getConnection()->getFieldBindType($key));
|
||||
$updates[] = $this->parseKey($query, $key) . " = :" . $name;
|
||||
|
@ -69,7 +69,7 @@ class Pgsql extends Builder
|
||||
if (is_int($key)) {
|
||||
return (string) $key;
|
||||
} elseif ($key instanceof Raw) {
|
||||
return $key->getValue();
|
||||
return $this->parseRaw($query, $key);
|
||||
}
|
||||
|
||||
$key = trim($key);
|
||||
|
@ -68,7 +68,7 @@ class Sqlite extends Builder
|
||||
if (is_int($key)) {
|
||||
return (string) $key;
|
||||
} elseif ($key instanceof Raw) {
|
||||
return $key->getValue();
|
||||
return $this->parseRaw($query, $key);
|
||||
}
|
||||
|
||||
$key = trim($key);
|
||||
|
@ -73,7 +73,7 @@ class Sqlsrv extends Builder
|
||||
|
||||
foreach ($order as $key => $val) {
|
||||
if ($val instanceof Raw) {
|
||||
$array[] = $val->getValue();
|
||||
$array[] = $this->parseRaw($query, $val);
|
||||
} elseif ('[rand]' == $val) {
|
||||
$array[] = $this->parseRand($query);
|
||||
} else {
|
||||
@ -115,7 +115,7 @@ class Sqlsrv extends Builder
|
||||
if (is_int($key)) {
|
||||
return (string) $key;
|
||||
} elseif ($key instanceof Raw) {
|
||||
return $key->getValue();
|
||||
return $this->parseRaw($query, $key);
|
||||
}
|
||||
|
||||
$key = trim($key);
|
||||
|
@ -71,7 +71,7 @@ trait ParamsBind
|
||||
* @param array $bind 参数绑定
|
||||
* @return void
|
||||
*/
|
||||
protected function bindParams(string &$sql, array $bind = []): void
|
||||
public function bindParams(string &$sql, array $bind = []): void
|
||||
{
|
||||
foreach ($bind as $key => $value) {
|
||||
if (is_array($value)) {
|
||||
|
@ -290,11 +290,7 @@ trait WhereQuery
|
||||
*/
|
||||
public function whereExp(string $field, string $where, array $bind = [], string $logic = 'AND')
|
||||
{
|
||||
if (!empty($bind)) {
|
||||
$this->bindParams($where, $bind);
|
||||
}
|
||||
|
||||
$this->options['where'][$logic][] = [$field, 'EXP', new Raw($where)];
|
||||
$this->options['where'][$logic][] = [$field, 'EXP', new Raw($where, $bind)];
|
||||
|
||||
return $this;
|
||||
}
|
||||
@ -329,11 +325,7 @@ trait WhereQuery
|
||||
*/
|
||||
public function whereRaw(string $where, array $bind = [], string $logic = 'AND')
|
||||
{
|
||||
if (!empty($bind)) {
|
||||
$this->bindParams($where, $bind);
|
||||
}
|
||||
|
||||
$this->options['where'][$logic][] = new Raw($where);
|
||||
$this->options['where'][$logic][] = new Raw($where, $bind);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
104
vendor/topthink/think-orm/src/db/connector/Mongo.php
vendored
104
vendor/topthink/think-orm/src/db/connector/Mongo.php
vendored
@ -27,14 +27,13 @@ use MongoDB\Driver\WriteConcern;
|
||||
use think\db\BaseQuery;
|
||||
use think\db\builder\Mongo as Builder;
|
||||
use think\db\Connection;
|
||||
use think\db\ConnectionInterface;
|
||||
use think\db\exception\DbException as Exception;
|
||||
use think\db\Mongo as Query;
|
||||
|
||||
/**
|
||||
* Mongo数据库驱动
|
||||
*/
|
||||
class Mongo extends Connection implements ConnectionInterface
|
||||
class Mongo extends Connection
|
||||
{
|
||||
|
||||
// 查询数据类型
|
||||
@ -45,6 +44,9 @@ class Mongo extends Connection implements ConnectionInterface
|
||||
protected $session_uuid; // sessions会话列表当前会话数组key 随机生成
|
||||
protected $sessions = []; // 会话列表
|
||||
|
||||
/** @var Builder */
|
||||
protected $builder;
|
||||
|
||||
// 数据库连接参数配置
|
||||
protected $config = [
|
||||
// 数据库类型
|
||||
@ -97,23 +99,6 @@ class Mongo extends Connection implements ConnectionInterface
|
||||
'type_map' => ['root' => 'array', 'document' => 'array'],
|
||||
];
|
||||
|
||||
/**
|
||||
* 架构函数 读取数据库配置信息
|
||||
* @access public
|
||||
* @param array $config 数据库配置数组
|
||||
*/
|
||||
public function __construct(array $config = [])
|
||||
{
|
||||
if (!empty($config)) {
|
||||
$this->config = array_merge($this->config, $config);
|
||||
}
|
||||
|
||||
// 创建Builder对象
|
||||
$class = $this->getBuilderClass();
|
||||
|
||||
$this->builder = new $class($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前连接器类对应的Query类
|
||||
* @access public
|
||||
@ -129,7 +114,7 @@ class Mongo extends Connection implements ConnectionInterface
|
||||
* @access public
|
||||
* @return Builder
|
||||
*/
|
||||
public function getBuilder(): Builder
|
||||
public function getBuilder()
|
||||
{
|
||||
return $this->builder;
|
||||
}
|
||||
@ -200,8 +185,8 @@ class Mongo extends Connection implements ConnectionInterface
|
||||
/**
|
||||
* 设置/获取当前操作的database
|
||||
* @access public
|
||||
* @param string $db db
|
||||
* @throws Exception
|
||||
* @param string $db db
|
||||
* @return string
|
||||
*/
|
||||
public function db(string $db = null)
|
||||
{
|
||||
@ -215,10 +200,10 @@ class Mongo extends Connection implements ConnectionInterface
|
||||
/**
|
||||
* 执行查询但只返回Cursor对象
|
||||
* @access public
|
||||
* @param BaseQuery $query 查询对象
|
||||
* @param Query $query 查询对象
|
||||
* @return Cursor
|
||||
*/
|
||||
public function cursor(BaseQuery $query)
|
||||
public function cursor($query)
|
||||
{
|
||||
// 分析查询表达式
|
||||
$options = $query->parseOptions();
|
||||
@ -271,7 +256,7 @@ class Mongo extends Connection implements ConnectionInterface
|
||||
if ($session = $this->getSession()) {
|
||||
$this->cursor = $this->mongo->executeQuery($namespace, $query, [
|
||||
'readPreference' => is_null($readPreference) ? new ReadPreference(ReadPreference::RP_PRIMARY) : $readPreference,
|
||||
'session' => $session
|
||||
'session' => $session,
|
||||
]);
|
||||
} else {
|
||||
$this->cursor = $this->mongo->executeQuery($namespace, $mongoQuery, $readPreference);
|
||||
@ -286,8 +271,39 @@ class Mongo extends Connection implements ConnectionInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行查询
|
||||
* 执行查询 返回数据集
|
||||
* @access public
|
||||
* @param MongoQuery $query 查询对象
|
||||
* @return mixed
|
||||
* @throws AuthenticationException
|
||||
* @throws InvalidArgumentException
|
||||
* @throws ConnectionException
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function query(MongoQuery $query)
|
||||
{
|
||||
return $this->mongoQuery($this->newQuery(), $query);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行语句
|
||||
* @access public
|
||||
* @param BulkWrite $bulk
|
||||
* @return int
|
||||
* @throws AuthenticationException
|
||||
* @throws InvalidArgumentException
|
||||
* @throws ConnectionException
|
||||
* @throws RuntimeException
|
||||
* @throws BulkWriteException
|
||||
*/
|
||||
public function execute(BulkWrite $bulk)
|
||||
{
|
||||
return $this->mongoExecute($this->newQuery(), $bulk);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行查询
|
||||
* @access protected
|
||||
* @param BaseQuery $query 查询对象
|
||||
* @param MongoQuery|Closure $mongoQuery Mongo查询对象
|
||||
* @return array
|
||||
@ -296,7 +312,7 @@ class Mongo extends Connection implements ConnectionInterface
|
||||
* @throws ConnectionException
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function query(BaseQuery $query, $mongoQuery): array
|
||||
protected function mongoQuery(BaseQuery $query, $mongoQuery): array
|
||||
{
|
||||
$options = $query->parseOptions();
|
||||
|
||||
@ -330,7 +346,7 @@ class Mongo extends Connection implements ConnectionInterface
|
||||
|
||||
/**
|
||||
* 执行写操作
|
||||
* @access public
|
||||
* @access protected
|
||||
* @param BaseQuery $query
|
||||
* @param BulkWrite $bulk
|
||||
*
|
||||
@ -341,7 +357,7 @@ class Mongo extends Connection implements ConnectionInterface
|
||||
* @throws RuntimeException
|
||||
* @throws BulkWriteException
|
||||
*/
|
||||
public function execute(BaseQuery $query, BulkWrite $bulk)
|
||||
protected function mongoExecute(BaseQuery $query, BulkWrite $bulk)
|
||||
{
|
||||
$this->initConnect(true);
|
||||
$this->db->updateQueryTimes();
|
||||
@ -363,8 +379,8 @@ class Mongo extends Connection implements ConnectionInterface
|
||||
|
||||
if ($session = $this->getSession()) {
|
||||
$writeResult = $this->mongo->executeBulkWrite($namespace, $bulk, [
|
||||
'session' => $session,
|
||||
'writeConcern' => is_null($writeConcern) ? new WriteConcern(1) : $writeConcern
|
||||
'session' => $session,
|
||||
'writeConcern' => is_null($writeConcern) ? new WriteConcern(1) : $writeConcern,
|
||||
]);
|
||||
} else {
|
||||
$writeResult = $this->mongo->executeBulkWrite($namespace, $bulk, $writeConcern);
|
||||
@ -423,7 +439,7 @@ class Mongo extends Connection implements ConnectionInterface
|
||||
if ($session = $this->getSession()) {
|
||||
$this->cursor = $this->mongo->executeCommand($dbName, $command, [
|
||||
'readPreference' => is_null($readPreference) ? new ReadPreference(ReadPreference::RP_PRIMARY) : $readPreference,
|
||||
'session' => $session
|
||||
'session' => $session,
|
||||
]);
|
||||
} else {
|
||||
$this->cursor = $this->mongo->executeCommand($dbName, $command, $readPreference);
|
||||
@ -705,7 +721,7 @@ class Mongo extends Connection implements ConnectionInterface
|
||||
// 生成bulk对象
|
||||
$bulk = $this->builder->insert($query);
|
||||
|
||||
$writeResult = $this->execute($query, $bulk);
|
||||
$writeResult = $this->mongoExecute($query, $bulk);
|
||||
$result = $writeResult->getInsertedCount();
|
||||
|
||||
if ($result) {
|
||||
@ -776,7 +792,7 @@ class Mongo extends Connection implements ConnectionInterface
|
||||
// 生成bulkWrite对象
|
||||
$bulk = $this->builder->insertAll($query, $dataSet);
|
||||
|
||||
$writeResult = $this->execute($query, $bulk);
|
||||
$writeResult = $this->mongoExecute($query, $bulk);
|
||||
|
||||
return $writeResult->getInsertedCount();
|
||||
}
|
||||
@ -800,7 +816,7 @@ class Mongo extends Connection implements ConnectionInterface
|
||||
// 生成bulkWrite对象
|
||||
$bulk = $this->builder->update($query);
|
||||
|
||||
$writeResult = $this->execute($query, $bulk);
|
||||
$writeResult = $this->mongoExecute($query, $bulk);
|
||||
|
||||
$result = $writeResult->getModifiedCount();
|
||||
|
||||
@ -832,7 +848,7 @@ class Mongo extends Connection implements ConnectionInterface
|
||||
$bulk = $this->builder->delete($query);
|
||||
|
||||
// 执行操作
|
||||
$writeResult = $this->execute($query, $bulk);
|
||||
$writeResult = $this->mongoExecute($query, $bulk);
|
||||
|
||||
$result = $writeResult->getDeletedCount();
|
||||
|
||||
@ -860,7 +876,7 @@ class Mongo extends Connection implements ConnectionInterface
|
||||
$resultSet = $this->db->trigger('before_select', $query);
|
||||
|
||||
if (!$resultSet) {
|
||||
$resultSet = $this->query($query, function ($query) {
|
||||
$resultSet = $this->mongoQuery($query, function ($query) {
|
||||
return $this->builder->select($query);
|
||||
});
|
||||
}
|
||||
@ -887,7 +903,7 @@ class Mongo extends Connection implements ConnectionInterface
|
||||
|
||||
if (!$result) {
|
||||
// 执行查询
|
||||
$resultSet = $this->query($query, function ($query) {
|
||||
$resultSet = $this->mongoQuery($query, function ($query) {
|
||||
return $this->builder->select($query, true);
|
||||
});
|
||||
|
||||
@ -932,7 +948,7 @@ class Mongo extends Connection implements ConnectionInterface
|
||||
}
|
||||
|
||||
// 执行查询操作
|
||||
$resultSet = $this->query($query, $mongoQuery);
|
||||
$resultSet = $this->mongoQuery($query, $mongoQuery);
|
||||
|
||||
if (!empty($resultSet)) {
|
||||
$data = array_shift($resultSet);
|
||||
@ -992,7 +1008,7 @@ class Mongo extends Connection implements ConnectionInterface
|
||||
}
|
||||
|
||||
// 执行查询操作
|
||||
$resultSet = $this->query($query, $mongoQuery);
|
||||
$resultSet = $this->mongoQuery($query, $mongoQuery);
|
||||
|
||||
if (('*' == $field || strpos($field, ',')) && $key) {
|
||||
$result = array_column($resultSet, null, $key);
|
||||
@ -1035,7 +1051,7 @@ class Mongo extends Connection implements ConnectionInterface
|
||||
|
||||
return $this->command($command, $db);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取数据库字段
|
||||
* @access public
|
||||
@ -1085,7 +1101,7 @@ class Mongo extends Connection implements ConnectionInterface
|
||||
public function startTrans()
|
||||
{
|
||||
$this->initConnect(true);
|
||||
$this->session_uuid = uniqid();
|
||||
$this->session_uuid = uniqid();
|
||||
$this->sessions[$this->session_uuid] = $this->getMongo()->startSession();
|
||||
|
||||
$this->sessions[$this->session_uuid]->startTransaction([]);
|
||||
@ -1145,7 +1161,7 @@ class Mongo extends Connection implements ConnectionInterface
|
||||
public function getSession()
|
||||
{
|
||||
return ($this->session_uuid && isset($this->sessions[$this->session_uuid]))
|
||||
? $this->sessions[$this->session_uuid]
|
||||
: null;
|
||||
? $this->sessions[$this->session_uuid]
|
||||
: null;
|
||||
}
|
||||
}
|
||||
|
@ -74,10 +74,10 @@ class Mysql extends PDOConnection
|
||||
$info[$val['field']] = [
|
||||
'name' => $val['field'],
|
||||
'type' => $val['type'],
|
||||
'notnull' => (bool) ('' === $val['null']), // not null is empty, null is yes
|
||||
'notnull' => 'NO' == $val['null'],
|
||||
'default' => $val['default'],
|
||||
'primary' => (strtolower($val['key']) == 'pri'),
|
||||
'autoinc' => (strtolower($val['extra']) == 'auto_increment'),
|
||||
'primary' => strtolower($val['key']) == 'pri',
|
||||
'autoinc' => strtolower($val['extra']) == 'auto_increment',
|
||||
'comment' => $val['comment'],
|
||||
];
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ class BelongsTo extends OneToOne
|
||||
if ($relationModel) {
|
||||
if (!empty($this->bindAttr)) {
|
||||
// 绑定关联属性
|
||||
$this->bindAttr($relationModel, $this->parent);
|
||||
$this->bindAttr($this->parent, $relationModel);
|
||||
}
|
||||
|
||||
$relationModel->setParent(clone $this->parent);
|
||||
@ -233,9 +233,9 @@ class BelongsTo extends OneToOne
|
||||
$relationModel->exists(true);
|
||||
}
|
||||
|
||||
if ($relationModel && !empty($this->bindAttr)) {
|
||||
if (!empty($this->bindAttr)) {
|
||||
// 绑定关联属性
|
||||
$this->bindAttr($relationModel, $result);
|
||||
$this->bindAttr($result, $relationModel);
|
||||
} else {
|
||||
// 设置关联属性
|
||||
$result->setRelation($relation, $relationModel);
|
||||
@ -274,9 +274,9 @@ class BelongsTo extends OneToOne
|
||||
$relationModel->exists(true);
|
||||
}
|
||||
|
||||
if ($relationModel && !empty($this->bindAttr)) {
|
||||
if (!empty($this->bindAttr)) {
|
||||
// 绑定关联属性
|
||||
$this->bindAttr($relationModel, $result);
|
||||
$this->bindAttr($result, $relationModel);
|
||||
} else {
|
||||
// 设置关联属性
|
||||
$result->setRelation($relation, $relationModel);
|
||||
|
@ -16,7 +16,6 @@ use think\Collection;
|
||||
use think\db\BaseQuery as Query;
|
||||
use think\db\exception\DbException as Exception;
|
||||
use think\db\Raw;
|
||||
use think\helper\Str;
|
||||
use think\Model;
|
||||
use think\model\Pivot;
|
||||
use think\model\Relation;
|
||||
@ -146,22 +145,6 @@ class BelongsToMany extends Relation
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建关联查询Query对象
|
||||
* @access protected
|
||||
* @return Query
|
||||
*/
|
||||
protected function buildQuery(): Query
|
||||
{
|
||||
$foreignKey = $this->foreignKey;
|
||||
$localKey = $this->localKey;
|
||||
|
||||
// 关联查询
|
||||
$condition = ['pivot.' . $localKey, '=', $this->parent->getKey()];
|
||||
|
||||
return $this->belongsToManyQuery($foreignKey, $localKey, [$condition]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 延迟获取关联数据
|
||||
* @access public
|
||||
@ -175,8 +158,7 @@ class BelongsToMany extends Relation
|
||||
$closure($this->getClosureType($closure));
|
||||
}
|
||||
|
||||
$result = $this->buildQuery()
|
||||
->relation($subRelation)
|
||||
$result = $this->relation($subRelation)
|
||||
->select()
|
||||
->setParent(clone $this->parent);
|
||||
|
||||
@ -193,7 +175,8 @@ class BelongsToMany extends Relation
|
||||
*/
|
||||
public function select($data = null): Collection
|
||||
{
|
||||
$result = $this->buildQuery()->select($data);
|
||||
$this->baseQuery();
|
||||
$result = $this->query->select($data);
|
||||
$this->hydratePivot($result);
|
||||
|
||||
return $result;
|
||||
@ -208,7 +191,8 @@ class BelongsToMany extends Relation
|
||||
*/
|
||||
public function paginate($listRows = null, $simple = false): Paginator
|
||||
{
|
||||
$result = $this->buildQuery()->paginate($listRows, $simple);
|
||||
$this->baseQuery();
|
||||
$result = $this->query->paginate($listRows, $simple);
|
||||
$this->hydratePivot($result);
|
||||
|
||||
return $result;
|
||||
@ -222,37 +206,16 @@ class BelongsToMany extends Relation
|
||||
*/
|
||||
public function find($data = null)
|
||||
{
|
||||
$result = $this->buildQuery()->findOrEmpty($data);
|
||||
$this->baseQuery();
|
||||
$result = $this->query->find($data);
|
||||
|
||||
if (!$result->isEmpty()) {
|
||||
if ($result && !$result->isEmpty()) {
|
||||
$this->hydratePivot([$result]);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找多条记录 如果不存在则抛出异常
|
||||
* @access public
|
||||
* @param array|string|Query|\Closure $data
|
||||
* @return Collection
|
||||
*/
|
||||
public function selectOrFail($data = null): Collection
|
||||
{
|
||||
return $this->buildQuery()->failException(true)->select($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找单条记录 如果不存在则抛出异常
|
||||
* @access public
|
||||
* @param array|string|Query|\Closure $data
|
||||
* @return Model
|
||||
*/
|
||||
public function findOrFail($data = null): Model
|
||||
{
|
||||
return $this->buildQuery()->failException(true)->find($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据关联条件查询当前模型
|
||||
* @access public
|
||||
@ -485,17 +448,13 @@ class BelongsToMany extends Relation
|
||||
$this->query->limit($this->withLimit);
|
||||
}
|
||||
|
||||
$query = $this->query
|
||||
$this->query
|
||||
->field($fields)
|
||||
->tableField(true, $table, 'pivot', 'pivot__');
|
||||
->tableField(true, $table, 'pivot', 'pivot__')
|
||||
->join([$table => 'pivot'], 'pivot.' . $foreignKey . '=' . $tableName . '.' . $this->query->getPk())
|
||||
->where($condition);
|
||||
|
||||
if (empty($this->baseQuery)) {
|
||||
$relationFk = $this->query->getPk();
|
||||
$query->join([$table => 'pivot'], 'pivot.' . $foreignKey . '=' . $tableName . '.' . $relationFk)
|
||||
->where($condition);
|
||||
}
|
||||
|
||||
return $query;
|
||||
return $this->query;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -695,4 +654,24 @@ class BelongsToMany extends Relation
|
||||
return $changes;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行基础查询(仅执行一次)
|
||||
* @access protected
|
||||
* @return void
|
||||
*/
|
||||
protected function baseQuery(): void
|
||||
{
|
||||
if (empty($this->baseQuery)) {
|
||||
$foreignKey = $this->foreignKey;
|
||||
$localKey = $this->localKey;
|
||||
|
||||
// 关联查询
|
||||
$condition = ['pivot.' . $localKey, '=', $this->parent->getKey()];
|
||||
|
||||
$this->belongsToManyQuery($foreignKey, $localKey, [$condition]);
|
||||
|
||||
$this->baseQuery = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ class HasOne extends OneToOne
|
||||
if ($relationModel) {
|
||||
if (!empty($this->bindAttr)) {
|
||||
// 绑定关联属性
|
||||
$this->bindAttr($relationModel, $this->parent);
|
||||
$this->bindAttr($this->parent, $relationModel);
|
||||
}
|
||||
|
||||
$relationModel->setParent(clone $this->parent);
|
||||
@ -232,9 +232,9 @@ class HasOne extends OneToOne
|
||||
$relationModel->exists(true);
|
||||
}
|
||||
|
||||
if ($relationModel && !empty($this->bindAttr)) {
|
||||
if (!empty($this->bindAttr)) {
|
||||
// 绑定关联属性
|
||||
$this->bindAttr($relationModel, $result);
|
||||
$this->bindAttr($result, $relationModel);
|
||||
} else {
|
||||
// 设置关联属性
|
||||
$result->setRelation($relation, $relationModel);
|
||||
@ -273,9 +273,9 @@ class HasOne extends OneToOne
|
||||
$relationModel->exists(true);
|
||||
}
|
||||
|
||||
if ($relationModel && !empty($this->bindAttr)) {
|
||||
if (!empty($this->bindAttr)) {
|
||||
// 绑定关联属性
|
||||
$this->bindAttr($relationModel, $result);
|
||||
$this->bindAttr($result, $relationModel);
|
||||
} else {
|
||||
$result->setRelation($relation, $relationModel);
|
||||
}
|
||||
|
@ -12,11 +12,11 @@
|
||||
namespace think\model\relation;
|
||||
|
||||
use Closure;
|
||||
use Exception;
|
||||
use think\db\BaseQuery as Query;
|
||||
use think\db\Raw;
|
||||
use think\helper\Str;
|
||||
use think\Model;
|
||||
use think\model\Relation;
|
||||
use think\model\Pivot;
|
||||
|
||||
/**
|
||||
* 多态多对多关联
|
||||
@ -24,12 +24,6 @@ use think\model\Relation;
|
||||
class MorphToMany extends BelongsToMany
|
||||
{
|
||||
|
||||
/**
|
||||
* 多态关联外键
|
||||
* @var string
|
||||
*/
|
||||
protected $morphKey;
|
||||
|
||||
/**
|
||||
* 多态字段名
|
||||
* @var string
|
||||
@ -61,12 +55,14 @@ class MorphToMany extends BelongsToMany
|
||||
*/
|
||||
public function __construct(Model $parent, string $model, string $middle, string $morphType, string $morphKey, string $localKey, bool $inverse = false)
|
||||
{
|
||||
$this->morphKey = $morphKey;
|
||||
$this->morphType = $morphType;
|
||||
$this->inverse = $inverse;
|
||||
$this->morphClass = $inverse ? $model : get_class($parent);
|
||||
|
||||
parent::__construct($parent, $model, $middle, $morphKey, $localKey);
|
||||
$foreignKey = $inverse ? $morphKey : $localKey;
|
||||
$localKey = $inverse ? $localKey : $morphKey;
|
||||
|
||||
parent::__construct($parent, $model, $middle, $foreignKey, $localKey);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -94,7 +90,7 @@ class MorphToMany extends BelongsToMany
|
||||
if (!empty($range)) {
|
||||
// 查询关联数据
|
||||
$data = $this->eagerlyManyToMany([
|
||||
['pivot.' . $this->morphKey, 'in', $range],
|
||||
['pivot.' . $this->localKey, 'in', $range],
|
||||
['pivot.' . $this->morphType, '=', $this->morphClass],
|
||||
], $subRelation, $closure, $cache);
|
||||
|
||||
@ -127,7 +123,7 @@ class MorphToMany extends BelongsToMany
|
||||
$pk = $result->$pk;
|
||||
// 查询管理数据
|
||||
$data = $this->eagerlyManyToMany([
|
||||
['pivot.' . $this->morphKey, '=', $pk],
|
||||
['pivot.' . $this->localKey, '=', $pk],
|
||||
['pivot.' . $this->morphType, '=', $this->morphClass],
|
||||
], $subRelation, $closure, $cache);
|
||||
|
||||
@ -164,8 +160,8 @@ class MorphToMany extends BelongsToMany
|
||||
$closure($this->getClosureType($closure), $name);
|
||||
}
|
||||
|
||||
return $this->belongsToManyQuery($this->morphKey, $this->localKey, [
|
||||
['pivot.' . ($this->inverse ? $this->localKey : $this->morphKey), '=', $pk],
|
||||
return $this->belongsToManyQuery($this->foreignKey, $this->localKey, [
|
||||
['pivot.' . $this->localKey, '=', $pk],
|
||||
['pivot.' . $this->morphType, '=', $this->morphClass],
|
||||
])->$aggregate($field);
|
||||
}
|
||||
@ -185,8 +181,8 @@ class MorphToMany extends BelongsToMany
|
||||
$closure($this->getClosureType($closure), $name);
|
||||
}
|
||||
|
||||
return $this->belongsToManyQuery($this->morphKey, $this->localKey, [
|
||||
['pivot.' . ($this->inverse ? $this->localKey : $this->morphKey), 'exp', new Raw('=' . $this->parent->db(false)->getTable() . '.' . $this->parent->getPk())],
|
||||
return $this->belongsToManyQuery($this->foreignKey, $this->localKey, [
|
||||
['pivot.' . $this->localKey, 'exp', new Raw('=' . $this->parent->db(false)->getTable() . '.' . $this->parent->getPk())],
|
||||
['pivot.' . $this->morphType, '=', $this->morphClass],
|
||||
])->fetchSql()->$aggregate($field);
|
||||
}
|
||||
@ -239,7 +235,7 @@ class MorphToMany extends BelongsToMany
|
||||
}
|
||||
|
||||
// 预载入关联查询 支持嵌套预载入
|
||||
$list = $this->belongsToManyQuery($this->morphKey, $this->localKey, $where)
|
||||
$list = $this->belongsToManyQuery($this->foreignKey, $this->localKey, $where)
|
||||
->with($subRelation)
|
||||
->cache($cache[0] ?? false, $cache[1] ?? null, $cache[2] ?? null)
|
||||
->select();
|
||||
@ -258,7 +254,7 @@ class MorphToMany extends BelongsToMany
|
||||
}
|
||||
}
|
||||
|
||||
$key = $pivot[$this->morphKey];
|
||||
$key = $pivot[$this->localKey];
|
||||
|
||||
if ($this->withLimit && isset($data[$key]) && count($data[$key]) >= $this->withLimit) {
|
||||
continue;
|
||||
@ -278,7 +274,6 @@ class MorphToMany extends BelongsToMany
|
||||
* @param mixed $data 数据 可以使用数组、关联模型对象 或者 关联对象的主键
|
||||
* @param array $pivot 中间表额外数据
|
||||
* @return array|Pivot
|
||||
* @throws Exception
|
||||
*/
|
||||
public function attach($data, array $pivot = [])
|
||||
{
|
||||
@ -290,23 +285,24 @@ class MorphToMany extends BelongsToMany
|
||||
$model = new $this->model;
|
||||
$id = $model->insertGetId($data);
|
||||
}
|
||||
} elseif (is_numeric($data) || is_string($data)) {
|
||||
} else if (is_numeric($data) || is_string($data)) {
|
||||
// 根据关联表主键直接写入中间表
|
||||
$id = $data;
|
||||
} elseif ($data instanceof Model) {
|
||||
} else if ($data instanceof Model) {
|
||||
// 根据关联表主键直接写入中间表
|
||||
$id = $data->getKey();
|
||||
}
|
||||
|
||||
if (!empty($id)) {
|
||||
// 保存中间表数据
|
||||
$pivot[$this->inverse ? $this->localKey : $this->morphKey] = $this->parent->getKey();
|
||||
|
||||
$pivot[$this->localKey] = $this->parent->getKey();
|
||||
$pivot[$this->morphType] = $this->morphClass;
|
||||
$ids = (array) $id;
|
||||
|
||||
$result = [];
|
||||
|
||||
foreach ($ids as $id) {
|
||||
$pivot[$this->inverse ? $this->morphKey : $this->localKey] = $id;
|
||||
$pivot[$this->foreignKey] = $id;
|
||||
|
||||
$this->pivot->replace()
|
||||
->exists(false)
|
||||
@ -341,9 +337,9 @@ class MorphToMany extends BelongsToMany
|
||||
}
|
||||
|
||||
$pivot = $this->pivot
|
||||
->where($this->inverse ? $this->localKey : $this->morphKey, $this->parent->getKey())
|
||||
->where($this->localKey, $this->parent->getKey())
|
||||
->where($this->morphType, $this->morphClass)
|
||||
->where($this->inverse ? $this->morphKey : $this->localKey, $id)
|
||||
->where($this->foreignKey, $id)
|
||||
->find();
|
||||
|
||||
return $pivot ?: false;
|
||||
@ -360,22 +356,22 @@ class MorphToMany extends BelongsToMany
|
||||
{
|
||||
if (is_array($data)) {
|
||||
$id = $data;
|
||||
} elseif (is_numeric($data) || is_string($data)) {
|
||||
} else if (is_numeric($data) || is_string($data)) {
|
||||
// 根据关联表主键直接写入中间表
|
||||
$id = $data;
|
||||
} elseif ($data instanceof Model) {
|
||||
} else if ($data instanceof Model) {
|
||||
// 根据关联表主键直接写入中间表
|
||||
$id = $data->getKey();
|
||||
}
|
||||
|
||||
// 删除中间表数据
|
||||
$pivot = [
|
||||
[$this->inverse ? $this->localKey : $this->morphKey, '=', $this->parent->getKey()],
|
||||
[$this->localKey, '=', $this->parent->getKey()],
|
||||
[$this->morphType, '=', $this->morphClass],
|
||||
];
|
||||
|
||||
if (isset($id)) {
|
||||
$pivot[] = [$this->inverse ? $this->morphKey : $this->localKey, is_array($id) ? 'in' : '=', $id];
|
||||
$pivot[] = [$this->foreignKey, is_array($id) ? 'in' : '=', $id];
|
||||
}
|
||||
|
||||
$result = $this->pivot->where($pivot)->delete();
|
||||
@ -405,9 +401,9 @@ class MorphToMany extends BelongsToMany
|
||||
];
|
||||
|
||||
$current = $this->pivot
|
||||
->where($this->inverse ? $this->localKey : $this->morphKey, $this->parent->getKey())
|
||||
->where($this->localKey, $this->parent->getKey())
|
||||
->where($this->morphType, $this->morphClass)
|
||||
->column($this->inverse ? $this->morphKey : $this->localKey);
|
||||
->column($this->foreignKey);
|
||||
|
||||
$records = [];
|
||||
|
||||
@ -430,7 +426,7 @@ class MorphToMany extends BelongsToMany
|
||||
if (!in_array($id, $current)) {
|
||||
$this->attach($id, $attributes);
|
||||
$changes['attached'][] = $id;
|
||||
} elseif (count($attributes) > 0 && $this->attach($id, $attributes)) {
|
||||
} else if (count($attributes) > 0 && $this->attach($id, $attributes)) {
|
||||
$changes['updated'][] = $id;
|
||||
}
|
||||
}
|
||||
@ -438,22 +434,6 @@ class MorphToMany extends BelongsToMany
|
||||
return $changes;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建关联查询Query对象
|
||||
* @access protected
|
||||
* @return Query
|
||||
*/
|
||||
protected function buildQuery(): Query
|
||||
{
|
||||
// 关联查询
|
||||
$condition = [
|
||||
['pivot.' . $this->morphKey, '=', $this->parent->getKey()],
|
||||
['pivot.' . $this->morphType, '=', $this->morphClass],
|
||||
];
|
||||
|
||||
return $this->belongsToManyQuery($this->morphKey, $this->localKey, $condition);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行基础查询(仅执行一次)
|
||||
* @access protected
|
||||
@ -461,10 +441,14 @@ class MorphToMany extends BelongsToMany
|
||||
*/
|
||||
protected function baseQuery(): void
|
||||
{
|
||||
if (empty($this->baseQuery) && $this->parent->getData()) {
|
||||
$this->query->where([
|
||||
[$this->morphKey, '=', $this->parent->getKey()],
|
||||
[$this->morphType, '=', $this->morphClass],
|
||||
if (empty($this->baseQuery)) {
|
||||
$foreignKey = $this->foreignKey;
|
||||
$localKey = $this->localKey;
|
||||
|
||||
// 关联查询
|
||||
$this->belongsToManyQuery($foreignKey, $localKey, [
|
||||
['pivot.' . $localKey, '=', $this->parent->getKey()],
|
||||
['pivot.' . $this->morphType, '=', $this->morphClass],
|
||||
]);
|
||||
|
||||
$this->baseQuery = true;
|
||||
|
@ -253,8 +253,8 @@ abstract class OneToOne extends Relation
|
||||
$relationModel->exists(true);
|
||||
}
|
||||
|
||||
if ($relationModel && !empty($this->bindAttr)) {
|
||||
$this->bindAttr($relationModel, $result);
|
||||
if (!empty($this->bindAttr)) {
|
||||
$this->bindAttr($result, $relationModel);
|
||||
}
|
||||
} else {
|
||||
$relationModel = null;
|
||||
@ -266,12 +266,12 @@ abstract class OneToOne extends Relation
|
||||
/**
|
||||
* 绑定关联属性到父模型
|
||||
* @access protected
|
||||
* @param Model $model 关联模型对象
|
||||
* @param Model $result 父模型对象
|
||||
* @param Model $model 关联模型对象
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function bindAttr(Model $model, Model $result): void
|
||||
protected function bindAttr(Model $result, Model $model = null): void
|
||||
{
|
||||
foreach ($this->bindAttr as $key => $attr) {
|
||||
$key = is_numeric($key) ? $attr : $key;
|
||||
|
@ -13,32 +13,41 @@
|
||||
// | github 代码仓库:https://github.com/zoujingli/ThinkLibrary
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\admin\service;
|
||||
namespace think\admin;
|
||||
|
||||
use think\admin\Service;
|
||||
use ZipArchive;
|
||||
|
||||
/**
|
||||
* 应用模块安装服务
|
||||
* Class ModuleService
|
||||
* @package think\admin\service
|
||||
* Class Module
|
||||
* @package think\admin
|
||||
*/
|
||||
class ModuleService extends Service
|
||||
abstract class Module extends Service
|
||||
{
|
||||
abstract public function getName();
|
||||
|
||||
abstract public function getTitle();
|
||||
|
||||
abstract public function getRemark();
|
||||
|
||||
abstract public function getVersion();
|
||||
|
||||
abstract public function callUpdate();
|
||||
|
||||
abstract public function callInstall();
|
||||
|
||||
/**
|
||||
* 安装应用模块
|
||||
* @param string $name 模块名称
|
||||
* @param ZipArchive $file 安装包
|
||||
* @param ZipArchive $zip 安装包
|
||||
* @return array
|
||||
*/
|
||||
public function install(string $name, ZipArchive $file): array
|
||||
protected function _install(ZipArchive $zip): array
|
||||
{
|
||||
// 安装包检查
|
||||
list($state, $message) = $this->checkInstall($name, $file);
|
||||
list($state, $message) = $this->_checkzip($zip);
|
||||
if (empty($state)) return [$state, $message];
|
||||
// 执行文件安装
|
||||
if ($file->extractTo($this->app->getBasePath() . $name)) {
|
||||
if ($zip->extractTo($this->app->getBasePath() . $this->getName())) {
|
||||
return [1, '应用模块安装成功'];
|
||||
} else {
|
||||
return [0, '应用模块安装失败'];
|
||||
@ -47,12 +56,11 @@ class ModuleService extends Service
|
||||
|
||||
/**
|
||||
* 移除应用模块
|
||||
* @param string $name 模块名称
|
||||
* @return array
|
||||
*/
|
||||
public function remove(string $name): array
|
||||
protected function _remove(): array
|
||||
{
|
||||
$directory = $this->app->getBasePath() . $name;
|
||||
$directory = $this->app->getBasePath() . $this->getName();
|
||||
if (file_exists($directory) && is_dir($directory)) {
|
||||
return [0, '提交移除应用模块指令成功'];
|
||||
} else {
|
||||
@ -62,41 +70,44 @@ class ModuleService extends Service
|
||||
|
||||
/**
|
||||
* 检测安装包是否正常
|
||||
* @param string $name 模块名称
|
||||
* @param ZipArchive $file 安装包
|
||||
* @param ZipArchive $zip 安装包
|
||||
* @return array
|
||||
*/
|
||||
private function checkInstall(string $name, ZipArchive $file): array
|
||||
protected function _checkzip(ZipArchive $zip): array
|
||||
{
|
||||
$directory = "{$file->filename}.files";
|
||||
$directory = "{$zip->filename}.files";
|
||||
file_exists($directory) || mkdir($directory, 0755, true);
|
||||
// 尝试解压应用安装包
|
||||
if ($file->extractTo($directory) === false) {
|
||||
// 尝试解压应用包
|
||||
if ($zip->extractTo($directory) === false) {
|
||||
return [0, '应用模块压缩文件解压失败'];
|
||||
}
|
||||
// 检测应用模块配置文件
|
||||
// 检测应用配置文件
|
||||
$info = @include($directory . DIRECTORY_SEPARATOR . 'app.php');
|
||||
$this->forceRemove($directory);
|
||||
// 删除临时解压的文件
|
||||
$this->_forceRemove($directory);
|
||||
// 返回应用模块检查结果
|
||||
if (empty($info)) return [0, '未获取到应用模块配置信息'];
|
||||
if ($info['name'] !== $name) return [0, '应用模块名称与注册名称不一致'];
|
||||
return [1, '应用模块基础检查通过'];
|
||||
if (empty($info)) {
|
||||
return [0, '未获取到应用模块配置信息'];
|
||||
} elseif ($info['name'] !== $this->getName()) {
|
||||
return [0, '应用模块名称与注册名称不一致'];
|
||||
} else {
|
||||
return [1, '应用模块基础检查通过'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 强制删除指定的目录
|
||||
* @param string $directory
|
||||
*/
|
||||
private function forceRemove(string $directory)
|
||||
private function _forceRemove(string $directory)
|
||||
{
|
||||
if (file_exists($directory) && is_dir($directory) && $handle = opendir($directory)) {
|
||||
while (false !== ($item = readdir($handle))) if (!in_array($item, ['.', '..'])) {
|
||||
$this->forceRemove("{$directory}/{$item}");
|
||||
$this->_forceRemove("{$directory}/{$item}");
|
||||
}
|
||||
[closedir($handle), rmdir($directory)];
|
||||
} else {
|
||||
file_exists($directory) && is_file($directory) && @unlink($directory);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -25,12 +25,6 @@ use think\db\Query;
|
||||
*/
|
||||
class DeleteHelper extends Helper
|
||||
{
|
||||
/**
|
||||
* 表单额外更新条件
|
||||
* @var array
|
||||
*/
|
||||
protected $where;
|
||||
|
||||
/**
|
||||
* 数据对象主键名称
|
||||
* @var string
|
||||
@ -53,18 +47,22 @@ class DeleteHelper extends Helper
|
||||
*/
|
||||
public function init($dbQuery, $field = '', $where = [])
|
||||
{
|
||||
$this->where = $where;
|
||||
$this->query = $this->buildQuery($dbQuery);
|
||||
$this->field = $field ?: $this->query->getPk();
|
||||
$this->value = $this->app->request->post($this->field, null);
|
||||
// 主键限制处理
|
||||
if (!isset($this->where[$this->field]) && is_string($this->value)) {
|
||||
// 查询限制处理
|
||||
if (!empty($where)) $this->query->where($where);
|
||||
if (!isset($where[$this->field]) && is_string($this->value)) {
|
||||
$this->query->whereIn($this->field, explode(',', $this->value));
|
||||
}
|
||||
// 前置回调处理
|
||||
if (false === $this->controller->callback('_delete_filter', $this->query, $this->where)) {
|
||||
if (false === $this->controller->callback('_delete_filter', $this->query, $where)) {
|
||||
return null;
|
||||
}
|
||||
// 阻止危险操作
|
||||
if (!$this->query->getOptions('where')) {
|
||||
$this->controller->error(lang('think_library_delete_error'));
|
||||
}
|
||||
// 组装执行数据
|
||||
$data = [];
|
||||
if (method_exists($this->query, 'getTableFields')) {
|
||||
@ -72,23 +70,17 @@ class DeleteHelper extends Helper
|
||||
if (in_array('deleted', $fields)) $data['deleted'] = 1;
|
||||
if (in_array('is_deleted', $fields)) $data['is_deleted'] = 1;
|
||||
}
|
||||
if (!empty($this->where)) $this->query->where($this->where);
|
||||
// 阻止危险操作
|
||||
if (!$this->query->getOptions('where')) {
|
||||
$this->controller->error(lang('think_library_delete_error'));
|
||||
}
|
||||
// 执行删除操作
|
||||
$result = empty($data) ? $this->query->delete() : $this->query->update($data);
|
||||
// 结果回调处理
|
||||
if (false === $this->controller->callback('_delete_result', $result)) {
|
||||
return $result;
|
||||
}
|
||||
// 回复前端结果
|
||||
// 回复返回结果
|
||||
if ($result !== false) {
|
||||
$this->controller->success(lang('think_library_delete_success'), '');
|
||||
} else {
|
||||
$this->controller->error(lang('think_library_delete_error'));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user