From fb0b87973f163a6591b7a94fe861e37302ec006e Mon Sep 17 00:00:00 2001 From: WispX <1591788658@qq.com> Date: Sat, 16 Feb 2019 12:39:35 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=8B=93=E5=B1=95=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- composer.lock | 158 +++++++++++++---- thinkphp/helper.php | 6 +- thinkphp/library/think/App.php | 6 +- thinkphp/library/think/Controller.php | 2 + thinkphp/library/think/File.php | 2 +- thinkphp/library/think/Model.php | 30 +++- thinkphp/library/think/Request.php | 16 +- thinkphp/library/think/Route.php | 2 +- thinkphp/library/think/Template.php | 2 +- thinkphp/library/think/Validate.php | 46 +++-- thinkphp/library/think/cache/Driver.php | 18 +- thinkphp/library/think/cache/driver/File.php | 2 +- thinkphp/library/think/cache/driver/Lite.php | 2 +- .../library/think/cache/driver/Memcache.php | 5 +- .../library/think/cache/driver/Memcached.php | 65 ++++++- thinkphp/library/think/cache/driver/Redis.php | 64 ++++++- .../library/think/cache/driver/Sqlite.php | 2 +- .../library/think/cache/driver/Wincache.php | 15 +- .../library/think/cache/driver/Xcache.php | 4 +- thinkphp/library/think/db/Builder.php | 2 + thinkphp/library/think/db/Query.php | 47 ++--- thinkphp/library/think/db/builder/Mysql.php | 12 +- thinkphp/library/think/db/builder/Sqlsrv.php | 2 +- thinkphp/library/think/log/driver/File.php | 24 +-- .../library/think/model/concern/Attribute.php | 11 +- .../think/model/relation/BelongsToMany.php | 5 +- .../library/think/model/relation/HasMany.php | 4 +- .../think/model/relation/MorphMany.php | 2 +- .../library/think/model/relation/MorphOne.php | 4 +- thinkphp/library/think/response/Download.php | 10 +- thinkphp/library/think/route/Rule.php | 18 +- .../library/think/route/dispatch/Module.php | 8 - thinkphp/library/think/route/dispatch/Url.php | 4 + vendor/composer/ClassLoader.php | 2 +- vendor/composer/installed.json | 164 ++++++++++++++---- vendor/phpmailer/phpmailer/COMMITMENT | 46 +++++ vendor/phpmailer/phpmailer/README.md | 2 +- vendor/phpmailer/phpmailer/VERSION | 2 +- vendor/phpmailer/phpmailer/composer.json | 55 ++++++ .../phpmailer/language/phpmailer.lang-ms.php | 2 +- vendor/phpmailer/phpmailer/src/PHPMailer.php | 2 +- vendor/phpmailer/phpmailer/src/POP3.php | 2 +- vendor/phpmailer/phpmailer/src/SMTP.php | 2 +- vendor/qcloud/cos-sdk-v5/README.md | 91 +++++----- .../src/Qcloud/Cos/BucketStyleListener.php | 36 +++- .../cos-sdk-v5/src/Qcloud/Cos/Client.php | 58 ++----- .../cos-sdk-v5/src/Qcloud/Cos/Service.php | 50 +++++- .../cos-sdk-v5/src/Qcloud/Cos/Signature.php | 1 + .../cos-sdk-v5/src/Qcloud/Cos/Tests/Test.php | 21 --- 49 files changed, 837 insertions(+), 299 deletions(-) create mode 100644 vendor/phpmailer/phpmailer/COMMITMENT create mode 100644 vendor/phpmailer/phpmailer/composer.json diff --git a/composer.lock b/composer.lock index b0defeca..5f9df7a6 100644 --- a/composer.lock +++ b/composer.lock @@ -18,7 +18,13 @@ "type": "zip", "url": "https://api.github.com/repos/aliyun/aliyun-oss-php-sdk/zipball/e69f57916678458642ac9d2fd341ae78a56996c8", "reference": "e69f57916678458642ac9d2fd341ae78a56996c8", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "php": ">=5.3" @@ -59,7 +65,13 @@ "type": "zip", "url": "https://api.github.com/repos/guzzle/guzzle3/zipball/0645b70d953bc1c067bbc8d5bc53194706b628d9", "reference": "0645b70d953bc1c067bbc8d5bc53194706b628d9", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "ext-curl": "*", @@ -155,7 +167,13 @@ "type": "zip", "url": "https://api.github.com/repos/guzzle/guzzle/zipball/407b0cb880ace85c9b63c5f9551db498cb2d50ba", "reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "guzzlehttp/promises": "^1.0", @@ -220,7 +238,13 @@ "type": "zip", "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646", "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "php": ">=5.5.0" @@ -271,7 +295,13 @@ "type": "zip", "url": "https://api.github.com/repos/guzzle/psr7/zipball/9f83dded91781a01c63574e387eaa769be769115", "reference": "9f83dded91781a01c63574e387eaa769be769115", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "php": ">=5.4.0", @@ -328,17 +358,23 @@ }, { "name": "phpmailer/phpmailer", - "version": "v6.0.6", + "version": "v6.0.7", "source": { "type": "git", "url": "https://github.com/PHPMailer/PHPMailer.git", - "reference": "8190d73eb5def11a43cfb020b7f36db65330698c" + "reference": "0c41a36d4508d470e376498c1c0c527aa36a2d59" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/8190d73eb5def11a43cfb020b7f36db65330698c", - "reference": "8190d73eb5def11a43cfb020b7f36db65330698c", - "shasum": "" + "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/0c41a36d4508d470e376498c1c0c527aa36a2d59", + "reference": "0c41a36d4508d470e376498c1c0c527aa36a2d59", + "shasum": "", + "mirrors": [ + { + "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "ext-ctype": "*", @@ -390,7 +426,7 @@ } ], "description": "PHPMailer is a full-featured email creation and transfer class for PHP", - "time": "2018-11-16T00:41:32+00:00" + "time": "2019-02-01T15:04:28+00:00" }, { "name": "psr/http-message", @@ -404,7 +440,13 @@ "type": "zip", "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "php": ">=5.3.0" @@ -444,17 +486,23 @@ }, { "name": "qcloud/cos-sdk-v5", - "version": "v1.3.0", + "version": "v1.3.1", "source": { "type": "git", "url": "https://github.com/tencentyun/cos-php-sdk-v5.git", - "reference": "989c087a5aaf9b5df020b1d2633644e7c9f694e0" + "reference": "ca816d61a5412dd7a248119992b7d32687b10f86" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/tencentyun/cos-php-sdk-v5/zipball/989c087a5aaf9b5df020b1d2633644e7c9f694e0", - "reference": "989c087a5aaf9b5df020b1d2633644e7c9f694e0", - "shasum": "" + "url": "https://api.github.com/repos/tencentyun/cos-php-sdk-v5/zipball/ca816d61a5412dd7a248119992b7d32687b10f86", + "reference": "ca816d61a5412dd7a248119992b7d32687b10f86", + "shasum": "", + "mirrors": [ + { + "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "guzzle/guzzle": "~3.7", @@ -486,7 +534,7 @@ "php", "qcloud" ], - "time": "2018-11-27T13:31:54+00:00" + "time": "2019-01-28T12:46:20+00:00" }, { "name": "qiniu/php-sdk", @@ -500,7 +548,13 @@ "type": "zip", "url": "https://api.github.com/repos/qiniu/php-sdk/zipball/88d11a5857ebc6871204e9be6ceec54bf5f381e6", "reference": "88d11a5857ebc6871204e9be6ceec54bf5f381e6", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "php": ">=5.3.3" @@ -551,7 +605,13 @@ "type": "zip", "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/5601c8a83fbba7ef674a7369456d12f1e0d0eafa", "reference": "5601c8a83fbba7ef674a7369456d12f1e0d0eafa", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "php": ">=5.3" @@ -591,7 +651,13 @@ "type": "zip", "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/a77e974a5fecb4398833b0709210e3d5e334ffb0", "reference": "a77e974a5fecb4398833b0709210e3d5e334ffb0", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "php": ">=5.3.9" @@ -641,17 +707,23 @@ }, { "name": "topthink/framework", - "version": "v5.1.31", + "version": "v5.1.34", "source": { "type": "git", "url": "https://github.com/top-think/framework.git", - "reference": "93339b1a4df5a73e0143db0847a4c5e0b2e46fb0" + "reference": "7c8cd1ea2bd4683a6ef46af415334260c6e2cc15" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/top-think/framework/zipball/93339b1a4df5a73e0143db0847a4c5e0b2e46fb0", - "reference": "93339b1a4df5a73e0143db0847a4c5e0b2e46fb0", - "shasum": "" + "url": "https://api.github.com/repos/top-think/framework/zipball/7c8cd1ea2bd4683a6ef46af415334260c6e2cc15", + "reference": "7c8cd1ea2bd4683a6ef46af415334260c6e2cc15", + "shasum": "", + "mirrors": [ + { + "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "php": ">=5.6.0", @@ -688,7 +760,7 @@ "orm", "thinkphp" ], - "time": "2018-12-09T12:41:21+00:00" + "time": "2019-01-30T06:38:38+00:00" }, { "name": "topthink/think-captcha", @@ -702,7 +774,13 @@ "type": "zip", "url": "https://api.github.com/repos/top-think/think-captcha/zipball/54c8a51552f99ff9ea89ea9c272383a8f738ceee", "reference": "54c8a51552f99ff9ea89ea9c272383a8f738ceee", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "topthink/framework": "5.1.*" @@ -741,7 +819,13 @@ "type": "zip", "url": "https://api.github.com/repos/top-think/think-image/zipball/8586cf47f117481c6d415b20f7dedf62e79d5512", "reference": "8586cf47f117481c6d415b20f7dedf62e79d5512", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "ext-gd": "*" @@ -781,7 +865,13 @@ "type": "zip", "url": "https://api.github.com/repos/top-think/think-installer/zipball/f5400a12c60e513911aef41fe443fa6920952675", "reference": "f5400a12c60e513911aef41fe443fa6920952675", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "composer-plugin-api": "^1.0" @@ -822,7 +912,13 @@ "type": "zip", "url": "https://api.github.com/repos/upyun/php-sdk/zipball/1a2dd5ae31047956c733aef0f764f3a527d30628", "reference": "1a2dd5ae31047956c733aef0f764f3a527d30628", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "ext-curl": "*", diff --git a/thinkphp/helper.php b/thinkphp/helper.php index 9c465335..fc2ca8c8 100644 --- a/thinkphp/helper.php +++ b/thinkphp/helper.php @@ -313,9 +313,9 @@ if (!function_exists('download')) { * @param integer $expire 有效期(秒) * @return \think\response\Download */ - function download($filename, $name = '', $content = false, $expire = 360, $openinBrower = false) + function download($filename, $name = '', $content = false, $expire = 360, $openinBrowser = false) { - return Response::create($filename, 'download')->name($name)->isContent($content)->expire($expire)->openinBrower($openinBrower); + return Response::create($filename, 'download')->name($name)->isContent($content)->expire($expire)->openinBrowser($openinBrowser); } } @@ -533,7 +533,7 @@ if (!function_exists('response')) { * @param string $type * @return Response */ - function response($data = [], $code = 200, $header = [], $type = 'html') + function response($data = '', $code = 200, $header = [], $type = 'html') { return Response::create($data, $type, $code, $header); } diff --git a/thinkphp/library/think/App.php b/thinkphp/library/think/App.php index cfa2601e..6e713240 100644 --- a/thinkphp/library/think/App.php +++ b/thinkphp/library/think/App.php @@ -20,7 +20,7 @@ use think\route\Dispatch; */ class App extends Container { - const VERSION = '5.1.31 LTS'; + const VERSION = '5.1.34 LTS'; /** * 当前模块路径 @@ -722,9 +722,9 @@ class App extends Container list($module, $class) = $this->parseModuleAndClass($name, $layer, $appendSuffix); if (class_exists($class)) { - return $this->__get($class); + return $this->make($class, true); } elseif ($empty && class_exists($emptyClass = $this->parseClass($module, $layer, $empty, $appendSuffix))) { - return $this->__get($emptyClass); + return $this->make($emptyClass, true); } throw new ClassNotFoundException('class not exists:' . $class, $class); diff --git a/thinkphp/library/think/Controller.php b/thinkphp/library/think/Controller.php index a57da9e3..d16a1ed5 100644 --- a/thinkphp/library/think/Controller.php +++ b/thinkphp/library/think/Controller.php @@ -67,6 +67,8 @@ class Controller // 控制器初始化 $this->initialize(); + $this->registerMiddleware(); + // 前置操作方法 即将废弃 foreach ((array) $this->beforeActionList as $method => $options) { is_numeric($method) ? diff --git a/thinkphp/library/think/File.php b/thinkphp/library/think/File.php index b2906097..b24b7770 100644 --- a/thinkphp/library/think/File.php +++ b/thinkphp/library/think/File.php @@ -300,7 +300,7 @@ class File extends SplFileObject */ public function checkSize($size) { - if ($this->getSize() > $size) { + if ($this->getSize() > (int) $size) { $this->error = 'filesize not match'; return false; } diff --git a/thinkphp/library/think/Model.php b/thinkphp/library/think/Model.php index e0dcecf6..b22ee5bc 100644 --- a/thinkphp/library/think/Model.php +++ b/thinkphp/library/think/Model.php @@ -18,6 +18,33 @@ use think\db\Query; * Class Model * @package think * @mixin Query + * @method Query where(mixed $field, string $op = null, mixed $condition = null) static 查询条件 + * @method Query whereRaw(string $where, array $bind = []) static 表达式查询 + * @method Query whereExp(string $field, string $condition, array $bind = []) static 字段表达式查询 + * @method Query when(mixed $condition, mixed $query, mixed $otherwise = null) static 条件查询 + * @method Query join(mixed $join, mixed $condition = null, string $type = 'INNER') static JOIN查询 + * @method Query view(mixed $join, mixed $field = null, mixed $on = null, string $type = 'INNER') static 视图查询 + * @method Query with(mixed $with) static 关联预载入 + * @method Query count(string $field) static Count统计查询 + * @method Query min(string $field) static Min统计查询 + * @method Query max(string $field) static Max统计查询 + * @method Query sum(string $field) static SUM统计查询 + * @method Query avg(string $field) static Avg统计查询 + * @method Query field(mixed $field, boolean $except = false) static 指定查询字段 + * @method Query fieldRaw(string $field, array $bind = []) static 指定查询字段 + * @method Query union(mixed $union, boolean $all = false) static UNION查询 + * @method Query limit(mixed $offset, integer $length = null) static 查询LIMIT + * @method Query order(mixed $field, string $order = null) static 查询ORDER + * @method Query orderRaw(string $field, array $bind = []) static 查询ORDER + * @method Query cache(mixed $key = null , integer $expire = null) static 设置查询缓存 + * @method mixed value(string $field) static 获取某个字段的值 + * @method array column(string $field, string $key = '') static 获取某个列的值 + * @method mixed find(mixed $data = null) static 查询单个记录 + * @method mixed select(mixed $data = null) static 查询多个记录 + * @method mixed get(mixed $data = null,mixed $with =[],bool $cache= false) static 查询单个记录 支持关联预载入 + * @method mixed getOrFail(mixed $data = null,mixed $with =[],bool $cache= false) static 查询单个记录 不存在则抛出异常 + * @method mixed findOrEmpty(mixed $data = null,mixed $with =[],bool $cache= false) static 查询单个记录 不存在则返回空模型 + * @method mixed all(mixed $data = null,mixed $with =[],bool $cache= false) static 查询多个记录 支持关联预载入 * @method \think\Model withAttr(array $name,\Closure $closure) 动态定义获取器 */ abstract class Model implements \JsonSerializable, \ArrayAccess @@ -392,11 +419,12 @@ abstract class Model implements \JsonSerializable, \ArrayAccess * 设置数据是否存在 * @access public * @param bool $exists - * @return void + * @return $this */ public function exists($exists) { $this->exists = $exists; + return $this; } /** diff --git a/thinkphp/library/think/Request.php b/thinkphp/library/think/Request.php index 6ba6e7d7..f6529d03 100644 --- a/thinkphp/library/think/Request.php +++ b/thinkphp/library/think/Request.php @@ -809,9 +809,14 @@ class Request return $this->server('REQUEST_METHOD') ?: 'GET'; } elseif (!$this->method) { if (isset($_POST[$this->config['var_method']])) { - $this->method = strtoupper($_POST[$this->config['var_method']]); - $method = strtolower($this->method); - $this->{$method} = $_POST; + $method = strtolower($_POST[$this->config['var_method']]); + if (in_array($method, ['get', 'post', 'put', 'patch', 'delete'])) { + $this->method = strtoupper($method); + $this->{$method} = $_POST; + } else { + $this->method = 'POST'; + } + unset($_POST[$this->config['var_method']]); } elseif ($this->server('HTTP_X_HTTP_METHOD_OVERRIDE')) { $this->method = strtoupper($this->server('HTTP_X_HTTP_METHOD_OVERRIDE')); } else { @@ -1320,7 +1325,8 @@ class Request * @param array $data 数据源 * @return void */ - public function arrayReset(array &$data) { + public function arrayReset(array &$data) + { foreach ($data as &$value) { if (is_array($value)) { $this->arrayReset($value); @@ -1523,7 +1529,7 @@ class Request */ public function has($name, $type = 'param', $checkEmpty = false) { - if (!in_array($type, ['param', 'get', 'post', 'request', 'put', 'file', 'session', 'cookie', 'env', 'header', 'route'])) { + if (!in_array($type, ['param', 'get', 'post', 'request', 'put', 'patch', 'file', 'session', 'cookie', 'env', 'header', 'route'])) { return false; } diff --git a/thinkphp/library/think/Route.php b/thinkphp/library/think/Route.php index 7bd468ba..44af9871 100644 --- a/thinkphp/library/think/Route.php +++ b/thinkphp/library/think/Route.php @@ -408,7 +408,7 @@ class Route $result = $this->bind[$domain]; } elseif (isset($name) && isset($this->bind[$name])) { $result = $this->bind[$name]; - } elseif (isset($this->bind['*'])) { + } elseif (!empty($subDomain) && isset($this->bind['*'])) { $result = $this->bind['*']; } else { $result = null; diff --git a/thinkphp/library/think/Template.php b/thinkphp/library/think/Template.php index dc1acfa5..2855cbcb 100644 --- a/thinkphp/library/think/Template.php +++ b/thinkphp/library/think/Template.php @@ -1311,7 +1311,7 @@ class Template public function __debugInfo() { $data = get_object_vars($this); - unset($data['app'], $data['storege']); + unset($data['app'], $data['storage']); return $data; } diff --git a/thinkphp/library/think/Validate.php b/thinkphp/library/think/Validate.php index 4672a5cb..12cefc0f 100644 --- a/thinkphp/library/think/Validate.php +++ b/thinkphp/library/think/Validate.php @@ -131,7 +131,7 @@ class Validate * 内置正则验证规则 * @var array */ - protected $regex = [ + protected $defaultRegex = [ 'alphaDash' => '/^[A-Za-z0-9\-\_]+$/', 'chs' => '/^[\x{4e00}-\x{9fa5}]+$/u', 'chsAlpha' => '/^[\x{4e00}-\x{9fa5}a-zA-Z]+$/u', @@ -178,6 +178,12 @@ class Validate */ protected $append = []; + /** + * 验证正则定义 + * @var array + */ + protected $regex = []; + /** * 架构函数 * @access public @@ -516,7 +522,7 @@ class Validate $rules = array_merge($rules, $this->append[$field]); } - $i = 0; + $i = 0; $result = true; foreach ($rules as $key => $rule) { @@ -561,10 +567,11 @@ class Validate } elseif (true !== $result) { // 返回自定义错误信息 if (is_string($result) && false !== strpos($result, ':')) { - $result = str_replace( - [':attribute', ':rule'], - [$title, (string) $rule], - $result); + $result = str_replace(':attribute', $title, $result); + + if (strpos($result, ':rule') && is_scalar($rule)) { + $msg = str_replace(':rule', (string) $rule, $result); + } } return $result; @@ -1002,10 +1009,16 @@ class Validate // 支持多个字段验证 $fields = explode('^', $key); foreach ($fields as $key) { - $map[] = [$key, '=', $data[$key]]; + if (isset($data[$key])) { + $map[] = [$key, '=', $data[$key]]; + } } - } else { + } elseif (strpos($key, '=')) { + parse_str($key, $map); + } elseif (isset($data[$field])) { $map[] = [$key, '=', $data[$field]]; + } else { + $map = []; } $pk = !empty($rule[3]) ? $rule[3] : $db->getPk(); @@ -1356,6 +1369,8 @@ class Validate { if (isset($this->regex[$rule])) { $rule = $this->regex[$rule]; + } elseif (isset($this->defaultRegex[$rule])) { + $rule = $this->defaultRegex[$rule]; } if (0 !== strpos($rule, '/') && !preg_match('/\/[imsU]{0,4}$/', $rule)) { @@ -1457,13 +1472,17 @@ class Validate $msg = $title . $lang->get('not conform to the rules'); } - if (is_string($msg) && 0 === strpos($msg, '{%')) { + if (!is_string($msg)) { + return $msg; + } + + if (0 === strpos($msg, '{%')) { $msg = $lang->get(substr($msg, 2, -1)); } elseif ($lang->has($msg)) { $msg = $lang->get($msg); } - if (is_string($msg) && is_scalar($rule) && false !== strpos($msg, ':')) { + if (is_scalar($rule) && false !== strpos($msg, ':')) { // 变量替换 if (is_string($rule) && strpos($rule, ',')) { $array = array_pad(explode(',', $rule), 3, ''); @@ -1471,9 +1490,12 @@ class Validate $array = array_pad([], 3, ''); } $msg = str_replace( - [':attribute', ':rule', ':1', ':2', ':3'], - [$title, (string) $rule, $array[0], $array[1], $array[2]], + [':attribute', ':1', ':2', ':3'], + [$title, $array[0], $array[1], $array[2]], $msg); + if (strpos($msg, ':rule')) { + $msg = str_replace(':rule', (string) $rule, $msg); + } } return $msg; diff --git a/thinkphp/library/think/cache/Driver.php b/thinkphp/library/think/cache/Driver.php index f0ec7baf..f4c5dcbf 100644 --- a/thinkphp/library/think/cache/Driver.php +++ b/thinkphp/library/think/cache/Driver.php @@ -219,7 +219,7 @@ abstract class Driver } elseif (is_null($keys)) { $this->tag = $name; } else { - $key = 'tag_' . md5($name); + $key = $this->getTagkey($name); if (is_string($keys)) { $keys = explode(',', $keys); @@ -248,14 +248,19 @@ abstract class Driver protected function setTagItem($name) { if ($this->tag) { - $key = 'tag_' . md5($this->tag); + $key = $this->getTagkey($this->tag); $prev = $this->tag; $this->tag = null; if ($this->has($key)) { $value = explode(',', $this->get($key)); $value[] = $name; - $value = implode(',', array_unique($value)); + + if (count($value) > 1000) { + array_shift($value); + } + + $value = implode(',', array_unique($value)); } else { $value = $name; } @@ -273,7 +278,7 @@ abstract class Driver */ protected function getTagItem($tag) { - $key = 'tag_' . md5($tag); + $key = $this->getTagkey($tag); $value = $this->get($key); if ($value) { @@ -283,6 +288,11 @@ abstract class Driver } } + protected function getTagKey($tag) + { + return 'tag_' . md5($tag); + } + /** * 序列化数据 * @access protected diff --git a/thinkphp/library/think/cache/driver/File.php b/thinkphp/library/think/cache/driver/File.php index 7c5661e3..93d321f2 100644 --- a/thinkphp/library/think/cache/driver/File.php +++ b/thinkphp/library/think/cache/driver/File.php @@ -266,7 +266,7 @@ class File extends Driver foreach ($keys as $key) { $this->unlink($key); } - $this->rm('tag_' . md5($tag)); + $this->rm($this->getTagKey($tag)); return true; } diff --git a/thinkphp/library/think/cache/driver/Lite.php b/thinkphp/library/think/cache/driver/Lite.php index 544663c0..0cfe3907 100644 --- a/thinkphp/library/think/cache/driver/Lite.php +++ b/thinkphp/library/think/cache/driver/Lite.php @@ -198,7 +198,7 @@ class Lite extends Driver unlink($key); } - $this->rm('tag_' . md5($tag)); + $this->rm($this->getTagKey($tag)); return true; } diff --git a/thinkphp/library/think/cache/driver/Memcache.php b/thinkphp/library/think/cache/driver/Memcache.php index 162ca520..1c535597 100644 --- a/thinkphp/library/think/cache/driver/Memcache.php +++ b/thinkphp/library/think/cache/driver/Memcache.php @@ -188,11 +188,13 @@ class Memcache extends Driver if ($tag) { // 指定标签清除 $keys = $this->getTagItem($tag); + foreach ($keys as $key) { $this->handler->delete($key); } - $this->rm('tag_' . md5($tag)); + $tagName = $this->getTagKey($tag); + $this->rm($tagName); return true; } @@ -200,4 +202,5 @@ class Memcache extends Driver return $this->handler->flush(); } + } diff --git a/thinkphp/library/think/cache/driver/Memcached.php b/thinkphp/library/think/cache/driver/Memcached.php index d04fac08..6af60d19 100644 --- a/thinkphp/library/think/cache/driver/Memcached.php +++ b/thinkphp/library/think/cache/driver/Memcached.php @@ -204,7 +204,7 @@ class Memcached extends Driver $keys = $this->getTagItem($tag); $this->handler->deleteMulti($keys); - $this->rm('tag_' . md5($tag)); + $this->rm($this->getTagKey($tag)); return true; } @@ -213,4 +213,67 @@ class Memcached extends Driver return $this->handler->flush(); } + + /** + * 缓存标签 + * @access public + * @param string $name 标签名 + * @param string|array $keys 缓存标识 + * @param bool $overlay 是否覆盖 + * @return $this + */ + public function tag($name, $keys = null, $overlay = false) + { + if (is_null($keys)) { + $this->tag = $name; + } else { + $tagName = $this->getTagKey($name); + if ($overlay) { + $this->handler->delete($tagName); + } + + if (!$this->handler->has($tagName)) { + $this->handler->set($tagName, ''); + } + + foreach ($keys as $key) { + $this->handler->append($tagName, ',' . $key); + } + } + + return $this; + } + + /** + * 更新标签 + * @access protected + * @param string $name 缓存标识 + * @return void + */ + protected function setTagItem($name) + { + if ($this->tag) { + $tagName = $this->getTagKey($this->tag); + + if ($this->handler->has($tagName)) { + $this->handler->append($tagName, ',' . $name); + } else { + $this->handler->set($tagName, $name); + } + + $this->tag = null; + } + } + + /** + * 获取标签包含的缓存标识 + * @access public + * @param string $tag 缓存标签 + * @return array + */ + public function getTagItem($tag) + { + $tagName = $this->getTagKey($tag); + return explode(',', trim($this->handler->get($tagName), ',')); + } } diff --git a/thinkphp/library/think/cache/driver/Redis.php b/thinkphp/library/think/cache/driver/Redis.php index b924ec3d..813746e7 100644 --- a/thinkphp/library/think/cache/driver/Redis.php +++ b/thinkphp/library/think/cache/driver/Redis.php @@ -70,6 +70,10 @@ class Redis extends Driver } } + if ('' == $this->options['password']) { + unset($this->options['password']); + } + $this->handler = new \Predis\Client($this->options, $params); $this->options['prefix'] = ''; @@ -187,7 +191,7 @@ class Redis extends Driver { $this->writeTimes++; - return $this->handler->delete($this->getCacheKey($name)); + return $this->handler->del($this->getCacheKey($name)); } /** @@ -202,11 +206,10 @@ class Redis extends Driver // 指定标签清除 $keys = $this->getTagItem($tag); - foreach ($keys as $key) { - $this->handler->delete($key); - } + $this->handler->del($keys); - $this->rm('tag_' . md5($tag)); + $tagName = $this->getTagKey($tag); + $this->handler->del($tagName); return true; } @@ -215,4 +218,55 @@ class Redis extends Driver return $this->handler->flushDB(); } + /** + * 缓存标签 + * @access public + * @param string $name 标签名 + * @param string|array $keys 缓存标识 + * @param bool $overlay 是否覆盖 + * @return $this + */ + public function tag($name, $keys = null, $overlay = false) + { + if (is_null($keys)) { + $this->tag = $name; + } else { + $tagName = $this->getTagKey($name); + if ($overlay) { + $this->handler->del($tagName); + } + + foreach ($keys as $key) { + $this->handler->sAdd($tagName, $key); + } + } + + return $this; + } + + /** + * 更新标签 + * @access protected + * @param string $name 缓存标识 + * @return void + */ + protected function setTagItem($name) + { + if ($this->tag) { + $tagName = $this->getTagKey($this->tag); + $this->handler->sAdd($tagName, $name); + } + } + + /** + * 获取标签包含的缓存标识 + * @access protected + * @param string $tag 缓存标签 + * @return array + */ + protected function getTagItem($tag) + { + $tagName = $this->getTagKey($tag); + return $this->handler->sMembers($tagName); + } } diff --git a/thinkphp/library/think/cache/driver/Sqlite.php b/thinkphp/library/think/cache/driver/Sqlite.php index 7e78ec12..f57361e3 100644 --- a/thinkphp/library/think/cache/driver/Sqlite.php +++ b/thinkphp/library/think/cache/driver/Sqlite.php @@ -216,7 +216,7 @@ class Sqlite extends Driver public function clear($tag = null) { if ($tag) { - $name = sqlite_escape_string($tag); + $name = sqlite_escape_string($this->getTagKey($tag)); $sql = 'DELETE FROM ' . $this->options['table'] . ' WHERE tag=\'' . $name . '\''; sqlite_query($this->handler, $sql); return true; diff --git a/thinkphp/library/think/cache/driver/Wincache.php b/thinkphp/library/think/cache/driver/Wincache.php index 10966e78..ef157841 100644 --- a/thinkphp/library/think/cache/driver/Wincache.php +++ b/thinkphp/library/think/cache/driver/Wincache.php @@ -160,15 +160,16 @@ class Wincache extends Driver { if ($tag) { $keys = $this->getTagItem($tag); - foreach ($keys as $key) { - wincache_ucache_delete($key); - } - $this->rm('tag_' . md5($tag)); + + wincache_ucache_delete($keys); + + $tagName = $this->getTagkey($tag); + $this->rm($tagName); return true; - } else { - $this->writeTimes++; - return wincache_ucache_clear(); } + + $this->writeTimes++; + return wincache_ucache_clear(); } } diff --git a/thinkphp/library/think/cache/driver/Xcache.php b/thinkphp/library/think/cache/driver/Xcache.php index 6d1bf3f6..4e698597 100644 --- a/thinkphp/library/think/cache/driver/Xcache.php +++ b/thinkphp/library/think/cache/driver/Xcache.php @@ -159,10 +159,12 @@ class Xcache extends Driver if ($tag) { // 指定标签清除 $keys = $this->getTagItem($tag); + foreach ($keys as $key) { xcache_unset($key); } - $this->rm('tag_' . md5($tag)); + + $this->rm($this->getTagKey($tag)); return true; } diff --git a/thinkphp/library/think/db/Builder.php b/thinkphp/library/think/db/Builder.php index 3dbbf768..7f810059 100644 --- a/thinkphp/library/think/db/Builder.php +++ b/thinkphp/library/think/db/Builder.php @@ -647,6 +647,8 @@ abstract class Builder // IN 查询 if ($value instanceof \Closure) { $value = $this->parseClosure($query, $value, false); + } elseif ($value instanceof Expression) { + $value = $value->getValue(); } else { $value = array_unique(is_array($value) ? $value : explode(',', $value)); diff --git a/thinkphp/library/think/db/Query.php b/thinkphp/library/think/db/Query.php index 00483328..df23b8f8 100644 --- a/thinkphp/library/think/db/Query.php +++ b/thinkphp/library/think/db/Query.php @@ -611,9 +611,9 @@ class Query /** * 聚合查询 * @access public - * @param string $aggregate 聚合方法 - * @param string $field 字段名 - * @param bool $force 强制转为数字类型 + * @param string $aggregate 聚合方法 + * @param string|Expression $field 字段名 + * @param bool $force 强制转为数字类型 * @return mixed */ public function aggregate($aggregate, $field, $force = false) @@ -628,16 +628,13 @@ class Query $result = (float) $result; } - // 查询完成后清空聚合字段信息 - $this->removeOption('field'); - return $result; } /** * COUNT查询 * @access public - * @param string $field 字段名 + * @param string|Expression $field 字段名 * @return float|string */ public function count($field = '*') @@ -667,7 +664,7 @@ class Query /** * SUM查询 * @access public - * @param string $field 字段名 + * @param string|Expression $field 字段名 * @return float */ public function sum($field) @@ -678,8 +675,8 @@ class Query /** * MIN查询 * @access public - * @param string $field 字段名 - * @param bool $force 强制转为数字类型 + * @param string|Expression $field 字段名 + * @param bool $force 强制转为数字类型 * @return mixed */ public function min($field, $force = true) @@ -690,8 +687,8 @@ class Query /** * MAX查询 * @access public - * @param string $field 字段名 - * @param bool $force 强制转为数字类型 + * @param string|Expression $field 字段名 + * @param bool $force 强制转为数字类型 * @return mixed */ public function max($field, $force = true) @@ -702,7 +699,7 @@ class Query /** * AVG查询 * @access public - * @param string $field 字段名 + * @param string|Expression $field 字段名 * @return float */ public function avg($field) @@ -837,9 +834,10 @@ class Query * @param mixed $join 关联的表名 * @param mixed $condition 条件 * @param string $type JOIN类型 + * @param array $bind 参数绑定 * @return $this */ - public function join($join, $condition = null, $type = 'INNER') + public function join($join, $condition = null, $type = 'INNER', $bind = []) { if (empty($condition)) { // 如果为组数,则循环调用join @@ -850,7 +848,9 @@ class Query } } else { $table = $this->getJoinTable($join); - + if ($bind) { + $this->bindParams($condition, $bind); + } $this->options['join'][] = [$table, strtoupper($type), $condition]; } @@ -862,9 +862,10 @@ class Query * @access public * @param mixed $join 关联的表名 * @param mixed $condition 条件 + * @param array $bind 参数绑定 * @return $this */ - public function leftJoin($join, $condition = null) + public function leftJoin($join, $condition = null, $bind = []) { return $this->join($join, $condition, 'LEFT'); } @@ -874,9 +875,10 @@ class Query * @access public * @param mixed $join 关联的表名 * @param mixed $condition 条件 + * @param array $bind 参数绑定 * @return $this */ - public function rightJoin($join, $condition = null) + public function rightJoin($join, $condition = null, $bind = []) { return $this->join($join, $condition, 'RIGHT'); } @@ -886,9 +888,10 @@ class Query * @access public * @param mixed $join 关联的表名 * @param mixed $condition 条件 + * @param array $bind 参数绑定 * @return $this */ - public function fullJoin($join, $condition = null) + public function fullJoin($join, $condition = null, $bind = []) { return $this->join($join, $condition, 'FULL'); } @@ -946,6 +949,10 @@ class Query */ public function union($union, $all = false) { + if (empty($union)) { + return $this; + } + $this->options['union']['type'] = $all ? 'UNION ALL' : 'UNION'; if (is_array($union)) { @@ -1523,7 +1530,7 @@ class Query return $this->whereRaw($field, is_array($op) ? $op : []); } elseif ($strict) { // 使用严格模式查询 - $where = [$field, $op, $condition]; + $where = [$field, $op, $condition, $logic]; } elseif (is_array($field)) { // 解析数组批量查询 return $this->parseArrayWhereItems($field, $logic); @@ -1575,7 +1582,7 @@ class Query // 字段相等查询 $where = [$field, '=', $op]; } - } elseif (in_array(strtoupper($op), ['REGEXP', 'NOT REGEXP', 'EXISTS', 'NOT EXISTS', 'NOTEXISTS'], true)) { + } elseif (in_array(strtoupper($op), ['EXISTS', 'NOT EXISTS', 'NOTEXISTS'], true)) { $where = [$field, $op, is_string($condition) ? $this->raw($condition) : $condition]; } else { $where = $field ? [$field, $op, $condition, isset($param[2]) ? $param[2] : null] : null; diff --git a/thinkphp/library/think/db/builder/Mysql.php b/thinkphp/library/think/db/builder/Mysql.php index 7ec3bf85..22f33900 100644 --- a/thinkphp/library/think/db/builder/Mysql.php +++ b/thinkphp/library/think/db/builder/Mysql.php @@ -94,13 +94,17 @@ class Mysql extends Builder * @param Query $query 查询对象 * @param string $key * @param string $exp - * @param Expression $value + * @param mixed $value * @param string $field * @return string */ - protected function parseRegexp(Query $query, $key, $exp, Expression $value, $field) + protected function parseRegexp(Query $query, $key, $exp, $value, $field) { - return $key . ' ' . $exp . ' ' . $value->getValue(); + if ($value instanceof Expression) { + $value = $value->getValue(); + } + + return $key . ' ' . $exp . ' ' . $value; } /** @@ -145,7 +149,7 @@ class Mysql extends Builder throw new Exception('not support data:' . $key); } - if ('*' != $key && ($strict || !preg_match('/[,\'\"\*\(\)`.\s]/', $key))) { + if ('*' != $key && !preg_match('/[,\'\"\*\(\)`.\s]/', $key)) { $key = '`' . $key . '`'; } diff --git a/thinkphp/library/think/db/builder/Sqlsrv.php b/thinkphp/library/think/db/builder/Sqlsrv.php index e24f7d25..ef27aafa 100644 --- a/thinkphp/library/think/db/builder/Sqlsrv.php +++ b/thinkphp/library/think/db/builder/Sqlsrv.php @@ -114,7 +114,7 @@ class Sqlsrv extends Builder throw new Exception('not support data:' . $key); } - if ('*' != $key && ($strict || !preg_match('/[,\'\"\*\(\)\[.\s]/', $key))) { + if ('*' != $key && !preg_match('/[,\'\"\*\(\)\[.\s]/', $key)) { $key = '[' . $key . ']'; } diff --git a/thinkphp/library/think/log/driver/File.php b/thinkphp/library/think/log/driver/File.php index 10f745d2..c506105f 100644 --- a/thinkphp/library/think/log/driver/File.php +++ b/thinkphp/library/think/log/driver/File.php @@ -19,7 +19,7 @@ use think\App; class File { protected $config = [ - 'time_format' => ' c ', + 'time_format' => 'c', 'single' => false, 'file_size' => 2097152, 'path' => '', @@ -107,7 +107,13 @@ class File $info['timestamp'] = date($this->config['time_format']); foreach ($message as $type => $msg) { - $info[$type] = is_array($msg) ? implode("\r\n", $msg) : $msg; + $msg = is_array($msg) ? implode("\r\n", $msg) : $msg; + if (PHP_SAPI == 'cli') { + $info['msg'] = $msg; + $info['type'] = $type; + } else { + $info[$type] = $msg; + } } if (PHP_SAPI == 'cli') { @@ -140,13 +146,13 @@ class File } } + $cli = PHP_SAPI == 'cli' ? '_cli' : ''; + if ($this->config['single']) { $name = is_string($this->config['single']) ? $this->config['single'] : 'single'; - $destination = $this->config['path'] . $name . '.log'; + $destination = $this->config['path'] . $name . $cli . '.log'; } else { - $cli = PHP_SAPI == 'cli' ? '_cli' : ''; - if ($this->config['max_files']) { $filename = date('Ymd') . $cli . '.log'; } else { @@ -172,15 +178,13 @@ class File if ($this->config['single']) { $name = is_string($this->config['single']) ? $this->config['single'] : 'single'; - - $name .= '_' . $type; } elseif ($this->config['max_files']) { - $name = date('Ymd') . '_' . $type . $cli; + $name = date('Ymd'); } else { - $name = date('d') . '_' . $type . $cli; + $name = date('d'); } - return $path . DIRECTORY_SEPARATOR . $name . '.log'; + return $path . DIRECTORY_SEPARATOR . $name . '_' . $type . $cli . '.log'; } /** diff --git a/thinkphp/library/think/model/concern/Attribute.php b/thinkphp/library/think/model/concern/Attribute.php index 75b02ab5..0605478a 100644 --- a/thinkphp/library/think/model/concern/Attribute.php +++ b/thinkphp/library/think/model/concern/Attribute.php @@ -12,6 +12,7 @@ namespace think\model\concern; use InvalidArgumentException; +use think\db\Expression; use think\Exception; use think\Loader; use think\model\Relation; @@ -371,7 +372,8 @@ trait Attribute case 'datetime': case 'date': $format = !empty($param) ? $param : $this->dateFormat; - $value = $this->formatDateTime($format . '.u'); + $format .= strpos($format, 'u') || false !== strpos($format, '\\') ? '' : '.u'; + $value = $this->formatDateTime($format); break; case 'timestamp': case 'integer': @@ -384,7 +386,8 @@ trait Attribute 'date', 'timestamp', ])) { - $value = $this->formatDateTime($this->dateFormat . '.u'); + $format = strpos($this->dateFormat, 'u') || false !== strpos($this->dateFormat, '\\') ? '' : '.u'; + $value = $this->formatDateTime($this->dateFormat . $format); } else { $value = time(); } @@ -405,6 +408,10 @@ trait Attribute return; } + if ($value instanceof Expression) { + return $value; + } + if (is_array($type)) { list($type, $param) = $type; } elseif (strpos($type, ':')) { diff --git a/thinkphp/library/think/model/relation/BelongsToMany.php b/thinkphp/library/think/model/relation/BelongsToMany.php index b7cdebe1..54df68b0 100644 --- a/thinkphp/library/think/model/relation/BelongsToMany.php +++ b/thinkphp/library/think/model/relation/BelongsToMany.php @@ -559,7 +559,10 @@ class BelongsToMany extends Relation foreach ($ids as $id) { $pivot[$this->foreignKey] = $id; - $this->pivot->replace()->save($pivot); + $this->pivot->replace() + ->exists(false) + ->data([]) + ->save($pivot); $result[] = $this->newPivot($pivot, true); } diff --git a/thinkphp/library/think/model/relation/HasMany.php b/thinkphp/library/think/model/relation/HasMany.php index 72d83144..dbb8fa08 100644 --- a/thinkphp/library/think/model/relation/HasMany.php +++ b/thinkphp/library/think/model/relation/HasMany.php @@ -241,9 +241,9 @@ class HasMany extends Relation */ public function save($data, $replace = true) { - $model = $this->make($data); + $model = $this->make(); - return $model->replace($replace)->save() ? $model : false; + return $model->replace($replace)->save($data) ? $model : false; } /** diff --git a/thinkphp/library/think/model/relation/MorphMany.php b/thinkphp/library/think/model/relation/MorphMany.php index 1a7f15eb..a1f54889 100644 --- a/thinkphp/library/think/model/relation/MorphMany.php +++ b/thinkphp/library/think/model/relation/MorphMany.php @@ -277,7 +277,7 @@ class MorphMany extends Relation */ public function save($data) { - $model = $this->make($data); + $model = $this->make(); return $model->save($data) ? $model : false; } diff --git a/thinkphp/library/think/model/relation/MorphOne.php b/thinkphp/library/think/model/relation/MorphOne.php index 716539f4..775b2dfd 100644 --- a/thinkphp/library/think/model/relation/MorphOne.php +++ b/thinkphp/library/think/model/relation/MorphOne.php @@ -211,8 +211,8 @@ class MorphOne extends Relation */ public function save($data) { - $model = $this->make($data); - return $model->save() ? $model : false; + $model = $this->make(); + return $model->save($data) ? $model : false; } /** diff --git a/thinkphp/library/think/response/Download.php b/thinkphp/library/think/response/Download.php index d5fcb444..5595f9ab 100644 --- a/thinkphp/library/think/response/Download.php +++ b/thinkphp/library/think/response/Download.php @@ -20,7 +20,7 @@ class Download extends Response protected $name; protected $mimeType; protected $isContent = false; - protected $openinBrower = false; + protected $openinBrowser = false; /** * 处理数据 * @access protected @@ -53,7 +53,7 @@ class Download 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'] = $this->openinBrower ? 'inline' : 'attachment; filename="' . $name . '"'; + $this->header['Content-Disposition'] = $this->openinBrowser ? 'inline' : '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'; @@ -138,11 +138,11 @@ class Download extends Response /** * 设置是否在浏览器中显示文件 * @access public - * @param bool $openinBrower 是否在浏览器中显示文件 + * @param bool $openinBrowser 是否在浏览器中显示文件 * @return $this */ - public function openinBrower($openinBrower) { - $this->openinBrower = $openinBrower; + public function openinBrowser($openinBrowser) { + $this->openinBrowser = $openinBrowser; return $this; } } diff --git a/thinkphp/library/think/route/Rule.php b/thinkphp/library/think/route/Rule.php index 35730fee..f841ada6 100644 --- a/thinkphp/library/think/route/Rule.php +++ b/thinkphp/library/think/route/Rule.php @@ -722,13 +722,17 @@ abstract class Rule // 替换路由地址中的变量 if (is_string($route) && !empty($matches)) { - foreach ($matches as $key => $val) { - if (false !== strpos($route, '<' . $key . '>')) { - $route = str_replace('<' . $key . '>', $val, $route); - } elseif (false !== strpos($route, ':' . $key)) { - $route = str_replace(':' . $key, $val, $route); - } + $search = $replace = []; + + foreach ($matches as $key => $value) { + $search[] = '<' . $key . '>'; + $replace[] = $value; + + $search[] = ':' . $key; + $replace[] = $value; } + + $route = str_replace($search, $replace, $route); } // 解析额外参数 @@ -997,7 +1001,7 @@ abstract class Rule } } - $regex = str_replace($match, $replace, $rule); + $regex = str_replace(array_unique($match), array_unique($replace), $rule); $regex = str_replace([')?/', ')/', ')?-', ')-', '\\\\/'], [')\/', ')\/', ')\-', ')\-', '\/'], $regex); if (isset($hasSlash)) { diff --git a/thinkphp/library/think/route/dispatch/Module.php b/thinkphp/library/think/route/dispatch/Module.php index dc1974ce..e8842cd3 100644 --- a/thinkphp/library/think/route/dispatch/Module.php +++ b/thinkphp/library/think/route/dispatch/Module.php @@ -69,10 +69,6 @@ class Module extends Dispatch // 获取控制器名 $controller = strip_tags($result[1] ?: $this->rule->getConfig('default_controller')); - if (!preg_match('/^[A-Za-z](\w|\.)*$/', $controller)) { - throw new HttpException(404, 'controller not exists:' . $controller); - } - $this->controller = $convert ? strtolower($controller) : $controller; // 获取操作名 @@ -97,10 +93,6 @@ class Module extends Dispatch $this->rule->getConfig('url_controller_layer'), $this->rule->getConfig('controller_suffix'), $this->rule->getConfig('empty_controller')); - - if ($instance instanceof Controller) { - $instance->registerMiddleware(); - } } catch (ClassNotFoundException $e) { throw new HttpException(404, 'controller not exists:' . $e->getClass()); } diff --git a/thinkphp/library/think/route/dispatch/Url.php b/thinkphp/library/think/route/dispatch/Url.php index 95ee9e53..00dc8cca 100644 --- a/thinkphp/library/think/route/dispatch/Url.php +++ b/thinkphp/library/think/route/dispatch/Url.php @@ -60,6 +60,10 @@ class Url extends Dispatch $controller = !empty($path) ? array_shift($path) : null; } + if ($controller && !preg_match('/^[A-Za-z][\w|\.]*$/', $controller)) { + throw new HttpException(404, 'controller not exists:' . $controller); + } + // 解析操作 $action = !empty($path) ? array_shift($path) : null; diff --git a/vendor/composer/ClassLoader.php b/vendor/composer/ClassLoader.php index fce8549f..95f7e097 100644 --- a/vendor/composer/ClassLoader.php +++ b/vendor/composer/ClassLoader.php @@ -279,7 +279,7 @@ class ClassLoader */ public function setApcuPrefix($apcuPrefix) { - $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; + $this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null; } /** diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index cad0b7ec..530972d2 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -12,7 +12,13 @@ "type": "zip", "url": "https://api.github.com/repos/aliyun/aliyun-oss-php-sdk/zipball/e69f57916678458642ac9d2fd341ae78a56996c8", "reference": "e69f57916678458642ac9d2fd341ae78a56996c8", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "php": ">=5.3" @@ -55,7 +61,13 @@ "type": "zip", "url": "https://api.github.com/repos/guzzle/guzzle3/zipball/0645b70d953bc1c067bbc8d5bc53194706b628d9", "reference": "0645b70d953bc1c067bbc8d5bc53194706b628d9", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "ext-curl": "*", @@ -153,7 +165,13 @@ "type": "zip", "url": "https://api.github.com/repos/guzzle/guzzle/zipball/407b0cb880ace85c9b63c5f9551db498cb2d50ba", "reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "guzzlehttp/promises": "^1.0", @@ -220,7 +238,13 @@ "type": "zip", "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646", "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "php": ">=5.5.0" @@ -273,7 +297,13 @@ "type": "zip", "url": "https://api.github.com/repos/guzzle/psr7/zipball/9f83dded91781a01c63574e387eaa769be769115", "reference": "9f83dded91781a01c63574e387eaa769be769115", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "php": ">=5.4.0", @@ -331,18 +361,24 @@ }, { "name": "phpmailer/phpmailer", - "version": "v6.0.6", - "version_normalized": "6.0.6.0", + "version": "v6.0.7", + "version_normalized": "6.0.7.0", "source": { "type": "git", "url": "https://github.com/PHPMailer/PHPMailer.git", - "reference": "8190d73eb5def11a43cfb020b7f36db65330698c" + "reference": "0c41a36d4508d470e376498c1c0c527aa36a2d59" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/8190d73eb5def11a43cfb020b7f36db65330698c", - "reference": "8190d73eb5def11a43cfb020b7f36db65330698c", - "shasum": "" + "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/0c41a36d4508d470e376498c1c0c527aa36a2d59", + "reference": "0c41a36d4508d470e376498c1c0c527aa36a2d59", + "shasum": "", + "mirrors": [ + { + "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "ext-ctype": "*", @@ -366,7 +402,7 @@ "stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication", "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)" }, - "time": "2018-11-16T00:41:32+00:00", + "time": "2019-02-01T15:04:28+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -410,7 +446,13 @@ "type": "zip", "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "php": ">=5.3.0" @@ -451,24 +493,30 @@ }, { "name": "qcloud/cos-sdk-v5", - "version": "v1.3.0", - "version_normalized": "1.3.0.0", + "version": "v1.3.1", + "version_normalized": "1.3.1.0", "source": { "type": "git", "url": "https://github.com/tencentyun/cos-php-sdk-v5.git", - "reference": "989c087a5aaf9b5df020b1d2633644e7c9f694e0" + "reference": "ca816d61a5412dd7a248119992b7d32687b10f86" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/tencentyun/cos-php-sdk-v5/zipball/989c087a5aaf9b5df020b1d2633644e7c9f694e0", - "reference": "989c087a5aaf9b5df020b1d2633644e7c9f694e0", - "shasum": "" + "url": "https://api.github.com/repos/tencentyun/cos-php-sdk-v5/zipball/ca816d61a5412dd7a248119992b7d32687b10f86", + "reference": "ca816d61a5412dd7a248119992b7d32687b10f86", + "shasum": "", + "mirrors": [ + { + "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "guzzle/guzzle": "~3.7", "php": ">=5.3.0" }, - "time": "2018-11-27T13:31:54+00:00", + "time": "2019-01-28T12:46:20+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -510,7 +558,13 @@ "type": "zip", "url": "https://api.github.com/repos/qiniu/php-sdk/zipball/88d11a5857ebc6871204e9be6ceec54bf5f381e6", "reference": "88d11a5857ebc6871204e9be6ceec54bf5f381e6", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "php": ">=5.3.3" @@ -563,7 +617,13 @@ "type": "zip", "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/5601c8a83fbba7ef674a7369456d12f1e0d0eafa", "reference": "5601c8a83fbba7ef674a7369456d12f1e0d0eafa", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "php": ">=5.3" @@ -605,7 +665,13 @@ "type": "zip", "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/a77e974a5fecb4398833b0709210e3d5e334ffb0", "reference": "a77e974a5fecb4398833b0709210e3d5e334ffb0", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "php": ">=5.3.9" @@ -656,18 +722,24 @@ }, { "name": "topthink/framework", - "version": "v5.1.31", - "version_normalized": "5.1.31.0", + "version": "v5.1.34", + "version_normalized": "5.1.34.0", "source": { "type": "git", "url": "https://github.com/top-think/framework.git", - "reference": "93339b1a4df5a73e0143db0847a4c5e0b2e46fb0" + "reference": "7c8cd1ea2bd4683a6ef46af415334260c6e2cc15" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/top-think/framework/zipball/93339b1a4df5a73e0143db0847a4c5e0b2e46fb0", - "reference": "93339b1a4df5a73e0143db0847a4c5e0b2e46fb0", - "shasum": "" + "url": "https://api.github.com/repos/top-think/framework/zipball/7c8cd1ea2bd4683a6ef46af415334260c6e2cc15", + "reference": "7c8cd1ea2bd4683a6ef46af415334260c6e2cc15", + "shasum": "", + "mirrors": [ + { + "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "php": ">=5.6.0", @@ -682,7 +754,7 @@ "sebastian/phpcpd": "2.*", "squizlabs/php_codesniffer": "2.*" }, - "time": "2018-12-09T12:41:21+00:00", + "time": "2019-01-30T06:38:38+00:00", "type": "think-framework", "installation-source": "dist", "notification-url": "https://packagist.org/downloads/", @@ -720,7 +792,13 @@ "type": "zip", "url": "https://api.github.com/repos/top-think/think-captcha/zipball/54c8a51552f99ff9ea89ea9c272383a8f738ceee", "reference": "54c8a51552f99ff9ea89ea9c272383a8f738ceee", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "topthink/framework": "5.1.*" @@ -761,7 +839,13 @@ "type": "zip", "url": "https://api.github.com/repos/top-think/think-image/zipball/8586cf47f117481c6d415b20f7dedf62e79d5512", "reference": "8586cf47f117481c6d415b20f7dedf62e79d5512", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "ext-gd": "*" @@ -803,7 +887,13 @@ "type": "zip", "url": "https://api.github.com/repos/top-think/think-installer/zipball/f5400a12c60e513911aef41fe443fa6920952675", "reference": "f5400a12c60e513911aef41fe443fa6920952675", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "composer-plugin-api": "^1.0" @@ -846,7 +936,13 @@ "type": "zip", "url": "https://api.github.com/repos/upyun/php-sdk/zipball/1a2dd5ae31047956c733aef0f764f3a527d30628", "reference": "1a2dd5ae31047956c733aef0f764f3a527d30628", - "shasum": "" + "shasum": "", + "mirrors": [ + { + "url": "https://dl.laravel-china.org/%package%/%reference%.%type%", + "preferred": true + } + ] }, "require": { "ext-curl": "*", diff --git a/vendor/phpmailer/phpmailer/COMMITMENT b/vendor/phpmailer/phpmailer/COMMITMENT new file mode 100644 index 00000000..a687e0dd --- /dev/null +++ b/vendor/phpmailer/phpmailer/COMMITMENT @@ -0,0 +1,46 @@ +GPL Cooperation Commitment +Version 1.0 + +Before filing or continuing to prosecute any legal proceeding or claim +(other than a Defensive Action) arising from termination of a Covered +License, we commit to extend to the person or entity ('you') accused +of violating the Covered License the following provisions regarding +cure and reinstatement, taken from GPL version 3. As used here, the +term 'this License' refers to the specific Covered License being +enforced. + + However, if you cease all violation of this License, then your + license from a particular copyright holder is reinstated (a) + provisionally, unless and until the copyright holder explicitly + and finally terminates your license, and (b) permanently, if the + copyright holder fails to notify you of the violation by some + reasonable means prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is + reinstated permanently if the copyright holder notifies you of the + violation by some reasonable means, this is the first time you + have received notice of violation of this License (for any work) + from that copyright holder, and you cure the violation prior to 30 + days after your receipt of the notice. + +We intend this Commitment to be irrevocable, and binding and +enforceable against us and assignees of or successors to our +copyrights. + +Definitions + +'Covered License' means the GNU General Public License, version 2 +(GPLv2), the GNU Lesser General Public License, version 2.1 +(LGPLv2.1), or the GNU Library General Public License, version 2 +(LGPLv2), all as published by the Free Software Foundation. + +'Defensive Action' means a legal proceeding or claim that We bring +against you in response to a prior proceeding or claim initiated by +you or your affiliate. + +'We' means each contributor to this repository as of the date of +inclusion of this file, including subsidiaries of a corporate +contributor. + +This work is available under a Creative Commons Attribution-ShareAlike +4.0 International license (https://creativecommons.org/licenses/by-sa/4.0/). diff --git a/vendor/phpmailer/phpmailer/README.md b/vendor/phpmailer/phpmailer/README.md index 85f758d1..62706463 100644 --- a/vendor/phpmailer/phpmailer/README.md +++ b/vendor/phpmailer/phpmailer/README.md @@ -34,7 +34,7 @@ Formatting email correctly is surprisingly difficult. There are myriad overlappi The PHP `mail()` function usually sends via a local mail server, typically fronted by a `sendmail` binary on Linux, BSD and OS X platforms, however, Windows usually doesn't include a local mail server; PHPMailer's integrated SMTP implementation allows email sending on Windows platforms without a local mail server. ## License -This software is distributed under the [LGPL 2.1](http://www.gnu.org/licenses/lgpl-2.1.html) license. Please read LICENSE for information on the software availability and distribution. +This software is distributed under the [LGPL 2.1](http://www.gnu.org/licenses/lgpl-2.1.html) license, along with the [GPL Cooperation Commitment](https://gplcc.github.io/gplcc/). Please read LICENSE for information on the software availability and distribution. ## Installation & loading PHPMailer is available on [Packagist](https://packagist.org/packages/phpmailer/phpmailer) (using semantic versioning), and installation via [Composer](https://getcomposer.org) is the recommended way to install PHPMailer. Just add this line to your `composer.json` file: diff --git a/vendor/phpmailer/phpmailer/VERSION b/vendor/phpmailer/phpmailer/VERSION index e8738082..41bd15e2 100644 --- a/vendor/phpmailer/phpmailer/VERSION +++ b/vendor/phpmailer/phpmailer/VERSION @@ -1 +1 @@ -6.0.6 \ No newline at end of file +6.0.7 \ No newline at end of file diff --git a/vendor/phpmailer/phpmailer/composer.json b/vendor/phpmailer/phpmailer/composer.json new file mode 100644 index 00000000..ee4e890d --- /dev/null +++ b/vendor/phpmailer/phpmailer/composer.json @@ -0,0 +1,55 @@ +{ + "name": "phpmailer/phpmailer", + "type": "library", + "description": "PHPMailer is a full-featured email creation and transfer class for PHP", + "authors": [ + { + "name": "Marcus Bointon", + "email": "phpmailer@synchromedia.co.uk" + }, + { + "name": "Jim Jagielski", + "email": "jimjag@gmail.com" + }, + { + "name": "Andy Prevost", + "email": "codeworxtech@users.sourceforge.net" + }, + { + "name": "Brent R. Matzelle" + } + ], + "require": { + "php": ">=5.5.0", + "ext-ctype": "*", + "ext-filter": "*" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.2", + "phpdocumentor/phpdocumentor": "2.*", + "phpunit/phpunit": "^4.8 || ^5.7", + "zendframework/zend-serializer": "2.7.*", + "doctrine/annotations": "1.2.*", + "zendframework/zend-eventmanager": "3.0.*", + "zendframework/zend-i18n": "2.7.3" + }, + "suggest": { + "psr/log": "For optional PSR-3 debug logging", + "league/oauth2-google": "Needed for Google XOAUTH2 authentication", + "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication", + "stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication", + "ext-mbstring": "Needed to send email in multibyte encoding charset", + "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)" + }, + "autoload": { + "psr-4": { + "PHPMailer\\PHPMailer\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "PHPMailer\\Test\\": "test/" + } + }, + "license": "LGPL-2.1" +} diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-ms.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-ms.php index 4e2c3408..f12a6ad4 100644 --- a/vendor/phpmailer/phpmailer/language/phpmailer.lang-ms.php +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-ms.php @@ -23,4 +23,4 @@ $PHPMAILER_LANG['signing'] = 'Ralat pada tanda tangan: '; $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() telah gagal.'; $PHPMAILER_LANG['smtp_error'] = 'Ralat pada pelayan SMTP: '; $PHPMAILER_LANG['variable_set'] = 'Tidak boleh menetapkan atau menetapkan semula pembolehubah: '; -//$PHPMAILER_LANG['extension_missing'] = 'Extension missing: '; +$PHPMAILER_LANG['extension_missing'] = 'Sambungan hilang: '; diff --git a/vendor/phpmailer/phpmailer/src/PHPMailer.php b/vendor/phpmailer/phpmailer/src/PHPMailer.php index a3be338b..52104924 100644 --- a/vendor/phpmailer/phpmailer/src/PHPMailer.php +++ b/vendor/phpmailer/phpmailer/src/PHPMailer.php @@ -701,7 +701,7 @@ class PHPMailer * * @var string */ - const VERSION = '6.0.6'; + const VERSION = '6.0.7'; /** * Error severity: message only, continue processing. diff --git a/vendor/phpmailer/phpmailer/src/POP3.php b/vendor/phpmailer/phpmailer/src/POP3.php index 9dab992e..66cf2730 100644 --- a/vendor/phpmailer/phpmailer/src/POP3.php +++ b/vendor/phpmailer/phpmailer/src/POP3.php @@ -45,7 +45,7 @@ class POP3 * * @var string */ - const VERSION = '6.0.6'; + const VERSION = '6.0.7'; /** * Default POP3 port number. diff --git a/vendor/phpmailer/phpmailer/src/SMTP.php b/vendor/phpmailer/phpmailer/src/SMTP.php index 9651e52e..da85442b 100644 --- a/vendor/phpmailer/phpmailer/src/SMTP.php +++ b/vendor/phpmailer/phpmailer/src/SMTP.php @@ -34,7 +34,7 @@ class SMTP * * @var string */ - const VERSION = '6.0.6'; + const VERSION = '6.0.7'; /** * SMTP line break constant. diff --git a/vendor/qcloud/cos-sdk-v5/README.md b/vendor/qcloud/cos-sdk-v5/README.md index 2a404c51..db5e2cf7 100644 --- a/vendor/qcloud/cos-sdk-v5/README.md +++ b/vendor/qcloud/cos-sdk-v5/README.md @@ -1,38 +1,42 @@ # COS-PHP-SDK-V5 腾讯云COS-PHP-SDK-V5([XML API](https://cloud.tencent.com/document/product/436/7751)) +[![Latest Stable Version](https://poser.pugx.org/qcloud/cos-sdk-v5/v/stable)](https://packagist.org/packages/qcloud/cos-sdk-v5) [![Total Downloads](https://img.shields.io/packagist/dt/qcloud/cos-sdk-v5.svg?style=flat)](https://packagist.org/packages/qcloud/cos-sdk-v5) [![Build Status](https://travis-ci.org/tencentyun/cos-php-sdk-v5.svg?branch=master)](https://travis-ci.org/tencentyun/cos-php-sdk-v5) ## 环境准备 * PHP 5.3+ - 您可以通过`php -v`命令查看当前的PHP版本。 - + 您可以通过`php -v`命令查看当前的 PHP 版本。 * cURL 扩展 - 您可以通过`php -m`命令查看cURL扩展是否已经安装好。 + 您可以通过`php -m`命令查看 cURL 扩展是否已经安装好。 -> **说明:** -> -> * Ubuntu系统中,您可以使用apt-get包管理器安装PHP的cURL扩展 `sudo apt-get install php-curl`。 -> * CentOS系统中,您可以使用yum包管理器安装PHP的cURL扩展 `sudo yum install php-curl`。 +>- Ubuntu 系统中,您可以使用 apt-get 包管理器安装 PHP 的 cURL 扩展,安装命令如下。 +``` +sudo apt-get install php-curl +``` +>- CentOS 系统中,您可以使用 yum 包管理器安装 PHP 的 cURL 扩展。 +``` +sudo yum install php-curl +``` -### SDK 安装 -有三种方式安装SDK: -* Composer方式 -* Phar方式 +## SDK 安装 +SDK 安装有三种方式: +* Composer 方式 +* Phar 方式 * 源码方式 -#### 1、Composer方式 -推荐用户使用 Composer 安装 cos-php-sdk-v5,Composer是PHP的依赖管理工具,允许您声明项目所需的依赖,然后自动将它们安装到您的项目中。 -> **提示**:您可以在 [getcomposer.org](getcomposer.org) 上找到更多关于如何安装Composer,配置自动加载以及用于定义依赖项的其他最佳实践。 +### Composer 方式 +推荐使用 Composer 安装 cos-php-sdk-v5,Composer 是 PHP 的依赖管理工具,允许您声明项目所需的依赖,然后自动将它们安装到您的项目中。 +> 您可以在 [Composer 官网](https://getcomposer.org/) 上找到更多关于如何安装 Composer,配置自动加载以及用于定义依赖项的其他最佳实践等相关信息。 -**使用 Composer 安装 COS-PHP-SDK-V5** -1. 打开终端 -2. 下载 Composer +#### 安装步骤: +1. 打开终端。 +2. 下载 Composer,执行以下命令。 ``` curl -sS https://getcomposer.org/installer | php ``` -3. 创建一个名为`composer.json`的文件,内容为 +3. 创建一个名为`composer.json`的文件,内容如下。 ``` { "require": { @@ -40,50 +44,58 @@ curl -sS https://getcomposer.org/installer | php } } ``` -4. 使用 Composer 安装 +4. 使用 Composer 安装,执行以下命令。 ``` php composer.phar install ``` -使用该命令后会在当前目录中创建一个vendor文件夹,里面包含 sdk 的依赖库和一个 autoload.php 脚本,方便用户在自己的项目中调用。 -5. 通过 autoloader 脚本调用cos-php-sdk-v5 +使用该命令后会在当前目录中创建一个 vendor 文件夹,里面包含 SDK 的依赖库和一个 autoload.php 脚本,方便在项目中调用。 +5. 通过 autoloader 脚本调用 cos-php-sdk-v5。 ``` require '/path/to/sdk/vendor/autoload.php'; ``` -现在您的项目已经可以使用COS的V5 SDK了。 +现在您的项目已经可以使用 COS 的 V5 版本 SDK 了。 -#### 2、Phar方式 -phar方式安装SDK的步骤如下: - -1. 在[github发布页面](https://github.com/tencentyun/cos-php-sdk-v5/releases)下载相应的phar文件 - -2. 在代码中引入phar文件: +### Phar 方式 +Phar 方式安装 SDK 的步骤如下: +1. 在 [GitHub 发布页面](https://github.com/tencentyun/cos-php-sdk-v5/releases) 下载相应的 phar 文件。 +2. 在代码中引入 phar 文件: ``` require '/path/to/cos-sdk-v5.phar'; ``` -#### 3、源码方式 -源码方式安装SDK的步骤如下: - -1. 在[github发布页面](https://github.com/tencentyun/cos-php-sdk-v5/releases)下载相应的zip文件 - -2. 解压通过 autoload.php 脚本加载sdk +### 源码方式 +源码方式安装 SDK 的步骤如下: +1. 在 [GitHub 发布页面](https://github.com/tencentyun/cos-php-sdk-v5/releases) 下载相应的 zip 文件。 +2. 解压通过 autoload.php 脚本加载 SDK: ``` require '/path/to/sdk/vendor/autoload.php'; ``` - ## 快速入门 -可参照Demo程序,详见 [sample.php](https://github.com/tencentyun/cos-php-sdk-v5/blob/master/sample.php) +可参照 Demo 程序,详见 [sample.php](https://github.com/tencentyun/cos-php-sdk-v5/blob/master/sample.php)。 + ## 接口文档 php sdk 接口文档,详见https://cloud.tencent.com/document/product/436/12267 + ### 配置文件 ```php -$cosClient = new Qcloud\Cos\Client(array('region' => 'COS_REGION', +$cosClient = new Qcloud\Cos\Client(array('region' => '', 'credentials'=> array( - 'secretId' => 'COS_KEY', - 'secretKey' => 'COS_SECRET'))); + 'secretId' => '', + 'secretKey' => ''))); ``` + +若您使用 [临时密钥](https://cloud.tencent.com/document/product/436/14048) 初始化,请用下面方式创建实例。 + +``` +$cosClient = new Qcloud\Cos\Client(array('region' => '', + 'credentials'=> array( + 'secretId' => '', + 'secretKey' => '', + 'token' => ''))); +``` + ### 上传文件 * 使用putObject接口上传文件(最大5G) * 使用Upload接口分块上传文件 @@ -255,3 +267,4 @@ try { print_r($e); } ``` + diff --git a/vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/BucketStyleListener.php b/vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/BucketStyleListener.php index a035d053..a91d1ec0 100644 --- a/vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/BucketStyleListener.php +++ b/vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/BucketStyleListener.php @@ -19,9 +19,21 @@ function endWith($haystack, $needle) { class BucketStyleListener implements EventSubscriberInterface { private $appId; // string: application id. + private $ip; + private $port; + private $ipport; - public function __construct($appId) { + public function __construct($appId, $ip=null, $port=null) { $this->appId = $appId; + $this->ip = $ip; + $this->port = $port; + $this->ipport = null; + if ($ip != null) { + $this->ipport = $ip; + if ($port != null) { + $this->ipport = $ip.":".$port; + } + } } public static function getSubscribedEvents() { @@ -33,13 +45,19 @@ class BucketStyleListener implements EventSubscriberInterface { * @param Event $event Event emitted. */ public function onCommandAfterPrepare(Event $event) { + $command = $event['command']; $bucket = $command['Bucket']; $request = $command->getRequest(); - if ($command->getName() == 'ListBuckets') { - $request->setHost('service.cos.myqcloud.com'); + if ($this->ipport != null) { + $request->setHost($this->ipport); + $request->setHeader('Host', 'service.cos.myqcloud.com'); + } else { + + $request->setHost('service.cos.myqcloud.com'); + } return ; } if ($key = $command['Key']) { @@ -55,12 +73,16 @@ class BucketStyleListener implements EventSubscriberInterface { { $bucket = $bucket.'-'.$this->appId; } - // Set the key and bucket on the request +// $request->setPath(urldecode($request->getPath())); $request->getParams()->set('bucket', $bucket)->set('key', $key); - //$request->setPath(urldecode($request->getPath())); - // Switch to virtual hosted bucket - $request->setHost($bucket. '.' . $request->getHost()); + $realHost = $bucket. '.' . $request->getHost(); + if($this->ipport != null) { + $request->setHost($this->ipport); + $request->setHeader('Host', $realHost); + } else { + $request->setHost($realHost); + } if (!$bucket) { $request->getParams()->set('cos.resource', '/'); } else { diff --git a/vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/Client.php b/vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/Client.php index e6dd11f8..a58c3861 100644 --- a/vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/Client.php +++ b/vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/Client.php @@ -12,7 +12,7 @@ use Qcloud\Cos\Signature; use Qcloud\Cos\TokenListener; class Client extends GSClient { - const VERSION = '1.3.0'; + const VERSION = '1.3.1'; private $region; // string: region. private $credentials; @@ -22,11 +22,15 @@ class Client extends GSClient { private $timeout; // int: timeout private $connect_timeout; // int: connect_timeout private $signature; + private $schema; + private $ip; + private $port; + public function __construct($config) { $this->region = $config['region']; $regionmap = array('cn-east'=>'ap-shanghai', - 'cn-sorth'=>'ap-guangzhou', + 'cn-south'=>'ap-guangzhou', 'cn-north'=>'ap-beijing-1', 'cn-south-2'=>'ap-guangzhou-2', 'cn-southwest'=>'ap-chengdu', @@ -37,6 +41,9 @@ class Client extends GSClient { 'gz'=>'ap-guangzhou', 'cd'=>'ap-chengdu', 'sgp'=>'ap-singapore',); + $this->schema = isset($config['schema']) ? $config['schema'] : 'http'; + $this->ip = isset($config['ip']) ? $config['ip'] : null; + $this->port = isset($config['port']) ? $config['port'] : null; $this->region = isset($regionmap[$this->region]) ? $regionmap[$this->region] : $this->region; $this->credentials = $config['credentials']; $this->appId = isset($config['credentials']['appId']) ? $config['credentials']['appId'] : null; @@ -47,57 +54,28 @@ class Client extends GSClient { $this->connect_timeout = isset($config['connect_timeout']) ? $config['connect_timeout'] : 3600; $this->signature = new signature($this->secretId, $this->secretKey); parent::__construct( - 'http://cos.' . $this->region . '.myqcloud.com/', // base url + $this->schema.'://cos.' . $this->region . '.myqcloud.com/', // base url array('request.options' => array('timeout' => $this->timeout, 'connect_timeout' => $this->connect_timeout), )); // show curl verbose or not - $desc = ServiceDescription::factory(Service::getService()); $this->setDescription($desc); $this->setUserAgent('cos-php-sdk-v5.' . Client::VERSION, true); - $this->addSubscriber(new ExceptionListener()); $this->addSubscriber(new Md5Listener($this->signature)); $this->addSubscriber(new TokenListener($this->token)); $this->addSubscriber(new SignatureListener($this->secretId, $this->secretKey)); - $this->addSubscriber(new BucketStyleListener($this->appId)); - + $this->addSubscriber(new BucketStyleListener($this->appId, $this->ip, $this->port)); // Allow for specifying bodies with file paths and file handles $this->addSubscriber(new UploadBodyListener(array('PutObject', 'UploadPart'))); } - public function set_config($config) { - $this->region = $config['region']; - $regionmap = array('cn-east'=>'ap-shanghai', - 'cn-sorth'=>'ap-guangzhou', - 'cn-north'=>'ap-beijing-1', - 'cn-south-2'=>'ap-guangzhou-2', - 'cn-southwest'=>'ap-chengdu', - 'sg'=>'ap-singapore', - 'tj'=>'ap-beijing-1', - 'bj'=>'ap-beijing', - 'sh'=>'ap-shanghai', - 'gz'=>'ap-guangzhou', - 'cd'=>'ap-chengdu', - 'sgp'=>'ap-singapore',); - $this->region = isset($regionmap[$this->region]) ? $regionmap[$this->region] : $this->region; - $this->credentials = $config['credentials']; - $this->appId = isset($config['credentials']['appId']) ? $config['credentials']['appId'] : null; - $this->secretId = $config['credentials']['secretId']; - $this->secretKey = $config['credentials']['secretKey']; - $this->token = isset($config['credentials']['token']) ? $config['credentials']['token'] : null; - $this->timeout = isset($config['timeout']) ? $config['timeout'] : 3600; - $this->connect_timeout = isset($config['connect_timeout']) ? $config['connect_timeout'] : 3600; - $this->signature = new signature($this->secretId, $this->secretKey); - parent::__construct( - 'http://cos.' . $this->region . '.myqcloud.com/', // base url - array('request.options' => array('timeout' => $this->timeout, 'connect_timeout' => $this->connect_timeout), - )); // show curl verbose or not - } + public function __destruct() { } public function __call($method, $args) { return parent::__call(ucfirst($method), $args); } + public function createAuthorization(RequestInterface $request, $expires) { if ($request->getClient() !== $this) { @@ -193,7 +171,7 @@ class Client extends GSClient { if (!key_exists('VersionId',$options['params'])) { $sourceversion = ""; } - else{ + else { $sourceversion = $options['params']['VersionId']; } $rt = $cosClient->headObject(array('Bucket'=>$sourcebucket, @@ -257,14 +235,14 @@ class Client extends GSClient { } } public static function encodeKey($key) { - return $key; +// return $key; return str_replace('%2F', '/', rawurlencode($key)); } public static function explodeKey($key) { // Remove a leading slash if one is found - //return explode('/', $key && $key[0] == '/' ? substr($key, 1) : $key); - return $key; - return ltrim($key, "/"); + return explode('/', $key && $key[0] == '/' ? substr($key, 1) : $key); +// return $key; +// return ltrim($key, "/"); } } diff --git a/vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/Service.php b/vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/Service.php index a2d0abb1..dd0abb18 100644 --- a/vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/Service.php +++ b/vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/Service.php @@ -43,7 +43,9 @@ class Service { 'required' => true, 'type' => 'string', 'location' => 'uri', - 'minLength' => 1), + 'minLength' => 1, + 'filters' => array( + 'Qcloud\\Cos\\Client::explodeKey')), 'UploadId' => array( 'required' => true, 'type' => 'string', @@ -133,7 +135,9 @@ class Service { 'required' => true, 'type' => 'string', 'location' => 'uri', - 'minLength' => 1), + 'minLength' => 1, + 'filters' => array( + 'Qcloud\\Cos\\Client::explodeKey')), 'Parts' => array( 'type' => 'array', 'location' => 'xml', @@ -235,6 +239,8 @@ class Service { 'type' => 'string', 'location' => 'uri', 'minLength' => 1, + 'filters' => array( + 'Qcloud\\Cos\\Client::explodeKey') ), 'Metadata' => array( 'type' => 'object', @@ -409,6 +415,8 @@ class Service { 'type' => 'string', 'location' => 'uri', 'minLength' => 1, + 'filters' => array( + 'Qcloud\\Cos\\Client::explodeKey') ), 'Metadata' => array( 'type' => 'object', @@ -590,7 +598,9 @@ class Service { 'required' => true, 'type' => 'string', 'location' => 'uri', - 'minLength' => 1), + 'minLength' => 1, + 'filters' => array( + 'Qcloud\\Cos\\Client::explodeKey')), 'MFA' => array( 'type' => 'string', 'location' => 'header', @@ -670,6 +680,8 @@ class Service { 'required' => true, 'type' => 'string', 'minLength' => 1, + 'filters' => array( + 'Qcloud\\Cos\\Client::explodeKey') ), 'VersionId' => array( 'type' => 'string', @@ -800,7 +812,9 @@ class Service { 'required' => true, 'type' => 'string', 'location' => 'uri', - 'minLength' => 1), + 'minLength' => 1, + 'filters' => array( + 'Qcloud\\Cos\\Client::explodeKey')), 'Range' => array( 'type' => 'string', 'location' => 'header'), @@ -880,6 +894,8 @@ class Service { 'type' => 'string', 'location' => 'uri', 'minLength' => 1, + 'filters' => array( + 'Qcloud\\Cos\\Client::explodeKey') ), 'VersionId' => array( 'type' => 'string', @@ -1171,7 +1187,9 @@ class Service { 'required' => true, 'type' => 'string', 'location' => 'uri', - 'minLength' => 1), + 'minLength' => 1, + 'filters' => array( + 'Qcloud\\Cos\\Client::explodeKey')), 'PartNumber' => array( 'required' => true, 'type' => 'numeric', @@ -1264,7 +1282,9 @@ class Service { 'required' => true, 'type' => 'string', 'location' => 'uri', - 'minLength' => 1), + 'minLength' => 1, + 'filters' => array( + 'Qcloud\\Cos\\Client::explodeKey')), 'Metadata' => array( 'type' => 'object', 'location' => 'header', @@ -1444,6 +1464,8 @@ class Service { 'type' => 'string', 'location' => 'uri', 'minLength' => 1, + 'filters' => array( + 'Qcloud\\Cos\\Client::explodeKey') ), 'RequestPayer' => array( 'type' => 'string', @@ -1833,6 +1855,8 @@ class Service { 'Key' => array( 'type' => 'string' ), + 'filters' => array( + 'Qcloud\\Cos\\Client::explodeKey'), 'Value' => array( 'type' => 'string' ), @@ -2103,6 +2127,8 @@ class Service { ), ), ), + 'filters' => array( + 'Qcloud\\Cos\\Client::explodeKey') ), ), ), @@ -2132,6 +2158,8 @@ class Service { 'type' => 'string', 'location' => 'uri', 'minLength' => 1, + 'filters' => array( + 'Qcloud\\Cos\\Client::explodeKey') ), 'VersionId' => array( 'type' => 'string', @@ -2197,7 +2225,9 @@ class Service { 'required' => true, 'type' => 'string', 'location' => 'uri', - 'minLength' => 1), + 'minLength' => 1, + 'filters' => array( + 'Qcloud\\Cos\\Client::explodeKey')), 'MaxParts' => array( 'type' => 'numeric', 'location' => 'query', @@ -2456,6 +2486,8 @@ class Service { 'type' => 'string', 'location' => 'uri', 'minLength' => 1, + 'filters' => array( + 'Qcloud\\Cos\\Client::explodeKey') ), 'Range' => array( 'type' => 'string', @@ -2599,6 +2631,8 @@ class Service { 'type' => 'string', 'location' => 'uri', 'minLength' => 1, + 'filters' => array( + 'Qcloud\\Cos\\Client::explodeKey') ), 'PartNumber' => array( 'required' => true, @@ -2685,7 +2719,7 @@ class Service { ), 'Key' => array( 'type' => 'string', - 'location' => 'xml', + 'location' => 'xml' ), 'Expiration' => array( 'type' => 'string', diff --git a/vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/Signature.php b/vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/Signature.php index 51c02e91..ae5fa10d 100644 --- a/vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/Signature.php +++ b/vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/Signature.php @@ -11,6 +11,7 @@ class Signature { public function __destruct() { } public function signRequest(RequestInterface $request) { + $signTime = (string)(time() - 60) . ';' . (string)(time() + 3600); $httpString = strtolower($request->getMethod()) . "\n" . urldecode($request->getPath()) . "\n\nhost=" . $request->getHost() . "\n"; diff --git a/vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/Tests/Test.php b/vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/Tests/Test.php index d32f6ac8..4a8462ec 100644 --- a/vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/Tests/Test.php +++ b/vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/Tests/Test.php @@ -778,27 +778,6 @@ class BucketTest extends \PHPUnit_Framework_TestCase } } - /* - * Copy大文件 - * 200 - */ - public function testCopyBigFile() - { - try { - $this->cosClient->createBucket(array('Bucket' => $this->bucket)); - $this->cosClient->Copy($bucket = $this->bucket, - $key = 'test10G', - $copysource = 'lewzylu01-1251668577.cos.ap-guangzhou.myqcloud.com/test10G'); - $rt = $this->cosClient->headObject(array('Bucket' => $this->$bucket, - 'Key' => 'test10G')); - assertTrue(true, $rt['ContentLength'] == 10485760000); - - } catch (ServiceResponseException $e) { - $this->assertFalse(true, $e); - } - } - - /* * 上传文件Bucket不存在 * NoSuchBucket