├── .gitignore ├── hyperf-provider ├── config │ ├── autoload │ │ ├── consul.php │ │ ├── aspects.php │ │ ├── commands.php │ │ ├── dependencies.php │ │ ├── listeners.php │ │ ├── processes.php │ │ ├── middlewares.php │ │ ├── exceptions.php │ │ ├── annotations.php │ │ ├── cache.php │ │ ├── redis.php │ │ ├── logger.php │ │ ├── devtool.php │ │ ├── databases.php │ │ └── server.php │ ├── routes.php │ ├── config.php │ └── container.php ├── .gitignore ├── app │ ├── Rpc │ │ ├── CalculatorServiceInterface.php │ │ └── CalculatorService.php │ ├── Model │ │ └── Model.php │ ├── Controller │ │ ├── IndexController.php │ │ └── AbstractController.php │ ├── Exception │ │ └── Handler │ │ │ └── AppExceptionHandler.php │ └── Listener │ │ └── DbQueryExecutedListener.php ├── .phpstorm.meta.php ├── .env.example ├── phpstan.neon ├── test │ ├── Cases │ │ └── ExampleTest.php │ ├── bootstrap.php │ └── HttpTestCase.php ├── deploy.test.yml ├── bin │ └── hyperf.php ├── phpunit.xml ├── .gitlab-ci.yml ├── Dockerfile ├── README.md ├── composer.json └── .php_cs ├── hyperf-consumer ├── .gitignore ├── app │ ├── Rpc │ │ └── CalculatorServiceInterface.php │ ├── Model │ │ └── Model.php │ ├── Controller │ │ ├── AbstractController.php │ │ └── IndexController.php │ ├── Exception │ │ └── Handler │ │ │ └── AppExceptionHandler.php │ └── Listener │ │ └── DbQueryExecutedListener.php ├── config │ ├── autoload │ │ ├── aspects.php │ │ ├── commands.php │ │ ├── dependencies.php │ │ ├── listeners.php │ │ ├── processes.php │ │ ├── middlewares.php │ │ ├── exceptions.php │ │ ├── annotations.php │ │ ├── cache.php │ │ ├── services.php │ │ ├── redis.php │ │ ├── logger.php │ │ ├── devtool.php │ │ ├── databases.php │ │ └── server.php │ ├── routes.php │ ├── config.php │ └── container.php ├── phpstan.neon ├── test │ ├── Cases │ │ └── ExampleTest.php │ ├── bootstrap.php │ └── HttpTestCase.php ├── deploy.test.yml ├── bin │ └── hyperf.php ├── phpunit.xml ├── Dockerfile ├── README.md └── composer.json └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | .idea -------------------------------------------------------------------------------- /hyperf-provider/config/autoload/consul.php: -------------------------------------------------------------------------------- 1 | 'http://127.0.0.1:8500', 5 | ]; -------------------------------------------------------------------------------- /hyperf-consumer/.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 | *.lock 13 | .phpunit* -------------------------------------------------------------------------------- /hyperf-consumer/app/Rpc/CalculatorServiceInterface.php: -------------------------------------------------------------------------------- 1 | [ 15 | ], 16 | ]; 17 | -------------------------------------------------------------------------------- /hyperf-provider/config/autoload/middlewares.php: -------------------------------------------------------------------------------- 1 | [ 15 | ], 16 | ]; 17 | -------------------------------------------------------------------------------- /hyperf-provider/config/routes.php: -------------------------------------------------------------------------------- 1 | [ 15 | 'http' => [ 16 | App\Exception\Handler\AppExceptionHandler::class, 17 | ], 18 | ], 19 | ]; 20 | -------------------------------------------------------------------------------- /hyperf-provider/config/autoload/exceptions.php: -------------------------------------------------------------------------------- 1 | [ 15 | 'http' => [ 16 | App\Exception\Handler\AppExceptionHandler::class, 17 | ], 18 | ], 19 | ]; 20 | -------------------------------------------------------------------------------- /hyperf-consumer/config/autoload/annotations.php: -------------------------------------------------------------------------------- 1 | [ 15 | 'paths' => [ 16 | BASE_PATH . '/app', 17 | ], 18 | 'ignore_annotations' => [ 19 | 'mixin', 20 | ], 21 | ], 22 | ]; 23 | -------------------------------------------------------------------------------- /hyperf-provider/config/autoload/annotations.php: -------------------------------------------------------------------------------- 1 | [ 15 | 'paths' => [ 16 | BASE_PATH . '/app', 17 | ], 18 | 'ignore_annotations' => [ 19 | 'mixin', 20 | ], 21 | ], 22 | ]; 23 | -------------------------------------------------------------------------------- /hyperf-consumer/config/autoload/cache.php: -------------------------------------------------------------------------------- 1 | [ 15 | 'driver' => Hyperf\Cache\Driver\RedisDriver::class, 16 | 'packer' => Hyperf\Utils\Packer\PhpSerializerPacker::class, 17 | 'prefix' => 'c:', 18 | ], 19 | ]; 20 | -------------------------------------------------------------------------------- /hyperf-provider/config/autoload/cache.php: -------------------------------------------------------------------------------- 1 | [ 15 | 'driver' => Hyperf\Cache\Driver\RedisDriver::class, 16 | 'packer' => Hyperf\Utils\Packer\PhpSerializerPacker::class, 17 | 'prefix' => 'c:', 18 | ], 19 | ]; 20 | -------------------------------------------------------------------------------- /hyperf-consumer/test/Cases/ExampleTest.php: -------------------------------------------------------------------------------- 1 | assertTrue(true); 26 | $this->assertTrue(is_array($this->get('/'))); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /hyperf-provider/test/Cases/ExampleTest.php: -------------------------------------------------------------------------------- 1 | assertTrue(true); 26 | $this->assertTrue(is_array($this->get('/'))); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /hyperf-consumer/deploy.test.yml: -------------------------------------------------------------------------------- 1 | version: '3.7' 2 | services: 3 | hyperf: 4 | image: $REGISTRY_URL/$PROJECT_NAME:test 5 | environment: 6 | - "APP_PROJECT=hyperf" 7 | - "APP_ENV=test" 8 | ports: 9 | - 9501:9501 10 | deploy: 11 | replicas: 1 12 | restart_policy: 13 | condition: on-failure 14 | delay: 5s 15 | max_attempts: 5 16 | update_config: 17 | parallelism: 2 18 | delay: 5s 19 | order: start-first 20 | networks: 21 | - hyperf_net 22 | configs: 23 | - source: hyperf_v1.0 24 | target: /opt/www/.env 25 | configs: 26 | hyperf_v1.0: 27 | external: true 28 | networks: 29 | hyperf_net: 30 | external: true 31 | -------------------------------------------------------------------------------- /hyperf-provider/app/Controller/IndexController.php: -------------------------------------------------------------------------------- 1 | request->input('user', 'Hyperf'); 20 | $method = $this->request->getMethod(); 21 | 22 | return [ 23 | 'method' => $method, 24 | 'message' => "Hello {$user}.", 25 | ]; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /hyperf-provider/deploy.test.yml: -------------------------------------------------------------------------------- 1 | version: '3.7' 2 | services: 3 | hyperf: 4 | image: $REGISTRY_URL/$PROJECT_NAME:test 5 | environment: 6 | - "APP_PROJECT=hyperf" 7 | - "APP_ENV=test" 8 | ports: 9 | - 9501:9501 10 | deploy: 11 | replicas: 1 12 | restart_policy: 13 | condition: on-failure 14 | delay: 5s 15 | max_attempts: 5 16 | update_config: 17 | parallelism: 2 18 | delay: 5s 19 | order: start-first 20 | networks: 21 | - hyperf_net 22 | configs: 23 | - source: hyperf_v1.0 24 | target: /opt/www/.env 25 | configs: 26 | hyperf_v1.0: 27 | external: true 28 | networks: 29 | hyperf_net: 30 | external: true 31 | -------------------------------------------------------------------------------- /hyperf-consumer/bin/hyperf.php: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | get(\Hyperf\Contract\ApplicationInterface::class); 20 | $application->run(); 21 | })(); 22 | -------------------------------------------------------------------------------- /hyperf-provider/bin/hyperf.php: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | get(\Hyperf\Contract\ApplicationInterface::class); 20 | $application->run(); 21 | })(); 22 | -------------------------------------------------------------------------------- /hyperf-consumer/phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | ./test 14 | 15 | 16 | 17 | 18 | ./app 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /hyperf-provider/phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | ./test 14 | 15 | 16 | 17 | 18 | ./app 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /hyperf-consumer/config/autoload/services.php: -------------------------------------------------------------------------------- 1 | [ 4 | [ 5 | // name 需与服务提供者的 name 属性相同 6 | 'name' => 'CalculatorService', 7 | // 服务接口名,可选,默认值等于 name 配置的值,如果 name 直接定义为接口类则可忽略此行配置,如 name 为字符串则需要配置 service 对应到接口类 8 | 'service' => \App\Rpc\CalculatorServiceInterface::class, 9 | 10 | 11 | // 这个消费者要从哪个服务中心获取节点信息,如不配置则不会从服务中心获取节点信息 12 | 'registry' => [ 13 | 'protocol' => 'consul', 14 | 'address' => 'http://127.0.0.1:8500', 15 | ], 16 | 17 | // 如果没有指定上面的 registry 配置,即为直接对指定的节点进行消费,通过下面的 nodes 参数来配置服务提供者的节点信息 18 | // 'nodes' => [ 19 | // ['host' => '127.0.0.1', 'port' => 9502], 20 | // ], 21 | ] 22 | ], 23 | ]; -------------------------------------------------------------------------------- /hyperf-consumer/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 | -------------------------------------------------------------------------------- /hyperf-provider/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 | -------------------------------------------------------------------------------- /hyperf-consumer/config/container.php: -------------------------------------------------------------------------------- 1 | get(Hyperf\Contract\ApplicationInterface::class); 29 | -------------------------------------------------------------------------------- /hyperf-provider/test/bootstrap.php: -------------------------------------------------------------------------------- 1 | get(Hyperf\Contract\ApplicationInterface::class); 29 | -------------------------------------------------------------------------------- /hyperf-consumer/config/autoload/redis.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 | -------------------------------------------------------------------------------- /hyperf-provider/config/autoload/redis.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 | -------------------------------------------------------------------------------- /hyperf-consumer/app/Controller/AbstractController.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 | -------------------------------------------------------------------------------- /hyperf-provider/config/autoload/logger.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 | -------------------------------------------------------------------------------- /hyperf-consumer/app/Controller/IndexController.php: -------------------------------------------------------------------------------- 1 | calculatorService->add(1,2); 35 | } 36 | 37 | public function test() 38 | { 39 | return "test"; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /hyperf-consumer/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 | -------------------------------------------------------------------------------- /hyperf-provider/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 | -------------------------------------------------------------------------------- /hyperf-consumer/config/autoload/devtool.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 | -------------------------------------------------------------------------------- /hyperf-provider/config/autoload/devtool.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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # hyperf-rpc-demo 2 | Hyperf RPC Demo - 基于Hyperf下json-RPC的Demo 3 | 4 | ### Step 1 - 安装并启动consul 5 | 6 | - 安装consul,并设置全局可访问 7 | 8 | - 新建consul目录,在consul目录下新建etc和data文件夹 9 | 10 | - 在etc下新建provider.json,并填入如下内容 11 | 12 | ``` 13 | { 14 | "service": { 15 | //这里写服务的ID,必须唯一 16 | "id": "CalculatorService", 17 | 18 | //这里写服务名称,一般也是ID名,非唯一 19 | "name": "CalculatorService", 20 | 21 | //服务提供者的IP地址,服务在哪台服务器上,就填写那台服务器IP 22 | "address": "127.0.0.1", 23 | 24 | //随便写 25 | "tags": [ 26 | "webapi" 27 | ], 28 | 29 | //填写服务提供者的端口, 30 | "port": 9502 31 | } 32 | } 33 | ``` 34 | 35 | 启动命令: 36 | 37 | `consul agent -dev -ui -config-dir=./etc -data-dir=./data -client=0.0.0.0` 38 | 39 | ### Step 2 - 启动服务提供者 40 | ``` 41 | - 切换到hyperf-provider目录 42 | - 执行composer install 43 | - php bin/hyperf.php start 44 | ``` 45 | 46 | 回过神来思考一下,留意config配置文件夹内的 47 | ``` 48 | - autoload/consul.php 49 | - autoload/server.php 50 | ``` 51 | 52 | 前者配置了注册到consul的地址,后者配置了服务提供的端口和地址,是不是就和provider.json的配置对应上了,这样consul就能发现到服务提供者了 53 | 54 | ### Step 3 - 启动服务消费者 55 | 56 | ``` 57 | - 切换到hyperf-consumer目录 58 | - 执行composer install 59 | - php bin/hyperf.php start 60 | ``` 61 | 62 | 访问:http://127.0.0.1:9503 63 | 64 | ### Done -------------------------------------------------------------------------------- /hyperf-consumer/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 | 'gen:model' => [ 34 | 'path' => 'app/Model', 35 | 'force_casts' => true, 36 | 'inheritance' => 'Model', 37 | ], 38 | ], 39 | ], 40 | ]; 41 | -------------------------------------------------------------------------------- /hyperf-provider/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 | 'gen:model' => [ 34 | 'path' => 'app/Model', 35 | 'force_casts' => true, 36 | 'inheritance' => 'Model', 37 | ], 38 | ], 39 | ], 40 | ]; 41 | -------------------------------------------------------------------------------- /hyperf-consumer/app/Exception/Handler/AppExceptionHandler.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->withHeader("Server", "Hyperf")->withStatus(500)->withBody(new SwooleStream('Internal Server Error.')); 38 | } 39 | 40 | public function isValid(Throwable $throwable): bool 41 | { 42 | return true; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /hyperf-provider/app/Exception/Handler/AppExceptionHandler.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->withHeader("Server", "Hyperf")->withStatus(500)->withBody(new SwooleStream('Internal Server Error.')); 38 | } 39 | 40 | public function isValid(Throwable $throwable): bool 41 | { 42 | return true; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /hyperf-provider/.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | # usermod -aG docker gitlab-runner 2 | 3 | stages: 4 | - build 5 | - deploy 6 | 7 | variables: 8 | PROJECT_NAME: hyperf 9 | REGISTRY_URL: registry-docker.org 10 | 11 | build_test_docker: 12 | stage: build 13 | before_script: 14 | # - git submodule sync --recursive 15 | # - git submodule update --init --recursive 16 | script: 17 | - docker build . -t $PROJECT_NAME 18 | - docker tag $PROJECT_NAME $REGISTRY_URL/$PROJECT_NAME:test 19 | - docker push $REGISTRY_URL/$PROJECT_NAME:test 20 | only: 21 | - test 22 | tags: 23 | - builder 24 | 25 | deploy_test_docker: 26 | stage: deploy 27 | script: 28 | - docker stack deploy -c deploy.test.yml --with-registry-auth $PROJECT_NAME 29 | only: 30 | - test 31 | tags: 32 | - test 33 | 34 | build_docker: 35 | stage: build 36 | before_script: 37 | # - git submodule sync --recursive 38 | # - git submodule update --init --recursive 39 | script: 40 | - docker build . -t $PROJECT_NAME 41 | - docker tag $PROJECT_NAME $REGISTRY_URL/$PROJECT_NAME:$CI_COMMIT_REF_NAME 42 | - docker tag $PROJECT_NAME $REGISTRY_URL/$PROJECT_NAME:latest 43 | - docker push $REGISTRY_URL/$PROJECT_NAME:$CI_COMMIT_REF_NAME 44 | - docker push $REGISTRY_URL/$PROJECT_NAME:latest 45 | only: 46 | - tags 47 | tags: 48 | - builder 49 | 50 | deploy_docker: 51 | stage: deploy 52 | script: 53 | - echo SUCCESS 54 | only: 55 | - tags 56 | tags: 57 | - builder 58 | -------------------------------------------------------------------------------- /hyperf-consumer/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' => 9503, 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' => swoole_cpu_num(), 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 | 'buffer_output_size' => 2 * 1024 * 1024, 40 | ], 41 | 'callbacks' => [ 42 | SwooleEvent::ON_BEFORE_START => [Hyperf\Framework\Bootstrap\ServerStartCallback::class, 'beforeStart'], 43 | SwooleEvent::ON_WORKER_START => [Hyperf\Framework\Bootstrap\WorkerStartCallback::class, 'onWorkerStart'], 44 | SwooleEvent::ON_PIPE_MESSAGE => [Hyperf\Framework\Bootstrap\PipeMessageCallback::class, 'onPipeMessage'], 45 | ], 46 | ]; 47 | -------------------------------------------------------------------------------- /hyperf-consumer/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 | -------------------------------------------------------------------------------- /hyperf-provider/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 | -------------------------------------------------------------------------------- /hyperf-consumer/Dockerfile: -------------------------------------------------------------------------------- 1 | # Default Dockerfile 2 | # 3 | # @link https://www.hyperf.io 4 | # @document https://doc.hyperf.io 5 | # @contact group@hyperf.io 6 | # @license https://github.com/hyperf-cloud/hyperf/blob/master/LICENSE 7 | 8 | FROM hyperf/hyperf:7.2-alpine-v3.9-cli 9 | LABEL maintainer="Hyperf Developers " 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 install --no-dev -o 56 | 57 | EXPOSE 9501 58 | 59 | ENTRYPOINT ["php", "/opt/www/bin/hyperf.php", "start"] 60 | -------------------------------------------------------------------------------- /hyperf-provider/Dockerfile: -------------------------------------------------------------------------------- 1 | # Default Dockerfile 2 | # 3 | # @link https://www.hyperf.io 4 | # @document https://doc.hyperf.io 5 | # @contact group@hyperf.io 6 | # @license https://github.com/hyperf-cloud/hyperf/blob/master/LICENSE 7 | 8 | FROM hyperf/hyperf:7.2-alpine-v3.9-cli 9 | LABEL maintainer="Hyperf Developers " 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 install --no-dev -o 56 | 57 | EXPOSE 9501 58 | 59 | ENTRYPOINT ["php", "/opt/www/bin/hyperf.php", "start"] 60 | -------------------------------------------------------------------------------- /hyperf-consumer/README.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | This is a skeleton application using the Hyperf framework. This application is meant to be used as a starting place for those looking to get their feet wet with Hyperf Framework. 4 | 5 | # Requirements 6 | 7 | Hyperf has some requirements for the system environment, it can only run under Linux and Mac environment, but due to the development of Docker virtualization technology, Docker for Windows can also be used as the running environment under Windows. 8 | 9 | The various versions of Dockerfile have been prepared for you in the [hyperf\hyperf-docker](https://github.com/hyperf/hyperf-docker) project, or directly based on the already built [hyperf\hyperf](https://hub.docker.com/r/hyperf/hyperf) Image to run. 10 | 11 | When you don't want to use Docker as the basis for your running environment, you need to make sure that your operating environment meets the following requirements: 12 | 13 | - PHP >= 7.2 14 | - Swoole PHP extension >= 4.4,and Disabled `Short Name` 15 | - OpenSSL PHP extension 16 | - JSON PHP extension 17 | - PDO PHP extension (If you need to use MySQL Client) 18 | - Redis PHP extension (If you need to use Redis Client) 19 | - Protobuf PHP extension (If you need to use gRPC Server of Client) 20 | 21 | # Installation using Composer 22 | 23 | The easiest way to create a new Hyperf project is to use Composer. If you don't have it already installed, then please install as per the documentation. 24 | 25 | To create your new Hyperf project: 26 | 27 | $ composer create-project hyperf/hyperf-skeleton path/to/install 28 | 29 | Once installed, you can run the server immediately using the command below. 30 | 31 | $ cd path/to/install 32 | $ php bin/hyperf.php start 33 | 34 | This will start the cli-server on port `9501`, and bind it to all network interfaces. You can then visit the site at `http://localhost:9501/` 35 | 36 | which will bring up Hyperf default home page. 37 | -------------------------------------------------------------------------------- /hyperf-provider/README.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | This is a skeleton application using the Hyperf framework. This application is meant to be used as a starting place for those looking to get their feet wet with Hyperf Framework. 4 | 5 | # Requirements 6 | 7 | Hyperf has some requirements for the system environment, it can only run under Linux and Mac environment, but due to the development of Docker virtualization technology, Docker for Windows can also be used as the running environment under Windows. 8 | 9 | The various versions of Dockerfile have been prepared for you in the [hyperf\hyperf-docker](https://github.com/hyperf/hyperf-docker) project, or directly based on the already built [hyperf\hyperf](https://hub.docker.com/r/hyperf/hyperf) Image to run. 10 | 11 | When you don't want to use Docker as the basis for your running environment, you need to make sure that your operating environment meets the following requirements: 12 | 13 | - PHP >= 7.2 14 | - Swoole PHP extension >= 4.4,and Disabled `Short Name` 15 | - OpenSSL PHP extension 16 | - JSON PHP extension 17 | - PDO PHP extension (If you need to use MySQL Client) 18 | - Redis PHP extension (If you need to use Redis Client) 19 | - Protobuf PHP extension (If you need to use gRPC Server of Client) 20 | 21 | # Installation using Composer 22 | 23 | The easiest way to create a new Hyperf project is to use Composer. If you don't have it already installed, then please install as per the documentation. 24 | 25 | To create your new Hyperf project: 26 | 27 | $ composer create-project hyperf/hyperf-skeleton path/to/install 28 | 29 | Once installed, you can run the server immediately using the command below. 30 | 31 | $ cd path/to/install 32 | $ php bin/hyperf.php start 33 | 34 | This will start the cli-server on port `9501`, and bind it to all network interfaces. You can then visit the site at `http://localhost:9501/` 35 | 36 | which will bring up Hyperf default home page. 37 | -------------------------------------------------------------------------------- /hyperf-provider/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 | 'name' => 'jsonrpc-http', 31 | 'type' => Server::SERVER_HTTP, 32 | 'host' => '0.0.0.0', 33 | 'port' => 9502, 34 | 'sock_type' => SWOOLE_SOCK_TCP, 35 | 'callbacks' => [ 36 | SwooleEvent::ON_REQUEST => [\Hyperf\JsonRpc\HttpServer::class, 'onRequest'], 37 | ], 38 | ], 39 | ], 40 | 'settings' => [ 41 | 'enable_coroutine' => true, 42 | 'worker_num' => swoole_cpu_num(), 43 | 'pid_file' => BASE_PATH . '/runtime/hyperf.pid', 44 | 'open_tcp_nodelay' => true, 45 | 'max_coroutine' => 100000, 46 | 'open_http2_protocol' => true, 47 | 'max_request' => 100000, 48 | 'socket_buffer_size' => 2 * 1024 * 1024, 49 | 'buffer_output_size' => 2 * 1024 * 1024, 50 | ], 51 | 'callbacks' => [ 52 | SwooleEvent::ON_BEFORE_START => [Hyperf\Framework\Bootstrap\ServerStartCallback::class, 'beforeStart'], 53 | SwooleEvent::ON_WORKER_START => [Hyperf\Framework\Bootstrap\WorkerStartCallback::class, 'onWorkerStart'], 54 | SwooleEvent::ON_PIPE_MESSAGE => [Hyperf\Framework\Bootstrap\PipeMessageCallback::class, 'onPipeMessage'], 55 | ], 56 | ]; 57 | -------------------------------------------------------------------------------- /hyperf-consumer/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/db-connection": "~1.1.0", 21 | "hyperf/framework": "~1.1.0", 22 | "hyperf/guzzle": "~1.1.0", 23 | "hyperf/http-server": "~1.1.0", 24 | "hyperf/logger": "~1.1.0", 25 | "hyperf/memory": "~1.1.0", 26 | "hyperf/process": "~1.1.0", 27 | "hyperf/redis": "~1.1.0", 28 | "hyperf/json-rpc": "^1.1", 29 | "hyperf/rpc": "~1.1.0", 30 | "hyperf/rpc-client": "~1.1.0", 31 | "hyperf/rpc-server": "~1.1.0", 32 | "hyperf/service-governance": "~1.1.0" 33 | }, 34 | "require-dev": { 35 | "swoft/swoole-ide-helper": "^4.2", 36 | "phpmd/phpmd": "^2.6", 37 | "friendsofphp/php-cs-fixer": "^2.14", 38 | "mockery/mockery": "^1.0", 39 | "doctrine/common": "^2.9", 40 | "phpstan/phpstan": "^0.11.2", 41 | "hyperf/devtool": "~1.1.0", 42 | "hyperf/testing": "~1.1.0" 43 | }, 44 | "suggest": { 45 | "ext-openssl": "Required to use HTTPS.", 46 | "ext-json": "Required to use JSON.", 47 | "ext-pdo": "Required to use MySQL Client.", 48 | "ext-pdo_mysql": "Required to use MySQL Client.", 49 | "ext-redis": "Required to use Redis Client." 50 | }, 51 | "autoload": { 52 | "psr-4": { 53 | "App\\": "app/" 54 | }, 55 | "files": [] 56 | }, 57 | "autoload-dev": { 58 | "psr-4": { 59 | "HyperfTest\\": "./test/" 60 | } 61 | }, 62 | "minimum-stability": "dev", 63 | "prefer-stable": true, 64 | "extra": [], 65 | "scripts": { 66 | "post-root-package-install": [ 67 | "@php -r \"file_exists('.env') || copy('.env.example', '.env');\"" 68 | ], 69 | "post-autoload-dump": [ 70 | "init-proxy.sh" 71 | ], 72 | "test": "co-phpunit -c phpunit.xml --colors=always", 73 | "cs-fix": "php-cs-fixer fix $1", 74 | "analyse": "phpstan analyse --memory-limit 300M -l 0 -c phpstan.neon ./app ./config", 75 | "start": "php ./bin/hyperf.php start", 76 | "init-proxy": "init-proxy.sh" 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /hyperf-provider/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/db-connection": "~1.1.0", 21 | "hyperf/framework": "~1.1.0", 22 | "hyperf/guzzle": "~1.1.0", 23 | "hyperf/http-server": "~1.1.0", 24 | "hyperf/logger": "~1.1.0", 25 | "hyperf/memory": "~1.1.0", 26 | "hyperf/process": "~1.1.0", 27 | "hyperf/redis": "~1.1.0", 28 | "hyperf/json-rpc": "^1.1", 29 | "hyperf/rpc": "~1.1.0", 30 | "hyperf/rpc-client": "~1.1.0", 31 | "hyperf/rpc-server": "~1.1.0", 32 | "hyperf/service-governance": "^1.1", 33 | "hyperf/consul": "^1.1" 34 | }, 35 | "require-dev": { 36 | "swoft/swoole-ide-helper": "^4.2", 37 | "phpmd/phpmd": "^2.6", 38 | "friendsofphp/php-cs-fixer": "^2.14", 39 | "mockery/mockery": "^1.0", 40 | "doctrine/common": "^2.9", 41 | "phpstan/phpstan": "^0.11.2", 42 | "hyperf/devtool": "~1.1.0", 43 | "hyperf/testing": "~1.1.0" 44 | }, 45 | "suggest": { 46 | "ext-openssl": "Required to use HTTPS.", 47 | "ext-json": "Required to use JSON.", 48 | "ext-pdo": "Required to use MySQL Client.", 49 | "ext-pdo_mysql": "Required to use MySQL Client.", 50 | "ext-redis": "Required to use Redis Client." 51 | }, 52 | "autoload": { 53 | "psr-4": { 54 | "App\\": "app/" 55 | }, 56 | "files": [] 57 | }, 58 | "autoload-dev": { 59 | "psr-4": { 60 | "HyperfTest\\": "./test/" 61 | } 62 | }, 63 | "minimum-stability": "dev", 64 | "prefer-stable": true, 65 | "extra": [], 66 | "scripts": { 67 | "post-root-package-install": [ 68 | "@php -r \"file_exists('.env') || copy('.env.example', '.env');\"" 69 | ], 70 | "post-autoload-dump": [ 71 | "init-proxy.sh" 72 | ], 73 | "test": "co-phpunit -c phpunit.xml --colors=always", 74 | "cs-fix": "php-cs-fixer fix $1", 75 | "analyse": "phpstan analyse --memory-limit 300M -l 0 -c phpstan.neon ./app ./config", 76 | "start": "php ./bin/hyperf.php start", 77 | "init-proxy": "init-proxy.sh" 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /hyperf-provider/.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 | --------------------------------------------------------------------------------