ComposerUpdate

This commit is contained in:
Anyon 2019-12-24 17:22:36 +08:00
parent 9890c4891f
commit 8cd55cb49d
38 changed files with 484 additions and 356 deletions

28
composer.lock generated
View File

@ -558,16 +558,16 @@
}, },
{ {
"name": "topthink/framework", "name": "topthink/framework",
"version": "v6.0.0", "version": "v6.0.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/top-think/framework.git", "url": "https://github.com/top-think/framework.git",
"reference": "79c555aab0313d1a33ddcdb3c395f2c47f37f597" "reference": "501f3dd17dc6266e17b7d8df3e9fd090bd2cc85f"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/top-think/framework/zipball/79c555aab0313d1a33ddcdb3c395f2c47f37f597", "url": "https://api.github.com/repos/top-think/framework/zipball/501f3dd17dc6266e17b7d8df3e9fd090bd2cc85f",
"reference": "79c555aab0313d1a33ddcdb3c395f2c47f37f597", "reference": "501f3dd17dc6266e17b7d8df3e9fd090bd2cc85f",
"shasum": "", "shasum": "",
"mirrors": [ "mirrors": [
{ {
@ -622,7 +622,7 @@
"orm", "orm",
"thinkphp" "thinkphp"
], ],
"time": "2019-10-23T23:28:43+00:00" "time": "2019-12-24T07:57:03+00:00"
}, },
{ {
"name": "topthink/think-helper", "name": "topthink/think-helper",
@ -721,16 +721,16 @@
}, },
{ {
"name": "topthink/think-orm", "name": "topthink/think-orm",
"version": "v2.0.28", "version": "v2.0.29",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/top-think/think-orm.git", "url": "https://github.com/top-think/think-orm.git",
"reference": "ff5f112f5559497222f2716385b5a709ab82741b" "reference": "37cde31af3725cf5460ad8dc18032326b88e6310"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/top-think/think-orm/zipball/ff5f112f5559497222f2716385b5a709ab82741b", "url": "https://api.github.com/repos/top-think/think-orm/zipball/37cde31af3725cf5460ad8dc18032326b88e6310",
"reference": "ff5f112f5559497222f2716385b5a709ab82741b", "reference": "37cde31af3725cf5460ad8dc18032326b88e6310",
"shasum": "", "shasum": "",
"mirrors": [ "mirrors": [
{ {
@ -768,7 +768,7 @@
"database", "database",
"orm" "orm"
], ],
"time": "2019-11-17T07:53:45+00:00" "time": "2019-12-23T13:50:01+00:00"
}, },
{ {
"name": "topthink/think-template", "name": "topthink/think-template",
@ -909,12 +909,12 @@
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/zoujingli/ThinkLibrary.git", "url": "https://github.com/zoujingli/ThinkLibrary.git",
"reference": "60807fa6416e2b9d30ee785d37c0e90f4eab5ea2" "reference": "9952e50062d5d8f447680cea4a557155b7353158"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/zoujingli/ThinkLibrary/zipball/60807fa6416e2b9d30ee785d37c0e90f4eab5ea2", "url": "https://api.github.com/repos/zoujingli/ThinkLibrary/zipball/9952e50062d5d8f447680cea4a557155b7353158",
"reference": "60807fa6416e2b9d30ee785d37c0e90f4eab5ea2", "reference": "9952e50062d5d8f447680cea4a557155b7353158",
"shasum": "", "shasum": "",
"mirrors": [ "mirrors": [
{ {
@ -958,7 +958,7 @@
], ],
"description": "ThinkPHP v6.0 Development Library", "description": "ThinkPHP v6.0 Development Library",
"homepage": "http://framework.thinkadmin.top", "homepage": "http://framework.thinkadmin.top",
"time": "2019-12-23T09:51:18+00:00" "time": "2019-12-24T02:28:27+00:00"
}, },
{ {
"name": "zoujingli/wechat-developer", "name": "zoujingli/wechat-developer",

View File

@ -569,17 +569,17 @@
}, },
{ {
"name": "topthink/framework", "name": "topthink/framework",
"version": "v6.0.0", "version": "v6.0.1",
"version_normalized": "6.0.0.0", "version_normalized": "6.0.1.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/top-think/framework.git", "url": "https://github.com/top-think/framework.git",
"reference": "79c555aab0313d1a33ddcdb3c395f2c47f37f597" "reference": "501f3dd17dc6266e17b7d8df3e9fd090bd2cc85f"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/top-think/framework/zipball/79c555aab0313d1a33ddcdb3c395f2c47f37f597", "url": "https://api.github.com/repos/top-think/framework/zipball/501f3dd17dc6266e17b7d8df3e9fd090bd2cc85f",
"reference": "79c555aab0313d1a33ddcdb3c395f2c47f37f597", "reference": "501f3dd17dc6266e17b7d8df3e9fd090bd2cc85f",
"shasum": "", "shasum": "",
"mirrors": [ "mirrors": [
{ {
@ -606,7 +606,7 @@
"mockery/mockery": "^1.2", "mockery/mockery": "^1.2",
"phpunit/phpunit": "^7.0" "phpunit/phpunit": "^7.0"
}, },
"time": "2019-10-23T23:28:43+00:00", "time": "2019-12-24T07:57:03+00:00",
"type": "library", "type": "library",
"installation-source": "dist", "installation-source": "dist",
"autoload": { "autoload": {
@ -738,17 +738,17 @@
}, },
{ {
"name": "topthink/think-orm", "name": "topthink/think-orm",
"version": "v2.0.28", "version": "v2.0.29",
"version_normalized": "2.0.28.0", "version_normalized": "2.0.29.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/top-think/think-orm.git", "url": "https://github.com/top-think/think-orm.git",
"reference": "ff5f112f5559497222f2716385b5a709ab82741b" "reference": "37cde31af3725cf5460ad8dc18032326b88e6310"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/top-think/think-orm/zipball/ff5f112f5559497222f2716385b5a709ab82741b", "url": "https://api.github.com/repos/top-think/think-orm/zipball/37cde31af3725cf5460ad8dc18032326b88e6310",
"reference": "ff5f112f5559497222f2716385b5a709ab82741b", "reference": "37cde31af3725cf5460ad8dc18032326b88e6310",
"shasum": "", "shasum": "",
"mirrors": [ "mirrors": [
{ {
@ -764,7 +764,7 @@
"psr/simple-cache": "^1.0", "psr/simple-cache": "^1.0",
"topthink/think-helper": "^3.1" "topthink/think-helper": "^3.1"
}, },
"time": "2019-11-17T07:53:45+00:00", "time": "2019-12-23T13:50:01+00:00",
"type": "library", "type": "library",
"installation-source": "dist", "installation-source": "dist",
"autoload": { "autoload": {
@ -935,12 +935,12 @@
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/zoujingli/ThinkLibrary.git", "url": "https://github.com/zoujingli/ThinkLibrary.git",
"reference": "60807fa6416e2b9d30ee785d37c0e90f4eab5ea2" "reference": "9952e50062d5d8f447680cea4a557155b7353158"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/zoujingli/ThinkLibrary/zipball/60807fa6416e2b9d30ee785d37c0e90f4eab5ea2", "url": "https://api.github.com/repos/zoujingli/ThinkLibrary/zipball/9952e50062d5d8f447680cea4a557155b7353158",
"reference": "60807fa6416e2b9d30ee785d37c0e90f4eab5ea2", "reference": "9952e50062d5d8f447680cea4a557155b7353158",
"shasum": "", "shasum": "",
"mirrors": [ "mirrors": [
{ {
@ -956,7 +956,7 @@
"ext-json": "*", "ext-json": "*",
"topthink/framework": "^6.0" "topthink/framework": "^6.0"
}, },
"time": "2019-12-23T09:51:18+00:00", "time": "2019-12-24T02:28:27+00:00",
"type": "library", "type": "library",
"extra": { "extra": {
"think": { "think": {

2
vendor/services.php vendored
View File

@ -1,5 +1,5 @@
<?php <?php
// This file is automatically generated at:2019-12-23 18:34:59 // This file is automatically generated at:2019-12-24 17:22:31
declare (strict_types = 1); declare (strict_types = 1);
return array ( return array (
0 => 'think\\app\\Service', 0 => 'think\\app\\Service',

View File

@ -38,7 +38,7 @@ ThinkPHP6.0底层架构采用PHP7.1改写和进一步优化。
## 安装 ## 安装
~~~ ~~~
composer create-project topthink/think tp 6.0.*-dev composer create-project topthink/think tp
~~~ ~~~
启动服务 启动服务

View File

@ -370,7 +370,7 @@ if (!function_exists('redirect')) {
* @param int $code 状态码 * @param int $code 状态码
* @return \think\response\Redirect * @return \think\response\Redirect
*/ */
function redirect(string $url, int $code = 302): Redirect function redirect(string $url = '', int $code = 302): Redirect
{ {
return Response::create($url, 'redirect', $code); return Response::create($url, 'redirect', $code);
} }
@ -523,7 +523,7 @@ if (!function_exists('validate')) {
} else { } else {
if (strpos($validate, '.')) { if (strpos($validate, '.')) {
// 支持场景 // 支持场景
list($validate, $scene) = explode('.', $validate); [$validate, $scene] = explode('.', $validate);
} }
$class = false !== strpos($validate, '\\') ? $validate : app()->parseClass('validate', $validate); $class = false !== strpos($validate, '\\') ? $validate : app()->parseClass('validate', $validate);

View File

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

View File

@ -304,7 +304,8 @@ class Container implements ContainerInterface, ArrayAccess, IteratorAggregate, C
{ {
if (is_array($method)) { if (is_array($method)) {
[$class, $method] = $method; [$class, $method] = $method;
$class = is_object($class) ? $class : $this->invokeClass($class);
$class = is_object($class) ? $class : $this->invokeClass($class);
} else { } else {
// 静态方法 // 静态方法
[$class, $method] = explode('::', $method); [$class, $method] = explode('::', $method);
@ -314,8 +315,7 @@ class Container implements ContainerInterface, ArrayAccess, IteratorAggregate, C
$reflect = new ReflectionMethod($class, $method); $reflect = new ReflectionMethod($class, $method);
} catch (ReflectionException $e) { } catch (ReflectionException $e) {
$class = is_object($class) ? get_class($class) : $class; $class = is_object($class) ? get_class($class) : $class;
$message = sprintf('method not exists: %d::%d()', $class, $method); throw new FuncNotFoundException('method not exists: ' . $class . '::' . $method . '()', "{$class}::{$method}", $e);
throw new FuncNotFoundException($message, "{$class}::{$method}", $e);
} }
$args = $this->bindParams($reflect, $vars); $args = $this->bindParams($reflect, $vars);

View File

@ -35,6 +35,8 @@ class Cookie
'secure' => false, 'secure' => false,
// httponly设置 // httponly设置
'httponly' => false, 'httponly' => false,
// samesite 设置,支持 'strict' 'lax'
'samesite' => '',
]; ];
/** /**
@ -181,9 +183,18 @@ class Cookie
public function save(): void public function save(): void
{ {
foreach ($this->cookie as $name => $val) { foreach ($this->cookie as $name => $val) {
list($value, $expire, $option) = $val; [$value, $expire, $option] = $val;
$this->saveCookie($name, $value, $expire, $option['path'], $option['domain'], $option['secure'] ? true : false, $option['httponly'] ? true : false); $this->saveCookie(
$name,
$value,
$expire,
$option['path'],
$option['domain'],
$option['secure'] ? true : false,
$option['httponly'] ? true : false,
$option['samesite']
);
} }
} }
@ -197,11 +208,23 @@ class Cookie
* @param string $domain 有效域名/子域名 * @param string $domain 有效域名/子域名
* @param bool $secure 是否仅仅通过HTTPS * @param bool $secure 是否仅仅通过HTTPS
* @param bool $httponly 仅可通过HTTP访问 * @param bool $httponly 仅可通过HTTP访问
* @param string $samesite 防止CSRF攻击和用户追踪
* @return void * @return void
*/ */
protected function saveCookie(string $name, string $value, int $expire, string $path, string $domain, bool $secure, bool $httponly): void protected function saveCookie(string $name, string $value, int $expire, string $path, string $domain, bool $secure, bool $httponly, string $samesite): void
{ {
setcookie($name, $value, $expire, $path, $domain, $secure, $httponly); if (version_compare(PHP_VERSION, '7.3.0', '>=')) {
setcookie($name, $value, [
'expires' => $expire,
'path' => $path,
'domain' => $domain,
'secure' => $secure,
'httponly' => $httponly,
'samesite' => $samesite,
]);
} else {
setcookie($name, $value, $expire, $path, $domain, $secure, $httponly);
}
} }
} }

View File

@ -253,6 +253,7 @@ class Event
$result = []; $result = [];
$listeners = $this->listener[$event] ?? []; $listeners = $this->listener[$event] ?? [];
$listeners = array_unique($listeners, SORT_REGULAR);
foreach ($listeners as $key => $listener) { foreach ($listeners as $key => $listener) {
$result[$key] = $this->dispatch($listener, $params); $result[$key] = $this->dispatch($listener, $params);

View File

@ -100,13 +100,13 @@ class File extends SplFileInfo
set_error_handler(function ($type, $msg) use (&$error) { set_error_handler(function ($type, $msg) use (&$error) {
$error = $msg; $error = $msg;
}); });
$renamed = rename($this->getPathname(), $target); $renamed = rename($this->getPathname(), (string) $target);
restore_error_handler(); restore_error_handler();
if (!$renamed) { if (!$renamed) {
throw new FileException(sprintf('Could not move the file "%s" to "%s" (%s)', $this->getPathname(), $target, strip_tags($error))); 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; return $target;
} }

View File

@ -169,7 +169,7 @@ class Lang
$range = $range ?: $this->range; $range = $range ?: $this->range;
if ($this->config['allow_group'] && strpos($name, '.')) { if ($this->config['allow_group'] && strpos($name, '.')) {
list($name1, $name2) = explode('.', $name, 2); [$name1, $name2] = explode('.', $name, 2);
return isset($this->lang[$range][strtolower($name1)][$name2]); return isset($this->lang[$range][strtolower($name1)][$name2]);
} }
@ -194,7 +194,7 @@ class Lang
} }
if ($this->config['allow_group'] && strpos($name, '.')) { if ($this->config['allow_group'] && strpos($name, '.')) {
list($name1, $name2) = explode('.', $name, 2); [$name1, $name2] = explode('.', $name, 2);
$value = $this->lang[$range][strtolower($name1)][$name2] ?? $name; $value = $this->lang[$range][strtolower($name1)][$name2] ?? $name;
} else { } else {

View File

@ -135,7 +135,7 @@ class Middleware
return (new Pipeline()) return (new Pipeline())
->through(array_map(function ($middleware) { ->through(array_map(function ($middleware) {
return function ($request, $next) use ($middleware) { return function ($request, $next) use ($middleware) {
list($call, $param) = $middleware; [$call, $param] = $middleware;
if (is_array($call) && is_string($call[0])) { if (is_array($call) && is_string($call[0])) {
$call = [$this->app->make($call[0]), $call[1]]; $call = [$this->app->make($call[0]), $call[1]];
} }
@ -158,7 +158,7 @@ class Middleware
{ {
foreach ($this->queue as $queue) { foreach ($this->queue as $queue) {
foreach ($queue as $middleware) { foreach ($queue as $middleware) {
list($call) = $middleware; [$call] = $middleware;
if (is_array($call) && is_string($call[0])) { if (is_array($call) && is_string($call[0])) {
$instance = $this->app->make($call[0]); $instance = $this->app->make($call[0]);
if (method_exists($instance, 'end')) { if (method_exists($instance, 'end')) {
@ -197,7 +197,7 @@ class Middleware
protected function buildMiddleware($middleware, string $type): array protected function buildMiddleware($middleware, string $type): array
{ {
if (is_array($middleware)) { if (is_array($middleware)) {
list($middleware, $param) = $middleware; [$middleware, $param] = $middleware;
} }
if ($middleware instanceof Closure) { if ($middleware instanceof Closure) {
@ -248,7 +248,7 @@ class Middleware
*/ */
protected function getMiddlewarePriority($priority, $middleware) protected function getMiddlewarePriority($priority, $middleware)
{ {
list($call) = $middleware; [$call] = $middleware;
if (is_array($call) && is_string($call[0])) { if (is_array($call) && is_string($call[0])) {
$index = array_search($call[0], array_reverse($priority)); $index = array_search($call[0], array_reverse($priority));
return false === $index ? -1 : $index; return false === $index ? -1 : $index;

View File

@ -307,15 +307,6 @@ class Request
{ {
$request = new static(); $request = new static();
$request->server = $_SERVER;
$request->env = $app->env;
$request->get = $_GET;
$request->post = $_POST ?: $request->getInputData($request->input);
$request->put = $request->getInputData($request->input);
$request->request = $_REQUEST;
$request->cookie = $_COOKIE;
$request->file = $_FILES ?? [];
if (function_exists('apache_request_headers') && $result = apache_request_headers()) { if (function_exists('apache_request_headers') && $result = apache_request_headers()) {
$header = $result; $header = $result;
} else { } else {
@ -337,6 +328,15 @@ class Request
$request->header = array_change_key_case($header); $request->header = array_change_key_case($header);
$request->server = $_SERVER;
$request->env = $app->env;
$request->get = $_GET;
$request->post = $_POST ?: $request->getInputData($request->input);
$request->put = $request->getInputData($request->input);
$request->request = $_REQUEST;
$request->cookie = $_COOKIE;
$request->file = $_FILES ?? [];
return $request; return $request;
} }
@ -1126,7 +1126,7 @@ class Request
if (!empty($files)) { if (!empty($files)) {
if (strpos($name, '.')) { if (strpos($name, '.')) {
list($name, $sub) = explode('.', $name); [$name, $sub] = explode('.', $name);
} }
// 处理上传文件 // 处理上传文件
@ -1244,7 +1244,7 @@ class Request
if ('' != $name) { if ('' != $name) {
// 解析name // 解析name
if (strpos($name, '/')) { if (strpos($name, '/')) {
list($name, $type) = explode('/', $name); [$name, $type] = explode('/', $name);
} }
$data = $this->getData($data, $name); $data = $this->getData($data, $name);
@ -1794,11 +1794,11 @@ class Request
*/ */
public function contentType(): string public function contentType(): string
{ {
$contentType = $this->server('CONTENT_TYPE'); $contentType = $this->header('Content-Type');
if ($contentType) { if ($contentType) {
if (strpos($contentType, ';')) { if (strpos($contentType, ';')) {
list($type) = explode(';', $contentType); [$type] = explode(';', $contentType);
} else { } else {
$type = $contentType; $type = $contentType;
} }
@ -2057,6 +2057,10 @@ class Request
public function withInput(string $input) public function withInput(string $input)
{ {
$this->input = $input; $this->input = $input;
if (!empty($input)) {
$this->post = $this->getInputData($input);
$this->put = $this->getInputData($input);
}
return $this; return $this;
} }

View File

@ -138,8 +138,9 @@ abstract class Response
header($name . (!is_null($val) ? ':' . $val : '')); header($name . (!is_null($val) ? ':' . $val : ''));
} }
} }
if ($this->cookie) {
$this->cookie->save(); $this->cookie->save();
}
$this->sendData($data); $this->sendData($data);

View File

@ -156,7 +156,7 @@ class Validate
/** /**
* 验证失败错误信息 * 验证失败错误信息
* @var array * @var string|array
*/ */
protected $error = []; protected $error = [];
@ -491,7 +491,7 @@ class Validate
// field => 'rule1|rule2...' field => ['rule1','rule2',...] // field => 'rule1|rule2...' field => ['rule1','rule2',...]
if (strpos($key, '|')) { if (strpos($key, '|')) {
// 字段|描述 用于指定属性名称 // 字段|描述 用于指定属性名称
list($key, $title) = explode('|', $key); [$key, $title] = explode('|', $key);
} else { } else {
$title = $this->field[$key] ?? $key; $title = $this->field[$key] ?? $key;
} }
@ -560,7 +560,7 @@ class Validate
$result = call_user_func_array($rule, [$value]); $result = call_user_func_array($rule, [$value]);
} else { } else {
// 判断验证类型 // 判断验证类型
list($type, $rule) = $this->getValidateType($key, $rule); [$type, $rule] = $this->getValidateType($key, $rule);
$callback = $this->type[$type] ?? [$this, $type]; $callback = $this->type[$type] ?? [$this, $type];
@ -614,7 +614,7 @@ class Validate
$info = is_numeric($key) ? '' : $key; $info = is_numeric($key) ? '' : $key;
} else { } else {
// 判断验证类型 // 判断验证类型
list($type, $rule, $info) = $this->getValidateType($key, $rule); [$type, $rule, $info] = $this->getValidateType($key, $rule);
if (isset($this->append[$field]) && in_array($info, $this->append[$field])) { if (isset($this->append[$field]) && in_array($info, $this->append[$field])) {
@ -682,7 +682,7 @@ class Validate
} }
if (strpos($rule, ':')) { if (strpos($rule, ':')) {
list($type, $rule) = explode(':', $rule, 2); [$type, $rule] = explode(':', $rule, 2);
if (isset($this->alias[$type])) { if (isset($this->alias[$type])) {
// 判断别名 // 判断别名
$type = $this->alias[$type]; $type = $this->alias[$type];
@ -1072,13 +1072,13 @@ class Validate
if ($rule) { if ($rule) {
$rule = explode(',', $rule); $rule = explode(',', $rule);
list($width, $height, $type) = getimagesize($file->getRealPath()); [$width, $height, $type] = getimagesize($file->getRealPath());
if (isset($rule[2])) { if (isset($rule[2])) {
$imageType = strtolower($rule[2]); $imageType = strtolower($rule[2]);
if ('jpeg' == $imageType) { if ('jpg' == $imageType) {
$imageType = 'jpg'; $imageType = 'jpeg';
} }
if (image_type_to_extension($type, false) != $imageType) { if (image_type_to_extension($type, false) != $imageType) {
@ -1086,7 +1086,7 @@ class Validate
} }
} }
list($w, $h) = $rule; [$w, $h] = $rule;
return $w == $width && $h == $height; return $w == $width && $h == $height;
} }
@ -1173,7 +1173,7 @@ class Validate
public function filter($value, $rule): bool public function filter($value, $rule): bool
{ {
if (is_string($rule) && strpos($rule, ',')) { if (is_string($rule) && strpos($rule, ',')) {
list($rule, $param) = explode(',', $rule); [$rule, $param] = explode(',', $rule);
} elseif (is_array($rule)) { } elseif (is_array($rule)) {
$param = $rule[1] ?? null; $param = $rule[1] ?? null;
$rule = $rule[0]; $rule = $rule[0];
@ -1194,7 +1194,7 @@ class Validate
*/ */
public function requireIf($value, $rule, array $data = []): bool public function requireIf($value, $rule, array $data = []): bool
{ {
list($field, $val) = explode(',', $rule); [$field, $val] = explode(',', $rule);
if ($this->getDataValue($data, $field) == $val) { if ($this->getDataValue($data, $field) == $val) {
return !empty($value) || '0' == $value; return !empty($value) || '0' == $value;
@ -1296,7 +1296,7 @@ class Validate
if (is_string($rule)) { if (is_string($rule)) {
$rule = explode(',', $rule); $rule = explode(',', $rule);
} }
list($min, $max) = $rule; [$min, $max] = $rule;
return $value >= $min && $value <= $max; return $value >= $min && $value <= $max;
} }
@ -1313,7 +1313,7 @@ class Validate
if (is_string($rule)) { if (is_string($rule)) {
$rule = explode(',', $rule); $rule = explode(',', $rule);
} }
list($min, $max) = $rule; [$min, $max] = $rule;
return $value < $min || $value > $max; return $value < $min || $value > $max;
} }
@ -1337,7 +1337,7 @@ class Validate
if (is_string($rule) && strpos($rule, ',')) { if (is_string($rule) && strpos($rule, ',')) {
// 长度区间 // 长度区间
list($min, $max) = explode(',', $rule); [$min, $max] = explode(',', $rule);
return $length >= $min && $length <= $max; return $length >= $min && $length <= $max;
} }
@ -1452,7 +1452,7 @@ class Validate
$rule = explode(',', $rule); $rule = explode(',', $rule);
} }
list($start, $end) = $rule; [$start, $end] = $rule;
if (!is_numeric($start)) { if (!is_numeric($start)) {
$start = strtotime($start); $start = strtotime($start);
@ -1512,7 +1512,10 @@ class Validate
return is_scalar($value) && 1 === preg_match($rule, (string) $value); return is_scalar($value) && 1 === preg_match($rule, (string) $value);
} }
// 获取错误信息 /**
* 获取错误信息
* @return array|string
*/
public function getError() public function getError()
{ {
return $this->error; return $this->error;

View File

@ -18,6 +18,7 @@ use DateTime;
use DateTimeInterface; use DateTimeInterface;
use Exception; use Exception;
use Psr\SimpleCache\CacheInterface; use Psr\SimpleCache\CacheInterface;
use think\Container;
use think\contract\CacheHandlerInterface; use think\contract\CacheHandlerInterface;
use think\exception\InvalidArgumentException; use think\exception\InvalidArgumentException;
use throwable; use throwable;
@ -156,7 +157,7 @@ abstract class Driver implements CacheInterface, CacheHandlerInterface
if ($value instanceof Closure) { if ($value instanceof Closure) {
// 获取缓存数据 // 获取缓存数据
$value = $value(); $value = Container::getInstance()->invokeFunction($value);
} }
// 缓存数据 // 缓存数据
@ -227,7 +228,7 @@ abstract class Driver implements CacheInterface, CacheHandlerInterface
return (string) $data; return (string) $data;
} }
$serialize = $this->options['serialize'][0] ?? "\Opis\Closure\serialize"; $serialize = $this->options['serialize'][0] ?? "serialize";
return $serialize($data); return $serialize($data);
} }
@ -244,7 +245,7 @@ abstract class Driver implements CacheInterface, CacheHandlerInterface
return $data; return $data;
} }
$unserialize = $this->options['serialize'][1] ?? "\Opis\Closure\unserialize"; $unserialize = $this->options['serialize'][1] ?? "unserialize";
return $unserialize($data); return $unserialize($data);
} }

View File

@ -64,7 +64,7 @@ class Memcache extends Driver
foreach ($hosts as $i => $host) { foreach ($hosts as $i => $host) {
$port = $ports[$i] ?? $ports[0]; $port = $ports[$i] ?? $ports[0];
$this->options['timeout'] > 0 ? $this->options['timeout'] > 0 ?
$this->handler->addServer($host, (int) $port, $this->options['persistent'], 1, $this->options['timeout']) : $this->handler->addServer($host, (int) $port, $this->options['persistent'], 1, (int) $this->options['timeout']) :
$this->handler->addServer($host, (int) $port, $this->options['persistent'], 1); $this->handler->addServer($host, (int) $port, $this->options['persistent'], 1);
} }
} }

View File

@ -181,15 +181,18 @@ class Memcached extends Driver
* 删除缓存 * 删除缓存
* @access public * @access public
* @param string $name 缓存变量名 * @param string $name 缓存变量名
* @param bool|false $ttl
* @return bool * @return bool
*/ */
public function delete($name): bool public function delete($name, $ttl = false): bool
{ {
$this->writeTimes++; $this->writeTimes++;
$key = $this->getCacheKey($name); $key = $this->getCacheKey($name);
return $this->handler->delete($key); return false === $ttl ?
$this->handler->delete($key) :
$this->handler->delete($key, $ttl);
} }
/** /**

View File

@ -58,9 +58,9 @@ class Redis extends Driver
$this->handler = new \Redis; $this->handler = new \Redis;
if ($this->options['persistent']) { if ($this->options['persistent']) {
$this->handler->pconnect($this->options['host'], (int) $this->options['port'], $this->options['timeout'], 'persistent_id_' . $this->options['select']); $this->handler->pconnect($this->options['host'], (int) $this->options['port'], (int) $this->options['timeout'], 'persistent_id_' . $this->options['select']);
} else { } else {
$this->handler->connect($this->options['host'], (int) $this->options['port'], $this->options['timeout']); $this->handler->connect($this->options['host'], (int) $this->options['port'], (int) $this->options['timeout']);
} }
if ('' != $this->options['password']) { if ('' != $this->options['password']) {
@ -115,7 +115,7 @@ class Redis extends Driver
$value = $this->handler->get($this->getCacheKey($name)); $value = $this->handler->get($this->getCacheKey($name));
if (false === $value) { if (false === $value || is_null($value)) {
return $default; return $default;
} }

View File

@ -79,7 +79,7 @@ abstract class Make extends Command
} }
if (strpos($name, '@')) { if (strpos($name, '@')) {
list($app, $name) = explode('@', $name); [$app, $name] = explode('@', $name);
} else { } else {
$app = ''; $app = '';
} }

View File

@ -46,7 +46,7 @@ class Route extends Command
$this->app->route->lazy(false); $this->app->route->lazy(false);
// 路由检测 // 路由检测
$path = $this->app->getRootPath() . 'route' . DIRECTORY_SEPARATOR . ($dir ? $dir . DIRECTORY_SEPARATOR : ''); $path = $this->app->getRootPath() . ($dir ? 'app' . DIRECTORY_SEPARATOR . $dir . DIRECTORY_SEPARATOR : '') . 'route' . DIRECTORY_SEPARATOR ;
$files = is_dir($path) ? scandir($path) : []; $files = is_dir($path) ? scandir($path) : [];

View File

@ -75,7 +75,9 @@ class Handle
$log .= PHP_EOL . $exception->getTraceAsString(); $log .= PHP_EOL . $exception->getTraceAsString();
} }
$this->app->log->record($log, 'error'); try {
$this->app->log->record($log, 'error');
} catch (Exception $e){}
} }
} }
@ -150,14 +152,23 @@ class Handle
{ {
if ($this->app->isDebug()) { if ($this->app->isDebug()) {
// 调试模式,获取详细的错误信息 // 调试模式,获取详细的错误信息
$traces = [];
$nextException = $exception;
do {
$traces[] = [
'name' => get_class($nextException),
'file' => $nextException->getFile(),
'line' => $nextException->getLine(),
'code' => $this->getCode($nextException),
'message' => $this->getMessage($nextException),
'trace' => $nextException->getTrace(),
'source' => $this->getSourceCode($nextException),
];
} while ($nextException = $nextException->getPrevious());
$data = [ $data = [
'name' => get_class($exception),
'file' => $exception->getFile(),
'line' => $exception->getLine(),
'message' => $this->getMessage($exception),
'trace' => $exception->getTrace(),
'code' => $this->getCode($exception), 'code' => $this->getCode($exception),
'source' => $this->getSourceCode($exception), 'message' => $this->getMessage($exception),
'traces' => $traces,
'datas' => $this->getExtendData($exception), 'datas' => $this->getExtendData($exception),
'tables' => [ 'tables' => [
'GET Data' => $this->app->request->get(), 'GET Data' => $this->app->request->get(),

View File

@ -12,6 +12,8 @@ declare (strict_types = 1);
namespace think\log\driver; namespace think\log\driver;
use Psr\Container\NotFoundExceptionInterface;
use think\App;
use think\contract\LogHandlerInterface; use think\contract\LogHandlerInterface;
/** /**
@ -20,11 +22,13 @@ use think\contract\LogHandlerInterface;
*/ */
class Socket implements LogHandlerInterface class Socket implements LogHandlerInterface
{ {
public $port = 1116; //SocketLog 服务的http的端口号 protected $app;
protected $config = [ protected $config = [
// socket服务器地址 // socket服务器地址
'host' => 'localhost', 'host' => 'localhost',
// socket服务器端口
'port' => 1116,
// 是否显示加载的文件列表 // 是否显示加载的文件列表
'show_included_files' => false, 'show_included_files' => false,
// 日志强制记录到配置的client_id // 日志强制记录到配置的client_id
@ -33,6 +37,10 @@ class Socket implements LogHandlerInterface
'allow_client_ids' => [], 'allow_client_ids' => [],
// 调试开关 // 调试开关
'debug' => false, 'debug' => false,
// 输出到浏览器时默认展开的日志级别
'expand_level' => ['debug'],
// 日志头渲染回调
'format_head' => null,
]; ];
protected $css = [ protected $css = [
@ -45,16 +53,25 @@ class Socket implements LogHandlerInterface
protected $allowForceClientIds = []; //配置强制推送且被授权的client_id protected $allowForceClientIds = []; //配置强制推送且被授权的client_id
protected $clientArg = [];
/** /**
* 架构函数 * 架构函数
* @access public * @access public
* @param App $app
* @param array $config 缓存参数 * @param array $config 缓存参数
*/ */
public function __construct(array $config = []) public function __construct(App $app, array $config = [])
{ {
$this->app = $app;
if (!empty($config)) { if (!empty($config)) {
$this->config = array_merge($this->config, $config); $this->config = array_merge($this->config, $config);
} }
if (!isset($config['debug'])) {
$this->config['debug'] = $app->isDebug();
}
} }
/** /**
@ -72,11 +89,18 @@ class Socket implements LogHandlerInterface
$trace = []; $trace = [];
if ($this->config['debug']) { if ($this->config['debug']) {
if ($this->app->exists('request')) {
if (isset($_SERVER['HTTP_HOST'])) { $current_uri = $this->app->request->url(true);
$current_uri = $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
} else { } else {
$current_uri = 'cmd:' . implode(' ', $_SERVER['argv']); $current_uri = 'cmd:' . implode(' ', $_SERVER['argv'] ?? []);
}
if (!empty($this->config['format_head'])) {
try {
$current_uri = $this->app->invoke($this->config['format_head'], [$current_uri]);
} catch (NotFoundExceptionInterface $notFoundException) {
// Ignore exception
}
} }
// 基本信息 // 基本信息
@ -87,11 +111,13 @@ class Socket implements LogHandlerInterface
]; ];
} }
$expand_level = array_flip($this->config['expand_level']);
foreach ($log as $type => $val) { foreach ($log as $type => $val) {
$trace[] = [ $trace[] = [
'type' => 'groupCollapsed', 'type' => isset($expand_level[$type]) ? 'group' : 'groupCollapsed',
'msg' => '[ ' . $type . ' ]', 'msg' => '[ ' . $type . ' ]',
'css' => isset($this->css[$type]) ? $this->css[$type] : '', 'css' => $this->css[$type] ?? '',
]; ];
foreach ($val as $msg) { foreach ($val as $msg) {
@ -160,11 +186,11 @@ class Socket implements LogHandlerInterface
/** /**
* 发送给指定客户端 * 发送给指定客户端
* @access protected * @access protected
* @author Zjmainstay
* @param $tabid * @param $tabid
* @param $client_id * @param $client_id
* @param $logs * @param $logs
* @param $force_client_id * @param $force_client_id
* @author Zjmainstay
*/ */
protected function sendToClient($tabid, $client_id, $logs, $force_client_id) protected function sendToClient($tabid, $client_id, $logs, $force_client_id)
{ {
@ -175,12 +201,17 @@ class Socket implements LogHandlerInterface
'force_client_id' => $force_client_id, 'force_client_id' => $force_client_id,
]; ];
$msg = @json_encode($logs); $msg = json_encode($logs, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PARTIAL_OUTPUT_ON_ERROR);
$address = '/' . $client_id; //将client_id作为地址 server端通过地址判断将日志发布给谁 $address = '/' . $client_id; //将client_id作为地址 server端通过地址判断将日志发布给谁
$this->send($this->config['host'], $msg, $address); $this->send($this->config['host'], $this->config['port'], $msg, $address);
} }
/**
* 检测客户授权
* @access protected
* @return bool
*/
protected function check() protected function check()
{ {
$tabid = $this->getClientArg('tabid'); $tabid = $this->getClientArg('tabid');
@ -211,45 +242,50 @@ class Socket implements LogHandlerInterface
return true; return true;
} }
protected function getClientArg($name) /**
* 获取客户参数
* @access protected
* @param string $name
* @return string
*/
protected function getClientArg(string $name)
{ {
static $args = []; if (!$this->app->exists('request')) {
return '';
$key = 'HTTP_USER_AGENT';
if (isset($_SERVER['HTTP_SOCKETLOG'])) {
$key = 'HTTP_SOCKETLOG';
} }
if (!isset($_SERVER[$key])) { if (empty($this->clientArg)) {
return; if (empty($socketLog = $this->app->request->header('socketlog'))) {
} if (empty($socketLog = $this->app->request->header('User-Agent'))) {
return '';
if (empty($args)) { }
if (!preg_match('/SocketLog\((.*?)\)/', $_SERVER[$key], $match)) {
$args = ['tabid' => null];
return;
} }
parse_str($match[1], $args);
if (!preg_match('/SocketLog\((.*?)\)/', $socketLog, $match)) {
$this->clientArg = ['tabid' => null, 'client_id' => null];
return '';
}
parse_str($match[1] ?? '', $this->clientArg);
} }
if (isset($args[$name])) { if (isset($this->clientArg[$name])) {
return $args[$name]; return $this->clientArg[$name];
} }
return; return '';
} }
/** /**
* @access protected * @access protected
* @param string $host - $host of socket server * @param string $host - $host of socket server
* @param int $port - $port of socket server
* @param string $message - 发送的消息 * @param string $message - 发送的消息
* @param string $address - 地址 * @param string $address - 地址
* @return bool * @return bool
*/ */
protected function send($host, $message = '', $address = '/') protected function send($host, $port, $message = '', $address = '/')
{ {
$url = 'http://' . $host . ':' . $this->port . $address; $url = 'http://' . $host . ':' . $port . $address;
$ch = curl_init(); $ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_URL, $url);
@ -267,5 +303,4 @@ class Socket implements LogHandlerInterface
return curl_exec($ch); return curl_exec($ch);
} }
} }

View File

@ -65,7 +65,7 @@ class CheckRequestCache
if ($cache) { if ($cache) {
if (is_array($cache)) { if (is_array($cache)) {
list($key, $expire, $tag) = $cache; [$key, $expire, $tag] = $cache;
} else { } else {
$key = str_replace('|', '/', $request->url()); $key = str_replace('|', '/', $request->url());
$expire = $cache; $expire = $cache;
@ -76,8 +76,8 @@ class CheckRequestCache
// 读取缓存 // 读取缓存
return Response::create()->code(304); return Response::create()->code(304);
} elseif (($hit = $this->cache->get($key)) !== null) { } elseif (($hit = $this->cache->get($key)) !== null) {
list($content, $header, $when) = $hit; [$content, $header, $when] = $hit;
if ($expire === null || $when + $expire > $request->server('REQUEST_TIME')) { if (null === $expire || $when + $expire > $request->server('REQUEST_TIME')) {
return Response::create($content)->header($header); return Response::create($content)->header($header);
} }
} }
@ -130,7 +130,7 @@ class CheckRequestCache
// 自动缓存功能 // 自动缓存功能
$key = '__URL__'; $key = '__URL__';
} elseif (strpos($key, '|')) { } elseif (strpos($key, '|')) {
list($key, $fun) = explode('|', $key); [$key, $fun] = explode('|', $key);
} }
// 特殊规则替换 // 特殊规则替换

View File

@ -139,16 +139,16 @@ abstract class Dispatch
$this->createBindModel($option['model'], $this->param); $this->createBindModel($option['model'], $this->param);
} }
// 数据自动验证
if (isset($option['validate'])) {
$this->autoValidate($option['validate']);
}
// 记录当前请求的路由规则 // 记录当前请求的路由规则
$this->request->setRule($this->rule); $this->request->setRule($this->rule);
// 记录路由变量 // 记录路由变量
$this->request->setRoute($this->param); $this->request->setRoute($this->param);
// 数据自动验证
if (isset($option['validate'])) {
$this->autoValidate($option['validate']);
}
} }
/** /**
@ -167,7 +167,7 @@ abstract class Dispatch
$fields = explode('&', $key); $fields = explode('&', $key);
if (is_array($val)) { if (is_array($val)) {
list($model, $exception) = $val; [$model, $exception] = $val;
} else { } else {
$model = $val; $model = $val;
$exception = true; $exception = true;
@ -206,7 +206,7 @@ abstract class Dispatch
*/ */
protected function autoValidate(array $option): void protected function autoValidate(array $option): void
{ {
list($validate, $scene, $message, $batch) = $option; [$validate, $scene, $message, $batch] = $option;
if (is_array($validate)) { if (is_array($validate)) {
// 指定验证规则 // 指定验证规则

View File

@ -110,7 +110,7 @@ class Domain extends RuleGroup
protected function parseBindAppendParam(string &$bind): void protected function parseBindAppendParam(string &$bind): void
{ {
if (false !== strpos($bind, '?')) { if (false !== strpos($bind, '?')) {
list($bind, $query) = explode('?', $bind); [$bind, $query] = explode('?', $bind);
parse_str($query, $vars); parse_str($query, $vars);
$this->append($vars); $this->append($vars);
} }

View File

@ -355,7 +355,7 @@ class RuleGroup extends Rule
$var = []; $var = [];
foreach ($match as $key => $val) { foreach ($match as $key => $val) {
if (is_string($key) && '' !== $val) { if (is_string($key) && '' !== $val) {
list($name, $pos) = explode('_THINK_', $key); [$name, $pos] = explode('_THINK_', $key);
$var[$name] = $val; $var[$name] = $val;
} }

View File

@ -213,7 +213,7 @@ class Url
if ($suffix) { if ($suffix) {
$suffix = true === $suffix ? $this->route->config('url_html_suffix') : $suffix; $suffix = true === $suffix ? $this->route->config('url_html_suffix') : $suffix;
if ($pos = strpos($suffix, '|')) { if (is_string($suffix) && $pos = strpos($suffix, '|')) {
$suffix = substr($suffix, 0, $pos); $suffix = substr($suffix, 0, $pos);
} }
} }
@ -324,11 +324,12 @@ class Url
} }
$type = $this->route->config('url_common_param'); $type = $this->route->config('url_common_param');
$keys = [];
foreach ($pattern as $key => $val) { foreach ($pattern as $key => $val) {
if (isset($vars[$key])) { if (isset($vars[$key])) {
$url = str_replace(['[:' . $key . ']', '<' . $key . '?>', ':' . $key, '<' . $key . '>'], $type ? $vars[$key] : urlencode((string) $vars[$key]), $url); $url = str_replace(['[:' . $key . ']', '<' . $key . '?>', ':' . $key, '<' . $key . '>'], $type ? $vars[$key] : urlencode((string) $vars[$key]), $url);
unset($vars[$key]); $keys[] = $key;
$url = str_replace(['/?', '-?'], ['/', '-'], $url); $url = str_replace(['/?', '-?'], ['/', '-'], $url);
$result = [rtrim($url, '?/-'), $domain, $suffix]; $result = [rtrim($url, '?/-'), $domain, $suffix];
} elseif (2 == $val) { } elseif (2 == $val) {
@ -336,10 +337,14 @@ class Url
$url = str_replace(['/?', '-?'], ['/', '-'], $url); $url = str_replace(['/?', '-?'], ['/', '-'], $url);
$result = [rtrim($url, '?/-'), $domain, $suffix]; $result = [rtrim($url, '?/-'), $domain, $suffix];
} else { } else {
$result = null;
$keys = [];
break; break;
} }
} }
$vars = array_diff_key($vars, array_flip($keys));
if (isset($result)) { if (isset($result)) {
return $result; return $result;
} }
@ -373,16 +378,16 @@ class Url
if (false !== strpos($anchor, '?')) { if (false !== strpos($anchor, '?')) {
// 解析参数 // 解析参数
list($anchor, $info['query']) = explode('?', $anchor, 2); [$anchor, $info['query']] = explode('?', $anchor, 2);
} }
if (false !== strpos($anchor, '@')) { if (false !== strpos($anchor, '@')) {
// 解析域名 // 解析域名
list($anchor, $domain) = explode('@', $anchor, 2); [$anchor, $domain] = explode('@', $anchor, 2);
} }
} elseif (strpos($url, '@') && false === strpos($url, '\\')) { } elseif (strpos($url, '@') && false === strpos($url, '\\')) {
// 解析域名 // 解析域名
list($url, $domain) = explode('@', $url, 2); [$url, $domain] = explode('@', $url, 2);
} }
} }

View File

@ -58,7 +58,7 @@ class Url extends Controller
// 解析控制器 // 解析控制器
$controller = !empty($path) ? array_shift($path) : null; $controller = !empty($path) ? array_shift($path) : null;
if ($controller && !preg_match('/^[A-Za-z][\w|\.]*$/', $controller)) { if ($controller && !preg_match('/^[A-Za-z0-9][\w|\.]*$/', $controller)) {
throw new HttpException(404, 'controller not exists:' . $controller); throw new HttpException(404, 'controller not exists:' . $controller);
} }
@ -100,7 +100,7 @@ class Url extends Controller
*/ */
protected function hasDefinedRoute(array $route): bool protected function hasDefinedRoute(array $route): bool
{ {
list($controller, $action) = $route; [$controller, $action] = $route;
// 检查地址是否被定义过路由 // 检查地址是否被定义过路由
$name = strtolower(Str::studly($controller) . '/' . $action); $name = strtolower(Str::studly($controller) . '/' . $action);

View File

@ -152,7 +152,7 @@ class File implements SessionHandlerInterface
if ($this->config['data_compress'] && function_exists('gzcompress')) { if ($this->config['data_compress'] && function_exists('gzcompress')) {
//启用数据压缩 //启用数据压缩
$content = gzuncompress($content); $content = (string) gzuncompress($content);
} }
return $content; return $content;

View File

@ -83,10 +83,6 @@ class Php implements TemplateHandlerInterface
$this->template = $template; $this->template = $template;
// 记录视图信息
$this->app->log
->record('[ VIEW ] ' . $template . ' [ ' . var_export(array_keys($data), true) . ' ]');
extract($data, EXTR_OVERWRITE); extract($data, EXTR_OVERWRITE);
include $this->template; include $this->template;
@ -119,8 +115,8 @@ class Php implements TemplateHandlerInterface
// 获取视图根目录 // 获取视图根目录
if (strpos($template, '@')) { if (strpos($template, '@')) {
// 跨模块调用 // 跨应用调用
list($app, $template) = explode('@', $template); [$app, $template] = explode('@', $template);
} }
if ($this->config['view_path'] && !isset($app)) { if ($this->config['view_path'] && !isset($app)) {

View File

@ -1,79 +1,93 @@
<?php <?php
if(!function_exists('parse_padding')){ /** @var array $traces */
function parse_padding($source) if (!function_exists('parse_padding')) {
{ function parse_padding($source)
$length = strlen(strval(count($source['source']) + $source['first'])); {
return 40 + ($length - 1) * 8; $length = strlen(strval(count($source['source']) + $source['first']));
} return 40 + ($length - 1) * 8;
} }
}
if(!function_exists('parse_class')){ if (!function_exists('parse_class')) {
function parse_class($name) function parse_class($name)
{ {
$names = explode('\\', $name); $names = explode('\\', $name);
return '<abbr title="'.$name.'">'.end($names).'</abbr>'; return '<abbr title="'.$name.'">'.end($names).'</abbr>';
}
} }
}
if(!function_exists('parse_file')){ if (!function_exists('parse_file')) {
function parse_file($file, $line) function parse_file($file, $line)
{ {
return '<a class="toggle" title="'."{$file} line {$line}".'">'.basename($file)." line {$line}".'</a>'; return '<a class="toggle" title="'."{$file} line {$line}".'">'.basename($file)." line {$line}".'</a>';
}
} }
}
if(!function_exists('parse_args')){ if (!function_exists('parse_args')) {
function parse_args($args) function parse_args($args)
{ {
$result = []; $result = [];
foreach ($args as $key => $item) {
foreach ($args as $key => $item) { switch (true) {
switch (true) { case is_object($item):
case is_object($item): $value = sprintf('<em>object</em>(%s)', parse_class(get_class($item)));
$value = sprintf('<em>object</em>(%s)', parse_class(get_class($item))); break;
break; case is_array($item):
case is_array($item): if (count($item) > 3) {
if(count($item) > 3){ $value = sprintf('[%s, ...]', parse_args(array_slice($item, 0, 3)));
$value = sprintf('[%s, ...]', parse_args(array_slice($item, 0, 3))); } else {
} else { $value = sprintf('[%s]', parse_args($item));
$value = sprintf('[%s]', parse_args($item)); }
} break;
break; case is_string($item):
case is_string($item): if (strlen($item) > 20) {
if(strlen($item) > 20){ $value = sprintf(
$value = sprintf( '\'<a class="toggle" title="%s">%s...</a>\'',
'\'<a class="toggle" title="%s">%s...</a>\'', htmlentities($item),
htmlentities($item), htmlentities(substr($item, 0, 20))
htmlentities(substr($item, 0, 20)) );
); } else {
} else { $value = sprintf("'%s'", htmlentities($item));
$value = sprintf("'%s'", htmlentities($item)); }
} break;
break; case is_int($item):
case is_int($item): case is_float($item):
case is_float($item): $value = $item;
$value = $item; break;
break; case is_null($item):
case is_null($item): $value = '<em>null</em>';
$value = '<em>null</em>'; break;
break; case is_bool($item):
case is_bool($item): $value = '<em>' . ($item ? 'true' : 'false') . '</em>';
$value = '<em>' . ($item ? 'true' : 'false') . '</em>'; break;
break; case is_resource($item):
case is_resource($item): $value = '<em>resource</em>';
$value = '<em>resource</em>'; break;
break; default:
default: $value = htmlentities(str_replace("\n", '', var_export(strval($item), true)));
$value = htmlentities(str_replace("\n", '', var_export(strval($item), true))); break;
break;
}
$result[] = is_int($key) ? $value : "'{$key}' => {$value}";
} }
return implode(', ', $result); $result[] = is_int($key) ? $value : "'{$key}' => {$value}";
}
return implode(', ', $result);
}
}
if (!function_exists('echo_value')) {
function echo_value($val)
{
if (is_array($val) || is_object($val)) {
echo htmlentities(json_encode($val, JSON_PRETTY_PRINT));
} elseif (is_bool($val)) {
echo $val ? 'true' : 'false';
} elseif (is_scalar($val)) {
echo htmlentities($val);
} else {
echo 'Resource';
} }
} }
}
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
@ -123,11 +137,9 @@
.line-error{ .line-error{
background: #f8cbcb; background: #f8cbcb;
} }
.echo table { .echo table {
width: 100%; width: 100%;
} }
.echo pre { .echo pre {
padding: 16px; padding: 16px;
overflow: auto; overflow: auto;
@ -138,12 +150,10 @@
border-radius: 3px; border-radius: 3px;
font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
} }
.echo pre > pre { .echo pre > pre {
padding: 0; padding: 0;
margin: 0; margin: 0;
} }
/* Exception Info */ /* Exception Info */
.exception { .exception {
margin-top: 20px; margin-top: 20px;
@ -156,9 +166,8 @@
font-size:16px; font-size:16px;
border-top-left-radius: 4px; border-top-left-radius: 4px;
border-top-right-radius: 4px; border-top-right-radius: 4px;
font-family: Consolas,"Liberation Mono",Courier,Verdana,"微软雅黑"; font-family: Consolas,"Liberation Mono",Courier,Verdana,"微软雅黑",serif;
} }
.exception .code{ .exception .code{
float: left; float: left;
text-align: center; text-align: center;
@ -185,8 +194,8 @@
display: inline-block; display: inline-block;
min-width: 100%; min-width: 100%;
box-sizing: border-box; box-sizing: border-box;
font-size:14px; font-size:14px;
font-family: "Century Gothic",Consolas,"Liberation Mono",Courier,Verdana; font-family: "Century Gothic",Consolas,"Liberation Mono",Courier,Verdana,serif;
padding-left: <?php echo (isset($source) && !empty($source)) ? parse_padding($source) : 40; ?>px; padding-left: <?php echo (isset($source) && !empty($source)) ? parse_padding($source) : 40; ?>px;
} }
.exception .source-code pre li{ .exception .source-code pre li{
@ -199,16 +208,20 @@
height: 100%; height: 100%;
display: inline-block; display: inline-block;
border-left: 1px solid #fff; border-left: 1px solid #fff;
font-size:14px; font-size:14px;
font-family: Consolas,"Liberation Mono",Courier,Verdana,"微软雅黑"; font-family: Consolas,"Liberation Mono",Courier,Verdana,"微软雅黑",serif;
} }
.exception .trace{ .exception .trace{
padding: 6px; padding: 6px;
border: 1px solid #ddd; border: 1px solid #ddd;
border-top: 0 none; border-top: 0 none;
line-height: 16px; line-height: 16px;
font-size:14px; font-size:14px;
font-family: Consolas,"Liberation Mono",Courier,Verdana,"微软雅黑"; font-family: Consolas,"Liberation Mono",Courier,Verdana,"微软雅黑",serif;
}
.exception .trace h2:hover {
text-decoration: underline;
cursor: pointer;
} }
.exception .trace ol{ .exception .trace ol{
margin: 12px; margin: 12px;
@ -227,7 +240,7 @@
margin: 12px 0; margin: 12px 0;
box-sizing: border-box; box-sizing: border-box;
table-layout:fixed; table-layout:fixed;
word-wrap:break-word; word-wrap:break-word;
} }
.exception-var table caption{ .exception-var table caption{
text-align: left; text-align: left;
@ -243,7 +256,7 @@
} }
.exception-var table tbody{ .exception-var table tbody{
font-size: 13px; font-size: 13px;
font-family: Consolas,"Liberation Mono",Courier,"微软雅黑"; font-family: Consolas, "Liberation Mono", Courier, "微软雅黑",serif;
} }
.exception-var table td{ .exception-var table td{
padding: 0 6px; padding: 0 6px;
@ -283,65 +296,63 @@
</style> </style>
</head> </head>
<body> <body>
<?php if(\think\facade\App::isDebug()) { ?> <?php if (\think\facade\App::isDebug()) { ?>
<?php foreach ($traces as $index => $trace) { ?>
<div class="exception"> <div class="exception">
<div class="message"> <div class="message">
<div class="info"> <div class="info">
<div> <div>
<h2>[<?php echo $code; ?>]&nbsp;<?php echo sprintf('%s in %s', parse_class($name), parse_file($file, $line)); ?></h2> <h2><?php echo "#{$index} [{$trace['code']}]" . sprintf('%s in %s', parse_class($trace['name']), parse_file($trace['file'], $trace['line'])); ?></h2>
</div> </div>
<div><h1><?php echo nl2br(htmlentities($message)); ?></h1></div> <div><h1><?php echo nl2br(htmlentities($trace['message'])); ?></h1></div>
</div> </div>
</div>
<?php if(!empty($source)){?>
<div class="source-code">
<pre class="prettyprint lang-php"><ol start="<?php echo $source['first']; ?>"><?php foreach ((array) $source['source'] as $key => $value) { ?><li class="line-<?php echo $key + $source['first']; ?>"><code><?php echo htmlentities($value); ?></code></li><?php } ?></ol></pre>
</div> </div>
<?php }?> <?php if (!empty($trace['source'])) { ?>
<div class="source-code">
<pre class="prettyprint lang-php"><ol start="<?php echo $trace['source']['first']; ?>"><?php foreach ((array) $trace['source']['source'] as $key => $value) { ?><li class="line-<?php echo "{$index}-"; echo $key + $trace['source']['first']; echo $trace['line'] === $key + $trace['source']['first'] ? ' line-error' : ''; ?>"><code><?php echo htmlentities($value); ?></code></li><?php } ?></ol></pre>
</div>
<?php }?>
<div class="trace"> <div class="trace">
<h2>Call Stack</h2> <h2 data-expand="<?php echo 0 === $index ? '1' : '0'; ?>">Call Stack</h2>
<ol> <ol>
<li><?php echo sprintf('in %s', parse_file($file, $line)); ?></li> <li><?php echo sprintf('in %s', parse_file($trace['file'], $trace['line'])); ?></li>
<?php foreach ((array) $trace as $value) { ?> <?php foreach ((array) $trace['trace'] as $value) { ?>
<li> <li>
<?php <?php
// Show Function // Show Function
if($value['function']){ if ($value['function']) {
echo sprintf( echo sprintf(
'at %s%s%s(%s)', 'at %s%s%s(%s)',
isset($value['class']) ? parse_class($value['class']) : '', isset($value['class']) ? parse_class($value['class']) : '',
isset($value['type']) ? $value['type'] : '', isset($value['type']) ? $value['type'] : '',
$value['function'], $value['function'],
isset($value['args'])?parse_args($value['args']):'' isset($value['args'])?parse_args($value['args']):''
); );
} }
// Show line // Show line
if (isset($value['file']) && isset($value['line'])) { if (isset($value['file']) && isset($value['line'])) {
echo sprintf(' in %s', parse_file($value['file'], $value['line'])); echo sprintf(' in %s', parse_file($value['file'], $value['line']));
} }
?> ?>
</li> </li>
<?php } ?> <?php } ?>
</ol> </ol>
</div> </div>
</div> </div>
<?php } ?>
<?php } else { ?> <?php } else { ?>
<div class="exception"> <div class="exception">
<div class="info"><h1><?php echo htmlentities($message); ?></h1></div>
<div class="info"><h1><?php echo htmlentities($message); ?></h1></div>
</div> </div>
<?php } ?> <?php } ?>
<?php if(!empty($datas)){ ?> <?php if (!empty($datas)) { ?>
<div class="exception-var"> <div class="exception-var">
<h2>Exception Datas</h2> <h2>Exception Datas</h2>
<?php foreach ((array) $datas as $label => $value) { ?> <?php foreach ((array) $datas as $label => $value) { ?>
<table> <table>
<?php if(empty($value)){ ?> <?php if (empty($value)) { ?>
<caption><?php echo $label; ?><small>empty</small></caption> <caption><?php echo $label; ?><small>empty</small></caption>
<?php } else { ?> <?php } else { ?>
<caption><?php echo $label; ?></caption> <caption><?php echo $label; ?></caption>
@ -349,19 +360,7 @@
<?php foreach ((array) $value as $key => $val) { ?> <?php foreach ((array) $value as $key => $val) { ?>
<tr> <tr>
<td><?php echo htmlentities($key); ?></td> <td><?php echo htmlentities($key); ?></td>
<td> <td><?php echo_value($val); ?></td>
<?php
if(is_array($val) || is_object($val)){
echo htmlentities(json_encode($val, JSON_PRETTY_PRINT));
} else if(is_bool($val)) {
echo $val ? 'true' : 'false';
} else if(is_scalar($val)) {
echo htmlentities($val);
} else {
echo 'Resource';
}
?>
</td>
</tr> </tr>
<?php } ?> <?php } ?>
</tbody> </tbody>
@ -371,12 +370,12 @@
</div> </div>
<?php } ?> <?php } ?>
<?php if(!empty($tables)){ ?> <?php if (!empty($tables)) { ?>
<div class="exception-var"> <div class="exception-var">
<h2>Environment Variables</h2> <h2>Environment Variables</h2>
<?php foreach ((array) $tables as $label => $value) { ?> <?php foreach ((array) $tables as $label => $value) { ?>
<table> <table>
<?php if(empty($value)){ ?> <?php if (empty($value)) { ?>
<caption><?php echo $label; ?><small>empty</small></caption> <caption><?php echo $label; ?><small>empty</small></caption>
<?php } else { ?> <?php } else { ?>
<caption><?php echo $label; ?></caption> <caption><?php echo $label; ?></caption>
@ -384,19 +383,7 @@
<?php foreach ((array) $value as $key => $val) { ?> <?php foreach ((array) $value as $key => $val) { ?>
<tr> <tr>
<td><?php echo htmlentities($key); ?></td> <td><?php echo htmlentities($key); ?></td>
<td> <td><?php echo_value($val); ?></td>
<?php
if(is_array($val) || is_object($val)){
echo htmlentities(json_encode($val, JSON_PRETTY_PRINT));
} else if(is_bool($val)) {
echo $val ? 'true' : 'false';
} else if(is_scalar($val)) {
echo htmlentities($val);
} else {
echo 'Resource';
}
?>
</td>
</tr> </tr>
<?php } ?> <?php } ?>
</tbody> </tbody>
@ -410,12 +397,10 @@
<a title="官方网站" href="http://www.thinkphp.cn">ThinkPHP</a> <a title="官方网站" href="http://www.thinkphp.cn">ThinkPHP</a>
<span>V<?php echo \think\facade\App::version(); ?></span> <span>V<?php echo \think\facade\App::version(); ?></span>
<span>{ -API开发设计的高性能框架 }</span> <span>{ -API开发设计的高性能框架 }</span>
<span>- <a title="官方手册" href="https://www.kancloud.cn/manual/thinkphp6_0/">官方手册</a></span> <span>- <a title="官方手册" href="https://www.kancloud.cn/manual/thinkphp6_0/content">官方手册</a></span>
</div> </div>
<?php if(\think\facade\App::isDebug()) { ?> <?php if (\think\facade\App::isDebug()) { ?>
<script> <script>
var LINE = <?php echo $line; ?>;
function $(selector, node){ function $(selector, node){
var elements; var elements;
@ -483,21 +468,33 @@
} }
} }
// 设置出错行 (function () {
var err_line = $('.line-' + LINE, ol[0])[0]; var expand = function (dom, expand) {
err_line.className = err_line.className + ' line-error'; var ol = $('ol', dom.parentNode)[0];
expand = undefined === expand ? dom.attributes['data-expand'].value === '0' : undefined;
if (expand) {
dom.attributes['data-expand'].value = '1';
ol.style.display = 'none';
dom.innerText = 'Call Stack (展开)';
} else {
dom.attributes['data-expand'].value = '0';
ol.style.display = 'block';
dom.innerText = 'Call Stack (折叠)';
}
};
var traces = $('.trace');
for (var i = 0; i < traces.length; i ++) {
var h2 = $('h2', traces[i])[0];
expand(h2);
h2.onclick = function () {
expand(this);
};
}
})();
$.getScript('//cdn.bootcss.com/prettify/r298/prettify.min.js', function(){ $.getScript('//cdn.bootcss.com/prettify/r298/prettify.min.js', function(){
prettyPrint(); prettyPrint();
// 解决Firefox浏览器一个很诡异的问题
// 当代码高亮后ol的行号莫名其妙的错位
// 但是只要刷新li里面的html重新渲染就没有问题了
if(window.navigator.userAgent.indexOf('Firefox') >= 0){
ol[0].innerHTML = ol[0].innerHTML;
}
}); });
})(); })();
</script> </script>
<?php } ?> <?php } ?>

View File

@ -121,11 +121,11 @@ class CacheTest extends TestCase
$redis->shouldReceive("decrby")->once()->with('foo', 2)->andReturnTrue(); $redis->shouldReceive("decrby")->once()->with('foo', 2)->andReturnTrue();
$redis->shouldReceive("get")->once()->with('foo')->andReturn(6); $redis->shouldReceive("get")->once()->with('foo')->andReturn(6);
$redis->shouldReceive("get")->once()->with('foo')->andReturn(4); $redis->shouldReceive("get")->once()->with('foo')->andReturn(4);
$redis->shouldReceive("set")->once()->with('bar', \Opis\Closure\serialize(true))->andReturnTrue(); $redis->shouldReceive("set")->once()->with('bar', serialize(true))->andReturnTrue();
$redis->shouldReceive("set")->once()->with('baz', \Opis\Closure\serialize(null))->andReturnTrue(); $redis->shouldReceive("set")->once()->with('baz', serialize(null))->andReturnTrue();
$redis->shouldReceive("del")->once()->with('baz')->andReturnTrue(); $redis->shouldReceive("del")->once()->with('baz')->andReturnTrue();
$redis->shouldReceive("flushDB")->once()->andReturnTrue(); $redis->shouldReceive("flushDB")->once()->andReturnTrue();
$redis->shouldReceive("set")->once()->with('bar', \Opis\Closure\serialize('foobar'))->andReturnTrue(); $redis->shouldReceive("set")->once()->with('bar', serialize('foobar'))->andReturnTrue();
$redis->shouldReceive("sAdd")->once()->with('tag:' . md5('foo'), 'bar')->andReturnTrue(); $redis->shouldReceive("sAdd")->once()->with('tag:' . md5('foo'), 'bar')->andReturnTrue();
$redis->shouldReceive("sMembers")->once()->with('tag:' . md5('foo'))->andReturn(['bar']); $redis->shouldReceive("sMembers")->once()->with('tag:' . md5('foo'))->andReturn(['bar']);
$redis->shouldReceive("del")->once()->with(['bar'])->andReturnTrue(); $redis->shouldReceive("del")->once()->with(['bar'])->andReturnTrue();

View File

@ -245,11 +245,22 @@ abstract class Model implements JsonSerializable, ArrayAccess, Arrayable, Jsonab
*/ */
public function newInstance(array $data = [], $where = null): Model public function newInstance(array $data = [], $where = null): Model
{ {
if (empty($data)) { $model = new static($data);
return new static();
if ($this->connection) {
$model->setConnection($this->connection);
} }
$model = (new static($data))->exists(true); if ($this->suffix) {
$model->setSuffix($this->suffix);
}
if (empty($data)) {
return $model;
}
$model->exists(true);
$model->setUpdateWhere($where); $model->setUpdateWhere($where);
$model->trigger('AfterRead'); $model->trigger('AfterRead');
@ -268,6 +279,28 @@ abstract class Model implements JsonSerializable, ArrayAccess, Arrayable, Jsonab
$this->updateWhere = $where; $this->updateWhere = $where;
} }
/**
* 设置当前模型的数据库连接
* @access public
* @param string $connection 数据表连接标识
* @return $this
*/
public function setConnection(string $connection)
{
$this->connection = $connection;
return $this;
}
/**
* 获取当前模型的数据库连接标识
* @access public
* @return string
*/
public function getConnection(): string
{
return $this->connection ?: '';
}
/** /**
* 设置当前模型数据表的后缀 * 设置当前模型数据表的后缀
* @access public * @access public
@ -686,13 +719,13 @@ abstract class Model implements JsonSerializable, ArrayAccess, Arrayable, Jsonab
{ {
$pk = $this->getPk(); $pk = $this->getPk();
if (is_string($pk) && isset($this->data[$pk])) { if (is_string($pk) && isset($this->origin[$pk])) {
$where = [[$pk, '=', $this->data[$pk]]]; $where = [[$pk, '=', $this->origin[$pk]]];
$this->key = $this->data[$pk]; $this->key = $this->origin[$pk];
} elseif (is_array($pk)) { } elseif (is_array($pk)) {
foreach ($pk as $field) { foreach ($pk as $field) {
if (isset($this->data[$field])) { if (isset($this->origin[$field])) {
$where[] = [$field, '=', $this->data[$field]]; $where[] = [$field, '=', $this->origin[$field]];
} }
} }
} }
@ -964,6 +997,20 @@ abstract class Model implements JsonSerializable, ArrayAccess, Arrayable, Jsonab
return $model; return $model;
} }
/**
* 切换数据库连接进行查询
* @access public
* @param string $connection 数据库连接标识
* @return Model
*/
public static function connect(string $connection)
{
$model = new static();
$model->setConnection($connection);
return $model;
}
public function __call($method, $args) public function __call($method, $args)
{ {
if ('withattr' == strtolower($method)) { if ('withattr' == strtolower($method)) {

View File

@ -1118,10 +1118,10 @@ abstract class PDOConnection extends Connection implements ConnectionInterface
if (!empty($options['cache'])) { if (!empty($options['cache'])) {
// 判断查询缓存 // 判断查询缓存
$cacheItem = $this->parseCache($query, $options['cache']); $cacheItem = $this->parseCache($query, $options['cache']);
$key = $cacheItem->getKey(); $name = $cacheItem->getKey();
if ($this->cache->has($key)) { if ($this->cache->has($name)) {
return $this->cache->get($key); return $this->cache->get($name);
} }
} }
@ -1144,8 +1144,9 @@ abstract class PDOConnection extends Connection implements ConnectionInterface
} elseif (('*' == $column || strpos($column, ',')) && $key) { } elseif (('*' == $column || strpos($column, ',')) && $key) {
$result = array_column($resultSet, null, $key); $result = array_column($resultSet, null, $key);
} else { } else {
$fields = array_keys($resultSet[0]); if (empty($key)) {
$key = $key ?: array_shift($fields); $key = null;
}
if (strpos($column, ',')) { if (strpos($column, ',')) {
$column = null; $column = null;
@ -1153,7 +1154,7 @@ abstract class PDOConnection extends Connection implements ConnectionInterface
[$alias, $column] = explode('.', $column); [$alias, $column] = explode('.', $column);
} }
if (strpos($key, '.')) { if (is_string($key) && strpos($key, '.')) {
[$alias, $key] = explode('.', $key); [$alias, $key] = explode('.', $key);
} }

View File

@ -353,12 +353,14 @@ class Query extends BaseQuery
/** /**
* 获取当前数据表的自增主键 * 获取当前数据表的自增主键
* @access public * @access public
* @return string * @return string|null
*/ */
public function getAutoInc() public function getAutoInc()
{ {
if (empty($this->autoinc)) { $tableName = $this->getTable();
$this->autoinc = $this->connection->getAutoInc($this->getTable());
if (empty($this->autoinc) && $tableName) {
$this->autoinc = $this->connection->getAutoInc($tableName);
} }
return $this->autoinc; return $this->autoinc;

View File

@ -120,7 +120,7 @@ class Mysql extends PDOConnection
public function startTransXa(string $xid) public function startTransXa(string $xid)
{ {
$this->initConnect(true); $this->initConnect(true);
$this->linkID->execute("XA START '$xid'"); $this->linkID->exec("XA START '$xid'");
} }
/** /**
@ -132,8 +132,8 @@ class Mysql extends PDOConnection
public function prepareXa(string $xid) public function prepareXa(string $xid)
{ {
$this->initConnect(true); $this->initConnect(true);
$this->linkID->execute("XA END '$xid'"); $this->linkID->exec("XA END '$xid'");
$this->linkID->execute("XA PREPARE '$xid'"); $this->linkID->exec("XA PREPARE '$xid'");
} }
/** /**
@ -145,7 +145,7 @@ class Mysql extends PDOConnection
public function commitXa(string $xid) public function commitXa(string $xid)
{ {
$this->initConnect(true); $this->initConnect(true);
$this->linkID->execute("XA COMMIT '$xid'"); $this->linkID->exec("XA COMMIT '$xid'");
} }
/** /**
@ -157,6 +157,6 @@ class Mysql extends PDOConnection
public function rollbackXa(string $xid) public function rollbackXa(string $xid)
{ {
$this->initConnect(true); $this->initConnect(true);
$this->linkID->execute("XA ROLLBACK '$xid'"); $this->linkID->exec("XA ROLLBACK '$xid'");
} }
} }

View File

@ -24,16 +24,16 @@ use think\admin\Service;
* @package app\store\service * @package app\store\service
* ================================= * =================================
* *
* CREATE TABLE `SystemMessageHistory` ( * CREATE TABLE `system_message_history` (
* `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, * `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
* `region` varchar(255) DEFAULT '0' COMMENT '国家编号',
* `phone` varchar(100) DEFAULT '' COMMENT '目标手机', * `phone` varchar(100) DEFAULT '' COMMENT '目标手机',
* `content` varchar(512) DEFAULT '' COMMENT '短信内容', * `region` varchar(100) DEFAULT '' COMMENT '国家编号',
* `result` varchar(100) DEFAULT '' COMMENT '返回结果', * `result` varchar(100) DEFAULT '' COMMENT '返回结果',
* `content` varchar(512) DEFAULT '' COMMENT '短信内容',
* `create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', * `create_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
* PRIMARY KEY (`id`) USING BTREE, * PRIMARY KEY (`id`) USING BTREE,
* KEY `idx_system_message_history_phone` (`phone`) USING BTREE, * KEY `idx_system_message_history_phone` (`phone`) USING BTREE
* ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='短信-记录'; * ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='系统-短信';
* *
* ================================= * =================================
* 发送国内短信需要给产品码 [productid] * 发送国内短信需要给产品码 [productid]
@ -154,7 +154,6 @@ class MessageService extends Service
/** /**
* 发送国内短信验证码 * 发送国内短信验证码
* @param string $mid 会员ID
* @param string $phone 目标手机 * @param string $phone 目标手机
* @param integer $wait 等待时间 * @param integer $wait 等待时间
* @param string $type 短信模板 * @param string $type 短信模板
@ -163,7 +162,7 @@ class MessageService extends Service
* @throws \think\db\exception\DbException * @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException * @throws \think\db\exception\ModelNotFoundException
*/ */
public function sendChinaSmsByCode($mid, $phone, $wait = 120, $type = 'sms_reg_template') public function sendChinaSmsByCode($phone, $wait = 120, $type = 'sms_reg_template')
{ {
$cache = $this->app->cache->get($ckey = "{$type}_{$phone}", []); $cache = $this->app->cache->get($ckey = "{$type}_{$phone}", []);
if (is_array($cache) && isset($cache['time']) && $cache['time'] > time() - $wait) { if (is_array($cache) && isset($cache['time']) && $cache['time'] > time() - $wait) {
@ -175,7 +174,7 @@ class MessageService extends Service
$content = '您的验证码为{code},请在十分钟内完成操作!'; $content = '您的验证码为{code},请在十分钟内完成操作!';
} }
$this->app->cache->set($ckey, $cache = ['code' => $code, 'time' => time()], 600); $this->app->cache->set($ckey, $cache = ['code' => $code, 'time' => time()], 600);
if ($this->sendChinaSms($mid, $phone, str_replace('{code}', $code, $content))) { if ($this->sendChinaSms($phone, str_replace('{code}', $code, $content))) {
$dtime = ($cache['time'] + $wait < time()) ? 0 : ($wait - time() + $cache['time']); $dtime = ($cache['time'] + $wait < time()) ? 0 : ($wait - time() + $cache['time']);
return [1, '短信验证码发送成功!', ['time' => $dtime]]; return [1, '短信验证码发送成功!', ['time' => $dtime]];
} else { } else {
@ -190,7 +189,7 @@ class MessageService extends Service
* @param string $type 短信模板 * @param string $type 短信模板
* @return boolean * @return boolean
*/ */
public function checkChinaSmsByCode($phone, $code, $type = 'sms_reg_template') public function check($phone, $code, $type = 'sms_reg_template')
{ {
$cache = $this->app->cache->get($cachekey = "{$type}_{$phone}", []); $cache = $this->app->cache->get($cachekey = "{$type}_{$phone}", []);
return is_array($cache) && isset($cache['code']) && $cache['code'] == $code; return is_array($cache) && isset($cache['code']) && $cache['code'] == $code;
@ -236,7 +235,6 @@ class MessageService extends Service
/** /**
* 发送国际短信内容 * 发送国际短信内容
* @param string $mid 会员编号
* @param string $code 国家代码 * @param string $code 国家代码
* @param string $mobile 手机号码 * @param string $mobile 手机号码
* @param string $content 发送内容 * @param string $content 发送内容
@ -245,7 +243,7 @@ class MessageService extends Service
* @throws \think\db\exception\DbException * @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException * @throws \think\db\exception\ModelNotFoundException
*/ */
public function sendGlobeSms($mid, $code, $mobile, $content) public function sendGlobeSms($code, $mobile, $content)
{ {
$tkey = date("YmdHis"); $tkey = date("YmdHis");
$result = HttpExtend::post('http://intl.zthysms.com/intSendSms.do', [ $result = HttpExtend::post('http://intl.zthysms.com/intSendSms.do', [
@ -254,7 +252,7 @@ class MessageService extends Service
'password' => md5(md5(sysconf('sms_zt_password2')) . $tkey), 'password' => md5(md5(sysconf('sms_zt_password2')) . $tkey),
]); ]);
$this->app->db->name($this->table)->insert([ $this->app->db->name($this->table)->insert([
'mid' => $mid, 'region' => $code, 'phone' => $mobile, 'content' => $content, 'result' => $result, 'region' => $code, 'phone' => $mobile, 'content' => $content, 'result' => $result,
]); ]);
return intval($result) === 1; return intval($result) === 1;
} }