├── .commitlintrc.js ├── .cz-config.js ├── .env.example ├── .gitignore ├── .php_cs ├── .phpstorm.meta.php ├── .versionrc.json ├── Dockerfile ├── README.md ├── app ├── Controller │ └── Controller.php ├── Exception │ └── Handler │ │ └── AppExceptionHandler.php ├── Listener │ └── DbQueryExecutedListener.php ├── Model │ └── Model.php └── Task │ └── SatisBuildTask.php ├── bin └── hyperf.php ├── composer.json ├── config ├── autoload │ ├── annotations.php │ ├── aspects.php │ ├── cache.php │ ├── commands.php │ ├── crontab.php │ ├── databases.php │ ├── dependencies.php │ ├── devtool.php │ ├── exceptions.php │ ├── listeners.php │ ├── logger.php │ ├── middlewares.php │ ├── processes.php │ ├── redis.php │ └── server.php ├── config.php ├── container.php └── routes.php ├── deploy.test.yml ├── package.json ├── phpstan.neon ├── phpunit.xml ├── satis.json └── test ├── Cases └── ExampleTest.php ├── HttpTestCase.php └── bootstrap.php /.commitlintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: [ 3 | '@commitlint/config-conventional' 4 | ], 5 | rules: { 6 | 7 | } 8 | }; -------------------------------------------------------------------------------- /.cz-config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | types: [ 5 | { 6 | value: 'feat', 7 | name : 'feat: 新特性' 8 | }, 9 | { 10 | value: 'fix', 11 | name : 'fix: 修复问题' 12 | }, 13 | { 14 | value: 'refactor', 15 | name : 'refactor: 代码重构' 16 | }, 17 | { 18 | value: 'docs', 19 | name : 'docs: 文档修改' 20 | }, 21 | { 22 | value: 'test', 23 | name : 'test: 添加或修改测试用例' 24 | }, 25 | { 26 | value: 'chore', 27 | name : 'chore: 其他修改, 比如:构建流程、依赖管理' 28 | }, 29 | { 30 | value: 'style', 31 | name : 'style: 代码格式修改,不影响代码执行' 32 | }, 33 | { 34 | value: 'revert', 35 | name : 'revert: 代码回退' 36 | } 37 | ], 38 | scopes: [], 39 | allowCustomScopes: false, 40 | allowBreakingChanges: ["feat", "fix"], 41 | messages: { 42 | type: "选择一个你正在提交的修改类型:", 43 | scope: '\n修改的范围 (可选):', 44 | // used if allowCustomScopes is true 45 | customScope: '修改的范围:', 46 | subject: '写一个简要的修改描述信息:\n', 47 | body: '写一个详细的修改描述信息 (可选). 使用 "|" 符号分割一个新行:\n', 48 | breaking: '列出不兼容的修改 (可选):\n', 49 | footer: '列出修改关闭的bug跟踪ID (可选). E.g.: #31, #34:\n', 50 | confirmCommit: '您确定要继续执行上面的提交吗?', 51 | }, 52 | }; 53 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | APP_NAME=skeleton -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .buildpath 2 | .settings/ 3 | .project 4 | *.patch 5 | .idea/ 6 | .git/ 7 | runtime/ 8 | vendor/ 9 | .phpintel/ 10 | .env 11 | .DS_Store 12 | .phpunit* 13 | node_modules/ 14 | public/ -------------------------------------------------------------------------------- /.php_cs: -------------------------------------------------------------------------------- 1 | setRiskyAllowed(true) 14 | ->setRules([ 15 | '@PSR2' => true, 16 | '@Symfony' => true, 17 | '@DoctrineAnnotation' => true, 18 | '@PhpCsFixer' => true, 19 | 'header_comment' => [ 20 | 'commentType' => 'PHPDoc', 21 | 'header' => $header, 22 | 'separate' => 'none', 23 | 'location' => 'after_declare_strict', 24 | ], 25 | 'array_syntax' => [ 26 | 'syntax' => 'short' 27 | ], 28 | 'list_syntax' => [ 29 | 'syntax' => 'short' 30 | ], 31 | 'concat_space' => [ 32 | 'spacing' => 'one' 33 | ], 34 | 'blank_line_before_statement' => [ 35 | 'statements' => [ 36 | 'declare', 37 | ], 38 | ], 39 | 'general_phpdoc_annotation_remove' => [ 40 | 'annotations' => [ 41 | 'author' 42 | ], 43 | ], 44 | 'ordered_imports' => [ 45 | 'imports_order' => [ 46 | 'class', 'function', 'const', 47 | ], 48 | 'sort_algorithm' => 'alpha', 49 | ], 50 | 'single_line_comment_style' => [ 51 | 'comment_types' => [ 52 | ], 53 | ], 54 | 'yoda_style' => [ 55 | 'always_move_variable' => false, 56 | 'equal' => false, 57 | 'identical' => false, 58 | ], 59 | 'phpdoc_align' => [ 60 | 'align' => 'left', 61 | ], 62 | 'multiline_whitespace_before_semicolons' => [ 63 | 'strategy' => 'no_multi_line', 64 | ], 65 | 'class_attributes_separation' => true, 66 | 'combine_consecutive_unsets' => true, 67 | 'declare_strict_types' => true, 68 | 'linebreak_after_opening_tag' => true, 69 | 'lowercase_constants' => true, 70 | 'lowercase_static_reference' => true, 71 | 'no_useless_else' => true, 72 | 'no_unused_imports' => true, 73 | 'not_operator_with_successor_space' => true, 74 | 'not_operator_with_space' => false, 75 | 'ordered_class_elements' => true, 76 | 'php_unit_strict' => false, 77 | 'phpdoc_separation' => false, 78 | 'single_quote' => true, 79 | 'standardize_not_equals' => true, 80 | 'multiline_comment_opening_closing' => true, 81 | ]) 82 | ->setFinder( 83 | PhpCsFixer\Finder::create() 84 | ->exclude('public') 85 | ->exclude('runtime') 86 | ->exclude('vendor') 87 | ->in(__DIR__) 88 | ) 89 | ->setUsingCache(false); 90 | -------------------------------------------------------------------------------- /.phpstorm.meta.php: -------------------------------------------------------------------------------- 1 | " version="1.0" license="MIT" 10 | 11 | ## 12 | # ---------- env settings ---------- 13 | ## 14 | # --build-arg timezone=Asia/Shanghai 15 | ARG timezone 16 | 17 | ENV TIMEZONE=${timezone:-"Asia/Shanghai"} \ 18 | COMPOSER_VERSION=1.9.1 \ 19 | APP_ENV=prod 20 | 21 | # update 22 | RUN set -ex \ 23 | && apk update \ 24 | # install composer 25 | && cd /tmp \ 26 | && wget https://github.com/composer/composer/releases/download/${COMPOSER_VERSION}/composer.phar \ 27 | && chmod u+x composer.phar \ 28 | && mv composer.phar /usr/local/bin/composer \ 29 | # show php version and extensions 30 | && php -v \ 31 | && php -m \ 32 | # ---------- some config ---------- 33 | && cd /etc/php7 \ 34 | # - config PHP 35 | && { \ 36 | echo "upload_max_filesize=100M"; \ 37 | echo "post_max_size=108M"; \ 38 | echo "memory_limit=1024M"; \ 39 | echo "date.timezone=${TIMEZONE}"; \ 40 | } | tee conf.d/99-overrides.ini \ 41 | # - config timezone 42 | && ln -sf /usr/share/zoneinfo/${TIMEZONE} /etc/localtime \ 43 | && echo "${TIMEZONE}" > /etc/timezone \ 44 | # ---------- clear works ---------- 45 | && rm -rf /var/cache/apk/* /tmp/* /usr/share/man \ 46 | && echo -e "\033[42;37m Build Completed :).\033[0m\n" 47 | 48 | WORKDIR /opt/www 49 | 50 | # Composer Cache 51 | # COPY ./composer.* /opt/www/ 52 | # RUN composer install --no-dev --no-scripts 53 | 54 | COPY . /opt/www 55 | RUN composer config -g http-basic.your-gitlab-domain your-gitlab-account your-gitlab-account-password \ 56 | && composer install --no-dev -o \ 57 | && composer satis-build 58 | 59 | EXPOSE 9501 60 | 61 | ENTRYPOINT ["php", "/opt/www/bin/hyperf.php", "start"] -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 介绍 2 | 3 | packagist基于Hyperf构建的私有composer仓库服务 4 | 5 | ## 配置项目 6 | 7 | ``` 8 | # 修改 satis.json 9 | { 10 | "name": "your-packagist-name", 11 | "homepage": "your-packagist-domain", 12 | "repositories": [ 13 | { 14 | "type": "git", // git方式 15 | "url": "https://gitlab.xxxxxxx.com/your-gitlab-group/your-component.git" // 项目的git地址 16 | }, 17 | { 18 | "type": "git", 19 | "url": "https://gitlab.xxxxxxx.com/your-gitlab-group/your-other-component.git" 20 | } 21 | ], 22 | "require": { 23 | "your-gitlab-group/your-component": "*", // 组件以及组件的约束 24 | "your-gitlab-group/your-other-component": "*" 25 | } 26 | } 27 | ``` 28 | 29 | ## 更新命令 30 | 31 | ```bash 32 | composer satis-build 33 | ``` 34 | 35 | ## 配置 36 | 37 | ``` 38 | # 配置全局 your-composerrepository 39 | 40 | # 阿里云镜像 41 | composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/ 42 | 43 | # 伊智私有仓库 44 | composer config -g repo.your-composer-repository composer https://your-composer-repository-domain/ 45 | 46 | # 查看是否配置成功 47 | 48 | composer config -g --list 49 | 50 | 看到下面两行表示配置成功 51 | 52 | [repositories.your-packagist.org.type] composer 53 | [repositories.your-packagist.org.url] https://your-composer-repository-domain/ 54 | [repositories.packagist.org.type] composer 55 | [repositories.packagist.org.url] https://mirrors.aliyun.com/composer/ 56 | 57 | 58 | # 项目配置 59 | 60 | "repositories": { 61 | "packagist": { 62 | "type": "composer", 63 | "url": "https://mirrors.aliyun.com/composer" 64 | }, 65 | "your-packagist": { 66 | "type": "composer", 67 | "url": "https://your-composer-repository-domain" 68 | } 69 | } 70 | 71 | ``` 72 | 73 | ## 使用 74 | 75 | ``` 76 | # 一般仓库使用 77 | 78 | composer require your-repository/your-component 79 | 80 | ``` -------------------------------------------------------------------------------- /app/Controller/Controller.php: -------------------------------------------------------------------------------- 1 | logger = $logger; 31 | } 32 | 33 | public function handle(Throwable $throwable, ResponseInterface $response) 34 | { 35 | $this->logger->error(sprintf('%s[%s] in %s', $throwable->getMessage(), $throwable->getLine(), $throwable->getFile())); 36 | $this->logger->error($throwable->getTraceAsString()); 37 | return $response->withStatus(500)->withBody(new SwooleStream('Internal Server Error.')); 38 | } 39 | 40 | public function isValid(Throwable $throwable): bool 41 | { 42 | return true; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/Listener/DbQueryExecutedListener.php: -------------------------------------------------------------------------------- 1 | logger = $container->get(LoggerFactory::class)->get('sql'); 37 | } 38 | 39 | public function listen(): array 40 | { 41 | return [ 42 | QueryExecuted::class, 43 | ]; 44 | } 45 | 46 | /** 47 | * @param QueryExecuted $event 48 | */ 49 | public function process(object $event) 50 | { 51 | if ($event instanceof QueryExecuted) { 52 | $sql = $event->sql; 53 | if (! Arr::isAssoc($event->bindings)) { 54 | foreach ($event->bindings as $key => $value) { 55 | $sql = Str::replaceFirst('?', "'{$value}'", $sql); 56 | } 57 | } 58 | 59 | $this->logger->info(sprintf('[%s] %s', $event->time, $sql)); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /app/Model/Model.php: -------------------------------------------------------------------------------- 1 | get(\Hyperf\Contract\ApplicationInterface::class); 21 | $application->run(); 22 | })(); -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hyperf/hyperf-skeleton", 3 | "type": "project", 4 | "keywords": [ 5 | "php", 6 | "swoole", 7 | "framework", 8 | "hyperf", 9 | "microservice", 10 | "middleware" 11 | ], 12 | "description": "A coroutine framework that focuses on hyperspeed and flexible, specifically use for build microservices and middlewares.", 13 | "license": "Apache-2.0", 14 | "require": { 15 | "php": ">=7.2", 16 | "ext-swoole": ">=4.4", 17 | "hyperf/cache": "~1.1.0", 18 | "hyperf/command": "~1.1.0", 19 | "hyperf/config": "~1.1.0", 20 | "hyperf/contract": "~1.1.0", 21 | "hyperf/database": "~1.1.0", 22 | "hyperf/db-connection": "~1.1.0", 23 | "hyperf/devtool": "~1.1.0", 24 | "hyperf/di": "~1.1.0", 25 | "hyperf/dispatcher": "~1.1.0", 26 | "hyperf/event": "~1.1.0", 27 | "hyperf/exception-handler": "~1.1.0", 28 | "hyperf/framework": "~1.1.0", 29 | "hyperf/guzzle": "~1.1.0", 30 | "hyperf/http-server": "~1.1.0", 31 | "hyperf/logger": "~1.1.0", 32 | "hyperf/memory": "~1.1.0", 33 | "hyperf/paginator": "~1.1.0", 34 | "hyperf/pool": "~1.1.0", 35 | "hyperf/process": "~1.1.0", 36 | "hyperf/redis": "~1.1.0", 37 | "hyperf/utils": "~1.1.0", 38 | "composer/satis": "^1.0.0", 39 | "hyperf/crontab": "^1.0" 40 | }, 41 | "require-dev": { 42 | "swoft/swoole-ide-helper": "^4.2", 43 | "phpmd/phpmd": "^2.6", 44 | "friendsofphp/php-cs-fixer": "^2.14", 45 | "mockery/mockery": "^1.0", 46 | "doctrine/common": "^2.9", 47 | "phpstan/phpstan": "^0.11.2", 48 | "hyperf/testing": "~1.1.0" 49 | }, 50 | "suggest": { 51 | "ext-openssl": "Required to use HTTPS.", 52 | "ext-json": "Required to use JSON.", 53 | "ext-pdo": "Required to use MySQL Client.", 54 | "ext-pdo_mysql": "Required to use MySQL Client.", 55 | "ext-redis": "Required to use Redis Client." 56 | }, 57 | "autoload": { 58 | "psr-4": { 59 | "App\\": "app/" 60 | }, 61 | "files": [] 62 | }, 63 | "autoload-dev": { 64 | "psr-4": { 65 | "HyperfTest\\": "./test/" 66 | } 67 | }, 68 | "minimum-stability": "dev", 69 | "prefer-stable": true, 70 | "extra": [], 71 | "scripts": { 72 | "post-root-package-install": [ 73 | "@php -r \"file_exists('.env') || copy('.env.example', '.env');\"" 74 | ], 75 | "test": "co-phpunit -c phpunit.xml --colors=always", 76 | "cs-fix": "php-cs-fixer fix $1", 77 | "analyze": "phpstan analyse --memory-limit 300M -l 0 -c phpstan.neon ./app ./config", 78 | "start": "php ./bin/hyperf.php start", 79 | "satis-build": "satis build ./satis.json ./public" 80 | }, 81 | "repositories": { 82 | "packagist": { 83 | "type": "composer", 84 | "url": "https://mirrors.aliyun.com/composer" 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /config/autoload/annotations.php: -------------------------------------------------------------------------------- 1 | [ 15 | 'paths' => [ 16 | BASE_PATH . '/app', 17 | ], 18 | 'ignore_annotations' => [ 19 | 'mixin', 20 | ], 21 | ], 22 | ]; 23 | -------------------------------------------------------------------------------- /config/autoload/aspects.php: -------------------------------------------------------------------------------- 1 | [ 15 | 'driver' => Hyperf\Cache\Driver\RedisDriver::class, 16 | 'packer' => Hyperf\Utils\Packer\PhpSerializerPacker::class, 17 | 'prefix' => 'c:', 18 | ], 19 | ]; 20 | -------------------------------------------------------------------------------- /config/autoload/commands.php: -------------------------------------------------------------------------------- 1 | true, 16 | ]; 17 | -------------------------------------------------------------------------------- /config/autoload/databases.php: -------------------------------------------------------------------------------- 1 | [ 15 | 'driver' => env('DB_DRIVER', 'mysql'), 16 | 'host' => env('DB_HOST', 'localhost'), 17 | 'database' => env('DB_DATABASE', 'hyperf'), 18 | 'port' => env('DB_PORT', 3306), 19 | 'username' => env('DB_USERNAME', 'root'), 20 | 'password' => env('DB_PASSWORD', ''), 21 | 'charset' => env('DB_CHARSET', 'utf8'), 22 | 'collation' => env('DB_COLLATION', 'utf8_unicode_ci'), 23 | 'prefix' => env('DB_PREFIX', ''), 24 | 'pool' => [ 25 | 'min_connections' => 1, 26 | 'max_connections' => 10, 27 | 'connect_timeout' => 10.0, 28 | 'wait_timeout' => 3.0, 29 | 'heartbeat' => -1, 30 | 'max_idle_time' => (float) env('DB_MAX_IDLE_TIME', 60), 31 | ], 32 | 'commands' => [ 33 | 'db:model' => [ 34 | 'path' => 'app/Model', 35 | 'force_casts' => true, 36 | 'inheritance' => 'Model', 37 | ], 38 | ], 39 | ], 40 | ]; 41 | -------------------------------------------------------------------------------- /config/autoload/dependencies.php: -------------------------------------------------------------------------------- 1 | [ 15 | 'amqp' => [ 16 | 'consumer' => [ 17 | 'namespace' => 'App\\Amqp\\Consumer', 18 | ], 19 | 'producer' => [ 20 | 'namespace' => 'App\\Amqp\\Producer', 21 | ], 22 | ], 23 | 'aspect' => [ 24 | 'namespace' => 'App\\Aspect', 25 | ], 26 | 'command' => [ 27 | 'namespace' => 'App\\Command', 28 | ], 29 | 'controller' => [ 30 | 'namespace' => 'App\\Controller', 31 | ], 32 | 'job' => [ 33 | 'namespace' => 'App\\Job', 34 | ], 35 | 'listener' => [ 36 | 'namespace' => 'App\\Listener', 37 | ], 38 | 'middleware' => [ 39 | 'namespace' => 'App\\Middleware', 40 | ], 41 | 'Process' => [ 42 | 'namespace' => 'App\\Processes', 43 | ], 44 | ], 45 | ]; 46 | -------------------------------------------------------------------------------- /config/autoload/exceptions.php: -------------------------------------------------------------------------------- 1 | [ 15 | 'http' => [ 16 | App\Exception\Handler\AppExceptionHandler::class, 17 | ], 18 | ], 19 | ]; 20 | -------------------------------------------------------------------------------- /config/autoload/listeners.php: -------------------------------------------------------------------------------- 1 | [ 15 | 'handler' => [ 16 | 'class' => Monolog\Handler\StreamHandler::class, 17 | 'constructor' => [ 18 | 'stream' => BASE_PATH . '/runtime/logs/hyperf.log', 19 | 'level' => Monolog\Logger::DEBUG, 20 | ], 21 | ], 22 | 'formatter' => [ 23 | 'class' => Monolog\Formatter\LineFormatter::class, 24 | 'constructor' => [ 25 | 'format' => null, 26 | 'dateFormat' => null, 27 | 'allowInlineLineBreaks' => true, 28 | ], 29 | ], 30 | ], 31 | ]; 32 | -------------------------------------------------------------------------------- /config/autoload/middlewares.php: -------------------------------------------------------------------------------- 1 | [ 15 | ], 16 | ]; 17 | -------------------------------------------------------------------------------- /config/autoload/processes.php: -------------------------------------------------------------------------------- 1 | [ 15 | 'host' => env('REDIS_HOST', 'localhost'), 16 | 'auth' => env('REDIS_AUTH', null), 17 | 'port' => (int) env('REDIS_PORT', 6379), 18 | 'db' => (int) env('REDIS_DB', 0), 19 | 'pool' => [ 20 | 'min_connections' => 1, 21 | 'max_connections' => 10, 22 | 'connect_timeout' => 10.0, 23 | 'wait_timeout' => 3.0, 24 | 'heartbeat' => -1, 25 | 'max_idle_time' => (float) env('REDIS_MAX_IDLE_TIME', 60), 26 | ], 27 | ], 28 | ]; 29 | -------------------------------------------------------------------------------- /config/autoload/server.php: -------------------------------------------------------------------------------- 1 | SWOOLE_PROCESS, 18 | 'servers' => [ 19 | [ 20 | 'name' => 'http', 21 | 'type' => Server::SERVER_HTTP, 22 | 'host' => '0.0.0.0', 23 | 'port' => 9501, 24 | 'sock_type' => SWOOLE_SOCK_TCP, 25 | 'callbacks' => [ 26 | SwooleEvent::ON_REQUEST => [Hyperf\HttpServer\Server::class, 'onRequest'], 27 | ], 28 | ], 29 | ], 30 | 'settings' => [ 31 | 'enable_coroutine' => true, 32 | 'worker_num' => 2, 33 | 'pid_file' => BASE_PATH . '/runtime/hyperf.pid', 34 | 'open_tcp_nodelay' => true, 35 | 'max_coroutine' => 100000, 36 | 'open_http2_protocol' => true, 37 | 'max_request' => 100000, 38 | 'socket_buffer_size' => 2 * 1024 * 1024, 39 | 'document_root' => BASE_PATH . '/public', 40 | 'enable_static_handler' => true, 41 | ], 42 | 'callbacks' => [ 43 | SwooleEvent::ON_BEFORE_START => [Hyperf\Framework\Bootstrap\ServerStartCallback::class, 'beforeStart'], 44 | SwooleEvent::ON_WORKER_START => [Hyperf\Framework\Bootstrap\WorkerStartCallback::class, 'onWorkerStart'], 45 | SwooleEvent::ON_PIPE_MESSAGE => [Hyperf\Framework\Bootstrap\PipeMessageCallback::class, 'onPipeMessage'], 46 | ], 47 | ]; 48 | -------------------------------------------------------------------------------- /config/config.php: -------------------------------------------------------------------------------- 1 | env('APP_NAME', 'skeleton'), 18 | StdoutLoggerInterface::class => [ 19 | 'log_level' => [ 20 | LogLevel::ALERT, 21 | LogLevel::CRITICAL, 22 | LogLevel::DEBUG, 23 | LogLevel::EMERGENCY, 24 | LogLevel::ERROR, 25 | LogLevel::INFO, 26 | LogLevel::NOTICE, 27 | LogLevel::WARNING, 28 | ], 29 | ], 30 | ]; 31 | -------------------------------------------------------------------------------- /config/container.php: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | ./test 14 | 15 | 16 | 17 | 18 | ./app 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /satis.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "your-packagist-name", 3 | "homepage": "your-packagist-domain", 4 | "repositories": [ 5 | { 6 | "type": "git", // git方式 7 | "url": "https://gitlab.xxxxxxx.com/your-gitlab-group/your-component.git" // 项目的git地址 8 | }, 9 | { 10 | "type": "git", 11 | "url": "https://gitlab.xxxxxxx.com/your-gitlab-group/your-other-component.git" 12 | } 13 | ], 14 | "require": { 15 | "your-gitlab-group/your-component": "*", // 组件以及组件的约束 16 | "your-gitlab-group/your-other-component": "*" 17 | } 18 | } -------------------------------------------------------------------------------- /test/Cases/ExampleTest.php: -------------------------------------------------------------------------------- 1 | assertTrue(true); 26 | $this->assertTrue(is_array($this->get('/'))); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /test/HttpTestCase.php: -------------------------------------------------------------------------------- 1 | client = make(Client::class); 36 | } 37 | 38 | public function __call($name, $arguments) 39 | { 40 | return $this->client->{$name}(...$arguments); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /test/bootstrap.php: -------------------------------------------------------------------------------- 1 | get(Hyperf\Contract\ApplicationInterface::class); 29 | --------------------------------------------------------------------------------