├── .env.example ├── .gitignore ├── LICENSE ├── README.md ├── app ├── controller │ └── IndexController.php ├── enum │ └── ErrorCode.php ├── functions.php ├── middleware │ ├── GlobalLog.php │ └── StaticFile.php ├── model │ └── Test.php ├── queue │ └── redis │ │ ├── GlobalLog.php │ │ └── HttplLog.php ├── service │ └── EncrypterService.php └── view │ └── index │ └── view.html ├── composer.json ├── composer.lock ├── config ├── app.php ├── autoload.php ├── bootstrap.php ├── container.php ├── database.php ├── dependence.php ├── exception.php ├── http.php ├── log.php ├── middleware.php ├── plugin │ └── webman │ │ └── redis-queue │ │ ├── app.php │ │ ├── command.php │ │ ├── process.php │ │ └── redis.php ├── process.php ├── redis.php ├── route.php ├── server.php ├── session.php ├── static.php ├── translation.php └── view.php ├── process └── Monitor.php ├── public ├── 404.html └── favicon.ico ├── runtime ├── .gitignore ├── logs │ └── .gitignore └── views │ └── .gitignore ├── start.php ├── support ├── Encrypter.php ├── Http.php ├── Request.php ├── Response.php ├── bootstrap.php └── helpers.php ├── windows.bat └── windows.php /.env.example: -------------------------------------------------------------------------------- 1 | APP_DEBUG=true 2 | 3 | DB_DRIVER=mysql 4 | DB_HOST=localhost 5 | DB_PORT=3306 6 | DB_DATABASE=aaa 7 | DB_USERNAME=root 8 | DB_PASSWORD=root 9 | DB_CHARSET=utf8mb4 10 | DB_COLLATION=utf8mb4_unicode_ci 11 | DB_PREFIX= 12 | 13 | REDIS_HOST=127.0.0.1 14 | REDIS_PORT=6379 15 | REDIS_AUTH=admin 16 | REDIS_DB=0 17 | 18 | REDIS_QUEUE_HOST=127.0.0.1 19 | REDIS_QUEUE_PORT=6379 20 | REDIS_QUEUE_AUTH=admin 21 | REDIS_QUEUE_DB=0 22 | 23 | #加解密key 24 | ENCRYPT_KEY= 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea 2 | /.vscode 3 | /vendor 4 | *.log 5 | .env 6 | /tests/tmp 7 | /tests/.phpunit.result.cache 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 walkor and contributors (see https://github.com/walkor/webman/contributors) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # webman-template 2 | 3 | 基于webman的项目模板,主要功能有: 4 | 5 | * 记录全局访问日志,包括请求参数、响应结果、请求耗时等 6 | * 统一返回值结构 7 | * 异常信息日志记录 8 | * 第三方接口http日志,包括请求参数、响应结果、请求耗时等 9 | * 所有日志异步写入数据库,不影响主流程性能,按天自动分表 10 | * 兼容laravel的加解密模块 11 | * env环境配置 12 | * 采用Laravel的数据库ORM 13 | 14 | # 环境要求 15 | 16 | PHP >= 7.3 -------------------------------------------------------------------------------- /app/controller/IndexController.php: -------------------------------------------------------------------------------- 1 | 'webman']); 19 | } 20 | 21 | public function json(Request $request) 22 | { 23 | $res = (new Http())->get('https://www.baidu.com', [ 24 | 'wd' => 'aaa', 25 | ]); 26 | return json(apiSuccess([$res])); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /app/enum/ErrorCode.php: -------------------------------------------------------------------------------- 1 | \app\enum\ErrorCode::SUCCESS, 10 | 'msg' => 'ok', 11 | ]; 12 | if ($data) { 13 | $res['data'] = $data; 14 | } 15 | return $res; 16 | } 17 | 18 | function apiError(int $code, string $msg, array $data = [], array $trace = []) 19 | { 20 | $res = [ 21 | 'code' => $code, 22 | 'msg' => $msg, 23 | ]; 24 | if ($data) { 25 | $res['data'] = $data; 26 | } 27 | if ($trace) { 28 | $res['trace'] = $trace; 29 | } 30 | return $res; 31 | } -------------------------------------------------------------------------------- /app/middleware/GlobalLog.php: -------------------------------------------------------------------------------- 1 | $this->getIp($request), 25 | 'uri' => $request->uri(), 26 | 'method' => $request->method(), 27 | 'appid' => '', //TODO 业务数据,如果项目中可直接获取到appid,记录在此处 28 | 'traceid' => $request->header('traceid', md5(microtime())), 29 | 'refer' => $request->header('referer'), 30 | 'user_agent' => $request->header('user-agent'), 31 | 'query' => $request->all(), 32 | 'cookie' => $request->cookie(), 33 | 'created_at' => date('Y-m-d H:i:s'), 34 | ]; 35 | 36 | //记录全局traceid 37 | Context::set('traceid', $data['traceid']); 38 | 39 | /** @var Response $response */ 40 | $response = $next($request); 41 | 42 | $err = $response->exception(); 43 | $res = []; 44 | if ($err instanceof \Exception) { 45 | $trace = [$err->getMessage(), $err->getFile(), $err->getLine(), $err->getTraceAsString()]; 46 | $data['exception'] = json_encode($trace, JSON_UNESCAPED_UNICODE); 47 | Log::error('server error', $trace); 48 | if (env('APP_DEBUG')) { 49 | $res = apiError(ErrorCode::SERVER_ERROR, '服务异常,请稍后重试', [], $trace); 50 | } else { 51 | $res = apiError(ErrorCode::SERVER_ERROR, '服务异常,请稍后重试'); 52 | } 53 | } 54 | 55 | $data['errcode'] = $response->getStatusCode(); 56 | $data['response'] = $res ? json_encode($res, JSON_UNESCAPED_UNICODE) : $response->rawBody(); 57 | $end = microtime(true); 58 | $exec_time = round(($end - $start) * 1000, 2); 59 | $data['exec_time'] = $exec_time; 60 | //投递到异步队列 61 | Redis::send('global-log', $data); 62 | 63 | if ($res) { 64 | return json($res); 65 | } 66 | return $response; 67 | } 68 | 69 | private function getIp(Request $request) 70 | { 71 | $forward_ip = $request->header('X-Forwarded-For'); 72 | $ip1 = $request->header('x-real-ip'); 73 | $ip2 = $request->header('remote_addr'); 74 | if (!$ip1 && !$ip2 && !$forward_ip) { 75 | return false; 76 | } 77 | $request_ips = []; 78 | if ($forward_ip) { 79 | $request_ips[] = $forward_ip; 80 | } 81 | if ($ip1) { 82 | $request_ips[] = $ip1; 83 | } 84 | if ($ip2) { 85 | $request_ips[] = $ip2; 86 | } 87 | return implode(',', $request_ips); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /app/middleware/StaticFile.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright walkor 11 | * @link http://www.workerman.net/ 12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 13 | */ 14 | 15 | namespace app\middleware; 16 | 17 | use Webman\MiddlewareInterface; 18 | use Webman\Http\Response; 19 | use Webman\Http\Request; 20 | 21 | /** 22 | * Class StaticFile 23 | * @package app\middleware 24 | */ 25 | class StaticFile implements MiddlewareInterface 26 | { 27 | public function process(Request $request, callable $next): Response 28 | { 29 | // Access to files beginning with. Is prohibited 30 | if (strpos($request->path(), '/.') !== false) { 31 | return response('

403 forbidden

', 403); 32 | } 33 | /** @var Response $response */ 34 | $response = $next($request); 35 | // Add cross domain HTTP header 36 | /*$response->withHeaders([ 37 | 'Access-Control-Allow-Origin' => '*', 38 | 'Access-Control-Allow-Credentials' => 'true', 39 | ]);*/ 40 | return $response; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/model/Test.php: -------------------------------------------------------------------------------- 1 | initTable($tableName); 25 | 26 | $cookie = $data['cookie'] ?? []; 27 | $appid = $data['appid'] ?? ''; 28 | $query = $data['query'] ?? []; 29 | $ticket = $query['ticket'] ?? ''; 30 | if (!$appid && $ticket) { 31 | //从ticket中解析appid 32 | try { 33 | $ticketStr = (new EncrypterService())->decrypt($ticket); 34 | $ticketArr = explode('|', $ticketStr); 35 | $appid = $ticketArr[0] ?? ''; 36 | } catch (\Exception $e) { 37 | //ticket解密失败,可能是环境不匹配或者ticket不正确,不处理 38 | $appid = 'ticket_error'; 39 | } 40 | } 41 | 42 | DB::table($tableName)->insert([ 43 | 'ip' => $data['ip'] ?? '', 44 | 'uri' => $data['uri'] ?? '', 45 | 'method' => $data['method'] ?? '', 46 | 'appid' => $appid, 47 | 'traceid' => $data['traceid'] ?? '', 48 | 'referer' => $data['referer'] ?? '', 49 | 'user_agent' => $data['user_agent'] ?? '', 50 | 'query' => $query ? json_encode($query, JSON_UNESCAPED_UNICODE) : '', 51 | 'errcode' => $data['errcode'] ?? '', 52 | 'response' => $data['response'] ?? '', 53 | 'exception' => $data['exception'] ?? '', 54 | 'exec_time' => $data['exec_time'] ?? '', 55 | 'cookie' => $cookie ? json_encode($data['cookie'], JSON_UNESCAPED_UNICODE) : '', 56 | 'created_at' => date('Y-m-d H:i:s'), 57 | ]); 58 | } catch (\Throwable $e) { 59 | Log::error('global_log_queue_error', [ 60 | 'msg' => $e->getMessage(), 61 | 'line' => $e->getLine(), 62 | 'file' => $e->getFile(), 63 | 'trace' => $e->getTraceAsString() 64 | ]); 65 | } 66 | } 67 | 68 | private function initTable($tableName) 69 | { 70 | //判断global_log表是否存在,按天分表 71 | if (!Db::schema()->hasTable($tableName)) { 72 | Db::schema()->create($tableName, function (Blueprint $table) { 73 | $table->increments('id')->autoIncrement()->unsigned(); 74 | $table->string('ip', 20)->nullable(true)->default(null)->comment('访问ip'); 75 | $table->string('uri', 255)->nullable(true)->default(null)->comment('访问uri'); 76 | $table->string('method', 10)->nullable(true)->default(null)->comment('get or post'); 77 | $table->string('appid', 50)->nullable(true)->default(null)->comment('应用平台appid'); 78 | $table->string('traceid', 255)->nullable(true)->default(null)->comment('traceid'); 79 | $table->text('referer')->nullable(true)->default(null)->comment('来源页'); 80 | $table->text('user_agent')->nullable(true)->default(null)->comment('user_agent'); 81 | $table->text('query')->nullable(true)->default(null)->comment('请求参数'); 82 | $table->string('errcode', 10)->nullable(true)->default(null)->comment('响应错误码'); 83 | $table->text('response')->nullable(true)->default(null)->comment('响应结果'); 84 | $table->text('exception')->nullable(true)->default(null)->comment('异常信息'); 85 | $table->text('exec_time')->nullable(true)->default(null)->comment('执行时间,单位毫秒'); 86 | $table->text('cookie')->nullable(true)->default(null)->comment('请求cookie'); 87 | $table->dateTime('created_at')->nullable(true)->default(null); 88 | 89 | $table->index('ip', 'ip'); 90 | $table->index('uri', 'uri'); 91 | $table->index('appid', 'appid'); 92 | $table->index('traceid', 'traceid'); 93 | $table->index('created_at', 'created_at'); 94 | 95 | $table->charset = 'utf8mb4'; 96 | $table->collation = 'utf8mb4_unicode_ci'; 97 | $table->engine = 'InnoDB'; 98 | }); 99 | } 100 | } 101 | } -------------------------------------------------------------------------------- /app/queue/redis/HttplLog.php: -------------------------------------------------------------------------------- 1 | initTable($tableName); 24 | 25 | $request_data = $data['data'] ?? []; 26 | $exception = $data['exception'] ?? []; 27 | Db::table($tableName)->insert([ 28 | 'url' => $data['url'] ?? '', 29 | 'method' => $data['method'] ?? '', 30 | 'data' => $request_data ? json_encode($request_data, JSON_UNESCAPED_UNICODE) : '', 31 | 'trace_id' => $data['trace_id'] ?? '', 32 | 'exception' => $exception ? json_encode($exception, JSON_UNESCAPED_UNICODE) : '', 33 | 'response' => $data['response'] ?? '', 34 | 'exec_time' => $data['exec_time'] ?? '', 35 | 'created_at' => date('Y-m-d H:i:s'), 36 | ]); 37 | } catch (\Throwable $e) { 38 | Log::error('http log error', [ 39 | 'msg' => $e->getMessage(), 40 | 'line' => $e->getLine(), 41 | 'file' => $e->getFile(), 42 | 'trace' => $e->getTraceAsString() 43 | ]); 44 | } 45 | } 46 | 47 | private function initTable($tableName) 48 | { 49 | //判断global_log表是否存在,按天分表 50 | if (!Db::schema()->hasTable($tableName)) { 51 | Db::schema()->create($tableName, function (Blueprint $table) { 52 | $table->increments('id')->autoIncrement()->unsigned(); 53 | $table->string('url', 255)->nullable(true)->default(null)->comment('访问url'); 54 | $table->string('method', 10)->nullable(true)->default(null)->comment('get or post'); 55 | $table->text('data')->nullable(true)->comment('请求参数'); 56 | $table->string('trace_id', 200)->nullable(true)->comment('trace_id'); 57 | $table->text('exception')->nullable(true)->comment('异常信息'); 58 | $table->text('response')->nullable(true)->comment('响应结果'); 59 | $table->string('exec_time', 10)->nullable(true)->comment('执行时长,单位毫秒'); 60 | $table->dateTime('created_at')->nullable(true)->default(null); 61 | 62 | $table->index('trace_id', 'idx_trace_id'); 63 | $table->index('created_at', 'idx_created_at'); 64 | 65 | $table->charset = 'utf8mb4'; 66 | $table->collation = 'utf8mb4_unicode_ci'; 67 | $table->engine = 'InnoDB'; 68 | }); 69 | } 70 | } 71 | } -------------------------------------------------------------------------------- /app/service/EncrypterService.php: -------------------------------------------------------------------------------- 1 | encrypter instanceof Encrypter) { 21 | $this->encrypter = new Encrypter($key); 22 | } 23 | } 24 | 25 | public function encrypt($str) 26 | { 27 | return $this->encrypter->encrypt($str); 28 | } 29 | 30 | public function decrypt($str) 31 | { 32 | return $this->encrypter->decrypt($str); 33 | } 34 | } -------------------------------------------------------------------------------- /app/view/index/view.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | webman 9 | 10 | 11 | 12 | hello 13 | 14 | 15 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "workerman/webman", 3 | "type": "project", 4 | "keywords": [ 5 | "high performance", 6 | "http service" 7 | ], 8 | "homepage": "https://www.workerman.net", 9 | "license": "MIT", 10 | "description": "High performance HTTP Service Framework.", 11 | "authors": [ 12 | { 13 | "name": "walkor", 14 | "email": "walkor@workerman.net", 15 | "homepage": "https://www.workerman.net", 16 | "role": "Developer" 17 | } 18 | ], 19 | "support": { 20 | "email": "walkor@workerman.net", 21 | "issues": "https://github.com/walkor/webman/issues", 22 | "forum": "https://wenda.workerman.net/", 23 | "wiki": "https://workerman.net/doc/webman", 24 | "source": "https://github.com/walkor/webman" 25 | }, 26 | "require": { 27 | "php": ">=7.3", 28 | "workerman/webman-framework": "^1.5.0", 29 | "monolog/monolog": "^2.0", 30 | "webman/redis-queue": "^1.2", 31 | "vlucas/phpdotenv": "^5.4", 32 | "ext-json": "*", 33 | "illuminate/database": "^8.83", 34 | "illuminate/pagination": "^8.83", 35 | "illuminate/events": "^8.83", 36 | "symfony/var-dumper": "^5.4", 37 | "guzzlehttp/guzzle": "^7.7" 38 | }, 39 | "suggest": { 40 | "ext-event": "For better performance. " 41 | }, 42 | "autoload": { 43 | "psr-4": { 44 | "": "./", 45 | "app\\": "./app", 46 | "App\\": "./app", 47 | "app\\View\\Components\\": "./app/view/components" 48 | }, 49 | "files": [ 50 | "./support/helpers.php" 51 | ] 52 | }, 53 | "scripts": { 54 | "post-package-install": [ 55 | "support\\Plugin::install" 56 | ], 57 | "post-package-update": [ 58 | "support\\Plugin::install" 59 | ], 60 | "pre-package-uninstall": [ 61 | "support\\Plugin::uninstall" 62 | ] 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "fc6281f792d3207f671194968f436bba", 8 | "packages": [ 9 | { 10 | "name": "doctrine/inflector", 11 | "version": "2.0.8", 12 | "source": { 13 | "type": "git", 14 | "url": "https://github.com/doctrine/inflector.git", 15 | "reference": "f9301a5b2fb1216b2b08f02ba04dc45423db6bff" 16 | }, 17 | "dist": { 18 | "type": "zip", 19 | "url": "https://api.github.com/repos/doctrine/inflector/zipball/f9301a5b2fb1216b2b08f02ba04dc45423db6bff", 20 | "reference": "f9301a5b2fb1216b2b08f02ba04dc45423db6bff", 21 | "shasum": "", 22 | "mirrors": [ 23 | { 24 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", 25 | "preferred": true 26 | } 27 | ] 28 | }, 29 | "require": { 30 | "php": "^7.2 || ^8.0" 31 | }, 32 | "require-dev": { 33 | "doctrine/coding-standard": "^11.0", 34 | "phpstan/phpstan": "^1.8", 35 | "phpstan/phpstan-phpunit": "^1.1", 36 | "phpstan/phpstan-strict-rules": "^1.3", 37 | "phpunit/phpunit": "^8.5 || ^9.5", 38 | "vimeo/psalm": "^4.25 || ^5.4" 39 | }, 40 | "type": "library", 41 | "autoload": { 42 | "psr-4": { 43 | "Doctrine\\Inflector\\": "lib/Doctrine/Inflector" 44 | } 45 | }, 46 | "notification-url": "https://packagist.org/downloads/", 47 | "license": [ 48 | "MIT" 49 | ], 50 | "authors": [ 51 | { 52 | "name": "Guilherme Blanco", 53 | "email": "guilhermeblanco@gmail.com" 54 | }, 55 | { 56 | "name": "Roman Borschel", 57 | "email": "roman@code-factory.org" 58 | }, 59 | { 60 | "name": "Benjamin Eberlei", 61 | "email": "kontakt@beberlei.de" 62 | }, 63 | { 64 | "name": "Jonathan Wage", 65 | "email": "jonwage@gmail.com" 66 | }, 67 | { 68 | "name": "Johannes Schmitt", 69 | "email": "schmittjoh@gmail.com" 70 | } 71 | ], 72 | "description": "PHP Doctrine Inflector is a small library that can perform string manipulations with regard to upper/lowercase and singular/plural forms of words.", 73 | "homepage": "https://www.doctrine-project.org/projects/inflector.html", 74 | "keywords": [ 75 | "inflection", 76 | "inflector", 77 | "lowercase", 78 | "manipulation", 79 | "php", 80 | "plural", 81 | "singular", 82 | "strings", 83 | "uppercase", 84 | "words" 85 | ], 86 | "support": { 87 | "issues": "https://github.com/doctrine/inflector/issues", 88 | "source": "https://github.com/doctrine/inflector/tree/2.0.8" 89 | }, 90 | "funding": [ 91 | { 92 | "url": "https://www.doctrine-project.org/sponsorship.html", 93 | "type": "custom" 94 | }, 95 | { 96 | "url": "https://www.patreon.com/phpdoctrine", 97 | "type": "patreon" 98 | }, 99 | { 100 | "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finflector", 101 | "type": "tidelift" 102 | } 103 | ], 104 | "time": "2023-06-16T13:40:37+00:00" 105 | }, 106 | { 107 | "name": "graham-campbell/result-type", 108 | "version": "v1.1.0", 109 | "source": { 110 | "type": "git", 111 | "url": "https://github.com/GrahamCampbell/Result-Type.git", 112 | "reference": "a878d45c1914464426dc94da61c9e1d36ae262a8" 113 | }, 114 | "dist": { 115 | "type": "zip", 116 | "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/a878d45c1914464426dc94da61c9e1d36ae262a8", 117 | "reference": "a878d45c1914464426dc94da61c9e1d36ae262a8", 118 | "shasum": "", 119 | "mirrors": [ 120 | { 121 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", 122 | "preferred": true 123 | } 124 | ] 125 | }, 126 | "require": { 127 | "php": "^7.2.5 || ^8.0", 128 | "phpoption/phpoption": "^1.9" 129 | }, 130 | "require-dev": { 131 | "phpunit/phpunit": "^8.5.28 || ^9.5.21" 132 | }, 133 | "type": "library", 134 | "autoload": { 135 | "psr-4": { 136 | "GrahamCampbell\\ResultType\\": "src/" 137 | } 138 | }, 139 | "notification-url": "https://packagist.org/downloads/", 140 | "license": [ 141 | "MIT" 142 | ], 143 | "authors": [ 144 | { 145 | "name": "Graham Campbell", 146 | "email": "hello@gjcampbell.co.uk", 147 | "homepage": "https://github.com/GrahamCampbell" 148 | } 149 | ], 150 | "description": "An Implementation Of The Result Type", 151 | "keywords": [ 152 | "Graham Campbell", 153 | "GrahamCampbell", 154 | "Result Type", 155 | "Result-Type", 156 | "result" 157 | ], 158 | "support": { 159 | "issues": "https://github.com/GrahamCampbell/Result-Type/issues", 160 | "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.0" 161 | }, 162 | "funding": [ 163 | { 164 | "url": "https://github.com/GrahamCampbell", 165 | "type": "github" 166 | }, 167 | { 168 | "url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type", 169 | "type": "tidelift" 170 | } 171 | ], 172 | "time": "2022-07-30T15:56:11+00:00" 173 | }, 174 | { 175 | "name": "guzzlehttp/guzzle", 176 | "version": "7.7.0", 177 | "source": { 178 | "type": "git", 179 | "url": "https://github.com/guzzle/guzzle.git", 180 | "reference": "fb7566caccf22d74d1ab270de3551f72a58399f5" 181 | }, 182 | "dist": { 183 | "type": "zip", 184 | "url": "https://api.github.com/repos/guzzle/guzzle/zipball/fb7566caccf22d74d1ab270de3551f72a58399f5", 185 | "reference": "fb7566caccf22d74d1ab270de3551f72a58399f5", 186 | "shasum": "", 187 | "mirrors": [ 188 | { 189 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", 190 | "preferred": true 191 | } 192 | ] 193 | }, 194 | "require": { 195 | "ext-json": "*", 196 | "guzzlehttp/promises": "^1.5.3 || ^2.0", 197 | "guzzlehttp/psr7": "^1.9.1 || ^2.4.5", 198 | "php": "^7.2.5 || ^8.0", 199 | "psr/http-client": "^1.0", 200 | "symfony/deprecation-contracts": "^2.2 || ^3.0" 201 | }, 202 | "provide": { 203 | "psr/http-client-implementation": "1.0" 204 | }, 205 | "require-dev": { 206 | "bamarni/composer-bin-plugin": "^1.8.1", 207 | "ext-curl": "*", 208 | "php-http/client-integration-tests": "dev-master#2c025848417c1135031fdf9c728ee53d0a7ceaee as 3.0.999", 209 | "php-http/message-factory": "^1.1", 210 | "phpunit/phpunit": "^8.5.29 || ^9.5.23", 211 | "psr/log": "^1.1 || ^2.0 || ^3.0" 212 | }, 213 | "suggest": { 214 | "ext-curl": "Required for CURL handler support", 215 | "ext-intl": "Required for Internationalized Domain Name (IDN) support", 216 | "psr/log": "Required for using the Log middleware" 217 | }, 218 | "type": "library", 219 | "extra": { 220 | "bamarni-bin": { 221 | "bin-links": true, 222 | "forward-command": false 223 | } 224 | }, 225 | "autoload": { 226 | "files": [ 227 | "src/functions_include.php" 228 | ], 229 | "psr-4": { 230 | "GuzzleHttp\\": "src/" 231 | } 232 | }, 233 | "notification-url": "https://packagist.org/downloads/", 234 | "license": [ 235 | "MIT" 236 | ], 237 | "authors": [ 238 | { 239 | "name": "Graham Campbell", 240 | "email": "hello@gjcampbell.co.uk", 241 | "homepage": "https://github.com/GrahamCampbell" 242 | }, 243 | { 244 | "name": "Michael Dowling", 245 | "email": "mtdowling@gmail.com", 246 | "homepage": "https://github.com/mtdowling" 247 | }, 248 | { 249 | "name": "Jeremy Lindblom", 250 | "email": "jeremeamia@gmail.com", 251 | "homepage": "https://github.com/jeremeamia" 252 | }, 253 | { 254 | "name": "George Mponos", 255 | "email": "gmponos@gmail.com", 256 | "homepage": "https://github.com/gmponos" 257 | }, 258 | { 259 | "name": "Tobias Nyholm", 260 | "email": "tobias.nyholm@gmail.com", 261 | "homepage": "https://github.com/Nyholm" 262 | }, 263 | { 264 | "name": "Márk Sági-Kazár", 265 | "email": "mark.sagikazar@gmail.com", 266 | "homepage": "https://github.com/sagikazarmark" 267 | }, 268 | { 269 | "name": "Tobias Schultze", 270 | "email": "webmaster@tubo-world.de", 271 | "homepage": "https://github.com/Tobion" 272 | } 273 | ], 274 | "description": "Guzzle is a PHP HTTP client library", 275 | "keywords": [ 276 | "client", 277 | "curl", 278 | "framework", 279 | "http", 280 | "http client", 281 | "psr-18", 282 | "psr-7", 283 | "rest", 284 | "web service" 285 | ], 286 | "support": { 287 | "issues": "https://github.com/guzzle/guzzle/issues", 288 | "source": "https://github.com/guzzle/guzzle/tree/7.7.0" 289 | }, 290 | "funding": [ 291 | { 292 | "url": "https://github.com/GrahamCampbell", 293 | "type": "github" 294 | }, 295 | { 296 | "url": "https://github.com/Nyholm", 297 | "type": "github" 298 | }, 299 | { 300 | "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle", 301 | "type": "tidelift" 302 | } 303 | ], 304 | "time": "2023-05-21T14:04:53+00:00" 305 | }, 306 | { 307 | "name": "guzzlehttp/promises", 308 | "version": "1.5.3", 309 | "source": { 310 | "type": "git", 311 | "url": "https://github.com/guzzle/promises.git", 312 | "reference": "67ab6e18aaa14d753cc148911d273f6e6cb6721e" 313 | }, 314 | "dist": { 315 | "type": "zip", 316 | "url": "https://api.github.com/repos/guzzle/promises/zipball/67ab6e18aaa14d753cc148911d273f6e6cb6721e", 317 | "reference": "67ab6e18aaa14d753cc148911d273f6e6cb6721e", 318 | "shasum": "", 319 | "mirrors": [ 320 | { 321 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", 322 | "preferred": true 323 | } 324 | ] 325 | }, 326 | "require": { 327 | "php": ">=5.5" 328 | }, 329 | "require-dev": { 330 | "symfony/phpunit-bridge": "^4.4 || ^5.1" 331 | }, 332 | "type": "library", 333 | "autoload": { 334 | "files": [ 335 | "src/functions_include.php" 336 | ], 337 | "psr-4": { 338 | "GuzzleHttp\\Promise\\": "src/" 339 | } 340 | }, 341 | "notification-url": "https://packagist.org/downloads/", 342 | "license": [ 343 | "MIT" 344 | ], 345 | "authors": [ 346 | { 347 | "name": "Graham Campbell", 348 | "email": "hello@gjcampbell.co.uk", 349 | "homepage": "https://github.com/GrahamCampbell" 350 | }, 351 | { 352 | "name": "Michael Dowling", 353 | "email": "mtdowling@gmail.com", 354 | "homepage": "https://github.com/mtdowling" 355 | }, 356 | { 357 | "name": "Tobias Nyholm", 358 | "email": "tobias.nyholm@gmail.com", 359 | "homepage": "https://github.com/Nyholm" 360 | }, 361 | { 362 | "name": "Tobias Schultze", 363 | "email": "webmaster@tubo-world.de", 364 | "homepage": "https://github.com/Tobion" 365 | } 366 | ], 367 | "description": "Guzzle promises library", 368 | "keywords": [ 369 | "promise" 370 | ], 371 | "support": { 372 | "issues": "https://github.com/guzzle/promises/issues", 373 | "source": "https://github.com/guzzle/promises/tree/1.5.3" 374 | }, 375 | "funding": [ 376 | { 377 | "url": "https://github.com/GrahamCampbell", 378 | "type": "github" 379 | }, 380 | { 381 | "url": "https://github.com/Nyholm", 382 | "type": "github" 383 | }, 384 | { 385 | "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", 386 | "type": "tidelift" 387 | } 388 | ], 389 | "time": "2023-05-21T12:31:43+00:00" 390 | }, 391 | { 392 | "name": "guzzlehttp/psr7", 393 | "version": "2.5.0", 394 | "source": { 395 | "type": "git", 396 | "url": "https://github.com/guzzle/psr7.git", 397 | "reference": "b635f279edd83fc275f822a1188157ffea568ff6" 398 | }, 399 | "dist": { 400 | "type": "zip", 401 | "url": "https://api.github.com/repos/guzzle/psr7/zipball/b635f279edd83fc275f822a1188157ffea568ff6", 402 | "reference": "b635f279edd83fc275f822a1188157ffea568ff6", 403 | "shasum": "", 404 | "mirrors": [ 405 | { 406 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", 407 | "preferred": true 408 | } 409 | ] 410 | }, 411 | "require": { 412 | "php": "^7.2.5 || ^8.0", 413 | "psr/http-factory": "^1.0", 414 | "psr/http-message": "^1.1 || ^2.0", 415 | "ralouphie/getallheaders": "^3.0" 416 | }, 417 | "provide": { 418 | "psr/http-factory-implementation": "1.0", 419 | "psr/http-message-implementation": "1.0" 420 | }, 421 | "require-dev": { 422 | "bamarni/composer-bin-plugin": "^1.8.1", 423 | "http-interop/http-factory-tests": "^0.9", 424 | "phpunit/phpunit": "^8.5.29 || ^9.5.23" 425 | }, 426 | "suggest": { 427 | "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" 428 | }, 429 | "type": "library", 430 | "extra": { 431 | "bamarni-bin": { 432 | "bin-links": true, 433 | "forward-command": false 434 | } 435 | }, 436 | "autoload": { 437 | "psr-4": { 438 | "GuzzleHttp\\Psr7\\": "src/" 439 | } 440 | }, 441 | "notification-url": "https://packagist.org/downloads/", 442 | "license": [ 443 | "MIT" 444 | ], 445 | "authors": [ 446 | { 447 | "name": "Graham Campbell", 448 | "email": "hello@gjcampbell.co.uk", 449 | "homepage": "https://github.com/GrahamCampbell" 450 | }, 451 | { 452 | "name": "Michael Dowling", 453 | "email": "mtdowling@gmail.com", 454 | "homepage": "https://github.com/mtdowling" 455 | }, 456 | { 457 | "name": "George Mponos", 458 | "email": "gmponos@gmail.com", 459 | "homepage": "https://github.com/gmponos" 460 | }, 461 | { 462 | "name": "Tobias Nyholm", 463 | "email": "tobias.nyholm@gmail.com", 464 | "homepage": "https://github.com/Nyholm" 465 | }, 466 | { 467 | "name": "Márk Sági-Kazár", 468 | "email": "mark.sagikazar@gmail.com", 469 | "homepage": "https://github.com/sagikazarmark" 470 | }, 471 | { 472 | "name": "Tobias Schultze", 473 | "email": "webmaster@tubo-world.de", 474 | "homepage": "https://github.com/Tobion" 475 | }, 476 | { 477 | "name": "Márk Sági-Kazár", 478 | "email": "mark.sagikazar@gmail.com", 479 | "homepage": "https://sagikazarmark.hu" 480 | } 481 | ], 482 | "description": "PSR-7 message implementation that also provides common utility methods", 483 | "keywords": [ 484 | "http", 485 | "message", 486 | "psr-7", 487 | "request", 488 | "response", 489 | "stream", 490 | "uri", 491 | "url" 492 | ], 493 | "support": { 494 | "issues": "https://github.com/guzzle/psr7/issues", 495 | "source": "https://github.com/guzzle/psr7/tree/2.5.0" 496 | }, 497 | "funding": [ 498 | { 499 | "url": "https://github.com/GrahamCampbell", 500 | "type": "github" 501 | }, 502 | { 503 | "url": "https://github.com/Nyholm", 504 | "type": "github" 505 | }, 506 | { 507 | "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7", 508 | "type": "tidelift" 509 | } 510 | ], 511 | "time": "2023-04-17T16:11:26+00:00" 512 | }, 513 | { 514 | "name": "illuminate/bus", 515 | "version": "v8.83.27", 516 | "source": { 517 | "type": "git", 518 | "url": "https://github.com/illuminate/bus.git", 519 | "reference": "d2a8ae4bfd881086e55455e470776358eab27eae" 520 | }, 521 | "dist": { 522 | "type": "zip", 523 | "url": "https://api.github.com/repos/illuminate/bus/zipball/d2a8ae4bfd881086e55455e470776358eab27eae", 524 | "reference": "d2a8ae4bfd881086e55455e470776358eab27eae", 525 | "shasum": "", 526 | "mirrors": [ 527 | { 528 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", 529 | "preferred": true 530 | } 531 | ] 532 | }, 533 | "require": { 534 | "illuminate/collections": "^8.0", 535 | "illuminate/contracts": "^8.0", 536 | "illuminate/pipeline": "^8.0", 537 | "illuminate/support": "^8.0", 538 | "php": "^7.3|^8.0" 539 | }, 540 | "suggest": { 541 | "illuminate/queue": "Required to use closures when chaining jobs (^7.0)." 542 | }, 543 | "type": "library", 544 | "extra": { 545 | "branch-alias": { 546 | "dev-master": "8.x-dev" 547 | } 548 | }, 549 | "autoload": { 550 | "psr-4": { 551 | "Illuminate\\Bus\\": "" 552 | } 553 | }, 554 | "notification-url": "https://packagist.org/downloads/", 555 | "license": [ 556 | "MIT" 557 | ], 558 | "authors": [ 559 | { 560 | "name": "Taylor Otwell", 561 | "email": "taylor@laravel.com" 562 | } 563 | ], 564 | "description": "The Illuminate Bus package.", 565 | "homepage": "https://laravel.com", 566 | "support": { 567 | "issues": "https://github.com/laravel/framework/issues", 568 | "source": "https://github.com/laravel/framework" 569 | }, 570 | "time": "2022-03-07T15:02:42+00:00" 571 | }, 572 | { 573 | "name": "illuminate/collections", 574 | "version": "v8.83.27", 575 | "source": { 576 | "type": "git", 577 | "url": "https://github.com/illuminate/collections.git", 578 | "reference": "705a4e1ef93cd492c45b9b3e7911cccc990a07f4" 579 | }, 580 | "dist": { 581 | "type": "zip", 582 | "url": "https://api.github.com/repos/illuminate/collections/zipball/705a4e1ef93cd492c45b9b3e7911cccc990a07f4", 583 | "reference": "705a4e1ef93cd492c45b9b3e7911cccc990a07f4", 584 | "shasum": "", 585 | "mirrors": [ 586 | { 587 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", 588 | "preferred": true 589 | } 590 | ] 591 | }, 592 | "require": { 593 | "illuminate/contracts": "^8.0", 594 | "illuminate/macroable": "^8.0", 595 | "php": "^7.3|^8.0" 596 | }, 597 | "suggest": { 598 | "symfony/var-dumper": "Required to use the dump method (^5.4)." 599 | }, 600 | "type": "library", 601 | "extra": { 602 | "branch-alias": { 603 | "dev-master": "8.x-dev" 604 | } 605 | }, 606 | "autoload": { 607 | "files": [ 608 | "helpers.php" 609 | ], 610 | "psr-4": { 611 | "Illuminate\\Support\\": "" 612 | } 613 | }, 614 | "notification-url": "https://packagist.org/downloads/", 615 | "license": [ 616 | "MIT" 617 | ], 618 | "authors": [ 619 | { 620 | "name": "Taylor Otwell", 621 | "email": "taylor@laravel.com" 622 | } 623 | ], 624 | "description": "The Illuminate Collections package.", 625 | "homepage": "https://laravel.com", 626 | "support": { 627 | "issues": "https://github.com/laravel/framework/issues", 628 | "source": "https://github.com/laravel/framework" 629 | }, 630 | "time": "2022-06-23T15:29:49+00:00" 631 | }, 632 | { 633 | "name": "illuminate/container", 634 | "version": "v8.83.27", 635 | "source": { 636 | "type": "git", 637 | "url": "https://github.com/illuminate/container.git", 638 | "reference": "14062628d05f75047c5a1360b9350028427d568e" 639 | }, 640 | "dist": { 641 | "type": "zip", 642 | "url": "https://api.github.com/repos/illuminate/container/zipball/14062628d05f75047c5a1360b9350028427d568e", 643 | "reference": "14062628d05f75047c5a1360b9350028427d568e", 644 | "shasum": "", 645 | "mirrors": [ 646 | { 647 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", 648 | "preferred": true 649 | } 650 | ] 651 | }, 652 | "require": { 653 | "illuminate/contracts": "^8.0", 654 | "php": "^7.3|^8.0", 655 | "psr/container": "^1.0" 656 | }, 657 | "provide": { 658 | "psr/container-implementation": "1.0" 659 | }, 660 | "type": "library", 661 | "extra": { 662 | "branch-alias": { 663 | "dev-master": "8.x-dev" 664 | } 665 | }, 666 | "autoload": { 667 | "psr-4": { 668 | "Illuminate\\Container\\": "" 669 | } 670 | }, 671 | "notification-url": "https://packagist.org/downloads/", 672 | "license": [ 673 | "MIT" 674 | ], 675 | "authors": [ 676 | { 677 | "name": "Taylor Otwell", 678 | "email": "taylor@laravel.com" 679 | } 680 | ], 681 | "description": "The Illuminate Container package.", 682 | "homepage": "https://laravel.com", 683 | "support": { 684 | "issues": "https://github.com/laravel/framework/issues", 685 | "source": "https://github.com/laravel/framework" 686 | }, 687 | "time": "2022-02-02T21:03:35+00:00" 688 | }, 689 | { 690 | "name": "illuminate/contracts", 691 | "version": "v8.83.27", 692 | "source": { 693 | "type": "git", 694 | "url": "https://github.com/illuminate/contracts.git", 695 | "reference": "5e0fd287a1b22a6b346a9f7cd484d8cf0234585d" 696 | }, 697 | "dist": { 698 | "type": "zip", 699 | "url": "https://api.github.com/repos/illuminate/contracts/zipball/5e0fd287a1b22a6b346a9f7cd484d8cf0234585d", 700 | "reference": "5e0fd287a1b22a6b346a9f7cd484d8cf0234585d", 701 | "shasum": "", 702 | "mirrors": [ 703 | { 704 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", 705 | "preferred": true 706 | } 707 | ] 708 | }, 709 | "require": { 710 | "php": "^7.3|^8.0", 711 | "psr/container": "^1.0", 712 | "psr/simple-cache": "^1.0" 713 | }, 714 | "type": "library", 715 | "extra": { 716 | "branch-alias": { 717 | "dev-master": "8.x-dev" 718 | } 719 | }, 720 | "autoload": { 721 | "psr-4": { 722 | "Illuminate\\Contracts\\": "" 723 | } 724 | }, 725 | "notification-url": "https://packagist.org/downloads/", 726 | "license": [ 727 | "MIT" 728 | ], 729 | "authors": [ 730 | { 731 | "name": "Taylor Otwell", 732 | "email": "taylor@laravel.com" 733 | } 734 | ], 735 | "description": "The Illuminate Contracts package.", 736 | "homepage": "https://laravel.com", 737 | "support": { 738 | "issues": "https://github.com/laravel/framework/issues", 739 | "source": "https://github.com/laravel/framework" 740 | }, 741 | "time": "2022-01-13T14:47:47+00:00" 742 | }, 743 | { 744 | "name": "illuminate/database", 745 | "version": "v8.83.27", 746 | "source": { 747 | "type": "git", 748 | "url": "https://github.com/illuminate/database.git", 749 | "reference": "1a5b0e4e6913415464fa2aab554a38b9e6fa44b1" 750 | }, 751 | "dist": { 752 | "type": "zip", 753 | "url": "https://api.github.com/repos/illuminate/database/zipball/1a5b0e4e6913415464fa2aab554a38b9e6fa44b1", 754 | "reference": "1a5b0e4e6913415464fa2aab554a38b9e6fa44b1", 755 | "shasum": "", 756 | "mirrors": [ 757 | { 758 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", 759 | "preferred": true 760 | } 761 | ] 762 | }, 763 | "require": { 764 | "ext-json": "*", 765 | "illuminate/collections": "^8.0", 766 | "illuminate/container": "^8.0", 767 | "illuminate/contracts": "^8.0", 768 | "illuminate/macroable": "^8.0", 769 | "illuminate/support": "^8.0", 770 | "php": "^7.3|^8.0", 771 | "symfony/console": "^5.4" 772 | }, 773 | "suggest": { 774 | "doctrine/dbal": "Required to rename columns and drop SQLite columns (^2.13.3|^3.1.4).", 775 | "fakerphp/faker": "Required to use the eloquent factory builder (^1.9.1).", 776 | "illuminate/console": "Required to use the database commands (^8.0).", 777 | "illuminate/events": "Required to use the observers with Eloquent (^8.0).", 778 | "illuminate/filesystem": "Required to use the migrations (^8.0).", 779 | "illuminate/pagination": "Required to paginate the result set (^8.0).", 780 | "symfony/finder": "Required to use Eloquent model factories (^5.4)." 781 | }, 782 | "type": "library", 783 | "extra": { 784 | "branch-alias": { 785 | "dev-master": "8.x-dev" 786 | } 787 | }, 788 | "autoload": { 789 | "psr-4": { 790 | "Illuminate\\Database\\": "" 791 | } 792 | }, 793 | "notification-url": "https://packagist.org/downloads/", 794 | "license": [ 795 | "MIT" 796 | ], 797 | "authors": [ 798 | { 799 | "name": "Taylor Otwell", 800 | "email": "taylor@laravel.com" 801 | } 802 | ], 803 | "description": "The Illuminate Database package.", 804 | "homepage": "https://laravel.com", 805 | "keywords": [ 806 | "database", 807 | "laravel", 808 | "orm", 809 | "sql" 810 | ], 811 | "support": { 812 | "issues": "https://github.com/laravel/framework/issues", 813 | "source": "https://github.com/laravel/framework" 814 | }, 815 | "time": "2022-08-31T16:16:06+00:00" 816 | }, 817 | { 818 | "name": "illuminate/events", 819 | "version": "v8.83.27", 820 | "source": { 821 | "type": "git", 822 | "url": "https://github.com/illuminate/events.git", 823 | "reference": "b7f06cafb6c09581617f2ca05d69e9b159e5a35d" 824 | }, 825 | "dist": { 826 | "type": "zip", 827 | "url": "https://api.github.com/repos/illuminate/events/zipball/b7f06cafb6c09581617f2ca05d69e9b159e5a35d", 828 | "reference": "b7f06cafb6c09581617f2ca05d69e9b159e5a35d", 829 | "shasum": "", 830 | "mirrors": [ 831 | { 832 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", 833 | "preferred": true 834 | } 835 | ] 836 | }, 837 | "require": { 838 | "illuminate/bus": "^8.0", 839 | "illuminate/collections": "^8.0", 840 | "illuminate/container": "^8.0", 841 | "illuminate/contracts": "^8.0", 842 | "illuminate/macroable": "^8.0", 843 | "illuminate/support": "^8.0", 844 | "php": "^7.3|^8.0" 845 | }, 846 | "type": "library", 847 | "extra": { 848 | "branch-alias": { 849 | "dev-master": "8.x-dev" 850 | } 851 | }, 852 | "autoload": { 853 | "files": [ 854 | "functions.php" 855 | ], 856 | "psr-4": { 857 | "Illuminate\\Events\\": "" 858 | } 859 | }, 860 | "notification-url": "https://packagist.org/downloads/", 861 | "license": [ 862 | "MIT" 863 | ], 864 | "authors": [ 865 | { 866 | "name": "Taylor Otwell", 867 | "email": "taylor@laravel.com" 868 | } 869 | ], 870 | "description": "The Illuminate Events package.", 871 | "homepage": "https://laravel.com", 872 | "support": { 873 | "issues": "https://github.com/laravel/framework/issues", 874 | "source": "https://github.com/laravel/framework" 875 | }, 876 | "time": "2021-09-15T14:32:50+00:00" 877 | }, 878 | { 879 | "name": "illuminate/macroable", 880 | "version": "v8.83.27", 881 | "source": { 882 | "type": "git", 883 | "url": "https://github.com/illuminate/macroable.git", 884 | "reference": "aed81891a6e046fdee72edd497f822190f61c162" 885 | }, 886 | "dist": { 887 | "type": "zip", 888 | "url": "https://api.github.com/repos/illuminate/macroable/zipball/aed81891a6e046fdee72edd497f822190f61c162", 889 | "reference": "aed81891a6e046fdee72edd497f822190f61c162", 890 | "shasum": "", 891 | "mirrors": [ 892 | { 893 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", 894 | "preferred": true 895 | } 896 | ] 897 | }, 898 | "require": { 899 | "php": "^7.3|^8.0" 900 | }, 901 | "type": "library", 902 | "extra": { 903 | "branch-alias": { 904 | "dev-master": "8.x-dev" 905 | } 906 | }, 907 | "autoload": { 908 | "psr-4": { 909 | "Illuminate\\Support\\": "" 910 | } 911 | }, 912 | "notification-url": "https://packagist.org/downloads/", 913 | "license": [ 914 | "MIT" 915 | ], 916 | "authors": [ 917 | { 918 | "name": "Taylor Otwell", 919 | "email": "taylor@laravel.com" 920 | } 921 | ], 922 | "description": "The Illuminate Macroable package.", 923 | "homepage": "https://laravel.com", 924 | "support": { 925 | "issues": "https://github.com/laravel/framework/issues", 926 | "source": "https://github.com/laravel/framework" 927 | }, 928 | "time": "2021-11-16T13:57:03+00:00" 929 | }, 930 | { 931 | "name": "illuminate/pagination", 932 | "version": "v8.83.27", 933 | "source": { 934 | "type": "git", 935 | "url": "https://github.com/illuminate/pagination.git", 936 | "reference": "16fe8dc35f9d18c58a3471469af656a02e9ab692" 937 | }, 938 | "dist": { 939 | "type": "zip", 940 | "url": "https://api.github.com/repos/illuminate/pagination/zipball/16fe8dc35f9d18c58a3471469af656a02e9ab692", 941 | "reference": "16fe8dc35f9d18c58a3471469af656a02e9ab692", 942 | "shasum": "", 943 | "mirrors": [ 944 | { 945 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", 946 | "preferred": true 947 | } 948 | ] 949 | }, 950 | "require": { 951 | "ext-json": "*", 952 | "illuminate/collections": "^8.0", 953 | "illuminate/contracts": "^8.0", 954 | "illuminate/support": "^8.0", 955 | "php": "^7.3|^8.0" 956 | }, 957 | "type": "library", 958 | "extra": { 959 | "branch-alias": { 960 | "dev-master": "8.x-dev" 961 | } 962 | }, 963 | "autoload": { 964 | "psr-4": { 965 | "Illuminate\\Pagination\\": "" 966 | } 967 | }, 968 | "notification-url": "https://packagist.org/downloads/", 969 | "license": [ 970 | "MIT" 971 | ], 972 | "authors": [ 973 | { 974 | "name": "Taylor Otwell", 975 | "email": "taylor@laravel.com" 976 | } 977 | ], 978 | "description": "The Illuminate Pagination package.", 979 | "homepage": "https://laravel.com", 980 | "support": { 981 | "issues": "https://github.com/laravel/framework/issues", 982 | "source": "https://github.com/laravel/framework" 983 | }, 984 | "time": "2022-06-27T13:26:06+00:00" 985 | }, 986 | { 987 | "name": "illuminate/pipeline", 988 | "version": "v8.83.27", 989 | "source": { 990 | "type": "git", 991 | "url": "https://github.com/illuminate/pipeline.git", 992 | "reference": "23aeff5b26ae4aee3f370835c76bd0f4e93f71d2" 993 | }, 994 | "dist": { 995 | "type": "zip", 996 | "url": "https://api.github.com/repos/illuminate/pipeline/zipball/23aeff5b26ae4aee3f370835c76bd0f4e93f71d2", 997 | "reference": "23aeff5b26ae4aee3f370835c76bd0f4e93f71d2", 998 | "shasum": "", 999 | "mirrors": [ 1000 | { 1001 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", 1002 | "preferred": true 1003 | } 1004 | ] 1005 | }, 1006 | "require": { 1007 | "illuminate/contracts": "^8.0", 1008 | "illuminate/support": "^8.0", 1009 | "php": "^7.3|^8.0" 1010 | }, 1011 | "type": "library", 1012 | "extra": { 1013 | "branch-alias": { 1014 | "dev-master": "8.x-dev" 1015 | } 1016 | }, 1017 | "autoload": { 1018 | "psr-4": { 1019 | "Illuminate\\Pipeline\\": "" 1020 | } 1021 | }, 1022 | "notification-url": "https://packagist.org/downloads/", 1023 | "license": [ 1024 | "MIT" 1025 | ], 1026 | "authors": [ 1027 | { 1028 | "name": "Taylor Otwell", 1029 | "email": "taylor@laravel.com" 1030 | } 1031 | ], 1032 | "description": "The Illuminate Pipeline package.", 1033 | "homepage": "https://laravel.com", 1034 | "support": { 1035 | "issues": "https://github.com/laravel/framework/issues", 1036 | "source": "https://github.com/laravel/framework" 1037 | }, 1038 | "time": "2021-03-26T18:39:16+00:00" 1039 | }, 1040 | { 1041 | "name": "illuminate/support", 1042 | "version": "v8.83.27", 1043 | "source": { 1044 | "type": "git", 1045 | "url": "https://github.com/illuminate/support.git", 1046 | "reference": "1c79242468d3bbd9a0f7477df34f9647dde2a09b" 1047 | }, 1048 | "dist": { 1049 | "type": "zip", 1050 | "url": "https://api.github.com/repos/illuminate/support/zipball/1c79242468d3bbd9a0f7477df34f9647dde2a09b", 1051 | "reference": "1c79242468d3bbd9a0f7477df34f9647dde2a09b", 1052 | "shasum": "", 1053 | "mirrors": [ 1054 | { 1055 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", 1056 | "preferred": true 1057 | } 1058 | ] 1059 | }, 1060 | "require": { 1061 | "doctrine/inflector": "^1.4|^2.0", 1062 | "ext-json": "*", 1063 | "ext-mbstring": "*", 1064 | "illuminate/collections": "^8.0", 1065 | "illuminate/contracts": "^8.0", 1066 | "illuminate/macroable": "^8.0", 1067 | "nesbot/carbon": "^2.53.1", 1068 | "php": "^7.3|^8.0", 1069 | "voku/portable-ascii": "^1.6.1" 1070 | }, 1071 | "conflict": { 1072 | "tightenco/collect": "<5.5.33" 1073 | }, 1074 | "suggest": { 1075 | "illuminate/filesystem": "Required to use the composer class (^8.0).", 1076 | "league/commonmark": "Required to use Str::markdown() and Stringable::markdown() (^1.3|^2.0.2).", 1077 | "ramsey/uuid": "Required to use Str::uuid() (^4.2.2).", 1078 | "symfony/process": "Required to use the composer class (^5.4).", 1079 | "symfony/var-dumper": "Required to use the dd function (^5.4).", 1080 | "vlucas/phpdotenv": "Required to use the Env class and env helper (^5.4.1)." 1081 | }, 1082 | "type": "library", 1083 | "extra": { 1084 | "branch-alias": { 1085 | "dev-master": "8.x-dev" 1086 | } 1087 | }, 1088 | "autoload": { 1089 | "files": [ 1090 | "helpers.php" 1091 | ], 1092 | "psr-4": { 1093 | "Illuminate\\Support\\": "" 1094 | } 1095 | }, 1096 | "notification-url": "https://packagist.org/downloads/", 1097 | "license": [ 1098 | "MIT" 1099 | ], 1100 | "authors": [ 1101 | { 1102 | "name": "Taylor Otwell", 1103 | "email": "taylor@laravel.com" 1104 | } 1105 | ], 1106 | "description": "The Illuminate Support package.", 1107 | "homepage": "https://laravel.com", 1108 | "support": { 1109 | "issues": "https://github.com/laravel/framework/issues", 1110 | "source": "https://github.com/laravel/framework" 1111 | }, 1112 | "time": "2022-09-21T21:30:03+00:00" 1113 | }, 1114 | { 1115 | "name": "monolog/monolog", 1116 | "version": "2.9.1", 1117 | "source": { 1118 | "type": "git", 1119 | "url": "https://github.com/Seldaek/monolog.git", 1120 | "reference": "f259e2b15fb95494c83f52d3caad003bbf5ffaa1" 1121 | }, 1122 | "dist": { 1123 | "type": "zip", 1124 | "url": "https://api.github.com/repos/Seldaek/monolog/zipball/f259e2b15fb95494c83f52d3caad003bbf5ffaa1", 1125 | "reference": "f259e2b15fb95494c83f52d3caad003bbf5ffaa1", 1126 | "shasum": "", 1127 | "mirrors": [ 1128 | { 1129 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", 1130 | "preferred": true 1131 | } 1132 | ] 1133 | }, 1134 | "require": { 1135 | "php": ">=7.2", 1136 | "psr/log": "^1.0.1 || ^2.0 || ^3.0" 1137 | }, 1138 | "provide": { 1139 | "psr/log-implementation": "1.0.0 || 2.0.0 || 3.0.0" 1140 | }, 1141 | "require-dev": { 1142 | "aws/aws-sdk-php": "^2.4.9 || ^3.0", 1143 | "doctrine/couchdb": "~1.0@dev", 1144 | "elasticsearch/elasticsearch": "^7 || ^8", 1145 | "ext-json": "*", 1146 | "graylog2/gelf-php": "^1.4.2 || ^2@dev", 1147 | "guzzlehttp/guzzle": "^7.4", 1148 | "guzzlehttp/psr7": "^2.2", 1149 | "mongodb/mongodb": "^1.8", 1150 | "php-amqplib/php-amqplib": "~2.4 || ^3", 1151 | "phpspec/prophecy": "^1.15", 1152 | "phpstan/phpstan": "^0.12.91", 1153 | "phpunit/phpunit": "^8.5.14", 1154 | "predis/predis": "^1.1 || ^2.0", 1155 | "rollbar/rollbar": "^1.3 || ^2 || ^3", 1156 | "ruflin/elastica": "^7", 1157 | "swiftmailer/swiftmailer": "^5.3|^6.0", 1158 | "symfony/mailer": "^5.4 || ^6", 1159 | "symfony/mime": "^5.4 || ^6" 1160 | }, 1161 | "suggest": { 1162 | "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", 1163 | "doctrine/couchdb": "Allow sending log messages to a CouchDB server", 1164 | "elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client", 1165 | "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", 1166 | "ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler", 1167 | "ext-mbstring": "Allow to work properly with unicode symbols", 1168 | "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)", 1169 | "ext-openssl": "Required to send log messages using SSL", 1170 | "ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)", 1171 | "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", 1172 | "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)", 1173 | "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", 1174 | "rollbar/rollbar": "Allow sending log messages to Rollbar", 1175 | "ruflin/elastica": "Allow sending log messages to an Elastic Search server" 1176 | }, 1177 | "type": "library", 1178 | "extra": { 1179 | "branch-alias": { 1180 | "dev-main": "2.x-dev" 1181 | } 1182 | }, 1183 | "autoload": { 1184 | "psr-4": { 1185 | "Monolog\\": "src/Monolog" 1186 | } 1187 | }, 1188 | "notification-url": "https://packagist.org/downloads/", 1189 | "license": [ 1190 | "MIT" 1191 | ], 1192 | "authors": [ 1193 | { 1194 | "name": "Jordi Boggiano", 1195 | "email": "j.boggiano@seld.be", 1196 | "homepage": "https://seld.be" 1197 | } 1198 | ], 1199 | "description": "Sends your logs to files, sockets, inboxes, databases and various web services", 1200 | "homepage": "https://github.com/Seldaek/monolog", 1201 | "keywords": [ 1202 | "log", 1203 | "logging", 1204 | "psr-3" 1205 | ], 1206 | "support": { 1207 | "issues": "https://github.com/Seldaek/monolog/issues", 1208 | "source": "https://github.com/Seldaek/monolog/tree/2.9.1" 1209 | }, 1210 | "funding": [ 1211 | { 1212 | "url": "https://github.com/Seldaek", 1213 | "type": "github" 1214 | }, 1215 | { 1216 | "url": "https://tidelift.com/funding/github/packagist/monolog/monolog", 1217 | "type": "tidelift" 1218 | } 1219 | ], 1220 | "time": "2023-02-06T13:44:46+00:00" 1221 | }, 1222 | { 1223 | "name": "nesbot/carbon", 1224 | "version": "2.68.1", 1225 | "source": { 1226 | "type": "git", 1227 | "url": "https://github.com/briannesbitt/Carbon.git", 1228 | "reference": "4f991ed2a403c85efbc4f23eb4030063fdbe01da" 1229 | }, 1230 | "dist": { 1231 | "type": "zip", 1232 | "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/4f991ed2a403c85efbc4f23eb4030063fdbe01da", 1233 | "reference": "4f991ed2a403c85efbc4f23eb4030063fdbe01da", 1234 | "shasum": "", 1235 | "mirrors": [ 1236 | { 1237 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", 1238 | "preferred": true 1239 | } 1240 | ] 1241 | }, 1242 | "require": { 1243 | "ext-json": "*", 1244 | "php": "^7.1.8 || ^8.0", 1245 | "symfony/polyfill-mbstring": "^1.0", 1246 | "symfony/polyfill-php80": "^1.16", 1247 | "symfony/translation": "^3.4 || ^4.0 || ^5.0 || ^6.0" 1248 | }, 1249 | "require-dev": { 1250 | "doctrine/dbal": "^2.0 || ^3.1.4", 1251 | "doctrine/orm": "^2.7", 1252 | "friendsofphp/php-cs-fixer": "^3.0", 1253 | "kylekatarnls/multi-tester": "^2.0", 1254 | "ondrejmirtes/better-reflection": "*", 1255 | "phpmd/phpmd": "^2.9", 1256 | "phpstan/extension-installer": "^1.0", 1257 | "phpstan/phpstan": "^0.12.99 || ^1.7.14", 1258 | "phpunit/php-file-iterator": "^2.0.5 || ^3.0.6", 1259 | "phpunit/phpunit": "^7.5.20 || ^8.5.26 || ^9.5.20", 1260 | "squizlabs/php_codesniffer": "^3.4" 1261 | }, 1262 | "bin": [ 1263 | "bin/carbon" 1264 | ], 1265 | "type": "library", 1266 | "extra": { 1267 | "branch-alias": { 1268 | "dev-3.x": "3.x-dev", 1269 | "dev-master": "2.x-dev" 1270 | }, 1271 | "laravel": { 1272 | "providers": [ 1273 | "Carbon\\Laravel\\ServiceProvider" 1274 | ] 1275 | }, 1276 | "phpstan": { 1277 | "includes": [ 1278 | "extension.neon" 1279 | ] 1280 | } 1281 | }, 1282 | "autoload": { 1283 | "psr-4": { 1284 | "Carbon\\": "src/Carbon/" 1285 | } 1286 | }, 1287 | "notification-url": "https://packagist.org/downloads/", 1288 | "license": [ 1289 | "MIT" 1290 | ], 1291 | "authors": [ 1292 | { 1293 | "name": "Brian Nesbitt", 1294 | "email": "brian@nesbot.com", 1295 | "homepage": "https://markido.com" 1296 | }, 1297 | { 1298 | "name": "kylekatarnls", 1299 | "homepage": "https://github.com/kylekatarnls" 1300 | } 1301 | ], 1302 | "description": "An API extension for DateTime that supports 281 different languages.", 1303 | "homepage": "https://carbon.nesbot.com", 1304 | "keywords": [ 1305 | "date", 1306 | "datetime", 1307 | "time" 1308 | ], 1309 | "support": { 1310 | "docs": "https://carbon.nesbot.com/docs", 1311 | "issues": "https://github.com/briannesbitt/Carbon/issues", 1312 | "source": "https://github.com/briannesbitt/Carbon" 1313 | }, 1314 | "funding": [ 1315 | { 1316 | "url": "https://github.com/sponsors/kylekatarnls", 1317 | "type": "github" 1318 | }, 1319 | { 1320 | "url": "https://opencollective.com/Carbon#sponsor", 1321 | "type": "opencollective" 1322 | }, 1323 | { 1324 | "url": "https://tidelift.com/subscription/pkg/packagist-nesbot-carbon?utm_source=packagist-nesbot-carbon&utm_medium=referral&utm_campaign=readme", 1325 | "type": "tidelift" 1326 | } 1327 | ], 1328 | "time": "2023-06-20T18:29:04+00:00" 1329 | }, 1330 | { 1331 | "name": "nikic/fast-route", 1332 | "version": "v1.3.0", 1333 | "source": { 1334 | "type": "git", 1335 | "url": "https://github.com/nikic/FastRoute.git", 1336 | "reference": "181d480e08d9476e61381e04a71b34dc0432e812" 1337 | }, 1338 | "dist": { 1339 | "type": "zip", 1340 | "url": "https://api.github.com/repos/nikic/FastRoute/zipball/181d480e08d9476e61381e04a71b34dc0432e812", 1341 | "reference": "181d480e08d9476e61381e04a71b34dc0432e812", 1342 | "shasum": "", 1343 | "mirrors": [ 1344 | { 1345 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", 1346 | "preferred": true 1347 | } 1348 | ] 1349 | }, 1350 | "require": { 1351 | "php": ">=5.4.0" 1352 | }, 1353 | "require-dev": { 1354 | "phpunit/phpunit": "^4.8.35|~5.7" 1355 | }, 1356 | "type": "library", 1357 | "autoload": { 1358 | "files": [ 1359 | "src/functions.php" 1360 | ], 1361 | "psr-4": { 1362 | "FastRoute\\": "src/" 1363 | } 1364 | }, 1365 | "notification-url": "https://packagist.org/downloads/", 1366 | "license": [ 1367 | "BSD-3-Clause" 1368 | ], 1369 | "authors": [ 1370 | { 1371 | "name": "Nikita Popov", 1372 | "email": "nikic@php.net" 1373 | } 1374 | ], 1375 | "description": "Fast request router for PHP", 1376 | "keywords": [ 1377 | "router", 1378 | "routing" 1379 | ], 1380 | "support": { 1381 | "issues": "https://github.com/nikic/FastRoute/issues", 1382 | "source": "https://github.com/nikic/FastRoute/tree/master" 1383 | }, 1384 | "time": "2018-02-13T20:26:39+00:00" 1385 | }, 1386 | { 1387 | "name": "phpoption/phpoption", 1388 | "version": "1.9.1", 1389 | "source": { 1390 | "type": "git", 1391 | "url": "https://github.com/schmittjoh/php-option.git", 1392 | "reference": "dd3a383e599f49777d8b628dadbb90cae435b87e" 1393 | }, 1394 | "dist": { 1395 | "type": "zip", 1396 | "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/dd3a383e599f49777d8b628dadbb90cae435b87e", 1397 | "reference": "dd3a383e599f49777d8b628dadbb90cae435b87e", 1398 | "shasum": "", 1399 | "mirrors": [ 1400 | { 1401 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", 1402 | "preferred": true 1403 | } 1404 | ] 1405 | }, 1406 | "require": { 1407 | "php": "^7.2.5 || ^8.0" 1408 | }, 1409 | "require-dev": { 1410 | "bamarni/composer-bin-plugin": "^1.8.2", 1411 | "phpunit/phpunit": "^8.5.32 || ^9.6.3 || ^10.0.12" 1412 | }, 1413 | "type": "library", 1414 | "extra": { 1415 | "bamarni-bin": { 1416 | "bin-links": true, 1417 | "forward-command": true 1418 | }, 1419 | "branch-alias": { 1420 | "dev-master": "1.9-dev" 1421 | } 1422 | }, 1423 | "autoload": { 1424 | "psr-4": { 1425 | "PhpOption\\": "src/PhpOption/" 1426 | } 1427 | }, 1428 | "notification-url": "https://packagist.org/downloads/", 1429 | "license": [ 1430 | "Apache-2.0" 1431 | ], 1432 | "authors": [ 1433 | { 1434 | "name": "Johannes M. Schmitt", 1435 | "email": "schmittjoh@gmail.com", 1436 | "homepage": "https://github.com/schmittjoh" 1437 | }, 1438 | { 1439 | "name": "Graham Campbell", 1440 | "email": "hello@gjcampbell.co.uk", 1441 | "homepage": "https://github.com/GrahamCampbell" 1442 | } 1443 | ], 1444 | "description": "Option Type for PHP", 1445 | "keywords": [ 1446 | "language", 1447 | "option", 1448 | "php", 1449 | "type" 1450 | ], 1451 | "support": { 1452 | "issues": "https://github.com/schmittjoh/php-option/issues", 1453 | "source": "https://github.com/schmittjoh/php-option/tree/1.9.1" 1454 | }, 1455 | "funding": [ 1456 | { 1457 | "url": "https://github.com/GrahamCampbell", 1458 | "type": "github" 1459 | }, 1460 | { 1461 | "url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption", 1462 | "type": "tidelift" 1463 | } 1464 | ], 1465 | "time": "2023-02-25T19:38:58+00:00" 1466 | }, 1467 | { 1468 | "name": "psr/container", 1469 | "version": "1.1.2", 1470 | "source": { 1471 | "type": "git", 1472 | "url": "https://github.com/php-fig/container.git", 1473 | "reference": "513e0666f7216c7459170d56df27dfcefe1689ea" 1474 | }, 1475 | "dist": { 1476 | "type": "zip", 1477 | "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea", 1478 | "reference": "513e0666f7216c7459170d56df27dfcefe1689ea", 1479 | "shasum": "", 1480 | "mirrors": [ 1481 | { 1482 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", 1483 | "preferred": true 1484 | } 1485 | ] 1486 | }, 1487 | "require": { 1488 | "php": ">=7.4.0" 1489 | }, 1490 | "type": "library", 1491 | "autoload": { 1492 | "psr-4": { 1493 | "Psr\\Container\\": "src/" 1494 | } 1495 | }, 1496 | "notification-url": "https://packagist.org/downloads/", 1497 | "license": [ 1498 | "MIT" 1499 | ], 1500 | "authors": [ 1501 | { 1502 | "name": "PHP-FIG", 1503 | "homepage": "https://www.php-fig.org/" 1504 | } 1505 | ], 1506 | "description": "Common Container Interface (PHP FIG PSR-11)", 1507 | "homepage": "https://github.com/php-fig/container", 1508 | "keywords": [ 1509 | "PSR-11", 1510 | "container", 1511 | "container-interface", 1512 | "container-interop", 1513 | "psr" 1514 | ], 1515 | "support": { 1516 | "issues": "https://github.com/php-fig/container/issues", 1517 | "source": "https://github.com/php-fig/container/tree/1.1.2" 1518 | }, 1519 | "time": "2021-11-05T16:50:12+00:00" 1520 | }, 1521 | { 1522 | "name": "psr/http-client", 1523 | "version": "1.0.1", 1524 | "source": { 1525 | "type": "git", 1526 | "url": "https://github.com/php-fig/http-client.git", 1527 | "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621" 1528 | }, 1529 | "dist": { 1530 | "type": "zip", 1531 | "url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", 1532 | "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", 1533 | "shasum": "", 1534 | "mirrors": [ 1535 | { 1536 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", 1537 | "preferred": true 1538 | } 1539 | ] 1540 | }, 1541 | "require": { 1542 | "php": "^7.0 || ^8.0", 1543 | "psr/http-message": "^1.0" 1544 | }, 1545 | "type": "library", 1546 | "extra": { 1547 | "branch-alias": { 1548 | "dev-master": "1.0.x-dev" 1549 | } 1550 | }, 1551 | "autoload": { 1552 | "psr-4": { 1553 | "Psr\\Http\\Client\\": "src/" 1554 | } 1555 | }, 1556 | "notification-url": "https://packagist.org/downloads/", 1557 | "license": [ 1558 | "MIT" 1559 | ], 1560 | "authors": [ 1561 | { 1562 | "name": "PHP-FIG", 1563 | "homepage": "http://www.php-fig.org/" 1564 | } 1565 | ], 1566 | "description": "Common interface for HTTP clients", 1567 | "homepage": "https://github.com/php-fig/http-client", 1568 | "keywords": [ 1569 | "http", 1570 | "http-client", 1571 | "psr", 1572 | "psr-18" 1573 | ], 1574 | "support": { 1575 | "source": "https://github.com/php-fig/http-client/tree/master" 1576 | }, 1577 | "time": "2020-06-29T06:28:15+00:00" 1578 | }, 1579 | { 1580 | "name": "psr/http-factory", 1581 | "version": "1.0.2", 1582 | "source": { 1583 | "type": "git", 1584 | "url": "https://github.com/php-fig/http-factory.git", 1585 | "reference": "e616d01114759c4c489f93b099585439f795fe35" 1586 | }, 1587 | "dist": { 1588 | "type": "zip", 1589 | "url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35", 1590 | "reference": "e616d01114759c4c489f93b099585439f795fe35", 1591 | "shasum": "", 1592 | "mirrors": [ 1593 | { 1594 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", 1595 | "preferred": true 1596 | } 1597 | ] 1598 | }, 1599 | "require": { 1600 | "php": ">=7.0.0", 1601 | "psr/http-message": "^1.0 || ^2.0" 1602 | }, 1603 | "type": "library", 1604 | "extra": { 1605 | "branch-alias": { 1606 | "dev-master": "1.0.x-dev" 1607 | } 1608 | }, 1609 | "autoload": { 1610 | "psr-4": { 1611 | "Psr\\Http\\Message\\": "src/" 1612 | } 1613 | }, 1614 | "notification-url": "https://packagist.org/downloads/", 1615 | "license": [ 1616 | "MIT" 1617 | ], 1618 | "authors": [ 1619 | { 1620 | "name": "PHP-FIG", 1621 | "homepage": "https://www.php-fig.org/" 1622 | } 1623 | ], 1624 | "description": "Common interfaces for PSR-7 HTTP message factories", 1625 | "keywords": [ 1626 | "factory", 1627 | "http", 1628 | "message", 1629 | "psr", 1630 | "psr-17", 1631 | "psr-7", 1632 | "request", 1633 | "response" 1634 | ], 1635 | "support": { 1636 | "source": "https://github.com/php-fig/http-factory/tree/1.0.2" 1637 | }, 1638 | "time": "2023-04-10T20:10:41+00:00" 1639 | }, 1640 | { 1641 | "name": "psr/http-message", 1642 | "version": "1.1", 1643 | "source": { 1644 | "type": "git", 1645 | "url": "https://github.com/php-fig/http-message.git", 1646 | "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba" 1647 | }, 1648 | "dist": { 1649 | "type": "zip", 1650 | "url": "https://api.github.com/repos/php-fig/http-message/zipball/cb6ce4845ce34a8ad9e68117c10ee90a29919eba", 1651 | "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba", 1652 | "shasum": "", 1653 | "mirrors": [ 1654 | { 1655 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", 1656 | "preferred": true 1657 | } 1658 | ] 1659 | }, 1660 | "require": { 1661 | "php": "^7.2 || ^8.0" 1662 | }, 1663 | "type": "library", 1664 | "extra": { 1665 | "branch-alias": { 1666 | "dev-master": "1.1.x-dev" 1667 | } 1668 | }, 1669 | "autoload": { 1670 | "psr-4": { 1671 | "Psr\\Http\\Message\\": "src/" 1672 | } 1673 | }, 1674 | "notification-url": "https://packagist.org/downloads/", 1675 | "license": [ 1676 | "MIT" 1677 | ], 1678 | "authors": [ 1679 | { 1680 | "name": "PHP-FIG", 1681 | "homepage": "http://www.php-fig.org/" 1682 | } 1683 | ], 1684 | "description": "Common interface for HTTP messages", 1685 | "homepage": "https://github.com/php-fig/http-message", 1686 | "keywords": [ 1687 | "http", 1688 | "http-message", 1689 | "psr", 1690 | "psr-7", 1691 | "request", 1692 | "response" 1693 | ], 1694 | "support": { 1695 | "source": "https://github.com/php-fig/http-message/tree/1.1" 1696 | }, 1697 | "time": "2023-04-04T09:50:52+00:00" 1698 | }, 1699 | { 1700 | "name": "psr/log", 1701 | "version": "1.1.4", 1702 | "source": { 1703 | "type": "git", 1704 | "url": "https://github.com/php-fig/log.git", 1705 | "reference": "d49695b909c3b7628b6289db5479a1c204601f11" 1706 | }, 1707 | "dist": { 1708 | "type": "zip", 1709 | "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", 1710 | "reference": "d49695b909c3b7628b6289db5479a1c204601f11", 1711 | "shasum": "", 1712 | "mirrors": [ 1713 | { 1714 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", 1715 | "preferred": true 1716 | } 1717 | ] 1718 | }, 1719 | "require": { 1720 | "php": ">=5.3.0" 1721 | }, 1722 | "type": "library", 1723 | "extra": { 1724 | "branch-alias": { 1725 | "dev-master": "1.1.x-dev" 1726 | } 1727 | }, 1728 | "autoload": { 1729 | "psr-4": { 1730 | "Psr\\Log\\": "Psr/Log/" 1731 | } 1732 | }, 1733 | "notification-url": "https://packagist.org/downloads/", 1734 | "license": [ 1735 | "MIT" 1736 | ], 1737 | "authors": [ 1738 | { 1739 | "name": "PHP-FIG", 1740 | "homepage": "https://www.php-fig.org/" 1741 | } 1742 | ], 1743 | "description": "Common interface for logging libraries", 1744 | "homepage": "https://github.com/php-fig/log", 1745 | "keywords": [ 1746 | "log", 1747 | "psr", 1748 | "psr-3" 1749 | ], 1750 | "support": { 1751 | "source": "https://github.com/php-fig/log/tree/1.1.4" 1752 | }, 1753 | "time": "2021-05-03T11:20:27+00:00" 1754 | }, 1755 | { 1756 | "name": "psr/simple-cache", 1757 | "version": "1.0.1", 1758 | "source": { 1759 | "type": "git", 1760 | "url": "https://github.com/php-fig/simple-cache.git", 1761 | "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b" 1762 | }, 1763 | "dist": { 1764 | "type": "zip", 1765 | "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", 1766 | "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", 1767 | "shasum": "", 1768 | "mirrors": [ 1769 | { 1770 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", 1771 | "preferred": true 1772 | } 1773 | ] 1774 | }, 1775 | "require": { 1776 | "php": ">=5.3.0" 1777 | }, 1778 | "type": "library", 1779 | "extra": { 1780 | "branch-alias": { 1781 | "dev-master": "1.0.x-dev" 1782 | } 1783 | }, 1784 | "autoload": { 1785 | "psr-4": { 1786 | "Psr\\SimpleCache\\": "src/" 1787 | } 1788 | }, 1789 | "notification-url": "https://packagist.org/downloads/", 1790 | "license": [ 1791 | "MIT" 1792 | ], 1793 | "authors": [ 1794 | { 1795 | "name": "PHP-FIG", 1796 | "homepage": "http://www.php-fig.org/" 1797 | } 1798 | ], 1799 | "description": "Common interfaces for simple caching", 1800 | "keywords": [ 1801 | "cache", 1802 | "caching", 1803 | "psr", 1804 | "psr-16", 1805 | "simple-cache" 1806 | ], 1807 | "support": { 1808 | "source": "https://github.com/php-fig/simple-cache/tree/master" 1809 | }, 1810 | "time": "2017-10-23T01:57:42+00:00" 1811 | }, 1812 | { 1813 | "name": "ralouphie/getallheaders", 1814 | "version": "3.0.3", 1815 | "source": { 1816 | "type": "git", 1817 | "url": "https://github.com/ralouphie/getallheaders.git", 1818 | "reference": "120b605dfeb996808c31b6477290a714d356e822" 1819 | }, 1820 | "dist": { 1821 | "type": "zip", 1822 | "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", 1823 | "reference": "120b605dfeb996808c31b6477290a714d356e822", 1824 | "shasum": "", 1825 | "mirrors": [ 1826 | { 1827 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", 1828 | "preferred": true 1829 | } 1830 | ] 1831 | }, 1832 | "require": { 1833 | "php": ">=5.6" 1834 | }, 1835 | "require-dev": { 1836 | "php-coveralls/php-coveralls": "^2.1", 1837 | "phpunit/phpunit": "^5 || ^6.5" 1838 | }, 1839 | "type": "library", 1840 | "autoload": { 1841 | "files": [ 1842 | "src/getallheaders.php" 1843 | ] 1844 | }, 1845 | "notification-url": "https://packagist.org/downloads/", 1846 | "license": [ 1847 | "MIT" 1848 | ], 1849 | "authors": [ 1850 | { 1851 | "name": "Ralph Khattar", 1852 | "email": "ralph.khattar@gmail.com" 1853 | } 1854 | ], 1855 | "description": "A polyfill for getallheaders.", 1856 | "support": { 1857 | "issues": "https://github.com/ralouphie/getallheaders/issues", 1858 | "source": "https://github.com/ralouphie/getallheaders/tree/develop" 1859 | }, 1860 | "time": "2019-03-08T08:55:37+00:00" 1861 | }, 1862 | { 1863 | "name": "symfony/console", 1864 | "version": "v5.4.24", 1865 | "source": { 1866 | "type": "git", 1867 | "url": "https://github.com/symfony/console.git", 1868 | "reference": "560fc3ed7a43e6d30ea94a07d77f9a60b8ed0fb8" 1869 | }, 1870 | "dist": { 1871 | "type": "zip", 1872 | "url": "https://api.github.com/repos/symfony/console/zipball/560fc3ed7a43e6d30ea94a07d77f9a60b8ed0fb8", 1873 | "reference": "560fc3ed7a43e6d30ea94a07d77f9a60b8ed0fb8", 1874 | "shasum": "", 1875 | "mirrors": [ 1876 | { 1877 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", 1878 | "preferred": true 1879 | } 1880 | ] 1881 | }, 1882 | "require": { 1883 | "php": ">=7.2.5", 1884 | "symfony/deprecation-contracts": "^2.1|^3", 1885 | "symfony/polyfill-mbstring": "~1.0", 1886 | "symfony/polyfill-php73": "^1.9", 1887 | "symfony/polyfill-php80": "^1.16", 1888 | "symfony/service-contracts": "^1.1|^2|^3", 1889 | "symfony/string": "^5.1|^6.0" 1890 | }, 1891 | "conflict": { 1892 | "psr/log": ">=3", 1893 | "symfony/dependency-injection": "<4.4", 1894 | "symfony/dotenv": "<5.1", 1895 | "symfony/event-dispatcher": "<4.4", 1896 | "symfony/lock": "<4.4", 1897 | "symfony/process": "<4.4" 1898 | }, 1899 | "provide": { 1900 | "psr/log-implementation": "1.0|2.0" 1901 | }, 1902 | "require-dev": { 1903 | "psr/log": "^1|^2", 1904 | "symfony/config": "^4.4|^5.0|^6.0", 1905 | "symfony/dependency-injection": "^4.4|^5.0|^6.0", 1906 | "symfony/event-dispatcher": "^4.4|^5.0|^6.0", 1907 | "symfony/lock": "^4.4|^5.0|^6.0", 1908 | "symfony/process": "^4.4|^5.0|^6.0", 1909 | "symfony/var-dumper": "^4.4|^5.0|^6.0" 1910 | }, 1911 | "suggest": { 1912 | "psr/log": "For using the console logger", 1913 | "symfony/event-dispatcher": "", 1914 | "symfony/lock": "", 1915 | "symfony/process": "" 1916 | }, 1917 | "type": "library", 1918 | "autoload": { 1919 | "psr-4": { 1920 | "Symfony\\Component\\Console\\": "" 1921 | }, 1922 | "exclude-from-classmap": [ 1923 | "/Tests/" 1924 | ] 1925 | }, 1926 | "notification-url": "https://packagist.org/downloads/", 1927 | "license": [ 1928 | "MIT" 1929 | ], 1930 | "authors": [ 1931 | { 1932 | "name": "Fabien Potencier", 1933 | "email": "fabien@symfony.com" 1934 | }, 1935 | { 1936 | "name": "Symfony Community", 1937 | "homepage": "https://symfony.com/contributors" 1938 | } 1939 | ], 1940 | "description": "Eases the creation of beautiful and testable command line interfaces", 1941 | "homepage": "https://symfony.com", 1942 | "keywords": [ 1943 | "cli", 1944 | "command-line", 1945 | "console", 1946 | "terminal" 1947 | ], 1948 | "support": { 1949 | "source": "https://github.com/symfony/console/tree/v5.4.24" 1950 | }, 1951 | "funding": [ 1952 | { 1953 | "url": "https://symfony.com/sponsor", 1954 | "type": "custom" 1955 | }, 1956 | { 1957 | "url": "https://github.com/fabpot", 1958 | "type": "github" 1959 | }, 1960 | { 1961 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 1962 | "type": "tidelift" 1963 | } 1964 | ], 1965 | "time": "2023-05-26T05:13:16+00:00" 1966 | }, 1967 | { 1968 | "name": "symfony/deprecation-contracts", 1969 | "version": "v2.5.2", 1970 | "source": { 1971 | "type": "git", 1972 | "url": "https://github.com/symfony/deprecation-contracts.git", 1973 | "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66" 1974 | }, 1975 | "dist": { 1976 | "type": "zip", 1977 | "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e8b495ea28c1d97b5e0c121748d6f9b53d075c66", 1978 | "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66", 1979 | "shasum": "", 1980 | "mirrors": [ 1981 | { 1982 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", 1983 | "preferred": true 1984 | } 1985 | ] 1986 | }, 1987 | "require": { 1988 | "php": ">=7.1" 1989 | }, 1990 | "type": "library", 1991 | "extra": { 1992 | "branch-alias": { 1993 | "dev-main": "2.5-dev" 1994 | }, 1995 | "thanks": { 1996 | "name": "symfony/contracts", 1997 | "url": "https://github.com/symfony/contracts" 1998 | } 1999 | }, 2000 | "autoload": { 2001 | "files": [ 2002 | "function.php" 2003 | ] 2004 | }, 2005 | "notification-url": "https://packagist.org/downloads/", 2006 | "license": [ 2007 | "MIT" 2008 | ], 2009 | "authors": [ 2010 | { 2011 | "name": "Nicolas Grekas", 2012 | "email": "p@tchwork.com" 2013 | }, 2014 | { 2015 | "name": "Symfony Community", 2016 | "homepage": "https://symfony.com/contributors" 2017 | } 2018 | ], 2019 | "description": "A generic function and convention to trigger deprecation notices", 2020 | "homepage": "https://symfony.com", 2021 | "support": { 2022 | "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.2" 2023 | }, 2024 | "funding": [ 2025 | { 2026 | "url": "https://symfony.com/sponsor", 2027 | "type": "custom" 2028 | }, 2029 | { 2030 | "url": "https://github.com/fabpot", 2031 | "type": "github" 2032 | }, 2033 | { 2034 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 2035 | "type": "tidelift" 2036 | } 2037 | ], 2038 | "time": "2022-01-02T09:53:40+00:00" 2039 | }, 2040 | { 2041 | "name": "symfony/polyfill-ctype", 2042 | "version": "v1.27.0", 2043 | "source": { 2044 | "type": "git", 2045 | "url": "https://github.com/symfony/polyfill-ctype.git", 2046 | "reference": "5bbc823adecdae860bb64756d639ecfec17b050a" 2047 | }, 2048 | "dist": { 2049 | "type": "zip", 2050 | "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a", 2051 | "reference": "5bbc823adecdae860bb64756d639ecfec17b050a", 2052 | "shasum": "", 2053 | "mirrors": [ 2054 | { 2055 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", 2056 | "preferred": true 2057 | } 2058 | ] 2059 | }, 2060 | "require": { 2061 | "php": ">=7.1" 2062 | }, 2063 | "provide": { 2064 | "ext-ctype": "*" 2065 | }, 2066 | "suggest": { 2067 | "ext-ctype": "For best performance" 2068 | }, 2069 | "type": "library", 2070 | "extra": { 2071 | "branch-alias": { 2072 | "dev-main": "1.27-dev" 2073 | }, 2074 | "thanks": { 2075 | "name": "symfony/polyfill", 2076 | "url": "https://github.com/symfony/polyfill" 2077 | } 2078 | }, 2079 | "autoload": { 2080 | "files": [ 2081 | "bootstrap.php" 2082 | ], 2083 | "psr-4": { 2084 | "Symfony\\Polyfill\\Ctype\\": "" 2085 | } 2086 | }, 2087 | "notification-url": "https://packagist.org/downloads/", 2088 | "license": [ 2089 | "MIT" 2090 | ], 2091 | "authors": [ 2092 | { 2093 | "name": "Gert de Pagter", 2094 | "email": "BackEndTea@gmail.com" 2095 | }, 2096 | { 2097 | "name": "Symfony Community", 2098 | "homepage": "https://symfony.com/contributors" 2099 | } 2100 | ], 2101 | "description": "Symfony polyfill for ctype functions", 2102 | "homepage": "https://symfony.com", 2103 | "keywords": [ 2104 | "compatibility", 2105 | "ctype", 2106 | "polyfill", 2107 | "portable" 2108 | ], 2109 | "support": { 2110 | "source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0" 2111 | }, 2112 | "funding": [ 2113 | { 2114 | "url": "https://symfony.com/sponsor", 2115 | "type": "custom" 2116 | }, 2117 | { 2118 | "url": "https://github.com/fabpot", 2119 | "type": "github" 2120 | }, 2121 | { 2122 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 2123 | "type": "tidelift" 2124 | } 2125 | ], 2126 | "time": "2022-11-03T14:55:06+00:00" 2127 | }, 2128 | { 2129 | "name": "symfony/polyfill-intl-grapheme", 2130 | "version": "v1.27.0", 2131 | "source": { 2132 | "type": "git", 2133 | "url": "https://github.com/symfony/polyfill-intl-grapheme.git", 2134 | "reference": "511a08c03c1960e08a883f4cffcacd219b758354" 2135 | }, 2136 | "dist": { 2137 | "type": "zip", 2138 | "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/511a08c03c1960e08a883f4cffcacd219b758354", 2139 | "reference": "511a08c03c1960e08a883f4cffcacd219b758354", 2140 | "shasum": "", 2141 | "mirrors": [ 2142 | { 2143 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", 2144 | "preferred": true 2145 | } 2146 | ] 2147 | }, 2148 | "require": { 2149 | "php": ">=7.1" 2150 | }, 2151 | "suggest": { 2152 | "ext-intl": "For best performance" 2153 | }, 2154 | "type": "library", 2155 | "extra": { 2156 | "branch-alias": { 2157 | "dev-main": "1.27-dev" 2158 | }, 2159 | "thanks": { 2160 | "name": "symfony/polyfill", 2161 | "url": "https://github.com/symfony/polyfill" 2162 | } 2163 | }, 2164 | "autoload": { 2165 | "files": [ 2166 | "bootstrap.php" 2167 | ], 2168 | "psr-4": { 2169 | "Symfony\\Polyfill\\Intl\\Grapheme\\": "" 2170 | } 2171 | }, 2172 | "notification-url": "https://packagist.org/downloads/", 2173 | "license": [ 2174 | "MIT" 2175 | ], 2176 | "authors": [ 2177 | { 2178 | "name": "Nicolas Grekas", 2179 | "email": "p@tchwork.com" 2180 | }, 2181 | { 2182 | "name": "Symfony Community", 2183 | "homepage": "https://symfony.com/contributors" 2184 | } 2185 | ], 2186 | "description": "Symfony polyfill for intl's grapheme_* functions", 2187 | "homepage": "https://symfony.com", 2188 | "keywords": [ 2189 | "compatibility", 2190 | "grapheme", 2191 | "intl", 2192 | "polyfill", 2193 | "portable", 2194 | "shim" 2195 | ], 2196 | "support": { 2197 | "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.27.0" 2198 | }, 2199 | "funding": [ 2200 | { 2201 | "url": "https://symfony.com/sponsor", 2202 | "type": "custom" 2203 | }, 2204 | { 2205 | "url": "https://github.com/fabpot", 2206 | "type": "github" 2207 | }, 2208 | { 2209 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 2210 | "type": "tidelift" 2211 | } 2212 | ], 2213 | "time": "2022-11-03T14:55:06+00:00" 2214 | }, 2215 | { 2216 | "name": "symfony/polyfill-intl-normalizer", 2217 | "version": "v1.27.0", 2218 | "source": { 2219 | "type": "git", 2220 | "url": "https://github.com/symfony/polyfill-intl-normalizer.git", 2221 | "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6" 2222 | }, 2223 | "dist": { 2224 | "type": "zip", 2225 | "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/19bd1e4fcd5b91116f14d8533c57831ed00571b6", 2226 | "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6", 2227 | "shasum": "", 2228 | "mirrors": [ 2229 | { 2230 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", 2231 | "preferred": true 2232 | } 2233 | ] 2234 | }, 2235 | "require": { 2236 | "php": ">=7.1" 2237 | }, 2238 | "suggest": { 2239 | "ext-intl": "For best performance" 2240 | }, 2241 | "type": "library", 2242 | "extra": { 2243 | "branch-alias": { 2244 | "dev-main": "1.27-dev" 2245 | }, 2246 | "thanks": { 2247 | "name": "symfony/polyfill", 2248 | "url": "https://github.com/symfony/polyfill" 2249 | } 2250 | }, 2251 | "autoload": { 2252 | "files": [ 2253 | "bootstrap.php" 2254 | ], 2255 | "psr-4": { 2256 | "Symfony\\Polyfill\\Intl\\Normalizer\\": "" 2257 | }, 2258 | "classmap": [ 2259 | "Resources/stubs" 2260 | ] 2261 | }, 2262 | "notification-url": "https://packagist.org/downloads/", 2263 | "license": [ 2264 | "MIT" 2265 | ], 2266 | "authors": [ 2267 | { 2268 | "name": "Nicolas Grekas", 2269 | "email": "p@tchwork.com" 2270 | }, 2271 | { 2272 | "name": "Symfony Community", 2273 | "homepage": "https://symfony.com/contributors" 2274 | } 2275 | ], 2276 | "description": "Symfony polyfill for intl's Normalizer class and related functions", 2277 | "homepage": "https://symfony.com", 2278 | "keywords": [ 2279 | "compatibility", 2280 | "intl", 2281 | "normalizer", 2282 | "polyfill", 2283 | "portable", 2284 | "shim" 2285 | ], 2286 | "support": { 2287 | "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.27.0" 2288 | }, 2289 | "funding": [ 2290 | { 2291 | "url": "https://symfony.com/sponsor", 2292 | "type": "custom" 2293 | }, 2294 | { 2295 | "url": "https://github.com/fabpot", 2296 | "type": "github" 2297 | }, 2298 | { 2299 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 2300 | "type": "tidelift" 2301 | } 2302 | ], 2303 | "time": "2022-11-03T14:55:06+00:00" 2304 | }, 2305 | { 2306 | "name": "symfony/polyfill-mbstring", 2307 | "version": "v1.27.0", 2308 | "source": { 2309 | "type": "git", 2310 | "url": "https://github.com/symfony/polyfill-mbstring.git", 2311 | "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" 2312 | }, 2313 | "dist": { 2314 | "type": "zip", 2315 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534", 2316 | "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", 2317 | "shasum": "", 2318 | "mirrors": [ 2319 | { 2320 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", 2321 | "preferred": true 2322 | } 2323 | ] 2324 | }, 2325 | "require": { 2326 | "php": ">=7.1" 2327 | }, 2328 | "provide": { 2329 | "ext-mbstring": "*" 2330 | }, 2331 | "suggest": { 2332 | "ext-mbstring": "For best performance" 2333 | }, 2334 | "type": "library", 2335 | "extra": { 2336 | "branch-alias": { 2337 | "dev-main": "1.27-dev" 2338 | }, 2339 | "thanks": { 2340 | "name": "symfony/polyfill", 2341 | "url": "https://github.com/symfony/polyfill" 2342 | } 2343 | }, 2344 | "autoload": { 2345 | "files": [ 2346 | "bootstrap.php" 2347 | ], 2348 | "psr-4": { 2349 | "Symfony\\Polyfill\\Mbstring\\": "" 2350 | } 2351 | }, 2352 | "notification-url": "https://packagist.org/downloads/", 2353 | "license": [ 2354 | "MIT" 2355 | ], 2356 | "authors": [ 2357 | { 2358 | "name": "Nicolas Grekas", 2359 | "email": "p@tchwork.com" 2360 | }, 2361 | { 2362 | "name": "Symfony Community", 2363 | "homepage": "https://symfony.com/contributors" 2364 | } 2365 | ], 2366 | "description": "Symfony polyfill for the Mbstring extension", 2367 | "homepage": "https://symfony.com", 2368 | "keywords": [ 2369 | "compatibility", 2370 | "mbstring", 2371 | "polyfill", 2372 | "portable", 2373 | "shim" 2374 | ], 2375 | "support": { 2376 | "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0" 2377 | }, 2378 | "funding": [ 2379 | { 2380 | "url": "https://symfony.com/sponsor", 2381 | "type": "custom" 2382 | }, 2383 | { 2384 | "url": "https://github.com/fabpot", 2385 | "type": "github" 2386 | }, 2387 | { 2388 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 2389 | "type": "tidelift" 2390 | } 2391 | ], 2392 | "time": "2022-11-03T14:55:06+00:00" 2393 | }, 2394 | { 2395 | "name": "symfony/polyfill-php73", 2396 | "version": "v1.27.0", 2397 | "source": { 2398 | "type": "git", 2399 | "url": "https://github.com/symfony/polyfill-php73.git", 2400 | "reference": "9e8ecb5f92152187c4799efd3c96b78ccab18ff9" 2401 | }, 2402 | "dist": { 2403 | "type": "zip", 2404 | "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/9e8ecb5f92152187c4799efd3c96b78ccab18ff9", 2405 | "reference": "9e8ecb5f92152187c4799efd3c96b78ccab18ff9", 2406 | "shasum": "", 2407 | "mirrors": [ 2408 | { 2409 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", 2410 | "preferred": true 2411 | } 2412 | ] 2413 | }, 2414 | "require": { 2415 | "php": ">=7.1" 2416 | }, 2417 | "type": "library", 2418 | "extra": { 2419 | "branch-alias": { 2420 | "dev-main": "1.27-dev" 2421 | }, 2422 | "thanks": { 2423 | "name": "symfony/polyfill", 2424 | "url": "https://github.com/symfony/polyfill" 2425 | } 2426 | }, 2427 | "autoload": { 2428 | "files": [ 2429 | "bootstrap.php" 2430 | ], 2431 | "psr-4": { 2432 | "Symfony\\Polyfill\\Php73\\": "" 2433 | }, 2434 | "classmap": [ 2435 | "Resources/stubs" 2436 | ] 2437 | }, 2438 | "notification-url": "https://packagist.org/downloads/", 2439 | "license": [ 2440 | "MIT" 2441 | ], 2442 | "authors": [ 2443 | { 2444 | "name": "Nicolas Grekas", 2445 | "email": "p@tchwork.com" 2446 | }, 2447 | { 2448 | "name": "Symfony Community", 2449 | "homepage": "https://symfony.com/contributors" 2450 | } 2451 | ], 2452 | "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", 2453 | "homepage": "https://symfony.com", 2454 | "keywords": [ 2455 | "compatibility", 2456 | "polyfill", 2457 | "portable", 2458 | "shim" 2459 | ], 2460 | "support": { 2461 | "source": "https://github.com/symfony/polyfill-php73/tree/v1.27.0" 2462 | }, 2463 | "funding": [ 2464 | { 2465 | "url": "https://symfony.com/sponsor", 2466 | "type": "custom" 2467 | }, 2468 | { 2469 | "url": "https://github.com/fabpot", 2470 | "type": "github" 2471 | }, 2472 | { 2473 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 2474 | "type": "tidelift" 2475 | } 2476 | ], 2477 | "time": "2022-11-03T14:55:06+00:00" 2478 | }, 2479 | { 2480 | "name": "symfony/polyfill-php80", 2481 | "version": "v1.27.0", 2482 | "source": { 2483 | "type": "git", 2484 | "url": "https://github.com/symfony/polyfill-php80.git", 2485 | "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936" 2486 | }, 2487 | "dist": { 2488 | "type": "zip", 2489 | "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", 2490 | "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", 2491 | "shasum": "", 2492 | "mirrors": [ 2493 | { 2494 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", 2495 | "preferred": true 2496 | } 2497 | ] 2498 | }, 2499 | "require": { 2500 | "php": ">=7.1" 2501 | }, 2502 | "type": "library", 2503 | "extra": { 2504 | "branch-alias": { 2505 | "dev-main": "1.27-dev" 2506 | }, 2507 | "thanks": { 2508 | "name": "symfony/polyfill", 2509 | "url": "https://github.com/symfony/polyfill" 2510 | } 2511 | }, 2512 | "autoload": { 2513 | "files": [ 2514 | "bootstrap.php" 2515 | ], 2516 | "psr-4": { 2517 | "Symfony\\Polyfill\\Php80\\": "" 2518 | }, 2519 | "classmap": [ 2520 | "Resources/stubs" 2521 | ] 2522 | }, 2523 | "notification-url": "https://packagist.org/downloads/", 2524 | "license": [ 2525 | "MIT" 2526 | ], 2527 | "authors": [ 2528 | { 2529 | "name": "Ion Bazan", 2530 | "email": "ion.bazan@gmail.com" 2531 | }, 2532 | { 2533 | "name": "Nicolas Grekas", 2534 | "email": "p@tchwork.com" 2535 | }, 2536 | { 2537 | "name": "Symfony Community", 2538 | "homepage": "https://symfony.com/contributors" 2539 | } 2540 | ], 2541 | "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", 2542 | "homepage": "https://symfony.com", 2543 | "keywords": [ 2544 | "compatibility", 2545 | "polyfill", 2546 | "portable", 2547 | "shim" 2548 | ], 2549 | "support": { 2550 | "source": "https://github.com/symfony/polyfill-php80/tree/v1.27.0" 2551 | }, 2552 | "funding": [ 2553 | { 2554 | "url": "https://symfony.com/sponsor", 2555 | "type": "custom" 2556 | }, 2557 | { 2558 | "url": "https://github.com/fabpot", 2559 | "type": "github" 2560 | }, 2561 | { 2562 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 2563 | "type": "tidelift" 2564 | } 2565 | ], 2566 | "time": "2022-11-03T14:55:06+00:00" 2567 | }, 2568 | { 2569 | "name": "symfony/service-contracts", 2570 | "version": "v2.5.2", 2571 | "source": { 2572 | "type": "git", 2573 | "url": "https://github.com/symfony/service-contracts.git", 2574 | "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c" 2575 | }, 2576 | "dist": { 2577 | "type": "zip", 2578 | "url": "https://api.github.com/repos/symfony/service-contracts/zipball/4b426aac47d6427cc1a1d0f7e2ac724627f5966c", 2579 | "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c", 2580 | "shasum": "", 2581 | "mirrors": [ 2582 | { 2583 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", 2584 | "preferred": true 2585 | } 2586 | ] 2587 | }, 2588 | "require": { 2589 | "php": ">=7.2.5", 2590 | "psr/container": "^1.1", 2591 | "symfony/deprecation-contracts": "^2.1|^3" 2592 | }, 2593 | "conflict": { 2594 | "ext-psr": "<1.1|>=2" 2595 | }, 2596 | "suggest": { 2597 | "symfony/service-implementation": "" 2598 | }, 2599 | "type": "library", 2600 | "extra": { 2601 | "branch-alias": { 2602 | "dev-main": "2.5-dev" 2603 | }, 2604 | "thanks": { 2605 | "name": "symfony/contracts", 2606 | "url": "https://github.com/symfony/contracts" 2607 | } 2608 | }, 2609 | "autoload": { 2610 | "psr-4": { 2611 | "Symfony\\Contracts\\Service\\": "" 2612 | } 2613 | }, 2614 | "notification-url": "https://packagist.org/downloads/", 2615 | "license": [ 2616 | "MIT" 2617 | ], 2618 | "authors": [ 2619 | { 2620 | "name": "Nicolas Grekas", 2621 | "email": "p@tchwork.com" 2622 | }, 2623 | { 2624 | "name": "Symfony Community", 2625 | "homepage": "https://symfony.com/contributors" 2626 | } 2627 | ], 2628 | "description": "Generic abstractions related to writing services", 2629 | "homepage": "https://symfony.com", 2630 | "keywords": [ 2631 | "abstractions", 2632 | "contracts", 2633 | "decoupling", 2634 | "interfaces", 2635 | "interoperability", 2636 | "standards" 2637 | ], 2638 | "support": { 2639 | "source": "https://github.com/symfony/service-contracts/tree/v2.5.2" 2640 | }, 2641 | "funding": [ 2642 | { 2643 | "url": "https://symfony.com/sponsor", 2644 | "type": "custom" 2645 | }, 2646 | { 2647 | "url": "https://github.com/fabpot", 2648 | "type": "github" 2649 | }, 2650 | { 2651 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 2652 | "type": "tidelift" 2653 | } 2654 | ], 2655 | "time": "2022-05-30T19:17:29+00:00" 2656 | }, 2657 | { 2658 | "name": "symfony/string", 2659 | "version": "v5.4.22", 2660 | "source": { 2661 | "type": "git", 2662 | "url": "https://github.com/symfony/string.git", 2663 | "reference": "8036a4c76c0dd29e60b6a7cafcacc50cf088ea62" 2664 | }, 2665 | "dist": { 2666 | "type": "zip", 2667 | "url": "https://api.github.com/repos/symfony/string/zipball/8036a4c76c0dd29e60b6a7cafcacc50cf088ea62", 2668 | "reference": "8036a4c76c0dd29e60b6a7cafcacc50cf088ea62", 2669 | "shasum": "", 2670 | "mirrors": [ 2671 | { 2672 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", 2673 | "preferred": true 2674 | } 2675 | ] 2676 | }, 2677 | "require": { 2678 | "php": ">=7.2.5", 2679 | "symfony/polyfill-ctype": "~1.8", 2680 | "symfony/polyfill-intl-grapheme": "~1.0", 2681 | "symfony/polyfill-intl-normalizer": "~1.0", 2682 | "symfony/polyfill-mbstring": "~1.0", 2683 | "symfony/polyfill-php80": "~1.15" 2684 | }, 2685 | "conflict": { 2686 | "symfony/translation-contracts": ">=3.0" 2687 | }, 2688 | "require-dev": { 2689 | "symfony/error-handler": "^4.4|^5.0|^6.0", 2690 | "symfony/http-client": "^4.4|^5.0|^6.0", 2691 | "symfony/translation-contracts": "^1.1|^2", 2692 | "symfony/var-exporter": "^4.4|^5.0|^6.0" 2693 | }, 2694 | "type": "library", 2695 | "autoload": { 2696 | "files": [ 2697 | "Resources/functions.php" 2698 | ], 2699 | "psr-4": { 2700 | "Symfony\\Component\\String\\": "" 2701 | }, 2702 | "exclude-from-classmap": [ 2703 | "/Tests/" 2704 | ] 2705 | }, 2706 | "notification-url": "https://packagist.org/downloads/", 2707 | "license": [ 2708 | "MIT" 2709 | ], 2710 | "authors": [ 2711 | { 2712 | "name": "Nicolas Grekas", 2713 | "email": "p@tchwork.com" 2714 | }, 2715 | { 2716 | "name": "Symfony Community", 2717 | "homepage": "https://symfony.com/contributors" 2718 | } 2719 | ], 2720 | "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", 2721 | "homepage": "https://symfony.com", 2722 | "keywords": [ 2723 | "grapheme", 2724 | "i18n", 2725 | "string", 2726 | "unicode", 2727 | "utf-8", 2728 | "utf8" 2729 | ], 2730 | "support": { 2731 | "source": "https://github.com/symfony/string/tree/v5.4.22" 2732 | }, 2733 | "funding": [ 2734 | { 2735 | "url": "https://symfony.com/sponsor", 2736 | "type": "custom" 2737 | }, 2738 | { 2739 | "url": "https://github.com/fabpot", 2740 | "type": "github" 2741 | }, 2742 | { 2743 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 2744 | "type": "tidelift" 2745 | } 2746 | ], 2747 | "time": "2023-03-14T06:11:53+00:00" 2748 | }, 2749 | { 2750 | "name": "symfony/translation", 2751 | "version": "v5.4.24", 2752 | "source": { 2753 | "type": "git", 2754 | "url": "https://github.com/symfony/translation.git", 2755 | "reference": "de237e59c5833422342be67402d487fbf50334ff" 2756 | }, 2757 | "dist": { 2758 | "type": "zip", 2759 | "url": "https://api.github.com/repos/symfony/translation/zipball/de237e59c5833422342be67402d487fbf50334ff", 2760 | "reference": "de237e59c5833422342be67402d487fbf50334ff", 2761 | "shasum": "", 2762 | "mirrors": [ 2763 | { 2764 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", 2765 | "preferred": true 2766 | } 2767 | ] 2768 | }, 2769 | "require": { 2770 | "php": ">=7.2.5", 2771 | "symfony/deprecation-contracts": "^2.1|^3", 2772 | "symfony/polyfill-mbstring": "~1.0", 2773 | "symfony/polyfill-php80": "^1.16", 2774 | "symfony/translation-contracts": "^2.3" 2775 | }, 2776 | "conflict": { 2777 | "symfony/config": "<4.4", 2778 | "symfony/console": "<5.3", 2779 | "symfony/dependency-injection": "<5.0", 2780 | "symfony/http-kernel": "<5.0", 2781 | "symfony/twig-bundle": "<5.0", 2782 | "symfony/yaml": "<4.4" 2783 | }, 2784 | "provide": { 2785 | "symfony/translation-implementation": "2.3" 2786 | }, 2787 | "require-dev": { 2788 | "psr/log": "^1|^2|^3", 2789 | "symfony/config": "^4.4|^5.0|^6.0", 2790 | "symfony/console": "^5.4|^6.0", 2791 | "symfony/dependency-injection": "^5.0|^6.0", 2792 | "symfony/finder": "^4.4|^5.0|^6.0", 2793 | "symfony/http-client-contracts": "^1.1|^2.0|^3.0", 2794 | "symfony/http-kernel": "^5.0|^6.0", 2795 | "symfony/intl": "^4.4|^5.0|^6.0", 2796 | "symfony/polyfill-intl-icu": "^1.21", 2797 | "symfony/service-contracts": "^1.1.2|^2|^3", 2798 | "symfony/yaml": "^4.4|^5.0|^6.0" 2799 | }, 2800 | "suggest": { 2801 | "psr/log-implementation": "To use logging capability in translator", 2802 | "symfony/config": "", 2803 | "symfony/yaml": "" 2804 | }, 2805 | "type": "library", 2806 | "autoload": { 2807 | "files": [ 2808 | "Resources/functions.php" 2809 | ], 2810 | "psr-4": { 2811 | "Symfony\\Component\\Translation\\": "" 2812 | }, 2813 | "exclude-from-classmap": [ 2814 | "/Tests/" 2815 | ] 2816 | }, 2817 | "notification-url": "https://packagist.org/downloads/", 2818 | "license": [ 2819 | "MIT" 2820 | ], 2821 | "authors": [ 2822 | { 2823 | "name": "Fabien Potencier", 2824 | "email": "fabien@symfony.com" 2825 | }, 2826 | { 2827 | "name": "Symfony Community", 2828 | "homepage": "https://symfony.com/contributors" 2829 | } 2830 | ], 2831 | "description": "Provides tools to internationalize your application", 2832 | "homepage": "https://symfony.com", 2833 | "support": { 2834 | "source": "https://github.com/symfony/translation/tree/v5.4.24" 2835 | }, 2836 | "funding": [ 2837 | { 2838 | "url": "https://symfony.com/sponsor", 2839 | "type": "custom" 2840 | }, 2841 | { 2842 | "url": "https://github.com/fabpot", 2843 | "type": "github" 2844 | }, 2845 | { 2846 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 2847 | "type": "tidelift" 2848 | } 2849 | ], 2850 | "time": "2023-05-19T12:34:17+00:00" 2851 | }, 2852 | { 2853 | "name": "symfony/translation-contracts", 2854 | "version": "v2.5.2", 2855 | "source": { 2856 | "type": "git", 2857 | "url": "https://github.com/symfony/translation-contracts.git", 2858 | "reference": "136b19dd05cdf0709db6537d058bcab6dd6e2dbe" 2859 | }, 2860 | "dist": { 2861 | "type": "zip", 2862 | "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/136b19dd05cdf0709db6537d058bcab6dd6e2dbe", 2863 | "reference": "136b19dd05cdf0709db6537d058bcab6dd6e2dbe", 2864 | "shasum": "", 2865 | "mirrors": [ 2866 | { 2867 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", 2868 | "preferred": true 2869 | } 2870 | ] 2871 | }, 2872 | "require": { 2873 | "php": ">=7.2.5" 2874 | }, 2875 | "suggest": { 2876 | "symfony/translation-implementation": "" 2877 | }, 2878 | "type": "library", 2879 | "extra": { 2880 | "branch-alias": { 2881 | "dev-main": "2.5-dev" 2882 | }, 2883 | "thanks": { 2884 | "name": "symfony/contracts", 2885 | "url": "https://github.com/symfony/contracts" 2886 | } 2887 | }, 2888 | "autoload": { 2889 | "psr-4": { 2890 | "Symfony\\Contracts\\Translation\\": "" 2891 | } 2892 | }, 2893 | "notification-url": "https://packagist.org/downloads/", 2894 | "license": [ 2895 | "MIT" 2896 | ], 2897 | "authors": [ 2898 | { 2899 | "name": "Nicolas Grekas", 2900 | "email": "p@tchwork.com" 2901 | }, 2902 | { 2903 | "name": "Symfony Community", 2904 | "homepage": "https://symfony.com/contributors" 2905 | } 2906 | ], 2907 | "description": "Generic abstractions related to translation", 2908 | "homepage": "https://symfony.com", 2909 | "keywords": [ 2910 | "abstractions", 2911 | "contracts", 2912 | "decoupling", 2913 | "interfaces", 2914 | "interoperability", 2915 | "standards" 2916 | ], 2917 | "support": { 2918 | "source": "https://github.com/symfony/translation-contracts/tree/v2.5.2" 2919 | }, 2920 | "funding": [ 2921 | { 2922 | "url": "https://symfony.com/sponsor", 2923 | "type": "custom" 2924 | }, 2925 | { 2926 | "url": "https://github.com/fabpot", 2927 | "type": "github" 2928 | }, 2929 | { 2930 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 2931 | "type": "tidelift" 2932 | } 2933 | ], 2934 | "time": "2022-06-27T16:58:25+00:00" 2935 | }, 2936 | { 2937 | "name": "symfony/var-dumper", 2938 | "version": "v5.4.25", 2939 | "source": { 2940 | "type": "git", 2941 | "url": "https://github.com/symfony/var-dumper.git", 2942 | "reference": "82269f73c0f0f9859ab9b6900eebacbe54954ede" 2943 | }, 2944 | "dist": { 2945 | "type": "zip", 2946 | "url": "https://api.github.com/repos/symfony/var-dumper/zipball/82269f73c0f0f9859ab9b6900eebacbe54954ede", 2947 | "reference": "82269f73c0f0f9859ab9b6900eebacbe54954ede", 2948 | "shasum": "", 2949 | "mirrors": [ 2950 | { 2951 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", 2952 | "preferred": true 2953 | } 2954 | ] 2955 | }, 2956 | "require": { 2957 | "php": ">=7.2.5", 2958 | "symfony/polyfill-mbstring": "~1.0", 2959 | "symfony/polyfill-php80": "^1.16" 2960 | }, 2961 | "conflict": { 2962 | "symfony/console": "<4.4" 2963 | }, 2964 | "require-dev": { 2965 | "ext-iconv": "*", 2966 | "symfony/console": "^4.4|^5.0|^6.0", 2967 | "symfony/process": "^4.4|^5.0|^6.0", 2968 | "symfony/uid": "^5.1|^6.0", 2969 | "twig/twig": "^2.13|^3.0.4" 2970 | }, 2971 | "suggest": { 2972 | "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", 2973 | "ext-intl": "To show region name in time zone dump", 2974 | "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script" 2975 | }, 2976 | "bin": [ 2977 | "Resources/bin/var-dump-server" 2978 | ], 2979 | "type": "library", 2980 | "autoload": { 2981 | "files": [ 2982 | "Resources/functions/dump.php" 2983 | ], 2984 | "psr-4": { 2985 | "Symfony\\Component\\VarDumper\\": "" 2986 | }, 2987 | "exclude-from-classmap": [ 2988 | "/Tests/" 2989 | ] 2990 | }, 2991 | "notification-url": "https://packagist.org/downloads/", 2992 | "license": [ 2993 | "MIT" 2994 | ], 2995 | "authors": [ 2996 | { 2997 | "name": "Nicolas Grekas", 2998 | "email": "p@tchwork.com" 2999 | }, 3000 | { 3001 | "name": "Symfony Community", 3002 | "homepage": "https://symfony.com/contributors" 3003 | } 3004 | ], 3005 | "description": "Provides mechanisms for walking through any arbitrary PHP variable", 3006 | "homepage": "https://symfony.com", 3007 | "keywords": [ 3008 | "debug", 3009 | "dump" 3010 | ], 3011 | "support": { 3012 | "source": "https://github.com/symfony/var-dumper/tree/v5.4.25" 3013 | }, 3014 | "funding": [ 3015 | { 3016 | "url": "https://symfony.com/sponsor", 3017 | "type": "custom" 3018 | }, 3019 | { 3020 | "url": "https://github.com/fabpot", 3021 | "type": "github" 3022 | }, 3023 | { 3024 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 3025 | "type": "tidelift" 3026 | } 3027 | ], 3028 | "time": "2023-06-20T20:56:26+00:00" 3029 | }, 3030 | { 3031 | "name": "vlucas/phpdotenv", 3032 | "version": "v5.4.1", 3033 | "source": { 3034 | "type": "git", 3035 | "url": "https://github.com/vlucas/phpdotenv.git", 3036 | "reference": "264dce589e7ce37a7ba99cb901eed8249fbec92f" 3037 | }, 3038 | "dist": { 3039 | "type": "zip", 3040 | "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/264dce589e7ce37a7ba99cb901eed8249fbec92f", 3041 | "reference": "264dce589e7ce37a7ba99cb901eed8249fbec92f", 3042 | "shasum": "", 3043 | "mirrors": [ 3044 | { 3045 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", 3046 | "preferred": true 3047 | } 3048 | ] 3049 | }, 3050 | "require": { 3051 | "ext-pcre": "*", 3052 | "graham-campbell/result-type": "^1.0.2", 3053 | "php": "^7.1.3 || ^8.0", 3054 | "phpoption/phpoption": "^1.8", 3055 | "symfony/polyfill-ctype": "^1.23", 3056 | "symfony/polyfill-mbstring": "^1.23.1", 3057 | "symfony/polyfill-php80": "^1.23.1" 3058 | }, 3059 | "require-dev": { 3060 | "bamarni/composer-bin-plugin": "^1.4.1", 3061 | "ext-filter": "*", 3062 | "phpunit/phpunit": "^7.5.20 || ^8.5.21 || ^9.5.10" 3063 | }, 3064 | "suggest": { 3065 | "ext-filter": "Required to use the boolean validator." 3066 | }, 3067 | "type": "library", 3068 | "extra": { 3069 | "branch-alias": { 3070 | "dev-master": "5.4-dev" 3071 | } 3072 | }, 3073 | "autoload": { 3074 | "psr-4": { 3075 | "Dotenv\\": "src/" 3076 | } 3077 | }, 3078 | "notification-url": "https://packagist.org/downloads/", 3079 | "license": [ 3080 | "BSD-3-Clause" 3081 | ], 3082 | "authors": [ 3083 | { 3084 | "name": "Graham Campbell", 3085 | "email": "hello@gjcampbell.co.uk", 3086 | "homepage": "https://github.com/GrahamCampbell" 3087 | }, 3088 | { 3089 | "name": "Vance Lucas", 3090 | "email": "vance@vancelucas.com", 3091 | "homepage": "https://github.com/vlucas" 3092 | } 3093 | ], 3094 | "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", 3095 | "keywords": [ 3096 | "dotenv", 3097 | "env", 3098 | "environment" 3099 | ], 3100 | "support": { 3101 | "issues": "https://github.com/vlucas/phpdotenv/issues", 3102 | "source": "https://github.com/vlucas/phpdotenv/tree/v5.4.1" 3103 | }, 3104 | "funding": [ 3105 | { 3106 | "url": "https://github.com/GrahamCampbell", 3107 | "type": "github" 3108 | }, 3109 | { 3110 | "url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv", 3111 | "type": "tidelift" 3112 | } 3113 | ], 3114 | "time": "2021-12-12T23:22:04+00:00" 3115 | }, 3116 | { 3117 | "name": "voku/portable-ascii", 3118 | "version": "1.6.1", 3119 | "source": { 3120 | "type": "git", 3121 | "url": "https://github.com/voku/portable-ascii.git", 3122 | "reference": "87337c91b9dfacee02452244ee14ab3c43bc485a" 3123 | }, 3124 | "dist": { 3125 | "type": "zip", 3126 | "url": "https://api.github.com/repos/voku/portable-ascii/zipball/87337c91b9dfacee02452244ee14ab3c43bc485a", 3127 | "reference": "87337c91b9dfacee02452244ee14ab3c43bc485a", 3128 | "shasum": "", 3129 | "mirrors": [ 3130 | { 3131 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", 3132 | "preferred": true 3133 | } 3134 | ] 3135 | }, 3136 | "require": { 3137 | "php": ">=7.0.0" 3138 | }, 3139 | "require-dev": { 3140 | "phpunit/phpunit": "~6.0 || ~7.0 || ~9.0" 3141 | }, 3142 | "suggest": { 3143 | "ext-intl": "Use Intl for transliterator_transliterate() support" 3144 | }, 3145 | "type": "library", 3146 | "autoload": { 3147 | "psr-4": { 3148 | "voku\\": "src/voku/" 3149 | } 3150 | }, 3151 | "notification-url": "https://packagist.org/downloads/", 3152 | "license": [ 3153 | "MIT" 3154 | ], 3155 | "authors": [ 3156 | { 3157 | "name": "Lars Moelleken", 3158 | "homepage": "http://www.moelleken.org/" 3159 | } 3160 | ], 3161 | "description": "Portable ASCII library - performance optimized (ascii) string functions for php.", 3162 | "homepage": "https://github.com/voku/portable-ascii", 3163 | "keywords": [ 3164 | "ascii", 3165 | "clean", 3166 | "php" 3167 | ], 3168 | "support": { 3169 | "issues": "https://github.com/voku/portable-ascii/issues", 3170 | "source": "https://github.com/voku/portable-ascii/tree/1.6.1" 3171 | }, 3172 | "funding": [ 3173 | { 3174 | "url": "https://www.paypal.me/moelleken", 3175 | "type": "custom" 3176 | }, 3177 | { 3178 | "url": "https://github.com/voku", 3179 | "type": "github" 3180 | }, 3181 | { 3182 | "url": "https://opencollective.com/portable-ascii", 3183 | "type": "open_collective" 3184 | }, 3185 | { 3186 | "url": "https://www.patreon.com/voku", 3187 | "type": "patreon" 3188 | }, 3189 | { 3190 | "url": "https://tidelift.com/funding/github/packagist/voku/portable-ascii", 3191 | "type": "tidelift" 3192 | } 3193 | ], 3194 | "time": "2022-01-24T18:55:24+00:00" 3195 | }, 3196 | { 3197 | "name": "webman/redis-queue", 3198 | "version": "v1.2.4", 3199 | "source": { 3200 | "type": "git", 3201 | "url": "https://github.com/webman-php/redis-queue.git", 3202 | "reference": "81667bf9ab3c1256e2c2f61b9d41d53791b8b34b" 3203 | }, 3204 | "dist": { 3205 | "type": "zip", 3206 | "url": "https://api.github.com/repos/webman-php/redis-queue/zipball/81667bf9ab3c1256e2c2f61b9d41d53791b8b34b", 3207 | "reference": "81667bf9ab3c1256e2c2f61b9d41d53791b8b34b", 3208 | "shasum": "", 3209 | "mirrors": [ 3210 | { 3211 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", 3212 | "preferred": true 3213 | } 3214 | ] 3215 | }, 3216 | "require": { 3217 | "workerman/redis-queue": "^1.0" 3218 | }, 3219 | "type": "library", 3220 | "autoload": { 3221 | "psr-4": { 3222 | "Webman\\RedisQueue\\": "./src" 3223 | } 3224 | }, 3225 | "notification-url": "https://packagist.org/downloads/", 3226 | "description": "Redis message queue plugin for webman.", 3227 | "support": { 3228 | "issues": "https://github.com/webman-php/redis-queue/issues", 3229 | "source": "https://github.com/webman-php/redis-queue/tree/v1.2.4" 3230 | }, 3231 | "time": "2022-06-27T08:07:13+00:00" 3232 | }, 3233 | { 3234 | "name": "workerman/redis", 3235 | "version": "v2.0.1", 3236 | "source": { 3237 | "type": "git", 3238 | "url": "https://github.com/walkor/redis.git", 3239 | "reference": "284f93cccc03603e616cf96b8cab847fe6b33b6a" 3240 | }, 3241 | "dist": { 3242 | "type": "zip", 3243 | "url": "https://api.github.com/repos/walkor/redis/zipball/284f93cccc03603e616cf96b8cab847fe6b33b6a", 3244 | "reference": "284f93cccc03603e616cf96b8cab847fe6b33b6a", 3245 | "shasum": "", 3246 | "mirrors": [ 3247 | { 3248 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", 3249 | "preferred": true 3250 | } 3251 | ] 3252 | }, 3253 | "require": { 3254 | "php": ">=7", 3255 | "workerman/workerman": "^4.1.0||^5.0.0" 3256 | }, 3257 | "type": "library", 3258 | "autoload": { 3259 | "psr-4": { 3260 | "Workerman\\Redis\\": "./src" 3261 | } 3262 | }, 3263 | "notification-url": "https://packagist.org/downloads/", 3264 | "license": [ 3265 | "MIT" 3266 | ], 3267 | "homepage": "http://www.workerman.net", 3268 | "support": { 3269 | "issues": "https://github.com/walkor/redis/issues", 3270 | "source": "https://github.com/walkor/redis/tree/v2.0.1" 3271 | }, 3272 | "time": "2023-04-07T10:35:41+00:00" 3273 | }, 3274 | { 3275 | "name": "workerman/redis-queue", 3276 | "version": "v1.1.0", 3277 | "source": { 3278 | "type": "git", 3279 | "url": "https://github.com/walkor/redis-queue.git", 3280 | "reference": "e325f5b09cd170a327597876f1d659cd81510388" 3281 | }, 3282 | "dist": { 3283 | "type": "zip", 3284 | "url": "https://api.github.com/repos/walkor/redis-queue/zipball/e325f5b09cd170a327597876f1d659cd81510388", 3285 | "reference": "e325f5b09cd170a327597876f1d659cd81510388", 3286 | "shasum": "", 3287 | "mirrors": [ 3288 | { 3289 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", 3290 | "preferred": true 3291 | } 3292 | ] 3293 | }, 3294 | "require": { 3295 | "php": ">=5.4", 3296 | "workerman/redis": "^1.0||^2.0", 3297 | "workerman/workerman": ">=4.0.20" 3298 | }, 3299 | "type": "library", 3300 | "autoload": { 3301 | "psr-4": { 3302 | "Workerman\\RedisQueue\\": "./src" 3303 | } 3304 | }, 3305 | "notification-url": "https://packagist.org/downloads/", 3306 | "license": [ 3307 | "MIT" 3308 | ], 3309 | "description": "Message queue system written in PHP based on workerman and backed by Redis.", 3310 | "homepage": "http://www.workerman.net", 3311 | "support": { 3312 | "issues": "https://github.com/walkor/redis-queue/issues", 3313 | "source": "https://github.com/walkor/redis-queue/tree/v1.1.0" 3314 | }, 3315 | "time": "2023-04-07T10:23:19+00:00" 3316 | }, 3317 | { 3318 | "name": "workerman/webman-framework", 3319 | "version": "v1.5.6", 3320 | "source": { 3321 | "type": "git", 3322 | "url": "https://github.com/walkor/webman-framework.git", 3323 | "reference": "99a57690f3a9e0694a00b97154c4448dd630c622" 3324 | }, 3325 | "dist": { 3326 | "type": "zip", 3327 | "url": "https://api.github.com/repos/walkor/webman-framework/zipball/99a57690f3a9e0694a00b97154c4448dd630c622", 3328 | "reference": "99a57690f3a9e0694a00b97154c4448dd630c622", 3329 | "shasum": "", 3330 | "mirrors": [ 3331 | { 3332 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", 3333 | "preferred": true 3334 | } 3335 | ] 3336 | }, 3337 | "require": { 3338 | "ext-json": "*", 3339 | "nikic/fast-route": "^1.3", 3340 | "php": ">=7.2", 3341 | "psr/container": ">=1.0", 3342 | "workerman/workerman": "^4.0.4 || ^5.0.0" 3343 | }, 3344 | "suggest": { 3345 | "ext-event": "For better performance. " 3346 | }, 3347 | "type": "library", 3348 | "autoload": { 3349 | "psr-4": { 3350 | "Webman\\": "./src", 3351 | "Support\\": "./src/support", 3352 | "support\\": "./src/support", 3353 | "Support\\View\\": "./src/support/view", 3354 | "Support\\Bootstrap\\": "./src/support/bootstrap", 3355 | "Support\\Exception\\": "./src/support/exception" 3356 | } 3357 | }, 3358 | "notification-url": "https://packagist.org/downloads/", 3359 | "license": [ 3360 | "MIT" 3361 | ], 3362 | "authors": [ 3363 | { 3364 | "name": "walkor", 3365 | "email": "walkor@workerman.net", 3366 | "homepage": "https://www.workerman.net", 3367 | "role": "Developer" 3368 | } 3369 | ], 3370 | "description": "High performance HTTP Service Framework.", 3371 | "homepage": "https://www.workerman.net", 3372 | "keywords": [ 3373 | "High Performance", 3374 | "http service" 3375 | ], 3376 | "support": { 3377 | "email": "walkor@workerman.net", 3378 | "forum": "https://wenda.workerman.net/", 3379 | "issues": "https://github.com/walkor/webman/issues", 3380 | "source": "https://github.com/walkor/webman-framework", 3381 | "wiki": "https://doc.workerman.net/" 3382 | }, 3383 | "time": "2023-05-27T12:27:43+00:00" 3384 | }, 3385 | { 3386 | "name": "workerman/workerman", 3387 | "version": "v4.1.10", 3388 | "source": { 3389 | "type": "git", 3390 | "url": "https://github.com/walkor/workerman.git", 3391 | "reference": "e967b79f95b9251a72acb971be05623ec1a51e83" 3392 | }, 3393 | "dist": { 3394 | "type": "zip", 3395 | "url": "https://api.github.com/repos/walkor/workerman/zipball/e967b79f95b9251a72acb971be05623ec1a51e83", 3396 | "reference": "e967b79f95b9251a72acb971be05623ec1a51e83", 3397 | "shasum": "", 3398 | "mirrors": [ 3399 | { 3400 | "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", 3401 | "preferred": true 3402 | } 3403 | ] 3404 | }, 3405 | "require": { 3406 | "php": ">=7.0" 3407 | }, 3408 | "suggest": { 3409 | "ext-event": "For better performance. " 3410 | }, 3411 | "type": "library", 3412 | "autoload": { 3413 | "psr-4": { 3414 | "Workerman\\": "./" 3415 | } 3416 | }, 3417 | "notification-url": "https://packagist.org/downloads/", 3418 | "license": [ 3419 | "MIT" 3420 | ], 3421 | "authors": [ 3422 | { 3423 | "name": "walkor", 3424 | "email": "walkor@workerman.net", 3425 | "homepage": "http://www.workerman.net", 3426 | "role": "Developer" 3427 | } 3428 | ], 3429 | "description": "An asynchronous event driven PHP framework for easily building fast, scalable network applications.", 3430 | "homepage": "http://www.workerman.net", 3431 | "keywords": [ 3432 | "asynchronous", 3433 | "event-loop" 3434 | ], 3435 | "support": { 3436 | "email": "walkor@workerman.net", 3437 | "forum": "http://wenda.workerman.net/", 3438 | "issues": "https://github.com/walkor/workerman/issues", 3439 | "source": "https://github.com/walkor/workerman", 3440 | "wiki": "http://doc.workerman.net/" 3441 | }, 3442 | "funding": [ 3443 | { 3444 | "url": "https://opencollective.com/workerman", 3445 | "type": "open_collective" 3446 | }, 3447 | { 3448 | "url": "https://www.patreon.com/walkor", 3449 | "type": "patreon" 3450 | } 3451 | ], 3452 | "time": "2023-05-01T02:12:20+00:00" 3453 | } 3454 | ], 3455 | "packages-dev": [], 3456 | "aliases": [], 3457 | "minimum-stability": "stable", 3458 | "stability-flags": [], 3459 | "prefer-stable": false, 3460 | "prefer-lowest": false, 3461 | "platform": { 3462 | "php": ">=7.3", 3463 | "ext-json": "*" 3464 | }, 3465 | "platform-dev": [], 3466 | "plugin-api-version": "2.3.0" 3467 | } 3468 | -------------------------------------------------------------------------------- /config/app.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright walkor 11 | * @link http://www.workerman.net/ 12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 13 | */ 14 | 15 | use support\Request; 16 | 17 | return [ 18 | 'debug' => env('APP_DEBUG', false), 19 | 'error_reporting' => E_ALL, 20 | 'default_timezone' => 'Asia/Shanghai', 21 | 'request_class' => Request::class, 22 | 'public_path' => base_path() . DIRECTORY_SEPARATOR . 'public', 23 | 'runtime_path' => base_path(false) . DIRECTORY_SEPARATOR . 'runtime', 24 | 'controller_suffix' => 'Controller', 25 | 'controller_reuse' => false, 26 | ]; 27 | -------------------------------------------------------------------------------- /config/autoload.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright walkor 11 | * @link http://www.workerman.net/ 12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 13 | */ 14 | 15 | return [ 16 | 'files' => [ 17 | base_path() . '/app/functions.php', 18 | base_path() . '/support/Request.php', 19 | base_path() . '/support/Response.php', 20 | ] 21 | ]; 22 | -------------------------------------------------------------------------------- /config/bootstrap.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright walkor 11 | * @link http://www.workerman.net/ 12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 13 | */ 14 | 15 | return [ 16 | support\bootstrap\Session::class, 17 | support\bootstrap\LaravelDb::class, 18 | ]; 19 | -------------------------------------------------------------------------------- /config/container.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright walkor 11 | * @link http://www.workerman.net/ 12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 13 | */ 14 | 15 | return new Webman\Container; -------------------------------------------------------------------------------- /config/database.php: -------------------------------------------------------------------------------- 1 | 'mysql', 5 | // 各种数据库配置 6 | 'connections' => [ 7 | 'mysql' => [ 8 | 'driver' => 'mysql', 9 | 'host' => env('DB_HOST', 'localhost'), 10 | 'port' => env('DB_PORT', 3306), 11 | 'database' => env('DB_DATABASE', 'test'), 12 | 'username' => env('DB_USERNAME', 'root'), 13 | 'password' => env('DB_PASSWORD', 'root'), 14 | 'unix_socket' => '', 15 | 'charset' => env('DB_CHARSET', 'utf8mb4'), 16 | 'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'), 17 | 'prefix' => env('DB_PREFIX', ''), 18 | 'strict' => true, 19 | 'engine' => null, 20 | ], 21 | ], 22 | ]; 23 | -------------------------------------------------------------------------------- /config/dependence.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright walkor 11 | * @link http://www.workerman.net/ 12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 13 | */ 14 | 15 | return []; -------------------------------------------------------------------------------- /config/exception.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright walkor 11 | * @link http://www.workerman.net/ 12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 13 | */ 14 | 15 | return [ 16 | '' => support\exception\Handler::class, 17 | ]; -------------------------------------------------------------------------------- /config/http.php: -------------------------------------------------------------------------------- 1 | 5.0 5 | ]; 6 | -------------------------------------------------------------------------------- /config/log.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright walkor 11 | * @link http://www.workerman.net/ 12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 13 | */ 14 | 15 | return [ 16 | 'default' => [ 17 | 'handlers' => [ 18 | [ 19 | 'class' => Monolog\Handler\RotatingFileHandler::class, 20 | 'constructor' => [ 21 | runtime_path() . '/logs/webman.log', 22 | 7, //$maxFiles 23 | Monolog\Logger::DEBUG, 24 | ], 25 | 'formatter' => [ 26 | 'class' => Monolog\Formatter\LineFormatter::class, 27 | 'constructor' => [null, 'Y-m-d H:i:s', true], 28 | ], 29 | ] 30 | ], 31 | ], 32 | ]; 33 | -------------------------------------------------------------------------------- /config/middleware.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright walkor 11 | * @link http://www.workerman.net/ 12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 13 | */ 14 | 15 | return [ 16 | //全局中间件 17 | '' => [ 18 | app\middleware\GlobalLog::class 19 | ] 20 | ]; -------------------------------------------------------------------------------- /config/plugin/webman/redis-queue/app.php: -------------------------------------------------------------------------------- 1 | true, 4 | ]; -------------------------------------------------------------------------------- /config/plugin/webman/redis-queue/command.php: -------------------------------------------------------------------------------- 1 | [ 4 | 'handler' => Webman\RedisQueue\Process\Consumer::class, 5 | 'count' => 8, // 可以设置多进程同时消费 6 | 'constructor' => [ 7 | // 消费者类目录 8 | 'consumer_dir' => app_path() . '/queue/redis' 9 | ] 10 | ] 11 | ]; -------------------------------------------------------------------------------- /config/plugin/webman/redis-queue/redis.php: -------------------------------------------------------------------------------- 1 | [ 4 | 'host' => 'redis://' . env('REDIS_QUEUE_HOST', '127.0.0.1') . ':' . env('REDIS_QUEUE_PORT', 6379), 5 | 'options' => [ 6 | 'auth' => env('REDIS_QUEUE_AUTH', null), // 密码,字符串类型,可选参数 7 | 'db' => env('REDIS_QUEUE_DB', 0), // 数据库 8 | 'prefix' => '', // key 前缀 9 | 'max_attempts' => 3, // 消费失败后,重试次数 10 | 'retry_seconds' => 5, // 重试间隔,单位秒 11 | ] 12 | ], 13 | ]; 14 | -------------------------------------------------------------------------------- /config/process.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright walkor 11 | * @link http://www.workerman.net/ 12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 13 | */ 14 | 15 | use Workerman\Worker; 16 | 17 | return [ 18 | // File update detection and automatic reload 19 | 'monitor' => [ 20 | 'handler' => process\Monitor::class, 21 | 'reloadable' => false, 22 | 'constructor' => [ 23 | // Monitor these directories 24 | 'monitorDir' => array_merge([ 25 | app_path(), 26 | config_path(), 27 | base_path() . '/process', 28 | base_path() . '/support', 29 | base_path() . '/resource', 30 | base_path() . '/.env', 31 | ], glob(base_path() . '/plugin/*/app'), glob(base_path() . '/plugin/*/config'), glob(base_path() . '/plugin/*/api')), 32 | // Files with these suffixes will be monitored 33 | 'monitorExtensions' => [ 34 | 'php', 'html', 'htm', 'env' 35 | ], 36 | 'options' => [ 37 | 'enable_file_monitor' => !Worker::$daemonize && DIRECTORY_SEPARATOR === '/', 38 | 'enable_memory_monitor' => DIRECTORY_SEPARATOR === '/', 39 | ] 40 | ] 41 | ] 42 | ]; 43 | -------------------------------------------------------------------------------- /config/redis.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright walkor 11 | * @link http://www.workerman.net/ 12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 13 | */ 14 | 15 | return [ 16 | 'default' => [ 17 | 'host' => env('REDIS_HOST', '127.0.0.1'), 18 | 'password' => env('REDIS_QUEUE_AUTH', null), 19 | 'port' => env('REDIS_PORT,6379'), 20 | 'database' => env('REDIS_DB', 0), 21 | ], 22 | ]; 23 | -------------------------------------------------------------------------------- /config/route.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright walkor 11 | * @link http://www.workerman.net/ 12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 13 | */ 14 | 15 | use Webman\Route; 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /config/server.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright walkor 11 | * @link http://www.workerman.net/ 12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 13 | */ 14 | 15 | return [ 16 | 'listen' => 'http://0.0.0.0:8787', 17 | 'transport' => 'tcp', 18 | 'context' => [], 19 | 'name' => 'webman', 20 | 'count' => cpu_count() * 4, 21 | 'user' => '', 22 | 'group' => '', 23 | 'reusePort' => false, 24 | 'event_loop' => '', 25 | 'stop_timeout' => 2, 26 | 'pid_file' => runtime_path() . '/webman.pid', 27 | 'status_file' => runtime_path() . '/webman.status', 28 | 'stdout_file' => runtime_path() . '/logs/stdout.log', 29 | 'log_file' => runtime_path() . '/logs/workerman.log', 30 | 'max_package_size' => 10 * 1024 * 1024 31 | ]; 32 | -------------------------------------------------------------------------------- /config/session.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright walkor 11 | * @link http://www.workerman.net/ 12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 13 | */ 14 | 15 | use Webman\Session\FileSessionHandler; 16 | use Webman\Session\RedisSessionHandler; 17 | use Webman\Session\RedisClusterSessionHandler; 18 | 19 | return [ 20 | 21 | 'type' => 'file', // or redis or redis_cluster 22 | 23 | 'handler' => FileSessionHandler::class, 24 | 25 | 'config' => [ 26 | 'file' => [ 27 | 'save_path' => runtime_path() . '/sessions', 28 | ], 29 | 'redis' => [ 30 | 'host' => '127.0.0.1', 31 | 'port' => 6379, 32 | 'auth' => '', 33 | 'timeout' => 2, 34 | 'database' => '', 35 | 'prefix' => 'redis_session_', 36 | ], 37 | 'redis_cluster' => [ 38 | 'host' => ['127.0.0.1:7000', '127.0.0.1:7001', '127.0.0.1:7001'], 39 | 'timeout' => 2, 40 | 'auth' => '', 41 | 'prefix' => 'redis_session_', 42 | ] 43 | ], 44 | 45 | 'session_name' => 'PHPSID', 46 | 47 | 'auto_update_timestamp' => false, 48 | 49 | 'lifetime' => 7*24*60*60, 50 | 51 | 'cookie_lifetime' => 365*24*60*60, 52 | 53 | 'cookie_path' => '/', 54 | 55 | 'domain' => '', 56 | 57 | 'http_only' => true, 58 | 59 | 'secure' => false, 60 | 61 | 'same_site' => '', 62 | 63 | 'gc_probability' => [1, 1000], 64 | 65 | ]; 66 | -------------------------------------------------------------------------------- /config/static.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright walkor 11 | * @link http://www.workerman.net/ 12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 13 | */ 14 | 15 | /** 16 | * Static file settings 17 | */ 18 | return [ 19 | 'enable' => true, 20 | 'middleware' => [ // Static file Middleware 21 | //app\middleware\StaticFile::class, 22 | ], 23 | ]; -------------------------------------------------------------------------------- /config/translation.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright walkor 11 | * @link http://www.workerman.net/ 12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 13 | */ 14 | 15 | /** 16 | * Multilingual configuration 17 | */ 18 | return [ 19 | // Default language 20 | 'locale' => 'zh_CN', 21 | // Fallback language 22 | 'fallback_locale' => ['zh_CN', 'en'], 23 | // Folder where language files are stored 24 | 'path' => base_path() . '/resource/translations', 25 | ]; -------------------------------------------------------------------------------- /config/view.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright walkor 11 | * @link http://www.workerman.net/ 12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 13 | */ 14 | 15 | use support\view\Raw; 16 | use support\view\Twig; 17 | use support\view\Blade; 18 | use support\view\ThinkPHP; 19 | 20 | return [ 21 | 'handler' => Raw::class 22 | ]; 23 | -------------------------------------------------------------------------------- /process/Monitor.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright walkor 11 | * @link http://www.workerman.net/ 12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 13 | */ 14 | 15 | namespace process; 16 | 17 | use FilesystemIterator; 18 | use RecursiveDirectoryIterator; 19 | use RecursiveIteratorIterator; 20 | use SplFileInfo; 21 | use Workerman\Timer; 22 | use Workerman\Worker; 23 | 24 | /** 25 | * Class FileMonitor 26 | * @package process 27 | */ 28 | class Monitor 29 | { 30 | /** 31 | * @var array 32 | */ 33 | protected $paths = []; 34 | 35 | /** 36 | * @var array 37 | */ 38 | protected $extensions = []; 39 | 40 | /** 41 | * @var string 42 | */ 43 | public static $lockFile = __DIR__ . '/../runtime/monitor.lock'; 44 | 45 | /** 46 | * Pause monitor 47 | * @return void 48 | */ 49 | public static function pause() 50 | { 51 | file_put_contents(static::$lockFile, time()); 52 | } 53 | 54 | /** 55 | * Resume monitor 56 | * @return void 57 | */ 58 | public static function resume(): void 59 | { 60 | clearstatcache(); 61 | if (is_file(static::$lockFile)) { 62 | unlink(static::$lockFile); 63 | } 64 | } 65 | 66 | /** 67 | * Whether monitor is paused 68 | * @return bool 69 | */ 70 | public static function isPaused(): bool 71 | { 72 | clearstatcache(); 73 | return file_exists(static::$lockFile); 74 | } 75 | 76 | /** 77 | * FileMonitor constructor. 78 | * @param $monitorDir 79 | * @param $monitorExtensions 80 | * @param array $options 81 | */ 82 | public function __construct($monitorDir, $monitorExtensions, array $options = []) 83 | { 84 | static::resume(); 85 | $this->paths = (array)$monitorDir; 86 | $this->extensions = $monitorExtensions; 87 | if (!Worker::getAllWorkers()) { 88 | return; 89 | } 90 | $disableFunctions = explode(',', ini_get('disable_functions')); 91 | if (in_array('exec', $disableFunctions, true)) { 92 | echo "\nMonitor file change turned off because exec() has been disabled by disable_functions setting in " . PHP_CONFIG_FILE_PATH . "/php.ini\n"; 93 | } else { 94 | if ($options['enable_file_monitor'] ?? true) { 95 | Timer::add(1, function () { 96 | $this->checkAllFilesChange(); 97 | }); 98 | } 99 | } 100 | 101 | $memoryLimit = $this->getMemoryLimit($options['memory_limit'] ?? null); 102 | if ($memoryLimit && ($options['enable_memory_monitor'] ?? true)) { 103 | Timer::add(60, [$this, 'checkMemory'], [$memoryLimit]); 104 | } 105 | } 106 | 107 | /** 108 | * @param $monitorDir 109 | * @return bool 110 | */ 111 | public function checkFilesChange($monitorDir): bool 112 | { 113 | static $lastMtime, $tooManyFilesCheck; 114 | if (!$lastMtime) { 115 | $lastMtime = time(); 116 | } 117 | clearstatcache(); 118 | if (!is_dir($monitorDir)) { 119 | if (!is_file($monitorDir)) { 120 | return false; 121 | } 122 | $iterator = [new SplFileInfo($monitorDir)]; 123 | } else { 124 | // recursive traversal directory 125 | $dirIterator = new RecursiveDirectoryIterator($monitorDir, FilesystemIterator::SKIP_DOTS | FilesystemIterator::FOLLOW_SYMLINKS); 126 | $iterator = new RecursiveIteratorIterator($dirIterator); 127 | } 128 | $count = 0; 129 | foreach ($iterator as $file) { 130 | $count ++; 131 | /** var SplFileInfo $file */ 132 | if (is_dir($file->getRealPath())) { 133 | continue; 134 | } 135 | // check mtime 136 | if (in_array($file->getExtension(), $this->extensions, true) && $lastMtime < $file->getMTime()) { 137 | $var = 0; 138 | exec('"'.PHP_BINARY . '" -l ' . $file, $out, $var); 139 | $lastMtime = $file->getMTime(); 140 | if ($var) { 141 | continue; 142 | } 143 | echo $file . " update and reload\n"; 144 | // send SIGUSR1 signal to master process for reload 145 | if (DIRECTORY_SEPARATOR === '/') { 146 | posix_kill(posix_getppid(), SIGUSR1); 147 | } else { 148 | return true; 149 | } 150 | break; 151 | } 152 | } 153 | if (!$tooManyFilesCheck && $count > 1000) { 154 | echo "Monitor: There are too many files ($count files) in $monitorDir which makes file monitoring very slow\n"; 155 | $tooManyFilesCheck = 1; 156 | } 157 | return false; 158 | } 159 | 160 | /** 161 | * @return bool 162 | */ 163 | public function checkAllFilesChange(): bool 164 | { 165 | if (static::isPaused()) { 166 | return false; 167 | } 168 | foreach ($this->paths as $path) { 169 | if ($this->checkFilesChange($path)) { 170 | return true; 171 | } 172 | } 173 | return false; 174 | } 175 | 176 | /** 177 | * @param $memoryLimit 178 | * @return void 179 | */ 180 | public function checkMemory($memoryLimit) 181 | { 182 | if (static::isPaused() || $memoryLimit <= 0) { 183 | return; 184 | } 185 | $ppid = posix_getppid(); 186 | $childrenFile = "/proc/$ppid/task/$ppid/children"; 187 | if (!is_file($childrenFile) || !($children = file_get_contents($childrenFile))) { 188 | return; 189 | } 190 | foreach (explode(' ', $children) as $pid) { 191 | $pid = (int)$pid; 192 | $statusFile = "/proc/$pid/status"; 193 | if (!is_file($statusFile) || !($status = file_get_contents($statusFile))) { 194 | continue; 195 | } 196 | $mem = 0; 197 | if (preg_match('/VmRSS\s*?:\s*?(\d+?)\s*?kB/', $status, $match)) { 198 | $mem = $match[1]; 199 | } 200 | $mem = (int)($mem / 1024); 201 | if ($mem >= $memoryLimit) { 202 | posix_kill($pid, SIGINT); 203 | } 204 | } 205 | } 206 | 207 | /** 208 | * Get memory limit 209 | * @return float 210 | */ 211 | protected function getMemoryLimit($memoryLimit) 212 | { 213 | if ($memoryLimit === 0) { 214 | return 0; 215 | } 216 | $usePhpIni = false; 217 | if (!$memoryLimit) { 218 | $memoryLimit = ini_get('memory_limit'); 219 | $usePhpIni = true; 220 | } 221 | 222 | if ($memoryLimit == -1) { 223 | return 0; 224 | } 225 | $unit = strtolower($memoryLimit[strlen($memoryLimit) - 1]); 226 | if ($unit === 'g') { 227 | $memoryLimit = 1024 * (int)$memoryLimit; 228 | } else if ($unit === 'm') { 229 | $memoryLimit = (int)$memoryLimit; 230 | } else if ($unit === 'k') { 231 | $memoryLimit = ((int)$memoryLimit / 1024); 232 | } else { 233 | $memoryLimit = ((int)$memoryLimit / (1024 * 1024)); 234 | } 235 | if ($memoryLimit < 30) { 236 | $memoryLimit = 30; 237 | } 238 | if ($usePhpIni) { 239 | $memoryLimit = (int)(0.8 * $memoryLimit); 240 | } 241 | return $memoryLimit; 242 | } 243 | } 244 | -------------------------------------------------------------------------------- /public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 404 Not Found - webman 4 | 5 | 6 |
7 |

404 Not Found

8 |
9 |
10 |
webman
11 | 12 | 13 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gedongdong/webman-template/0fcfa8a279e9574496f9674839dbb3a34d660180/public/favicon.ico -------------------------------------------------------------------------------- /runtime/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !logs 3 | !views 4 | !.gitignore 5 | -------------------------------------------------------------------------------- /runtime/logs/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /runtime/views/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /start.php: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | supported($key, $cipher)) { 37 | $this->key = $key; 38 | $this->cipher = $cipher; 39 | } else { 40 | throw new \Exception('The only supported ciphers are AES-128-CBC and AES-256-CBC with the correct key lengths.', ErrorCode::ENCRYPTER_ERROR); 41 | } 42 | } 43 | 44 | /** 45 | * Determine if the given key and cipher combination is valid. 46 | * 47 | * @param string $key 48 | * @param string $cipher 49 | * @return bool 50 | */ 51 | public function supported($key, $cipher) 52 | { 53 | $length = mb_strlen($key, '8bit'); 54 | 55 | return ($cipher === 'AES-128-CBC' && $length === 16) || 56 | ($cipher === 'AES-256-CBC' && $length === 32); 57 | } 58 | 59 | /** 60 | * Create a new encryption key for the given cipher. 61 | * 62 | * @param string $cipher 63 | * @return string 64 | */ 65 | public function generateKey($cipher) 66 | { 67 | return random_bytes($cipher === 'AES-128-CBC' ? 16 : 32); 68 | } 69 | 70 | /** 71 | * Encrypt the given value. 72 | * 73 | * @param mixed $value 74 | * @param bool $serialize 75 | * @return string 76 | * 77 | * @throws \Exception 78 | */ 79 | public function encrypt($value, $serialize = true) 80 | { 81 | $iv = random_bytes(openssl_cipher_iv_length($this->cipher)); 82 | 83 | // First we will encrypt the value using OpenSSL. After this is encrypted we 84 | // will proceed to calculating a MAC for the encrypted value so that this 85 | // value can be verified later as not having been changed by the users. 86 | $value = \openssl_encrypt( 87 | $serialize ? serialize($value) : $value, 88 | $this->cipher, $this->key, 0, $iv 89 | ); 90 | 91 | if ($value === false) { 92 | throw new \Exception('Could not encrypt the data.', ErrorCode::ENCRYPTER_ERROR); 93 | } 94 | 95 | // Once we get the encrypted value we'll go ahead and base64_encode the input 96 | // vector and create the MAC for the encrypted value so we can then verify 97 | // its authenticity. Then, we'll JSON the data into the "payload" array. 98 | $mac = $this->hash($iv = base64_encode($iv), $value); 99 | 100 | $json = json_encode(compact('iv', 'value', 'mac')); 101 | 102 | if (json_last_error() !== JSON_ERROR_NONE) { 103 | throw new \Exception('Could not encrypt the data.', ErrorCode::ENCRYPTER_ERROR); 104 | } 105 | 106 | return base64_encode($json); 107 | } 108 | 109 | /** 110 | * Encrypt a string without serialization. 111 | * 112 | * @param string $value 113 | * @return string 114 | * 115 | * @throws \Illuminate\Contracts\Encryption\EncryptException 116 | */ 117 | public function encryptString($value) 118 | { 119 | return $this->encrypt($value, false); 120 | } 121 | 122 | /** 123 | * Decrypt the given value. 124 | * 125 | * @param string $payload 126 | * @param bool $unserialize 127 | * @return mixed 128 | * 129 | * @throws \Exception 130 | */ 131 | public function decrypt($payload, $unserialize = true) 132 | { 133 | $payload = $this->getJsonPayload($payload); 134 | 135 | $iv = base64_decode($payload['iv']); 136 | 137 | // Here we will decrypt the value. If we are able to successfully decrypt it 138 | // we will then unserialize it and return it out to the caller. If we are 139 | // unable to decrypt this value we will throw out an exception message. 140 | $decrypted = \openssl_decrypt( 141 | $payload['value'], $this->cipher, $this->key, 0, $iv 142 | ); 143 | 144 | if ($decrypted === false) { 145 | throw new \Exception('Could not decrypt the data.', ErrorCode::ENCRYPTER_ERROR); 146 | } 147 | 148 | return $unserialize ? unserialize($decrypted) : $decrypted; 149 | } 150 | 151 | /** 152 | * Decrypt the given string without unserialization. 153 | * 154 | * @param string $payload 155 | * @return string 156 | * 157 | * @throws \Exception 158 | */ 159 | public function decryptString($payload) 160 | { 161 | return $this->decrypt($payload, false); 162 | } 163 | 164 | /** 165 | * Create a MAC for the given value. 166 | * 167 | * @param string $iv 168 | * @param mixed $value 169 | * @return string 170 | */ 171 | protected function hash($iv, $value) 172 | { 173 | return hash_hmac('sha256', $iv . $value, $this->key); 174 | } 175 | 176 | /** 177 | * Get the JSON array from the given payload. 178 | * 179 | * @param string $payload 180 | * @return array 181 | * 182 | * @throws \Exception 183 | */ 184 | protected function getJsonPayload($payload) 185 | { 186 | $payload = json_decode(base64_decode($payload), true); 187 | 188 | // If the payload is not valid JSON or does not have the proper keys set we will 189 | // assume it is invalid and bail out of the routine since we will not be able 190 | // to decrypt the given value. We'll also check the MAC for this encryption. 191 | if (!$this->validPayload($payload)) { 192 | throw new \Exception('The payload is invalid.', ErrorCode::ENCRYPTER_ERROR); 193 | } 194 | 195 | if (!$this->validMac($payload)) { 196 | throw new \Exception('The MAC is invalid.', ErrorCode::ENCRYPTER_ERROR); 197 | } 198 | 199 | return $payload; 200 | } 201 | 202 | /** 203 | * Verify that the encryption payload is valid. 204 | * 205 | * @param mixed $payload 206 | * @return bool 207 | */ 208 | protected function validPayload($payload) 209 | { 210 | return is_array($payload) && isset($payload['iv'], $payload['value'], $payload['mac']) && 211 | strlen(base64_decode($payload['iv'], true)) === openssl_cipher_iv_length($this->cipher); 212 | } 213 | 214 | /** 215 | * Determine if the MAC for the given payload is valid. 216 | * 217 | * @param array $payload 218 | * @return bool 219 | */ 220 | protected function validMac(array $payload) 221 | { 222 | $calculated = $this->calculateMac($payload, $bytes = random_bytes(16)); 223 | 224 | return hash_equals( 225 | hash_hmac('sha256', $payload['mac'], $bytes, true), $calculated 226 | ); 227 | } 228 | 229 | /** 230 | * Calculate the hash of the given payload. 231 | * 232 | * @param array $payload 233 | * @param string $bytes 234 | * @return string 235 | */ 236 | protected function calculateMac($payload, $bytes) 237 | { 238 | return hash_hmac( 239 | 'sha256', $this->hash($payload['iv'], $payload['value']), $bytes, true 240 | ); 241 | } 242 | 243 | /** 244 | * Get the encryption key. 245 | * 246 | * @return string 247 | */ 248 | public function getKey() 249 | { 250 | return $this->key; 251 | } 252 | } 253 | -------------------------------------------------------------------------------- /support/Http.php: -------------------------------------------------------------------------------- 1 | createHttpClient(); 18 | } 19 | 20 | /** 21 | * get请求 22 | * @param string $url 23 | * @param array $query 24 | * @return mixed 25 | * @throws \Psr\Container\ContainerExceptionInterface 26 | * @throws \Psr\Container\NotFoundExceptionInterface 27 | * @throws \Throwable 28 | */ 29 | public function get(string $url, array $query = []) 30 | { 31 | $data = [ 32 | 'query' => $query, 33 | ]; 34 | 35 | return $this->exec('GET', $url, $data); 36 | } 37 | 38 | /** 39 | * post请求 40 | * @param string $url 41 | * @param array $params post form参数 42 | * @param array $headers 请求头 43 | * @param bool $json 参数是否是json格式 44 | * @return false|mixed 45 | * @throws \Psr\Container\ContainerExceptionInterface 46 | * @throws \Psr\Container\NotFoundExceptionInterface 47 | * @throws \Throwable 48 | */ 49 | public function post(string $url, array $params = [], array $headers = [], bool $json = false) 50 | { 51 | $data = ['headers' => $headers]; 52 | if ($json) { 53 | $data['json'] = $params; 54 | } else { 55 | $data['form_params'] = $params; 56 | } 57 | 58 | return $this->exec('POST', $url, $data); 59 | } 60 | 61 | /** 62 | * @param $method 63 | * @param $url 64 | * @param $data 65 | * @return string 66 | * @throws \Psr\Container\ContainerExceptionInterface 67 | * @throws \Psr\Container\NotFoundExceptionInterface 68 | * @throws \Throwable 69 | */ 70 | private function exec($method, $url, $data): string 71 | { 72 | $exception = null; 73 | $start = microtime(true); 74 | try { 75 | $response = $this->httpClient->request($method, $url, $data); 76 | $result = $response->getBody()->getContents(); 77 | } catch (\Throwable $e) { 78 | $exception = $e; 79 | } 80 | 81 | $end = microtime(true); 82 | $exec_time = round(($end - $start) * 1000, 2); 83 | $log = [ 84 | 'url' => $url, 85 | 'method' => $method, 86 | 'data' => $data, 87 | 'trace_id' => Context::get('traceid', ''), 88 | 'exception' => $exception ? [$exception->getMessage(), $exception->getFile(), $exception->getLine(), $exception->getTraceAsString()] : [], 89 | 'response' => $result ?? '', 90 | 'exec_time' => $exec_time, 91 | ]; 92 | \Webman\RedisQueue\Redis::send('http-log', $log); 93 | 94 | if ($exception instanceof \Throwable) { 95 | Log::error('http request error:' . $exception->getMessage(), $log); 96 | throw $exception; 97 | } 98 | return $result ?? ''; 99 | } 100 | 101 | private function createHttpClient() 102 | { 103 | if (!$this->httpClient instanceof Client) { 104 | $this->httpClient = new Client([ 105 | 'timeout' => config('http.timeout', 5), 106 | ]); 107 | } 108 | } 109 | 110 | } -------------------------------------------------------------------------------- /support/Request.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright walkor 11 | * @link http://www.workerman.net/ 12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 13 | */ 14 | 15 | namespace support; 16 | 17 | /** 18 | * Class Request 19 | * @package support 20 | */ 21 | class Request extends \Webman\Http\Request 22 | { 23 | 24 | } -------------------------------------------------------------------------------- /support/Response.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright walkor 11 | * @link http://www.workerman.net/ 12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 13 | */ 14 | 15 | namespace support; 16 | 17 | /** 18 | * Class Response 19 | * @package support 20 | */ 21 | class Response extends \Webman\Http\Response 22 | { 23 | 24 | } -------------------------------------------------------------------------------- /support/bootstrap.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright walkor 11 | * @link http://www.workerman.net/ 12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 13 | */ 14 | 15 | use Dotenv\Dotenv; 16 | use support\Log; 17 | use Webman\Bootstrap; 18 | use Webman\Config; 19 | use Webman\Middleware; 20 | use Webman\Route; 21 | use Webman\Util; 22 | 23 | $worker = $worker ?? null; 24 | 25 | set_error_handler(function ($level, $message, $file = '', $line = 0) { 26 | if (error_reporting() & $level) { 27 | throw new ErrorException($message, 0, $level, $file, $line); 28 | } 29 | }); 30 | 31 | if ($worker) { 32 | register_shutdown_function(function ($startTime) { 33 | if (time() - $startTime <= 0.1) { 34 | sleep(1); 35 | } 36 | }, time()); 37 | } 38 | 39 | if (class_exists('Dotenv\Dotenv') && file_exists(base_path(false) . '/.env')) { 40 | if (method_exists('Dotenv\Dotenv', 'createUnsafeMutable')) { 41 | Dotenv::createUnsafeMutable(base_path(false))->load(); 42 | } else { 43 | Dotenv::createMutable(base_path(false))->load(); 44 | } 45 | } 46 | 47 | Config::clear(); 48 | support\App::loadAllConfig(['route']); 49 | if ($timezone = config('app.default_timezone')) { 50 | date_default_timezone_set($timezone); 51 | } 52 | 53 | foreach (config('autoload.files', []) as $file) { 54 | include_once $file; 55 | } 56 | foreach (config('plugin', []) as $firm => $projects) { 57 | foreach ($projects as $name => $project) { 58 | if (!is_array($project)) { 59 | continue; 60 | } 61 | foreach ($project['autoload']['files'] ?? [] as $file) { 62 | include_once $file; 63 | } 64 | } 65 | foreach ($projects['autoload']['files'] ?? [] as $file) { 66 | include_once $file; 67 | } 68 | } 69 | 70 | Middleware::load(config('middleware', [])); 71 | foreach (config('plugin', []) as $firm => $projects) { 72 | foreach ($projects as $name => $project) { 73 | if (!is_array($project) || $name === 'static') { 74 | continue; 75 | } 76 | Middleware::load($project['middleware'] ?? []); 77 | } 78 | Middleware::load($projects['middleware'] ?? [], $firm); 79 | if ($staticMiddlewares = config("plugin.$firm.static.middleware")) { 80 | Middleware::load(['__static__' => $staticMiddlewares], $firm); 81 | } 82 | } 83 | Middleware::load(['__static__' => config('static.middleware', [])]); 84 | 85 | foreach (config('bootstrap', []) as $className) { 86 | if (!class_exists($className)) { 87 | $log = "Warning: Class $className setting in config/bootstrap.php not found\r\n"; 88 | echo $log; 89 | Log::error($log); 90 | continue; 91 | } 92 | /** @var Bootstrap $className */ 93 | $className::start($worker); 94 | } 95 | 96 | foreach (config('plugin', []) as $firm => $projects) { 97 | foreach ($projects as $name => $project) { 98 | if (!is_array($project)) { 99 | continue; 100 | } 101 | foreach ($project['bootstrap'] ?? [] as $className) { 102 | if (!class_exists($className)) { 103 | $log = "Warning: Class $className setting in config/plugin/$firm/$name/bootstrap.php not found\r\n"; 104 | echo $log; 105 | Log::error($log); 106 | continue; 107 | } 108 | /** @var Bootstrap $className */ 109 | $className::start($worker); 110 | } 111 | } 112 | foreach ($projects['bootstrap'] ?? [] as $className) { 113 | /** @var string $className */ 114 | if (!class_exists($className)) { 115 | $log = "Warning: Class $className setting in plugin/$firm/config/bootstrap.php not found\r\n"; 116 | echo $log; 117 | Log::error($log); 118 | continue; 119 | } 120 | /** @var Bootstrap $className */ 121 | $className::start($worker); 122 | } 123 | } 124 | 125 | $directory = base_path() . '/plugin'; 126 | $paths = [config_path()]; 127 | foreach (Util::scanDir($directory) as $path) { 128 | if (is_dir($path = "$path/config")) { 129 | $paths[] = $path; 130 | } 131 | } 132 | Route::load($paths); 133 | 134 | -------------------------------------------------------------------------------- /support/helpers.php: -------------------------------------------------------------------------------- 1 | 11 | * @copyright walkor 12 | * @link http://www.workerman.net/ 13 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 14 | */ 15 | 16 | use support\Container; 17 | use support\Request; 18 | use support\Response; 19 | use support\Translation; 20 | use support\view\Blade; 21 | use support\view\Raw; 22 | use support\view\ThinkPHP; 23 | use support\view\Twig; 24 | use Twig\Error\LoaderError; 25 | use Twig\Error\RuntimeError; 26 | use Twig\Error\SyntaxError; 27 | use Webman\App; 28 | use Webman\Config; 29 | use Webman\Route; 30 | use Workerman\Worker; 31 | 32 | // Project base path 33 | define('BASE_PATH', dirname(__DIR__)); 34 | 35 | /** 36 | * return the program execute directory 37 | * @param string $path 38 | * @return string 39 | */ 40 | function run_path(string $path = ''): string 41 | { 42 | static $runPath = ''; 43 | if (!$runPath) { 44 | $runPath = is_phar() ? dirname(Phar::running(false)) : BASE_PATH; 45 | } 46 | return path_combine($runPath, $path); 47 | } 48 | 49 | /** 50 | * if the param $path equal false,will return this program current execute directory 51 | * @param string|false $path 52 | * @return string 53 | */ 54 | function base_path($path = ''): string 55 | { 56 | if (false === $path) { 57 | return run_path(); 58 | } 59 | return path_combine(BASE_PATH, $path); 60 | } 61 | 62 | /** 63 | * App path 64 | * @param string $path 65 | * @return string 66 | */ 67 | function app_path(string $path = ''): string 68 | { 69 | return path_combine(BASE_PATH . DIRECTORY_SEPARATOR . 'app', $path); 70 | } 71 | 72 | /** 73 | * Public path 74 | * @param string $path 75 | * @return string 76 | */ 77 | function public_path(string $path = ''): string 78 | { 79 | static $publicPath = ''; 80 | if (!$publicPath) { 81 | $publicPath = \config('app.public_path') ?: run_path('public'); 82 | } 83 | return path_combine($publicPath, $path); 84 | } 85 | 86 | /** 87 | * Config path 88 | * @param string $path 89 | * @return string 90 | */ 91 | function config_path(string $path = ''): string 92 | { 93 | return path_combine(BASE_PATH . DIRECTORY_SEPARATOR . 'config', $path); 94 | } 95 | 96 | /** 97 | * Runtime path 98 | * @param string $path 99 | * @return string 100 | */ 101 | function runtime_path(string $path = ''): string 102 | { 103 | static $runtimePath = ''; 104 | if (!$runtimePath) { 105 | $runtimePath = \config('app.runtime_path') ?: run_path('runtime'); 106 | } 107 | return path_combine($runtimePath, $path); 108 | } 109 | 110 | /** 111 | * Generate paths based on given information 112 | * @param string $front 113 | * @param string $back 114 | * @return string 115 | */ 116 | function path_combine(string $front, string $back): string 117 | { 118 | return $front . ($back ? (DIRECTORY_SEPARATOR . ltrim($back, DIRECTORY_SEPARATOR)) : $back); 119 | } 120 | 121 | /** 122 | * Response 123 | * @param int $status 124 | * @param array $headers 125 | * @param string $body 126 | * @return Response 127 | */ 128 | function response(string $body = '', int $status = 200, array $headers = []): Response 129 | { 130 | return new Response($status, $headers, $body); 131 | } 132 | 133 | /** 134 | * Json response 135 | * @param $data 136 | * @param int $options 137 | * @return Response 138 | */ 139 | function json($data, int $options = JSON_UNESCAPED_UNICODE): Response 140 | { 141 | return new Response(200, ['Content-Type' => 'application/json'], json_encode($data, $options)); 142 | } 143 | 144 | /** 145 | * Xml response 146 | * @param $xml 147 | * @return Response 148 | */ 149 | function xml($xml): Response 150 | { 151 | if ($xml instanceof SimpleXMLElement) { 152 | $xml = $xml->asXML(); 153 | } 154 | return new Response(200, ['Content-Type' => 'text/xml'], $xml); 155 | } 156 | 157 | /** 158 | * Jsonp response 159 | * @param $data 160 | * @param string $callbackName 161 | * @return Response 162 | */ 163 | function jsonp($data, string $callbackName = 'callback'): Response 164 | { 165 | if (!is_scalar($data) && null !== $data) { 166 | $data = json_encode($data); 167 | } 168 | return new Response(200, [], "$callbackName($data)"); 169 | } 170 | 171 | /** 172 | * Redirect response 173 | * @param string $location 174 | * @param int $status 175 | * @param array $headers 176 | * @return Response 177 | */ 178 | function redirect(string $location, int $status = 302, array $headers = []): Response 179 | { 180 | $response = new Response($status, ['Location' => $location]); 181 | if (!empty($headers)) { 182 | $response->withHeaders($headers); 183 | } 184 | return $response; 185 | } 186 | 187 | /** 188 | * View response 189 | * @param string $template 190 | * @param array $vars 191 | * @param string|null $app 192 | * @param string|null $plugin 193 | * @return Response 194 | */ 195 | function view(string $template, array $vars = [], string $app = null, string $plugin = null): Response 196 | { 197 | $request = \request(); 198 | $plugin = $plugin === null ? ($request->plugin ?? '') : $plugin; 199 | $handler = \config($plugin ? "plugin.$plugin.view.handler" : 'view.handler'); 200 | return new Response(200, [], $handler::render($template, $vars, $app, $plugin)); 201 | } 202 | 203 | /** 204 | * Raw view response 205 | * @param string $template 206 | * @param array $vars 207 | * @param string|null $app 208 | * @return Response 209 | * @throws Throwable 210 | */ 211 | function raw_view(string $template, array $vars = [], string $app = null): Response 212 | { 213 | return new Response(200, [], Raw::render($template, $vars, $app)); 214 | } 215 | 216 | /** 217 | * Blade view response 218 | * @param string $template 219 | * @param array $vars 220 | * @param string|null $app 221 | * @return Response 222 | */ 223 | function blade_view(string $template, array $vars = [], string $app = null): Response 224 | { 225 | return new Response(200, [], Blade::render($template, $vars, $app)); 226 | } 227 | 228 | /** 229 | * Think view response 230 | * @param string $template 231 | * @param array $vars 232 | * @param string|null $app 233 | * @return Response 234 | */ 235 | function think_view(string $template, array $vars = [], string $app = null): Response 236 | { 237 | return new Response(200, [], ThinkPHP::render($template, $vars, $app)); 238 | } 239 | 240 | /** 241 | * Twig view response 242 | * @param string $template 243 | * @param array $vars 244 | * @param string|null $app 245 | * @return Response 246 | * @throws LoaderError 247 | * @throws RuntimeError 248 | * @throws SyntaxError 249 | */ 250 | function twig_view(string $template, array $vars = [], string $app = null): Response 251 | { 252 | return new Response(200, [], Twig::render($template, $vars, $app)); 253 | } 254 | 255 | /** 256 | * Get request 257 | * @return \Webman\Http\Request|Request|null 258 | */ 259 | function request() 260 | { 261 | return App::request(); 262 | } 263 | 264 | /** 265 | * Get config 266 | * @param string|null $key 267 | * @param $default 268 | * @return array|mixed|null 269 | */ 270 | function config(string $key = null, $default = null) 271 | { 272 | return Config::get($key, $default); 273 | } 274 | 275 | /** 276 | * Create url 277 | * @param string $name 278 | * @param ...$parameters 279 | * @return string 280 | */ 281 | function route(string $name, ...$parameters): string 282 | { 283 | $route = Route::getByName($name); 284 | if (!$route) { 285 | return ''; 286 | } 287 | 288 | if (!$parameters) { 289 | return $route->url(); 290 | } 291 | 292 | if (is_array(current($parameters))) { 293 | $parameters = current($parameters); 294 | } 295 | 296 | return $route->url($parameters); 297 | } 298 | 299 | /** 300 | * Session 301 | * @param mixed $key 302 | * @param mixed $default 303 | * @return mixed 304 | */ 305 | function session($key = null, $default = null) 306 | { 307 | $session = \request()->session(); 308 | if (null === $key) { 309 | return $session; 310 | } 311 | if (is_array($key)) { 312 | $session->put($key); 313 | return null; 314 | } 315 | if (strpos($key, '.')) { 316 | $keyArray = explode('.', $key); 317 | $value = $session->all(); 318 | foreach ($keyArray as $index) { 319 | if (!isset($value[$index])) { 320 | return $default; 321 | } 322 | $value = $value[$index]; 323 | } 324 | return $value; 325 | } 326 | return $session->get($key, $default); 327 | } 328 | 329 | /** 330 | * Translation 331 | * @param string $id 332 | * @param array $parameters 333 | * @param string|null $domain 334 | * @param string|null $locale 335 | * @return string 336 | */ 337 | function trans(string $id, array $parameters = [], string $domain = null, string $locale = null): string 338 | { 339 | $res = Translation::trans($id, $parameters, $domain, $locale); 340 | return $res === '' ? $id : $res; 341 | } 342 | 343 | /** 344 | * Locale 345 | * @param string|null $locale 346 | * @return string 347 | */ 348 | function locale(string $locale = null): string 349 | { 350 | if (!$locale) { 351 | return Translation::getLocale(); 352 | } 353 | Translation::setLocale($locale); 354 | return $locale; 355 | } 356 | 357 | /** 358 | * 404 not found 359 | * @return Response 360 | */ 361 | function not_found(): Response 362 | { 363 | return new Response(404, [], file_get_contents(public_path() . '/404.html')); 364 | } 365 | 366 | /** 367 | * Copy dir 368 | * @param string $source 369 | * @param string $dest 370 | * @param bool $overwrite 371 | * @return void 372 | */ 373 | function copy_dir(string $source, string $dest, bool $overwrite = false) 374 | { 375 | if (is_dir($source)) { 376 | if (!is_dir($dest)) { 377 | if (!mkdir($dest) && !is_dir($dest)) { 378 | throw new \RuntimeException(sprintf('Directory "%s" was not created', $dest)); 379 | } 380 | } 381 | $files = scandir($source); 382 | foreach ($files as $file) { 383 | if ($file !== "." && $file !== "..") { 384 | copy_dir("$source/$file", "$dest/$file"); 385 | } 386 | } 387 | } else if (file_exists($source) && ($overwrite || !file_exists($dest))) { 388 | copy($source, $dest); 389 | } 390 | } 391 | 392 | /** 393 | * Remove dir 394 | * @param string $dir 395 | * @return bool 396 | */ 397 | function remove_dir(string $dir): bool 398 | { 399 | if (is_link($dir) || is_file($dir)) { 400 | return unlink($dir); 401 | } 402 | $files = array_diff(scandir($dir), array('.', '..')); 403 | foreach ($files as $file) { 404 | (is_dir("$dir/$file") && !is_link($dir)) ? remove_dir("$dir/$file") : unlink("$dir/$file"); 405 | } 406 | return rmdir($dir); 407 | } 408 | 409 | /** 410 | * Bind worker 411 | * @param $worker 412 | * @param $class 413 | */ 414 | function worker_bind($worker, $class) 415 | { 416 | $callbackMap = [ 417 | 'onConnect', 418 | 'onMessage', 419 | 'onClose', 420 | 'onError', 421 | 'onBufferFull', 422 | 'onBufferDrain', 423 | 'onWorkerStop', 424 | 'onWebSocketConnect', 425 | 'onWorkerReload' 426 | ]; 427 | foreach ($callbackMap as $name) { 428 | if (method_exists($class, $name)) { 429 | $worker->$name = [$class, $name]; 430 | } 431 | } 432 | if (method_exists($class, 'onWorkerStart')) { 433 | call_user_func([$class, 'onWorkerStart'], $worker); 434 | } 435 | } 436 | 437 | /** 438 | * Start worker 439 | * @param $processName 440 | * @param $config 441 | * @return void 442 | */ 443 | function worker_start($processName, $config) 444 | { 445 | $worker = new Worker($config['listen'] ?? null, $config['context'] ?? []); 446 | $propertyMap = [ 447 | 'count', 448 | 'user', 449 | 'group', 450 | 'reloadable', 451 | 'reusePort', 452 | 'transport', 453 | 'protocol', 454 | ]; 455 | $worker->name = $processName; 456 | foreach ($propertyMap as $property) { 457 | if (isset($config[$property])) { 458 | $worker->$property = $config[$property]; 459 | } 460 | } 461 | 462 | $worker->onWorkerStart = function ($worker) use ($config) { 463 | require_once base_path('/support/bootstrap.php'); 464 | if (isset($config['handler'])) { 465 | if (!class_exists($config['handler'])) { 466 | echo "process error: class {$config['handler']} not exists\r\n"; 467 | return; 468 | } 469 | 470 | $instance = Container::make($config['handler'], $config['constructor'] ?? []); 471 | worker_bind($worker, $instance); 472 | } 473 | }; 474 | } 475 | 476 | /** 477 | * Get realpath 478 | * @param string $filePath 479 | * @return string 480 | */ 481 | function get_realpath(string $filePath): string 482 | { 483 | if (strpos($filePath, 'phar://') === 0) { 484 | return $filePath; 485 | } 486 | 487 | return realpath($filePath); 488 | } 489 | 490 | /** 491 | * Is phar 492 | * @return bool 493 | */ 494 | function is_phar(): bool 495 | { 496 | return class_exists(Phar::class, false) && Phar::running(); 497 | } 498 | 499 | /** 500 | * Get cpu count 501 | * @return int 502 | */ 503 | function cpu_count(): int 504 | { 505 | // Windows does not support the number of processes setting. 506 | if (DIRECTORY_SEPARATOR === '\\') { 507 | return 1; 508 | } 509 | $count = 4; 510 | if (is_callable('shell_exec')) { 511 | if (strtolower(PHP_OS) === 'darwin') { 512 | $count = (int)shell_exec('sysctl -n machdep.cpu.core_count'); 513 | } else { 514 | $count = (int)shell_exec('nproc'); 515 | } 516 | } 517 | return $count > 0 ? $count : 4; 518 | } 519 | 520 | if (! function_exists('env')) { 521 | /** 522 | * Gets the value of an environment variable. 523 | * 524 | * @param string $key 525 | * @param null|mixed $default 526 | */ 527 | function env(string $key, $default = null) 528 | { 529 | $value = getenv($key); 530 | if ($value === false) { 531 | return value($default); 532 | } 533 | switch (strtolower($value)) { 534 | case 'true': 535 | case '(true)': 536 | return true; 537 | case 'false': 538 | case '(false)': 539 | return false; 540 | case 'empty': 541 | case '(empty)': 542 | return ''; 543 | case 'null': 544 | case '(null)': 545 | return null; 546 | } 547 | if (($valueLength = strlen($value)) > 1 && $value[0] === '"' && $value[$valueLength - 1] === '"') { 548 | return substr($value, 1, -1); 549 | } 550 | return $value; 551 | } 552 | } 553 | 554 | if (! function_exists('value')) { 555 | /** 556 | * Return the default value of the given value. 557 | * 558 | * @param mixed $value 559 | */ 560 | function value($value) 561 | { 562 | return $value instanceof \Closure ? $value() : $value; 563 | } 564 | } 565 | -------------------------------------------------------------------------------- /windows.bat: -------------------------------------------------------------------------------- 1 | CHCP 65001 2 | php windows.php 3 | pause -------------------------------------------------------------------------------- /windows.php: -------------------------------------------------------------------------------- 1 | load(); 18 | } else { 19 | Dotenv::createMutable(base_path())->load(); 20 | } 21 | } 22 | 23 | App::loadAllConfig(['route']); 24 | 25 | $errorReporting = config('app.error_reporting'); 26 | if (isset($errorReporting)) { 27 | error_reporting($errorReporting); 28 | } 29 | 30 | $runtimeProcessPath = runtime_path() . DIRECTORY_SEPARATOR . '/windows'; 31 | if (!is_dir($runtimeProcessPath)) { 32 | mkdir($runtimeProcessPath); 33 | } 34 | $processFiles = [ 35 | __DIR__ . DIRECTORY_SEPARATOR . 'start.php' 36 | ]; 37 | foreach (config('process', []) as $processName => $config) { 38 | $processFiles[] = write_process_file($runtimeProcessPath, $processName, ''); 39 | } 40 | 41 | foreach (config('plugin', []) as $firm => $projects) { 42 | foreach ($projects as $name => $project) { 43 | if (!is_array($project)) { 44 | continue; 45 | } 46 | foreach ($project['process'] ?? [] as $processName => $config) { 47 | $processFiles[] = write_process_file($runtimeProcessPath, $processName, "$firm.$name"); 48 | } 49 | } 50 | foreach ($projects['process'] ?? [] as $processName => $config) { 51 | $processFiles[] = write_process_file($runtimeProcessPath, $processName, $firm); 52 | } 53 | } 54 | 55 | function write_process_file($runtimeProcessPath, $processName, $firm): string 56 | { 57 | $processParam = $firm ? "plugin.$firm.$processName" : $processName; 58 | $configParam = $firm ? "config('plugin.$firm.process')['$processName']" : "config('process')['$processName']"; 59 | $fileContent = << true]); 99 | if (!$resource) { 100 | exit("Can not execute $cmd\r\n"); 101 | } 102 | return $resource; 103 | } 104 | 105 | $resource = popen_processes($processFiles); 106 | echo "\r\n"; 107 | while (1) { 108 | sleep(1); 109 | if (!empty($monitor) && $monitor->checkAllFilesChange()) { 110 | $status = proc_get_status($resource); 111 | $pid = $status['pid']; 112 | shell_exec("taskkill /F /T /PID $pid"); 113 | proc_close($resource); 114 | $resource = popen_processes($processFiles); 115 | } 116 | } 117 | --------------------------------------------------------------------------------