├── .dockerignore ├── .env.example ├── .php_cs ├── CONTRIBUTING.md ├── Dockerfile ├── LICENSE ├── README.md ├── README.zh-CN.md ├── app ├── Annotation │ ├── Mapping │ │ └── AlphaDash.php │ └── Parser │ │ └── AlphaDashParser.php ├── Application.php ├── Aspect │ ├── AnnotationAspect.php │ ├── BeanAspect.php │ └── RequestBeanAspect.php ├── AutoLoader.php ├── Common │ ├── DbSelector.php │ ├── MyBean.php │ └── RpcProvider.php ├── Console │ └── Command │ │ ├── AgentCommand.php │ │ ├── DemoCommand.php │ │ └── TestCommand.php ├── Exception │ ├── ApiException.php │ └── Handler │ │ ├── ApiExceptionHandler.php │ │ ├── HttpExceptionHandler.php │ │ ├── RpcExceptionHandler.php │ │ ├── WsHandshakeExceptionHandler.php │ │ └── WsMessageExceptionHandler.php ├── Helper │ └── Functions.php ├── Http │ ├── Controller │ │ ├── BeanController.php │ │ ├── BreakerController.php │ │ ├── CacheController.php │ │ ├── CoController.php │ │ ├── CookieController.php │ │ ├── DbBuilderController.php │ │ ├── DbModelController.php │ │ ├── DbTransactionController.php │ │ ├── ExceptionController.php │ │ ├── HomeController.php │ │ ├── LimiterController.php │ │ ├── LogController.php │ │ ├── ProcController.php │ │ ├── RedisController.php │ │ ├── RespController.php │ │ ├── RpcController.php │ │ ├── SelectDbController.php │ │ ├── SessionController.php │ │ ├── TaskController.php │ │ ├── TimerController.php │ │ ├── ValidatorController.php │ │ └── ViewController.php │ └── Middleware │ │ ├── DomainLimitMiddleware.php │ │ └── FavIconMiddleware.php ├── Listener │ ├── DbRanListener.php │ ├── DeregisterServiceListener.php │ ├── ModelSavedListener.php │ ├── RegisterServiceListener.php │ ├── Test │ │ ├── ShutDownListener.php │ │ ├── StartListener.php │ │ ├── TaskProcessListener.php │ │ ├── WorkerStartListener.php │ │ └── WorkerStopListener.php │ └── UserSavingListener.php ├── Migration │ └── User.php ├── Model │ ├── Dao │ │ └── UserDao.php │ ├── Data │ │ ├── GoodsData.php │ │ └── UserData.php │ ├── Entity │ │ ├── Count.php │ │ ├── Count2.php │ │ ├── Desc.php │ │ ├── User.php │ │ └── User3.php │ └── Logic │ │ ├── ApolloLogic.php │ │ ├── BreakerLogic.php │ │ ├── ConsulLogic.php │ │ ├── LimiterLogic.php │ │ ├── MonitorLogic.php │ │ ├── RequestBean.php │ │ ├── RequestBeanTwo.php │ │ └── UserLogic.php ├── Process │ ├── MonitorProcess.php │ ├── Worker1Process.php │ └── Worker2Process.php ├── Rpc │ ├── Lib │ │ └── UserInterface.php │ ├── Middleware │ │ └── ServiceMiddleware.php │ └── Service │ │ ├── UserService.php │ │ ├── UserServiceV2.php │ │ └── big.data ├── Task │ ├── Crontab │ │ └── CronTask.php │ ├── Listener │ │ └── FinishListener.php │ └── Task │ │ ├── SyncTask.php │ │ └── TestTask.php ├── Tcp │ ├── Controller │ │ └── DemoController.php │ └── Middleware │ │ ├── DemoMiddleware.php │ │ └── GlobalTcpMiddleware.php ├── Validator │ ├── CustomerValidator.php │ ├── Rule │ │ └── AlphaDashRule.php │ └── TestValidator.php ├── WebSocket │ ├── Chat │ │ └── HomeController.php │ ├── ChatModule.php │ ├── EchoModule.php │ ├── Middleware │ │ ├── DemoMiddleware.php │ │ └── GlobalWsMiddleware.php │ ├── Test │ │ └── TestController.php │ └── TestModule.php └── bean.php ├── bin ├── bootstrap.php └── swoft ├── composer.cn.json ├── composer.dev.json ├── composer.json ├── config ├── app.php ├── base.php ├── db.php └── dev │ └── db.php ├── database ├── AutoLoader.php └── Migration │ ├── Count.php │ └── Desc.php ├── docker-compose.yml ├── phpstan.neon.dist ├── public ├── .keep ├── favicon.ico └── image │ ├── start-http-server.jpg │ └── swoft-logo-mdl.png └── resource ├── language └── .keep └── views ├── home ├── index.php └── ws-test.php └── layouts ├── default.php └── default ├── footer.php └── header.php /.dockerignore: -------------------------------------------------------------------------------- 1 | runtime 2 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | # basic 2 | APP_DEBUG=0 3 | SWOFT_DEBUG=0 4 | 5 | # more ... 6 | -------------------------------------------------------------------------------- /.php_cs: -------------------------------------------------------------------------------- 1 | setRiskyAllowed(true) 14 | ->setRules([ 15 | '@PSR2' => true, 16 | 'array_syntax' => [ 17 | 'syntax' => 'short' 18 | ], 19 | 'class_attributes_separation' => true, 20 | 'declare_strict_types' => true, 21 | 'encoding' => true, // MUST use only UTF-8 without BOM 22 | 'global_namespace_import' => [ 23 | 'import_constants' => true, 24 | 'import_functions' => true, 25 | ], 26 | 'header_comment' => [ 27 | 'comment_type' => 'PHPDoc', 28 | 'header' => $header, 29 | 'separate' => 'bottom' 30 | ], 31 | 'no_unused_imports' => true, 32 | 'single_quote' => true, 33 | 'standardize_not_equals' => true, 34 | ]) 35 | ->setFinder( 36 | PhpCsFixer\Finder::create() 37 | ->exclude('public') 38 | ->exclude('resource') 39 | ->exclude('config') 40 | ->exclude('runtime') 41 | ->exclude('vendor') 42 | ->in(__DIR__) 43 | ) 44 | ->setUsingCache(false); 45 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # CONTRIBUTING 2 | 3 | ## Contributing code via Github 4 | 5 | Swoft currently uses Git to control the version of the program. If you want to contribute source code to Swoft, please get an overview of how Git is used. We currently host the project on GitHub, and any GitHub user can contribute code to us. 6 | 7 | The way to participate is very simple, fork a swoft-component or swoft-ext code into your warehouse, modify and submit, and send us a pull request, we will promptly review the code and process your application. After the review, your code will be merged into our repository, so you will automatically appear on the contributor list, very convenient. 8 | 9 | We hope that the code you contributed will be: 10 | 11 | - Swoft's coding specification 12 | - Appropriate comments that others can read 13 | - Follow the Apache2 open source protocol 14 | - Submit a commit message must be in English 15 | 16 | > If you would like more details or have any questions, please continue reading below 17 | 18 | Precautions 19 | 20 | - PSR-2 is selected for the code formatting standard of this project; 21 | - class name and class file name follow PSR-4; 22 | - For the processing of Issues, use the commit title such as `fix swoft-cloud/swoft#xxx(Issue ID)` to directly close the issue. 23 | - The system will automatically test and modify on PHP 7.1+ (`7.1 7.2 7.3`) Swoole 4.4.1+ 24 | - The administrator will not merge the changes that caused CI faild. If CI faild appears, please check your source code or modify the corresponding unit test file. 25 | 26 | ## GitHub Issue 27 | 28 | GitHub provides the Issue feature, which can be used to: 29 | 30 | - Raise a bug 31 | - propose functional improvements 32 | - Feedback experience 33 | 34 | This feature should not be used for: 35 | 36 | - Unfriendly remarks 37 | 38 | ## Quick modification 39 | 40 | GitHub provides the ability to quickly edit files 41 | 42 | - Log in to your GitHub account; 43 | - Browse the project file and find the file to be modified; 44 | - Click the pencil icon in the upper right corner to modify it; 45 | - Fill in Commit changes related content (Title is required) 46 | - Submit changes, wait for CI verification and administrator merge. 47 | 48 | > This method is suitable for modifying the document project. If you need to submit a large number of changes at once, please continue reading the following 49 | 50 | ## Complete process 51 | 52 | - fork swoft-component or swoft-ext project; 53 | - Clone your fork project to the local; 54 | - Create a new branch and checkout the new branch; 55 | - Make changes. If your changes include additions or subtractions of methods or functions, please remember to modify the unit test file. 56 | - Push your local repository to GitHub; 57 | - submit a pull request; 58 | - Wait for CI verification (if you don't pass, you need to fix the code yourself, GitHub will automatically update your pull request); 59 | - Waiting for administrator processing 60 | 61 | ## Precautions 62 | 63 | If you have any questions about the above process, please check out the GIT tutorial; 64 | 65 | For different aspects of the code, create different branches in your own fork project. 66 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # @description php image base on the debian 9.x 2 | # 3 | # Some Information 4 | # ------------------------------------------------------------------------------------ 5 | # @link https://hub.docker.com/_/debian/ alpine image 6 | # @link https://hub.docker.com/_/php/ php image 7 | # @link https://github.com/docker-library/php php dockerfiles 8 | # @see https://github.com/docker-library/php/tree/master/7.2/stretch/cli/Dockerfile 9 | # ------------------------------------------------------------------------------------ 10 | # @build-example docker build . -f Dockerfile -t swoft/swoft 11 | # 12 | FROM php:7.2 13 | 14 | LABEL maintainer="inhere " version="2.0" 15 | 16 | # --build-arg timezone=Asia/Shanghai 17 | ARG timezone 18 | # app env: prod pre test dev 19 | ARG app_env=test 20 | # default use www-data user 21 | ARG work_user=www-data 22 | 23 | # default APP_ENV = test 24 | ENV APP_ENV=${app_env:-"test"} \ 25 | TIMEZONE=${timezone:-"Asia/Shanghai"} \ 26 | PHPREDIS_VERSION=5.1.0 \ 27 | SWOOLE_VERSION=4.4.18 \ 28 | COMPOSER_ALLOW_SUPERUSER=1 29 | 30 | # Libs -y --no-install-recommends 31 | RUN apt-get update \ 32 | && apt-get install -y \ 33 | curl wget git zip unzip less vim procps lsof tcpdump htop openssl net-tools iputils-ping \ 34 | libz-dev \ 35 | libssl-dev \ 36 | libnghttp2-dev \ 37 | libpcre3-dev \ 38 | libjpeg-dev \ 39 | libpng-dev \ 40 | libfreetype6-dev \ 41 | # Install PHP extensions 42 | && docker-php-ext-install \ 43 | bcmath gd pdo_mysql mbstring sockets zip sysvmsg sysvsem sysvshm \ 44 | # Clean apt cache 45 | && rm -rf /var/lib/apt/lists/* 46 | 47 | # Install composer 48 | Run curl -sS https://getcomposer.org/installer | php \ 49 | && mv composer.phar /usr/local/bin/composer \ 50 | && composer self-update --clean-backups \ 51 | # Install redis extension 52 | && wget http://pecl.php.net/get/redis-${PHPREDIS_VERSION}.tgz -O /tmp/redis.tar.tgz \ 53 | && pecl install /tmp/redis.tar.tgz \ 54 | && rm -rf /tmp/redis.tar.tgz \ 55 | && docker-php-ext-enable redis \ 56 | # Install swoole extension 57 | && wget https://github.com/swoole/swoole-src/archive/v${SWOOLE_VERSION}.tar.gz -O swoole.tar.gz \ 58 | && mkdir -p swoole \ 59 | && tar -xf swoole.tar.gz -C swoole --strip-components=1 \ 60 | && rm swoole.tar.gz \ 61 | && ( \ 62 | cd swoole \ 63 | && phpize \ 64 | && ./configure --enable-mysqlnd --enable-sockets --enable-openssl --enable-http2 \ 65 | && make -j$(nproc) \ 66 | && make install \ 67 | ) \ 68 | && rm -r swoole \ 69 | && docker-php-ext-enable swoole \ 70 | # Clear dev deps 71 | && apt-get clean \ 72 | && apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \ 73 | # Timezone 74 | && cp /usr/share/zoneinfo/${TIMEZONE} /etc/localtime \ 75 | && echo "${TIMEZONE}" > /etc/timezone \ 76 | && echo "[Date]\ndate.timezone=${TIMEZONE}" > /usr/local/etc/php/conf.d/timezone.ini 77 | 78 | # Install composer deps 79 | ADD . /var/www/swoft 80 | RUN cd /var/www/swoft \ 81 | && composer install \ 82 | && composer clearcache 83 | 84 | WORKDIR /var/www/swoft 85 | EXPOSE 18306 18307 18308 86 | 87 | # ENTRYPOINT ["php", "/var/www/swoft/bin/swoft", "http:start"] 88 | CMD ["php", "/var/www/swoft/bin/swoft", "http:start"] 89 | -------------------------------------------------------------------------------- /README.zh-CN.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | swoft 4 | 5 |

6 | 7 | [![Latest Stable Version](http://img.shields.io/packagist/v/swoft/swoft.svg)](https://packagist.org/packages/swoft/swoft) 8 | [![Build Status](https://travis-ci.org/swoft-cloud/swoft.svg?branch=master)](https://travis-ci.org/swoft-cloud/swoft) 9 | [![Docker Build Status](https://img.shields.io/docker/build/swoft/swoft.svg)](https://hub.docker.com/r/swoft/swoft/) 10 | [![Php Version](https://img.shields.io/badge/php-%3E=7.1-brightgreen.svg?maxAge=2592000)](https://secure.php.net/) 11 | [![Swoole Version](https://img.shields.io/badge/swoole-%3E=4.3.3-brightgreen.svg?maxAge=2592000)](https://github.com/swoole/swoole-src) 12 | [![Swoft Doc](https://img.shields.io/badge/docs-passing-green.svg?maxAge=2592000)](https://www.swoft.org) 13 | [![Swoft License](https://img.shields.io/hexpm/l/plug.svg?maxAge=2592000)](https://github.com/swoft-cloud/swoft/blob/master/LICENSE) 14 | [![Gitter](https://img.shields.io/gitter/room/swoft-cloud/swoft.svg)](https://gitter.im/swoft-cloud/community) 15 | 16 | ![start-http-server](https://raw.githubusercontent.com/swoft-cloud/swoft/master/public/image/start-http-server.jpg) 17 | 18 | PHP 高性能微服务协程框架 19 | 20 | > **[EN README](README.md)** 21 | 22 | ## 简介 23 | 24 | Swoft 是一款基于 Swoole 扩展实现的 PHP 微服务协程框架。Swoft 能像 Go 一样,内置协程网络服务器及常用的协程客户端且常驻内存,不依赖传统的 PHP-FPM。有类似 Go 语言的协程操作方式,有类似 Spring Cloud 框架灵活的注解、强大的全局依赖注入容器、完善的服务治理、灵活强大的 AOP、标准的 PSR 规范实现等等。 25 | 26 | Swoft 通过长达三年的积累和方向的探索,把 Swoft 打造成 PHP 界的 Spring Cloud, 它是 PHP 高性能框架和微服务治理的最佳选择。 27 | 28 | ## 功能特色 29 | 30 | - 内置高性能网络服务器(Http/Websocket/RPC/TCP) 31 | - 灵活的组件功能 32 | - 强大的注解功能 33 | - 多样化的命令终端(控制台) 34 | - 强大的面向切面编程(AOP) 35 | - 容器管理,依赖注入(DI) 36 | - 灵活的事件机制 37 | - 基于PSR-7的HTTP消息的实现 38 | - 基于PSR-14的事件管理 39 | - 基于PSR-15的中间件 40 | - 国际化(i18n)支持 41 | - 简单有效的参数验证器 42 | - 高性能连接池(Mysql/Redis/RPC),自动重新连接 43 | - 数据库高度兼容Laravel的使用方式 44 | - Redis高度兼容Laravel的使用方式 45 | - 秒级定时任务 46 | - 进程池 47 | - 高效的任务处理 48 | - 灵活的异常处理 49 | - 强大的日志系统 50 | - 服务注册与发现 51 | - 配置中心 52 | - 服务限流 53 | - 服务降级 54 | - 服务熔断 55 | - Apollo 56 | - Consul 57 | 58 | ## 在线文档 59 | 60 | - [中文文档](https://www.swoft.org/documents/v2/index.html) 61 | - [English](http://swoft.io/docs/2.x/en) 62 | 63 | ## 学习交流 64 | 65 | - QQ Group3: 541038173 66 | - QQ Group2: 778656850(已满) 67 | - QQ Group1: 548173319(已满) 68 | - [swoft-cloud/community](https://gitter.im/swoft-cloud/community) 69 | 70 | ## 免费技术支持 71 | 72 | ![support](https://www.swoft.org/src/images/technical-support.png) 73 | 74 | ## Requirement 75 | 76 | - [PHP 7.1+](https://github.com/php/php-src/releases) 77 | - [Swoole 4.3.4+](https://github.com/swoole/swoole-src/releases) 78 | - [Composer](https://getcomposer.org/) 79 | 80 | ## Install 81 | 82 | ### Composer 83 | 84 | ```bash 85 | composer create-project swoft/swoft swoft 86 | ``` 87 | 88 | ## Start 89 | 90 | - Http server 91 | 92 | ```bash 93 | [root@swoft swoft]# php bin/swoft http:start 94 | ``` 95 | 96 | - WebSocket server 97 | 98 | ```bash 99 | [root@swoft swoft]# php bin/swoft ws:start 100 | ``` 101 | 102 | - RPC server 103 | 104 | ```bash 105 | [root@swoft swoft]# php bin/swoft rpc:start 106 | ``` 107 | 108 | ## 核心组件 109 | 110 | Component Name | Packagist Version 111 | --------------------|--------------------- 112 | swoft-annotation | [![Latest Stable Version](http://img.shields.io/packagist/v/swoft/annotation.svg)](https://packagist.org/packages/swoft/annotation) 113 | swoft-config | [![Latest Stable Version](http://img.shields.io/packagist/v/swoft/config.svg)](https://packagist.org/packages/swoft/config) 114 | swoft-db | [![Latest Stable Version](http://img.shields.io/packagist/v/swoft/db.svg)](https://packagist.org/packages/swoft/db) 115 | swoft-framework | [![Latest Stable Version](http://img.shields.io/packagist/v/swoft/framework.svg)](https://packagist.org/packages/swoft/framework) 116 | swoft-i18n | [![Latest Stable Version](http://img.shields.io/packagist/v/swoft/i18n.svg)](https://packagist.org/packages/swoft/i18n) 117 | swoft-proxy | [![Latest Stable Version](http://img.shields.io/packagist/v/swoft/proxy.svg)](https://packagist.org/packages/swoft/proxy) 118 | swoft-rpc-client | [![Latest Stable Version](http://img.shields.io/packagist/v/swoft/rpc-client.svg)](https://packagist.org/packages/swoft/rpc-client) 119 | swoft-stdlib | [![Latest Stable Version](http://img.shields.io/packagist/v/swoft/stdlib.svg)](https://packagist.org/packages/swoft/stdlib) 120 | swoft-tcp-server | [![Latest Stable Version](http://img.shields.io/packagist/v/swoft/tcp-server.svg)](https://packagist.org/packages/swoft/tcp-server) 121 | swoft-aop | [![Latest Stable Version](http://img.shields.io/packagist/v/swoft/aop.svg)](https://packagist.org/packages/swoft/aop) 122 | swoft-connection-pool | [![Latest Stable Version](http://img.shields.io/packagist/v/swoft/connection-pool.svg)](https://packagist.org/packages/swoft/connection-pool) 123 | swoft-error | [![Latest Stable Version](http://img.shields.io/packagist/v/swoft/error.svg)](https://packagist.org/packages/swoft/error) 124 | swoft-http-message | [![Latest Stable Version](http://img.shields.io/packagist/v/swoft/http-message.svg)](https://packagist.org/packages/swoft/http-message) 125 | swoft-log | [![Latest Stable Version](http://img.shields.io/packagist/v/swoft/log.svg)](https://packagist.org/packages/swoft/log) 126 | swoft-redis | [![Latest Stable Version](http://img.shields.io/packagist/v/swoft/redis.svg)](https://packagist.org/packages/swoft/redis) 127 | swoft-rpc-server | [![Latest Stable Version](http://img.shields.io/packagist/v/swoft/rpc-server.svg)](https://packagist.org/packages/swoft/rpc-server) 128 | swoft-task | [![Latest Stable Version](http://img.shields.io/packagist/v/swoft/task.svg)](https://packagist.org/packages/swoft/task) 129 | swoft-validator | [![Latest Stable Version](http://img.shields.io/packagist/v/swoft/validator.svg)](https://packagist.org/packages/swoft/validator) 130 | swoft-bean | [![Latest Stable Version](http://img.shields.io/packagist/v/swoft/bean.svg)](https://packagist.org/packages/swoft/bean) 131 | swoft-console | [![Latest Stable Version](http://img.shields.io/packagist/v/swoft/console.svg)](https://packagist.org/packages/swoft/console) 132 | swoft-event | [![Latest Stable Version](http://img.shields.io/packagist/v/swoft/event.svg)](https://packagist.org/packages/swoft/event) 133 | swoft-http-server | [![Latest Stable Version](http://img.shields.io/packagist/v/swoft/http-server.svg)](https://packagist.org/packages/swoft/http-server) 134 | swoft-process | [![Latest Stable Version](http://img.shields.io/packagist/v/swoft/process.svg)](https://packagist.org/packages/swoft/process) 135 | swoft-rpc | [![Latest Stable Version](http://img.shields.io/packagist/v/swoft/rpc.svg)](https://packagist.org/packages/swoft/rpc) 136 | swoft-server | [![Latest Stable Version](http://img.shields.io/packagist/v/swoft/server.svg)](https://packagist.org/packages/swoft/server) 137 | swoft-tcp | [![Latest Stable Version](http://img.shields.io/packagist/v/swoft/tcp.svg)](https://packagist.org/packages/swoft/tcp) 138 | swoft-websocket-server | [![Latest Stable Version](http://img.shields.io/packagist/v/swoft/websocket-server.svg)](https://packagist.org/packages/swoft/websocket-server) 139 | 140 | ## 扩展组件 141 | 142 | Component Name | Packagist Version 143 | -----------------|--------------------- 144 | swoft-apollo | [![Latest Stable Version](http://img.shields.io/packagist/v/swoft/apollo.svg)](https://packagist.org/packages/swoft/apollo) 145 | swoft-breaker | [![Latest Stable Version](http://img.shields.io/packagist/v/swoft/breaker.svg)](https://packagist.org/packages/swoft/breaker) 146 | swoft-cache | [![Latest Stable Version](http://img.shields.io/packagist/v/swoft/cache.svg)](https://packagist.org/packages/swoft/cache) 147 | swoft-crontab | [![Latest Stable Version](http://img.shields.io/packagist/v/swoft/crontab.svg)](https://packagist.org/packages/swoft/crontab) 148 | swoft-consul | [![Latest Stable Version](http://img.shields.io/packagist/v/swoft/consul.svg)](https://packagist.org/packages/swoft/consul) 149 | swoft-limiter | [![Latest Stable Version](http://img.shields.io/packagist/v/swoft/limiter.svg)](https://packagist.org/packages/swoft/limiter) 150 | swoft-view | [![Latest Stable Version](http://img.shields.io/packagist/v/swoft/view.svg)](https://packagist.org/packages/swoft/view) 151 | swoft-whoops | [![Latest Stable Version](http://img.shields.io/packagist/v/swoft/whoops.svg)](https://packagist.org/packages/swoft/whoops) 152 | swoft-session | [![Latest Stable Version](http://img.shields.io/packagist/v/swoft/session.svg)](https://packagist.org/packages/swoft/session) 153 | 154 | ## License 155 | 156 | Swoft is an open-source software licensed under the [LICENSE](LICENSE) 157 | -------------------------------------------------------------------------------- /app/Annotation/Mapping/AlphaDash.php: -------------------------------------------------------------------------------- 1 | message = $values['value']; 47 | } 48 | if (isset($values['message'])) { 49 | $this->message = $values['message']; 50 | } 51 | if (isset($values['name'])) { 52 | $this->name = $values['name']; 53 | } 54 | } 55 | 56 | /** 57 | * @return string 58 | */ 59 | public function getMessage(): string 60 | { 61 | return $this->message; 62 | } 63 | 64 | /** 65 | * @return string 66 | */ 67 | public function getName(): string 68 | { 69 | return $this->name; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /app/Annotation/Parser/AlphaDashParser.php: -------------------------------------------------------------------------------- 1 | className, $this->propertyName, $annotationObject); 41 | return []; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/Application.php: -------------------------------------------------------------------------------- 1 | temp); 41 | } 42 | 43 | /** 44 | * @After() 45 | */ 46 | public function afterRun(): void 47 | { 48 | $id = (string)Co::tid(); 49 | /** @var RequestBean $rb */ 50 | $rb = BF::getRequestBean('requestBean', $id); 51 | 52 | vdump(__METHOD__, $rb->temp); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /app/AutoLoader.php: -------------------------------------------------------------------------------- 1 | __DIR__, 29 | ]; 30 | } 31 | 32 | /** 33 | * @return array 34 | */ 35 | protected function metadata(): array 36 | { 37 | return []; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/Common/DbSelector.php: -------------------------------------------------------------------------------- 1 | getRequest()->query('id', 0); 32 | $createDbName = $connection->getDb(); 33 | 34 | if ($selectIndex == 0) { 35 | $selectIndex = ''; 36 | } 37 | 38 | if ($createDbName == 'test2') { 39 | $createDbName = 'test'; 40 | } 41 | 42 | $dbName = sprintf('%s%s', $createDbName, (string)$selectIndex); 43 | $connection->db($dbName); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/Common/MyBean.php: -------------------------------------------------------------------------------- 1 | agent->services(); 54 | 55 | $services = [ 56 | 57 | ]; 58 | 59 | return $services; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /app/Console/Command/AgentCommand.php: -------------------------------------------------------------------------------- 1 | config->listen($namespaces, [$this, 'updateConfigFile']); 51 | } catch (Throwable $e) { 52 | CLog::error('Config agent fail(%s %s %d)!', $e->getMessage(), $e->getFile(), $e->getLine()); 53 | } 54 | } 55 | } 56 | 57 | /** 58 | * @param array $data 59 | * 60 | * @throws SwoftException 61 | */ 62 | public function updateConfigFile(array $data): void 63 | { 64 | foreach ($data as $namespace => $namespaceData) { 65 | $configFile = sprintf('@config/%s.php', $namespace); 66 | 67 | $configKVs = $namespaceData['configurations'] ?? ''; 68 | $content = 'restart(); 76 | 77 | // /** @var ServiceServer $server */ 78 | // $server = bean('rpcServer'); 79 | // $server->restart(); 80 | 81 | /** @var WebSocketServer $server */ 82 | $server = bean('wsServer'); 83 | $server->restart(); 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /app/Console/Command/DemoCommand.php: -------------------------------------------------------------------------------- 1 | $input->getArgs(), 34 | 'opts' => $input->getOptions(), 35 | ]); 36 | } 37 | 38 | /** 39 | * @CommandMapping("err") 40 | * @throws ConsoleErrorException 41 | */ 42 | public function coError(): void 43 | { 44 | ConsoleErrorException::throw('this is an error message'); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /app/Console/Command/TestCommand.php: -------------------------------------------------------------------------------- 1 | get('type', ''); 37 | $uris = $this->uris(); 38 | 39 | // Format data 40 | if (empty($type)) { 41 | $exeUris = []; 42 | foreach ($uris as $name => $uriAry) { 43 | /** @noinspection SlowArrayOperationsInLoopInspection */ 44 | $exeUris = array_merge($exeUris, $uriAry); 45 | } 46 | } else { 47 | $exeUris = $uris[$type] ?? []; 48 | } 49 | 50 | foreach ($exeUris as $uri) { 51 | $curlResult = null; 52 | $abShell = sprintf('ab -k -n 10000 -c 500 127.0.0.1:18306%s', $uri); 53 | $curlShell = sprintf('curl 127.0.0.1:18306%s', $uri); 54 | 55 | exec($curlShell, $curlResult); 56 | output()->writeln('执行结果:' . json_encode($curlResult)); 57 | output()->writeln('执行URL:' . $abShell . PHP_EOL); 58 | 59 | exec($abShell, $abResult); 60 | 61 | sleep(1); 62 | } 63 | } 64 | 65 | /** 66 | * @return array 67 | */ 68 | private function uris(): array 69 | { 70 | return [ 71 | 'redis' => [ 72 | '/redis/str', 73 | '/redis/et', 74 | '/redis/ep', 75 | '/redis/release', 76 | '/redis/poolSet', 77 | '/redis/set', 78 | ], 79 | 'log' => [ 80 | '/log/test' 81 | ], 82 | 'db' => [ 83 | '/dbTransaction/ts', 84 | '/dbTransaction/cm', 85 | '/dbTransaction/rl', 86 | '/dbTransaction/ts2', 87 | '/dbTransaction/cm2', 88 | '/dbTransaction/rl2', 89 | '/dbTransaction/multiPool', 90 | '/dbModel/find', 91 | '/dbModel/update', 92 | '/dbModel/delete', 93 | '/dbModel/save', 94 | '/dbModel/batchUpdate', 95 | '/dbModel/propWhere', 96 | '/selectDb/modelNotExistDb', 97 | '/selectDb/queryNotExistDb', 98 | '/selectDb/dbNotExistDb', 99 | '/selectDb/modelDb', 100 | '/selectDb/queryDb', 101 | '/selectDb/dbDb', 102 | '/selectDb/select', 103 | '/builder/schema', 104 | ], 105 | 'task' => [ 106 | '/task/getListByCo', 107 | '/task/deleteByCo', 108 | '/task/getListByAsync', 109 | '/task/deleteByAsync', 110 | '/task/returnNull', 111 | '/task/returnVoid', 112 | ], 113 | 'rpc' => [ 114 | '/rpc/getList', 115 | '/rpc/returnBool', 116 | '/rpc/bigString', 117 | '/rpc/sendBigString', 118 | '/rpc/returnNull' 119 | ], 120 | 'co' => [ 121 | '/co/multi' 122 | ], 123 | 'bean' => [ 124 | '/bean/request', 125 | '/bean/requestClass' 126 | ], 127 | 'breaker' => [ 128 | '/breaker/unbreak', 129 | '/breaker/breaked', 130 | '/breaker/loopBreaker' 131 | ], 132 | 'limiter' => [ 133 | '/limiter/requestLimiter', 134 | '/limiter/requestLimiter2', 135 | '/limiter/paramLimiter?id=12', 136 | ] 137 | ]; 138 | } 139 | 140 | /** 141 | * Mock request some api for test server 142 | * 143 | * @CommandMapping("ca") 144 | */ 145 | public function checkAccess(): void 146 | { 147 | \bean('httpRouter')->each(function (Route $route) { 148 | $path = $route->getPath(); 149 | 150 | // Skip some routes 151 | if ($route->getMethod() !== 'GET' || false !== \strpos($path, '{')) { 152 | return; 153 | } 154 | 155 | $command = sprintf('curl -I 127.0.0.1:18306%s', $path); 156 | Show::colored('> ' . $command); 157 | \exec($command); 158 | }); 159 | } 160 | 161 | /** 162 | * @CommandMapping("err") 163 | * @throws ConsoleErrorException 164 | */ 165 | public function error(): void 166 | { 167 | ConsoleErrorException::throw('this is an error message'); 168 | } 169 | } 170 | -------------------------------------------------------------------------------- /app/Exception/ApiException.php: -------------------------------------------------------------------------------- 1 | $except->getCode(), 38 | 'error' => sprintf('(%s) %s', get_class($except), $except->getMessage()), 39 | 'file' => sprintf('At %s line %d', $except->getFile(), $except->getLine()), 40 | 'trace' => $except->getTraceAsString(), 41 | ]; 42 | 43 | return $response->withData($data); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/Exception/Handler/HttpExceptionHandler.php: -------------------------------------------------------------------------------- 1 | getMessage()); 40 | CLog::error('%s. (At %s line %d)', $e->getMessage(), $e->getFile(), $e->getLine()); 41 | 42 | // Debug is false 43 | if (!APP_DEBUG) { 44 | return $response->withStatus(500)->withContent($e->getMessage()); 45 | } 46 | 47 | $data = [ 48 | 'code' => $e->getCode(), 49 | 'error' => sprintf('(%s) %s', get_class($e), $e->getMessage()), 50 | 'file' => sprintf('At %s line %d', $e->getFile(), $e->getLine()), 51 | 'trace' => $e->getTraceAsString(), 52 | ]; 53 | 54 | // Debug is true 55 | return $response->withData($data); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /app/Exception/Handler/RpcExceptionHandler.php: -------------------------------------------------------------------------------- 1 | getCode(), $e->getMessage(), null); 41 | } else { 42 | $message = sprintf(' %s At %s line %d', $e->getMessage(), $e->getFile(), $e->getLine()); 43 | $error = Error::new($e->getCode(), $message, null); 44 | } 45 | 46 | Debug::log('Rpc server error(%s)', $e->getMessage()); 47 | 48 | $response->setError($error); 49 | 50 | // Debug is true 51 | return $response; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /app/Exception/Handler/WsHandshakeExceptionHandler.php: -------------------------------------------------------------------------------- 1 | withStatus(500)->withContent(sprintf( 39 | '%s At %s line %d', 40 | $e->getMessage(), 41 | $e->getFile(), 42 | $e->getLine() 43 | )); 44 | } 45 | 46 | $data = [ 47 | 'code' => $e->getCode(), 48 | 'error' => sprintf('(%s) %s', get_class($e), $e->getMessage()), 49 | 'file' => sprintf('At %s line %d', $e->getFile(), $e->getLine()), 50 | 'trace' => $e->getTraceAsString(), 51 | ]; 52 | 53 | // Debug is true 54 | return $response->withData($data); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /app/Exception/Handler/WsMessageExceptionHandler.php: -------------------------------------------------------------------------------- 1 | getMessage(), $e->getFile(), $e->getLine()); 37 | 38 | Log::error('Ws server error(%s)', $message); 39 | 40 | // Debug is false 41 | if (!APP_DEBUG) { 42 | server()->push($frame->fd, $e->getMessage()); 43 | return; 44 | } 45 | 46 | server()->push($frame->fd, $message); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /app/Helper/Functions.php: -------------------------------------------------------------------------------- 1 | myMethod()]; 40 | } 41 | 42 | /** 43 | * @RequestMapping("req") 44 | * 45 | * @return array 46 | */ 47 | public function request(): array 48 | { 49 | $id = (string)Co::tid(); 50 | 51 | /** @var RequestBean $request */ 52 | $request = BeanFactory::getRequestBean('requestBean', $id); 53 | 54 | $request->temp = ['rid' => $id]; 55 | 56 | return $request->getData(); 57 | } 58 | 59 | /** 60 | * @return array 61 | * 62 | * @RequestMapping("req2") 63 | */ 64 | public function requestTwo(): array 65 | { 66 | $id = (string)Co::tid(); 67 | 68 | /* @var RequestBeanTwo $request */ 69 | $request = BeanFactory::getRequestBean(RequestBeanTwo::class, $id); 70 | return $request->getData(); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /app/Http/Controller/BreakerController.php: -------------------------------------------------------------------------------- 1 | logic->func(); 44 | } 45 | 46 | /** 47 | * @RequestMapping() 48 | * 49 | * @return array 50 | * @throws Exception 51 | */ 52 | public function unbreak(): array 53 | { 54 | return [$this->logic->func2()]; 55 | } 56 | 57 | /** 58 | * @RequestMapping() 59 | * 60 | * @return string 61 | * @throws Exception 62 | */ 63 | public function loopBraker(): string 64 | { 65 | return $this->logic->loop(); 66 | } 67 | 68 | /** 69 | * @RequestMapping() 70 | * 71 | * @return string 72 | * @throws Exception 73 | */ 74 | public function unFallback(): string 75 | { 76 | return $this->logic->unFallback(); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /app/Http/Controller/CacheController.php: -------------------------------------------------------------------------------- 1 | $ok, 'ckey1' => $ok1]; 39 | } 40 | 41 | /** 42 | * @RequestMapping() 43 | * 44 | * @return array 45 | * @throws InvalidArgumentException 46 | */ 47 | public function get(): array 48 | { 49 | $val = Cache::get('ckey'); 50 | 51 | return [ 52 | 'ckey' => $val, 53 | 'ckey1' => Cache::get('ckey1') 54 | ]; 55 | } 56 | 57 | /** 58 | * @RequestMapping("del") 59 | * 60 | * @return array 61 | * @throws InvalidArgumentException 62 | */ 63 | public function del(): array 64 | { 65 | return ['del' => Cache::delete('ckey')]; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /app/Http/Controller/CoController.php: -------------------------------------------------------------------------------- 1 | [$this, 'addUser'], 43 | 'getUser' => "App\Http\Controller\CoController::getUser", 44 | 'curl' => function () { 45 | $cli = new Client('127.0.0.1', 18306); 46 | $cli->get('/redis/str'); 47 | $result = $cli->body; 48 | $cli->close(); 49 | 50 | return $result; 51 | } 52 | ]; 53 | 54 | return Co::multi($requests); 55 | } 56 | 57 | /** 58 | * @return array 59 | */ 60 | public static function getUser(): array 61 | { 62 | $result = Redis::set('key', 'value'); 63 | 64 | return [$result, Redis::get('key')]; 65 | } 66 | 67 | /** 68 | * @return array 69 | * @throws Throwable 70 | */ 71 | public function addUser(): array 72 | { 73 | $user = User::new(); 74 | $user->setAge(random_int(1, 100)); 75 | $user->setUserDesc('desc'); 76 | 77 | // Save result 78 | $result = $user->save(); 79 | 80 | return [$result, $user->getId()]; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /app/Http/Controller/CookieController.php: -------------------------------------------------------------------------------- 1 | getResponse(); 36 | 37 | return $resp->setCookie('c-name', 'c-value')->withData(['hello']); 38 | } 39 | 40 | /** 41 | * @RequestMapping() 42 | * 43 | * @param Request $request 44 | * 45 | * @return array 46 | */ 47 | public function get(Request $request): array 48 | { 49 | return $request->getCookieParams(); 50 | } 51 | 52 | /** 53 | * @RequestMapping("del") 54 | * 55 | * @return Response 56 | */ 57 | public function del(): Response 58 | { 59 | /** @var Response $resp */ 60 | $resp = context()->getResponse(); 61 | 62 | return $resp->delCookie('c-name')->withData(['ok']); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /app/Http/Controller/DbBuilderController.php: -------------------------------------------------------------------------------- 1 | increments('id'); 36 | }); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/Http/Controller/DbModelController.php: -------------------------------------------------------------------------------- 1 | getId(); 43 | $user = User::find($id); 44 | 45 | return $response->withData($user); 46 | } 47 | 48 | /** 49 | * @RequestMapping(route="save") 50 | * 51 | * @return array 52 | * 53 | * @throws Exception 54 | */ 55 | public function save(): array 56 | { 57 | $user = new User(); 58 | $user->setAge(random_int(1, 100)); 59 | $user->setUserDesc('desc'); 60 | 61 | $user->save(); 62 | 63 | $count = Count::new(); 64 | $count->setUserId($user->getId()); 65 | $count->save(); 66 | 67 | return $user->toArray(); 68 | } 69 | 70 | /** 71 | * @RequestMapping(route="update") 72 | * 73 | * @return array 74 | * 75 | * @throws Throwable 76 | */ 77 | public function update(): array 78 | { 79 | $id = $this->getId(); 80 | 81 | User::updateOrInsert(['id' => $id], ['name' => 'swoft', 'userDesc' => 'swoft']); 82 | 83 | $user = User::find($id); 84 | 85 | return $user->toArray(); 86 | } 87 | 88 | /** 89 | * @RequestMapping(route="delete") 90 | * 91 | * @return array 92 | * 93 | * @throws Throwable 94 | */ 95 | public function delete(): array 96 | { 97 | $id = $this->getId(); 98 | $result = User::find($id)->delete(); 99 | 100 | return [$result]; 101 | } 102 | 103 | /** 104 | * @return int 105 | * @throws Throwable 106 | */ 107 | public function getId(): int 108 | { 109 | $user = new User(); 110 | $user->setAge(random_int(1, 100)); 111 | $user->setUserDesc('desc'); 112 | 113 | $user->save(); 114 | 115 | return $user->getId(); 116 | } 117 | 118 | /** 119 | * @RequestMapping() 120 | * 121 | * @return array 122 | * @throws Throwable 123 | */ 124 | public function batchUpdate(): array 125 | { 126 | // User::truncate(); 127 | User::updateOrCreate(['id' => 1], ['age' => 23]); 128 | User::updateOrCreate(['id' => 2], ['age' => 23]); 129 | 130 | $values = [ 131 | ['id' => 1, 'age' => 18], 132 | ['id' => 2, 'age' => 19], 133 | ]; 134 | $values = array_column($values, null, 'id'); 135 | 136 | User::batchUpdateByIds($values); 137 | 138 | $users = User::find(array_column($values, 'id')); 139 | 140 | $updateResults = []; 141 | /** @var User $user */ 142 | foreach ($users as $user) { 143 | $updateResults[$user->getId()] = true; 144 | if ($user->getAge() != $values[$user->getId()]['age']) { 145 | $updateResults[$user->getId()] = false; 146 | } 147 | } 148 | 149 | 150 | return $updateResults; 151 | } 152 | 153 | /** 154 | * @RequestMapping() 155 | * 156 | * @return array 157 | * @throws Throwable 158 | */ 159 | public function propWhere(): array 160 | { 161 | User::updateOrInsert(['id' => 1000], ['userDesc' => 'swoft']); 162 | 163 | /** @var User|null $user */ 164 | $user = User::whereProp(['userDesc' => 'swoft'])->first(); 165 | 166 | return $user ? $user->toArray() : []; 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /app/Http/Controller/DbTransactionController.php: -------------------------------------------------------------------------------- 1 | getId(); 41 | 42 | DB::beginTransaction(); 43 | $user = User::find($id); 44 | 45 | sgo(function () use ($id) { 46 | DB::beginTransaction(); 47 | User::find($id); 48 | }); 49 | 50 | return json_encode($user->toArray()); 51 | } 52 | 53 | /** 54 | * @RequestMapping(route="cm") 55 | * 56 | * @return false|string 57 | * @throws Throwable 58 | */ 59 | public function cm() 60 | { 61 | $id = $this->getId(); 62 | 63 | DB::beginTransaction(); 64 | $user = User::find($id); 65 | DB::commit(); 66 | 67 | sgo(function () use ($id) { 68 | DB::beginTransaction(); 69 | User::find($id); 70 | DB::commit(); 71 | }); 72 | 73 | return json_encode($user->toArray()); 74 | } 75 | 76 | /** 77 | * @RequestMapping(route="rl") 78 | * 79 | * @return false|string 80 | * @throws Throwable 81 | */ 82 | public function rl() 83 | { 84 | $id = $this->getId(); 85 | 86 | DB::beginTransaction(); 87 | $user = User::find($id); 88 | DB::rollBack(); 89 | 90 | sgo(function () use ($id) { 91 | DB::beginTransaction(); 92 | User::find($id); 93 | DB::rollBack(); 94 | }); 95 | 96 | return json_encode($user->toArray()); 97 | } 98 | 99 | /** 100 | * @RequestMapping(route="ts2") 101 | * 102 | * @return false|string 103 | * @throws Throwable 104 | */ 105 | public function ts2() 106 | { 107 | $id = $this->getId(); 108 | 109 | DB::connection()->beginTransaction(); 110 | $user = User::find($id); 111 | 112 | sgo(function () use ($id) { 113 | DB::connection()->beginTransaction(); 114 | User::find($id); 115 | }); 116 | 117 | return json_encode($user->toArray()); 118 | } 119 | 120 | /** 121 | * @RequestMapping(route="cm2") 122 | * 123 | * @return false|string 124 | * @throws Throwable 125 | */ 126 | public function cm2() 127 | { 128 | $id = $this->getId(); 129 | 130 | DB::connection()->beginTransaction(); 131 | $user = User::find($id); 132 | DB::connection()->commit(); 133 | 134 | sgo(function () use ($id) { 135 | DB::connection()->beginTransaction(); 136 | User::find($id); 137 | DB::connection()->commit(); 138 | }); 139 | 140 | return json_encode($user->toArray()); 141 | } 142 | 143 | /** 144 | * @RequestMapping(route="rl2") 145 | * 146 | * @return false|string 147 | * @throws Throwable 148 | */ 149 | public function rl2() 150 | { 151 | $id = $this->getId(); 152 | 153 | DB::connection()->beginTransaction(); 154 | $user = User::find($id); 155 | DB::connection()->rollBack(); 156 | 157 | sgo(function () use ($id) { 158 | DB::connection()->beginTransaction(); 159 | User::find($id); 160 | DB::connection()->rollBack(); 161 | }); 162 | 163 | return json_encode($user->toArray()); 164 | } 165 | 166 | /** 167 | * @RequestMapping() 168 | * @return array 169 | * @throws DbException 170 | * @throws Throwable 171 | */ 172 | public function multiPool() 173 | { 174 | DB::beginTransaction(); 175 | 176 | // db3.pool 177 | $user = new User3(); 178 | $user->setAge(random_int(1, 100)); 179 | $user->setUserDesc('desc'); 180 | 181 | $user->save(); 182 | $uid3 = $user->getId(); 183 | 184 | 185 | //db.pool 186 | $uid = $this->getId(); 187 | 188 | $count = new Count(); 189 | $count->setUserId(random_int(1, 100)); 190 | $count->setAttributes('attr'); 191 | $count->setCreateTime(time()); 192 | 193 | $count->save(); 194 | $cid = $count->getId(); 195 | 196 | DB::rollBack(); 197 | 198 | $u3 = User3::find($uid3)->toArray(); 199 | $u = User::find($uid); 200 | $c = Count::find($cid); 201 | 202 | return [$u3, $u, $c]; 203 | } 204 | 205 | /** 206 | * @return int 207 | * @throws Throwable 208 | */ 209 | public function getId(): int 210 | { 211 | $user = new User(); 212 | $user->setAge(random_int(1, 100)); 213 | $user->setUserDesc('desc'); 214 | 215 | $user->save(); 216 | 217 | return $user->getId(); 218 | } 219 | } 220 | -------------------------------------------------------------------------------- /app/Http/Controller/ExceptionController.php: -------------------------------------------------------------------------------- 1 | render('home/index'); 39 | 40 | return context()->getResponse()->withContentType(ContentType::HTML)->withContent($content); 41 | } 42 | 43 | /** 44 | * @RequestMapping("/hi") 45 | * 46 | * @return Response 47 | */ 48 | public function hi(): Response 49 | { 50 | return context()->getResponse()->withContent('hi'); 51 | } 52 | 53 | /** 54 | * @RequestMapping("/hello[/{name}]") 55 | * @param string $name 56 | * 57 | * @return Response 58 | */ 59 | public function hello(string $name): Response 60 | { 61 | return context()->getResponse()->withContent('Hello' . ($name === '' ? '' : ", {$name}")); 62 | } 63 | 64 | /** 65 | * @RequestMapping("/wstest", method={"GET"}) 66 | * 67 | * @return Response 68 | * @throws Throwable 69 | */ 70 | public function wsTest(): Response 71 | { 72 | return view('home/ws-test'); 73 | } 74 | 75 | /** 76 | * @RequestMapping("/dataConfig", method={"GET"}) 77 | * 78 | * @return array 79 | * @throws Throwable 80 | */ 81 | public function dataConfig(): array 82 | { 83 | return bean(GoodsData::class)->getConfig(); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /app/Http/Controller/LimiterController.php: -------------------------------------------------------------------------------- 1 | getUriPath(); 38 | return ['requestLimiter', $uri]; 39 | } 40 | 41 | /** 42 | * @RequestMapping() 43 | * @RateLimiter(rate=20, fallback="limiterFallback") 44 | * 45 | * @param Request $request 46 | * 47 | * @return array 48 | */ 49 | public function requestLimiter2(Request $request): array 50 | { 51 | $uri = $request->getUriPath(); 52 | return ['requestLimiter2', $uri]; 53 | } 54 | 55 | /** 56 | * @RequestMapping() 57 | * @RateLimiter(key="request.getUriPath()~':'~request.query('id')") 58 | * 59 | * @param Request $request 60 | * 61 | * @return array 62 | */ 63 | public function paramLimiter(Request $request): array 64 | { 65 | $id = $request->query('id'); 66 | return ['paramLimiter', $id]; 67 | } 68 | 69 | /** 70 | * @param Request $request 71 | * 72 | * @return array 73 | */ 74 | public function limiterFallback(Request $request): array 75 | { 76 | $uri = $request->getUriPath(); 77 | return ['limiterFallback', $uri]; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /app/Http/Controller/LogController.php: -------------------------------------------------------------------------------- 1 | getSwooleProcess()->exportSocket()); 37 | 38 | return 'hello'; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /app/Http/Controller/RedisController.php: -------------------------------------------------------------------------------- 1 | redis->set($key, $value); 46 | 47 | $get = $this->redis->get($key); 48 | 49 | return [$get, $value]; 50 | } 51 | 52 | /** 53 | * @RequestMapping() 54 | */ 55 | public function set(): array 56 | { 57 | $key = 'key1'; 58 | 59 | $data = [ 60 | 'add' => 11.1, 61 | 'score2' => 11.1, 62 | 'score3' => 11.21 63 | ]; 64 | $this->redis->zAdd($key, $data); 65 | 66 | $res = Redis::zRangeByScore($key, '11.1', '11.21', ['withscores' => true]); 67 | 68 | return [$res, $res === $data]; 69 | } 70 | 71 | /** 72 | * @RequestMapping("str") 73 | */ 74 | public function str(): array 75 | { 76 | $key = 'key'; 77 | $result = Redis::set($key, 'key'); 78 | 79 | $keyVal = Redis::get($key); 80 | 81 | $isError = Redis::call(function (\Redis $redis) { 82 | $redis->eval('return 1'); 83 | 84 | return $redis->getLastError(); 85 | }); 86 | 87 | $data = [ 88 | $result, 89 | $keyVal, 90 | $isError 91 | ]; 92 | 93 | return $data; 94 | } 95 | 96 | /** 97 | * Only to use test. The wrong way to use it 98 | * 99 | * @RequestMapping("release") 100 | * 101 | * @return array 102 | * @throws RedisException 103 | */ 104 | public function release(): array 105 | { 106 | sgo(function () { 107 | Redis::connection(); 108 | }); 109 | 110 | Redis::connection(); 111 | 112 | return ['release']; 113 | } 114 | 115 | /** 116 | * Only to use test. The wrong way to use it 117 | * 118 | * @RequestMapping("ep") 119 | * 120 | * @return array 121 | */ 122 | public function exPipeline(): array 123 | { 124 | sgo(function () { 125 | Redis::pipeline(function () { 126 | throw new RuntimeException(''); 127 | }); 128 | }); 129 | 130 | Redis::pipeline(function () { 131 | throw new RuntimeException(''); 132 | }); 133 | 134 | return ['exPipeline']; 135 | } 136 | 137 | /** 138 | * Only to use test. The wrong way to use it 139 | * 140 | * @RequestMapping("et") 141 | * 142 | * @return array 143 | */ 144 | public function exTransaction(): array 145 | { 146 | sgo(function () { 147 | Redis::transaction(function () { 148 | throw new RuntimeException(''); 149 | }); 150 | }); 151 | 152 | Redis::transaction(function () { 153 | throw new RuntimeException(''); 154 | }); 155 | 156 | return ['exPipeline']; 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /app/Http/Controller/RespController.php: -------------------------------------------------------------------------------- 1 | userService->getList(12, 'type'); 51 | $result2 = $this->userService2->getList(12, 'type'); 52 | 53 | return [$result, $result2]; 54 | } 55 | 56 | /** 57 | * @RequestMapping("returnBool") 58 | * 59 | * @return array 60 | */ 61 | public function returnBool(): array 62 | { 63 | $result = $this->userService->delete(12); 64 | 65 | if (is_bool($result)) { 66 | return ['bool']; 67 | } 68 | 69 | return ['notBool']; 70 | } 71 | 72 | /** 73 | * @RequestMapping() 74 | * 75 | * @return array 76 | */ 77 | public function bigString(): array 78 | { 79 | $string = $this->userService->getBigContent(); 80 | 81 | return ['string', strlen($string)]; 82 | } 83 | 84 | /** 85 | * @RequestMapping() 86 | * 87 | * @return array 88 | */ 89 | public function sendBigString(): array 90 | { 91 | $content = Co::readFile(__DIR__ . '/../../Rpc/Service/big.data'); 92 | 93 | $len = strlen($content); 94 | $result = $this->userService->sendBigContent($content); 95 | return [$len, $result]; 96 | } 97 | 98 | /** 99 | * @RequestMapping() 100 | * 101 | * @return array 102 | */ 103 | public function returnNull(): array 104 | { 105 | $this->userService->returnNull(); 106 | return [null]; 107 | } 108 | 109 | /** 110 | * @RequestMapping() 111 | * 112 | * @return array 113 | * 114 | * @throws Exception 115 | */ 116 | public function exception(): array 117 | { 118 | $this->userService->exception(); 119 | 120 | return ['exception']; 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /app/Http/Controller/SelectDbController.php: -------------------------------------------------------------------------------- 1 | getId(); 41 | 42 | $user = User::find($id)->toArray(); 43 | 44 | sgo(function () { 45 | $id = $this->getId(); 46 | 47 | User::find($id)->toArray(); 48 | 49 | User::db('test_error'); 50 | User::db('test_error')->find($id); 51 | }); 52 | 53 | User::db('test_error'); 54 | User::db('test_error')->find($id); 55 | 56 | return $user; 57 | } 58 | 59 | /** 60 | * @RequestMapping() 61 | * 62 | * @return array 63 | * @throws Throwable 64 | */ 65 | public function modelDb(): array 66 | { 67 | $id = $this->getId(); 68 | $user = User::find($id)->toArray(); 69 | 70 | $this->insertId2(); 71 | $result = User::db('test2')->count('id'); 72 | 73 | $desc = $this->desc(); 74 | sgo(function () { 75 | $id = $this->getId(); 76 | User::find($id)->toArray(); 77 | 78 | $this->insertId2(); 79 | User::db('test2')->count('id'); 80 | 81 | $this->desc(); 82 | }); 83 | 84 | return [$user, $result, $desc]; 85 | } 86 | 87 | /** 88 | * @RequestMapping() 89 | * 90 | * @return array 91 | * @throws Throwable 92 | */ 93 | public function queryNotExistDb(): array 94 | { 95 | $id = $this->getId(); 96 | 97 | $user = User::find($id)->toArray(); 98 | 99 | DB::table('user')->db('test_error'); 100 | DB::table('user')->db('test_error')->where('id', '=', $id)->get(); 101 | 102 | sgo(function () { 103 | $id = $this->getId(); 104 | 105 | User::find($id)->toArray(); 106 | 107 | DB::table('user')->db('test_error'); 108 | DB::table('user')->db('test_error')->where('id', '=', $id)->get(); 109 | }); 110 | 111 | return $user; 112 | } 113 | 114 | /** 115 | * @RequestMapping() 116 | * 117 | * @return array 118 | * @throws Throwable 119 | */ 120 | public function queryDb(): array 121 | { 122 | $id = $this->getId(); 123 | 124 | $user = User::find($id)->toArray(); 125 | 126 | $this->insertId2(); 127 | 128 | $count = DB::table('user')->db('test2')->count(); 129 | 130 | $desc = $this->desc(); 131 | sgo(function () { 132 | $id = $this->getId(); 133 | 134 | User::find($id)->toArray(); 135 | 136 | $this->insertId2(); 137 | 138 | DB::table('user')->db('test2')->count(); 139 | 140 | $this->desc(); 141 | }); 142 | 143 | return [$user, $count, $desc]; 144 | } 145 | 146 | /** 147 | * @RequestMapping() 148 | * 149 | * @return array 150 | * @throws Throwable 151 | */ 152 | public function dbNotExistDb(): array 153 | { 154 | $id = $this->getId(); 155 | 156 | $user = User::find($id)->toArray(); 157 | 158 | sgo(function () { 159 | $id = $this->getId(); 160 | 161 | User::find($id)->toArray(); 162 | 163 | DB::db('test_error'); 164 | }); 165 | 166 | DB::db('test_error'); 167 | 168 | return $user; 169 | } 170 | 171 | /** 172 | * @RequestMapping() 173 | * 174 | * @return array 175 | * @throws Throwable 176 | */ 177 | public function dbDb(): array 178 | { 179 | $id = $this->getId(); 180 | $user = User::find($id)->toArray(); 181 | 182 | $result = DB::db('test2')->selectOne('select * from user limit 1'); 183 | 184 | $desc = $this->desc(); 185 | 186 | sgo(function () { 187 | $id = $this->getId(); 188 | User::find($id)->toArray(); 189 | 190 | DB::db('test2')->selectOne('select * from user limit 1'); 191 | 192 | $this->desc(); 193 | }); 194 | 195 | return [$user, $result, $desc]; 196 | } 197 | 198 | /** 199 | * @RequestMapping() 200 | * 201 | * @return array 202 | * @throws Exception 203 | */ 204 | public function select(): array 205 | { 206 | $count = new Count2(); 207 | $count->setUserId(mt_rand(1, 100)); 208 | $count->setAttributes('attr'); 209 | $count->setCreateTime(time()); 210 | 211 | $result = $count->save(); 212 | 213 | return [$result, $count->getId()]; 214 | } 215 | 216 | /** 217 | * @return bool 218 | * @throws DbException 219 | */ 220 | public function insertId2(): bool 221 | { 222 | $result = User::db('test2')->insert([ 223 | [ 224 | 'name' => uniqid(), 225 | 'password' => md5(uniqid()), 226 | 'age' => random_int(1, 100), 227 | 'user_desc' => 'u desc', 228 | 'foo' => 'bar' 229 | ] 230 | ]); 231 | 232 | return $result; 233 | } 234 | 235 | /** 236 | * @throws DbException 237 | */ 238 | public function desc(): array 239 | { 240 | $desc = new Desc(); 241 | $desc->setDesc('desc'); 242 | $desc->save(); 243 | 244 | return Desc::find($desc->getId())->toArray(); 245 | } 246 | 247 | /** 248 | * @return int 249 | * @throws Throwable 250 | */ 251 | public function getId(): int 252 | { 253 | $user = new User(); 254 | $user->setAge(mt_rand(1, 100)); 255 | $user->setUserDesc('desc'); 256 | 257 | $user->save(); 258 | 259 | return $user->getId(); 260 | } 261 | } 262 | -------------------------------------------------------------------------------- /app/Http/Controller/SessionController.php: -------------------------------------------------------------------------------- 1 | get('times', 0); 35 | $times++; 36 | 37 | $sess->set('times', $times); 38 | 39 | return $response->withData([ 40 | 'times' => $times, 41 | 'sessId' => $sess->getSessionId() 42 | ]); 43 | } 44 | 45 | /** 46 | * @RequestMapping("all") 47 | * 48 | * @return array 49 | */ 50 | public function all(): array 51 | { 52 | $sess = HttpSession::current(); 53 | 54 | return $sess->toArray(); 55 | } 56 | 57 | /** 58 | * @RequestMapping() 59 | * @param Response $response 60 | * 61 | * @return Response 62 | */ 63 | public function set(Response $response): Response 64 | { 65 | $sess = HttpSession::current(); 66 | $sess->set('testKey', 'test-value'); 67 | $sess->set('testKey1', ['k' => 'v', 'v1', 3]); 68 | 69 | return $response->withData(['testKey', 'testKey1']); 70 | } 71 | 72 | /** 73 | * @RequestMapping() 74 | * 75 | * @return array 76 | */ 77 | public function get(): array 78 | { 79 | $sess = HttpSession::current(); 80 | 81 | return ['get.testKey' => $sess->get('testKey')]; 82 | } 83 | 84 | /** 85 | * @RequestMapping("del") 86 | * 87 | * @return array 88 | */ 89 | public function del(): array 90 | { 91 | $sess = HttpSession::current(); 92 | $ok = $sess->delete('testKey'); 93 | 94 | return ['delete' => $ok]; 95 | } 96 | 97 | /** 98 | * @RequestMapping() 99 | * @param Response $response 100 | * 101 | * @return Response 102 | */ 103 | public function close(Response $response): Response 104 | { 105 | $sess = HttpSession::current(); 106 | 107 | return $response->withData(['destroy' => $sess->destroy()]); 108 | } 109 | 110 | /** 111 | * @RequestMapping() 112 | * 113 | * @return string 114 | */ 115 | public function not(): string 116 | { 117 | return 'not-use'; 118 | } 119 | 120 | // ------------ flash session usage 121 | 122 | /** 123 | * @RequestMapping() 124 | * 125 | * @return array 126 | */ 127 | public function flash(): array 128 | { 129 | $sess = HttpSession::current(); 130 | $sess->setFlash('flash1', 'test-value'); 131 | 132 | return ['set.testKey' => 'test-value']; 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /app/Http/Controller/TaskController.php: -------------------------------------------------------------------------------- 1 | setAge(random_int(1, 100)); 43 | $user->setUserDesc('desc'); 44 | 45 | $user->save(); 46 | $id = $user->getId(); 47 | 48 | Redis::set("$id", $user->toArray()); 49 | Log::info('用户ID=' . $id . ' timerId=' . $timerId); 50 | sgo(function () use ($id) { 51 | $user = User::find($id)->toArray(); 52 | Log::info(JsonHelper::encode($user)); 53 | Redis::del("$id"); 54 | }); 55 | }); 56 | 57 | return ['after']; 58 | } 59 | 60 | /** 61 | * @RequestMapping() 62 | * 63 | * @return array 64 | * @throws Exception 65 | */ 66 | public function tick(): array 67 | { 68 | Timer::tick(3 * 1000, function (int $timerId) { 69 | $user = new User(); 70 | $user->setAge(random_int(1, 100)); 71 | $user->setUserDesc('desc'); 72 | 73 | $user->save(); 74 | $id = $user->getId(); 75 | 76 | Redis::set("$id", $user->toArray()); 77 | Log::info('用户ID=' . $id . ' timerId=' . $timerId); 78 | sgo(function () use ($id) { 79 | $user = User::find($id)->toArray(); 80 | Log::info(JsonHelper::encode($user)); 81 | Redis::del("$id"); 82 | }); 83 | }); 84 | 85 | return ['tick']; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /app/Http/Controller/ValidatorController.php: -------------------------------------------------------------------------------- 1 | getMethod(); 39 | if ($method == RequestMethod::GET) { 40 | return $request->getParsedQuery(); 41 | } 42 | return $request->getParsedBody(); 43 | } 44 | 45 | /** 46 | * Verify only the type field in the TestValidator validator 47 | * 48 | * @RequestMapping() 49 | * @Validate(validator="TestValidator", fields={"type"}) 50 | * 51 | * @param Request $request 52 | * 53 | * @return array 54 | */ 55 | public function validateType(Request $request): array 56 | { 57 | $method = $request->getMethod(); 58 | if ($method == RequestMethod::GET) { 59 | return $request->getParsedQuery(); 60 | } 61 | return $request->getParsedBody(); 62 | } 63 | 64 | /** 65 | * Verify only the password field in the TestValidator validator 66 | * 67 | * @RequestMapping() 68 | * @Validate(validator="TestValidator", fields={"password"}) 69 | * 70 | * @param Request $request 71 | * 72 | * @return array 73 | */ 74 | public function validatePassword(Request $request): array 75 | { 76 | $method = $request->getMethod(); 77 | if ($method == RequestMethod::GET) { 78 | return $request->getParsedQuery(); 79 | } 80 | return $request->getParsedBody(); 81 | } 82 | 83 | /** 84 | * Customize the validator with userValidator 85 | * 86 | * @RequestMapping() 87 | * 88 | * @Validate(validator="userValidator") 89 | * 90 | * @param Request $request 91 | * 92 | * @return array 93 | */ 94 | public function validateCustomer(Request $request): array 95 | { 96 | $method = $request->getMethod(); 97 | if ($method == RequestMethod::GET) { 98 | return $request->getParsedQuery(); 99 | } 100 | return $request->getParsedBody(); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /app/Http/Controller/ViewController.php: -------------------------------------------------------------------------------- 1 | withContent('

Swoft framework

'); 39 | $response = $response->withContentType(ContentType::HTML); 40 | return $response; 41 | } 42 | 43 | /** 44 | * Will render view by annotation tag View 45 | * 46 | * @RequestMapping("/home") 47 | * @View("home/index") 48 | * 49 | * @throws Throwable 50 | */ 51 | public function indexByViewTag(): array 52 | { 53 | return [ 54 | 'msg' => 'hello' 55 | ]; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /app/Http/Middleware/DomainLimitMiddleware.php: -------------------------------------------------------------------------------- 1 | [ 31 | // match all /user/* 32 | '/user/', 33 | ], 34 | 'blog.com' => [ 35 | // match all /blog/* 36 | '/blog/', 37 | ] 38 | ]; 39 | 40 | /** 41 | * Process an incoming server request. 42 | * 43 | * @param ServerRequestInterface|Request $request 44 | * @param RequestHandlerInterface $handler 45 | * 46 | * @return ResponseInterface 47 | * @inheritdoc 48 | */ 49 | public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface 50 | { 51 | $uriPath = $request->getUriPath(); 52 | $domain = $request->getUri()->getHost(); 53 | 54 | if (!isset($this->domain2paths[$domain])) { 55 | return context()->getResponse()->withStatus(404)->withContent('invalid request domain'); 56 | } 57 | 58 | foreach ($this->domain2paths[$domain] as $prefix) { 59 | // not match route prefix 60 | if (strpos($uriPath, $prefix) !== 0) { 61 | return context()->getResponse()->withStatus(404)->withContent('page not found'); 62 | } 63 | } 64 | 65 | return $handler->handle($request); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /app/Http/Middleware/FavIconMiddleware.php: -------------------------------------------------------------------------------- 1 | getUriPath(); 40 | $domain = $request->getUri()->getHost(); 41 | 42 | if ($request->getUriPath() === '/favicon.ico') { 43 | return context()->getResponse()->withStatus(404); 44 | } 45 | 46 | return $handler->handle($request); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /app/Listener/DbRanListener.php: -------------------------------------------------------------------------------- 1 | getTarget(); 38 | 39 | $querySql = $event->getParam(0); 40 | $bindings = $event->getParam(1); 41 | 42 | $rawSql = $connection->getRawSql($querySql, $bindings); 43 | // output()->info($rawSql); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/Listener/DeregisterServiceListener.php: -------------------------------------------------------------------------------- 1 | getTarget(); 44 | 45 | //$this->agent->deregisterService('swoft'); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/Listener/ModelSavedListener.php: -------------------------------------------------------------------------------- 1 | getTarget(); 36 | 37 | if ($modelStatic instanceof User) { 38 | // to do something.... 39 | } 40 | 41 | // .... 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/Listener/RegisterServiceListener.php: -------------------------------------------------------------------------------- 1 | getTarget(); 44 | 45 | $service = [ 46 | 'ID' => 'swoft', 47 | 'Name' => 'swoft', 48 | 'Tags' => [ 49 | 'http' 50 | ], 51 | 'Address' => '127.0.0.1', 52 | 'Port' => $httpServer->getPort(), 53 | 'Meta' => [ 54 | 'version' => '1.0' 55 | ], 56 | 'EnableTagOverride' => false, 57 | 'Weights' => [ 58 | 'Passing' => 10, 59 | 'Warning' => 1 60 | ] 61 | ]; 62 | 63 | 64 | // Register 65 | // $this->agent->registerService($service); 66 | // CLog::info('Swoft http register service success by consul!'); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /app/Listener/Test/ShutDownListener.php: -------------------------------------------------------------------------------- 1 | getTarget(); 35 | 36 | /** 37 | * if ($user->getAge() > 100) { 38 | * // stopping saving 39 | * $event->stopPropagation(true); 40 | * } 41 | */ 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/Migration/User.php: -------------------------------------------------------------------------------- 1 | execute($sql); 42 | } 43 | 44 | /** 45 | * @return void 46 | */ 47 | public function down(): void 48 | { 49 | $dropSql = <<execute($dropSql); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /app/Model/Dao/UserDao.php: -------------------------------------------------------------------------------- 1 | id = $id; 80 | } 81 | 82 | /** 83 | * @param int|null $userId 84 | * 85 | * @return void 86 | */ 87 | public function setUserId(?int $userId): void 88 | { 89 | $this->userId = $userId; 90 | } 91 | 92 | /** 93 | * @param int|null $createTime 94 | * 95 | * @return void 96 | */ 97 | public function setCreateTime(?int $createTime): void 98 | { 99 | $this->createTime = $createTime; 100 | } 101 | 102 | /** 103 | * @param string|null $attributes 104 | * 105 | * @return void 106 | */ 107 | public function setAttributes(?string $attributes): void 108 | { 109 | $this->attributes = $attributes; 110 | } 111 | 112 | /** 113 | * @param string|null $updateTime 114 | * 115 | * @return void 116 | */ 117 | public function setUpdateTime(?string $updateTime): void 118 | { 119 | $this->updateTime = $updateTime; 120 | } 121 | 122 | /** 123 | * @return int|null 124 | */ 125 | public function getId(): ?int 126 | { 127 | return $this->id; 128 | } 129 | 130 | /** 131 | * @return int|null 132 | */ 133 | public function getUserId(): ?int 134 | { 135 | return $this->userId; 136 | } 137 | 138 | /** 139 | * @return int|null 140 | */ 141 | public function getCreateTime(): ?int 142 | { 143 | return $this->createTime; 144 | } 145 | 146 | /** 147 | * @return string|null 148 | */ 149 | public function getAttributes(): ?string 150 | { 151 | return $this->attributes; 152 | } 153 | 154 | /** 155 | * @return string|null 156 | */ 157 | public function getUpdateTime(): ?string 158 | { 159 | return $this->updateTime; 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /app/Model/Entity/Count2.php: -------------------------------------------------------------------------------- 1 | id; 63 | } 64 | 65 | /** 66 | * @param null|int $id 67 | */ 68 | public function setId(?int $id): void 69 | { 70 | $this->id = $id; 71 | } 72 | 73 | /** 74 | * @return null|int 75 | */ 76 | public function getUserId(): ?int 77 | { 78 | return $this->userId; 79 | } 80 | 81 | /** 82 | * @param null|int $userId 83 | */ 84 | public function setUserId(?int $userId): void 85 | { 86 | $this->userId = $userId; 87 | } 88 | 89 | /** 90 | * @return null|int 91 | */ 92 | public function getCreateTime(): ?int 93 | { 94 | return $this->createTime; 95 | } 96 | 97 | /** 98 | * @param null|int $createTime 99 | */ 100 | public function setCreateTime(?int $createTime): void 101 | { 102 | $this->createTime = $createTime; 103 | } 104 | 105 | /** 106 | * @return null|string 107 | */ 108 | public function getAttributes(): ?string 109 | { 110 | return $this->attributes; 111 | } 112 | 113 | /** 114 | * @param null|string $attributes 115 | */ 116 | public function setAttributes(?string $attributes): void 117 | { 118 | $this->attributes = $attributes; 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /app/Model/Entity/Desc.php: -------------------------------------------------------------------------------- 1 | id; 47 | } 48 | 49 | /** 50 | * @param int $id 51 | */ 52 | public function setId(int $id): void 53 | { 54 | $this->id = $id; 55 | } 56 | 57 | /** 58 | * @return string 59 | */ 60 | public function getDesc(): ?string 61 | { 62 | return $this->desc; 63 | } 64 | 65 | /** 66 | * @param string $desc 67 | */ 68 | public function setDesc(string $desc): void 69 | { 70 | $this->desc = $desc; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /app/Model/Entity/User.php: -------------------------------------------------------------------------------- 1 | id = $id; 80 | } 81 | 82 | /** 83 | * @param string $name 84 | * 85 | * @return void 86 | */ 87 | public function setName(string $name): void 88 | { 89 | $this->name = $name; 90 | } 91 | 92 | /** 93 | * @param int $age 94 | * 95 | * @return void 96 | */ 97 | public function setAge(int $age): void 98 | { 99 | $this->age = $age; 100 | } 101 | 102 | /** 103 | * @param string $password 104 | * 105 | * @return void 106 | */ 107 | public function setPassword(string $password): void 108 | { 109 | $this->password = $password; 110 | } 111 | 112 | /** 113 | * @param string $userDesc 114 | * 115 | * @return void 116 | */ 117 | public function setUserDesc(string $userDesc): void 118 | { 119 | $this->userDesc = $userDesc; 120 | } 121 | 122 | /** 123 | * @param array|null $testJson 124 | * 125 | * @return void 126 | */ 127 | public function setTestJson(?array $testJson): void 128 | { 129 | $this->testJson = $testJson; 130 | } 131 | 132 | /** 133 | * @return int|null 134 | */ 135 | public function getId(): ?int 136 | { 137 | return $this->id; 138 | } 139 | 140 | /** 141 | * @return string 142 | */ 143 | public function getName(): string 144 | { 145 | return $this->name; 146 | } 147 | 148 | /** 149 | * @return int 150 | */ 151 | public function getAge(): int 152 | { 153 | return $this->age; 154 | } 155 | 156 | /** 157 | * @return string 158 | */ 159 | public function getPassword(): string 160 | { 161 | return $this->password; 162 | } 163 | 164 | /** 165 | * @return string 166 | */ 167 | public function getUserDesc(): string 168 | { 169 | return $this->userDesc; 170 | } 171 | 172 | /** 173 | * @return array|null 174 | */ 175 | public function getTestJson(): ?array 176 | { 177 | return $this->testJson; 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /app/Model/Entity/User3.php: -------------------------------------------------------------------------------- 1 | id; 66 | } 67 | 68 | /** 69 | * @param int|null $id 70 | */ 71 | public function setId(?int $id): void 72 | { 73 | $this->id = $id; 74 | } 75 | 76 | /** 77 | * @return int|null 78 | */ 79 | public function getAge(): ?int 80 | { 81 | return $this->age; 82 | } 83 | 84 | /** 85 | * @param int|null $age 86 | */ 87 | public function setAge(?int $age): void 88 | { 89 | $this->age = $age; 90 | } 91 | 92 | /** 93 | * @return string|null 94 | */ 95 | public function getName(): ?string 96 | { 97 | return $this->name; 98 | } 99 | 100 | /** 101 | * @param string|null $name 102 | */ 103 | public function setName(?string $name): void 104 | { 105 | $this->name = $name; 106 | } 107 | 108 | /** 109 | * @return string|null 110 | */ 111 | public function getPwd(): ?string 112 | { 113 | return $this->pwd; 114 | } 115 | 116 | /** 117 | * @param string|null $pwd 118 | */ 119 | public function setPwd(?string $pwd): void 120 | { 121 | $this->pwd = $pwd; 122 | } 123 | 124 | /** 125 | * @return string|null 126 | */ 127 | public function getUserDesc(): ?string 128 | { 129 | return $this->userDesc; 130 | } 131 | 132 | /** 133 | * @param string|null $userDesc 134 | */ 135 | public function setUserDesc(?string $userDesc): void 136 | { 137 | $this->userDesc = $userDesc; 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /app/Model/Logic/ApolloLogic.php: -------------------------------------------------------------------------------- 1 | config->pull('application'); 40 | 41 | // Print data 42 | var_dump($data); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/Model/Logic/BreakerLogic.php: -------------------------------------------------------------------------------- 1 | kv->put('/test/my/key', $value); 75 | 76 | $response = $this->kv->get('/test/my/key'); 77 | var_dump($response->getBody(), $response->getResult()); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /app/Model/Logic/LimiterLogic.php: -------------------------------------------------------------------------------- 1 | exportSocket()); 38 | // $process->name('swoft-monitor'); 39 | 40 | while (true) { 41 | $connections = context()->getServer()->getSwooleServer()->connections; 42 | CLog::info('monitor = ' . json_encode($connections)); 43 | 44 | // Database 45 | // $user = User::find(1)->toArray(); 46 | // CLog::info('user=' . json_encode($user)); 47 | // 48 | // // Redis 49 | // Redis::set('test', 'ok'); 50 | // CLog::info('test=' . Redis::get('test')); 51 | 52 | Coroutine::sleep(3); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /app/Model/Logic/RequestBean.php: -------------------------------------------------------------------------------- 1 | logic->monitor($process); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/Process/Worker1Process.php: -------------------------------------------------------------------------------- 1 | toArray(); 43 | CLog::info('user=' . json_encode($user)); 44 | 45 | // Redis 46 | Redis::set('test', 'ok'); 47 | CLog::info('test=' . Redis::get('test')); 48 | 49 | CLog::info('worker-' . $workerId . ' context=' . context()->getWorkerId()); 50 | 51 | Coroutine::sleep(3); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /app/Rpc/Lib/UserInterface.php: -------------------------------------------------------------------------------- 1 | handle($request); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/Rpc/Service/UserService.php: -------------------------------------------------------------------------------- 1 | ['list']]; 38 | } 39 | 40 | /** 41 | * @param int $id 42 | * 43 | * @return bool 44 | */ 45 | public function delete(int $id): bool 46 | { 47 | return false; 48 | } 49 | 50 | /** 51 | * @return void 52 | */ 53 | public function returnNull(): void 54 | { 55 | } 56 | 57 | /** 58 | * @return string 59 | */ 60 | public function getBigContent(): string 61 | { 62 | return Co::readFile(__DIR__ . '/big.data'); 63 | } 64 | 65 | /** 66 | * Exception 67 | * 68 | * @throws Exception 69 | */ 70 | public function exception(): void 71 | { 72 | throw new RuntimeException('exception version'); 73 | } 74 | 75 | /** 76 | * @param string $content 77 | * 78 | * @return int 79 | */ 80 | public function sendBigContent(string $content): int 81 | { 82 | return strlen($content); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /app/Rpc/Service/UserServiceV2.php: -------------------------------------------------------------------------------- 1 | ['list'], 38 | 'v' => '1.2' 39 | ]; 40 | } 41 | 42 | /** 43 | * @return void 44 | */ 45 | public function returnNull(): void 46 | { 47 | return; 48 | } 49 | 50 | /** 51 | * @param int $id 52 | * 53 | * @return bool 54 | */ 55 | public function delete(int $id): bool 56 | { 57 | return false; 58 | } 59 | 60 | /** 61 | * @return string 62 | */ 63 | public function getBigContent(): string 64 | { 65 | $content = Co::readFile(__DIR__ . '/big.data'); 66 | return $content; 67 | } 68 | 69 | /** 70 | * Exception 71 | * 72 | * @throws Exception 73 | */ 74 | public function exception(): void 75 | { 76 | throw new Exception('exception version2'); 77 | } 78 | 79 | /** 80 | * @param string $content 81 | * 82 | * @return int 83 | */ 84 | public function sendBigContent(string $content): int 85 | { 86 | return strlen($content); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /app/Task/Crontab/CronTask.php: -------------------------------------------------------------------------------- 1 | setAge(mt_rand(1, 100)); 36 | // $user->setUserDesc('desc'); 37 | // 38 | // $user->save(); 39 | // 40 | // $id = $user->getId(); 41 | // $user = User::find($id)->toArray(); 42 | 43 | CLog::info('second task run: %s ', date('Y-m-d H:i:s')); 44 | // CLog::info(JsonHelper::encode($user)); 45 | } 46 | 47 | /** 48 | * @Cron("0 * * * * *") 49 | */ 50 | public function minuteTask(): void 51 | { 52 | CLog::info('minute task run: %s ', date('Y-m-d H:i:s')); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /app/Task/Listener/FinishListener.php: -------------------------------------------------------------------------------- 1 | getTaskUniqid()); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/Task/Task/SyncTask.php: -------------------------------------------------------------------------------- 1 | [1, 3, 3], 37 | 'id' => $id, 38 | 'default' => $default 39 | ]; 40 | } 41 | 42 | /** 43 | * @TaskMapping() 44 | * 45 | * @param int $id 46 | * 47 | * @return bool 48 | */ 49 | public function delete(int $id): bool 50 | { 51 | if ($id > 10) { 52 | return true; 53 | } 54 | 55 | return false; 56 | } 57 | 58 | /** 59 | * @TaskMapping() 60 | * 61 | * @param string $name 62 | * 63 | * @return null 64 | */ 65 | public function returnNull(string $name) 66 | { 67 | return null; 68 | } 69 | 70 | /** 71 | * @TaskMapping() 72 | * 73 | * @param string $name 74 | */ 75 | public function returnVoid(string $name): void 76 | { 77 | return; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /app/Tcp/Controller/DemoController.php: -------------------------------------------------------------------------------- 1 | setData('[list]allow command: list, echo, demo.echo'); 34 | } 35 | 36 | /** 37 | * @TcpMapping("echo") 38 | * @param Request $request 39 | * @param Response $response 40 | */ 41 | public function index(Request $request, Response $response): void 42 | { 43 | $str = $request->getPackage()->getDataString(); 44 | 45 | $response->setData('[demo.echo]hi, we received your message: ' . $str); 46 | } 47 | 48 | /** 49 | * @TcpMapping("strrev", root=true) 50 | * @param Request $request 51 | * @param Response $response 52 | */ 53 | public function strRev(Request $request, Response $response): void 54 | { 55 | $str = $request->getPackage()->getDataString(); 56 | 57 | $response->setData(strrev($str)); 58 | } 59 | 60 | /** 61 | * @TcpMapping("echo", root=true) 62 | * @param Request $request 63 | * @param Response $response 64 | */ 65 | public function echo(Request $request, Response $response): void 66 | { 67 | // $str = $request->getRawData(); 68 | $str = $request->getPackage()->getDataString(); 69 | 70 | $response->setData('[echo]hi, we received your message: ' . $str); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /app/Tcp/Middleware/DemoMiddleware.php: -------------------------------------------------------------------------------- 1 | before '; 36 | 37 | CLog::info('before handle'); 38 | 39 | $resp = $handler->handle($request); 40 | 41 | $resp->setData($start . $resp->getData() . ' after>'); 42 | 43 | CLog::info('after handle'); 44 | 45 | return $resp; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/Tcp/Middleware/GlobalTcpMiddleware.php: -------------------------------------------------------------------------------- 1 | before '; 36 | 37 | CLog::info('before handle'); 38 | 39 | $resp = $handler->handle($request); 40 | 41 | $resp->setData($start . $resp->getData() . ' after>'); 42 | 43 | CLog::info('after handle'); 44 | 45 | return $resp; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/Validator/CustomerValidator.php: -------------------------------------------------------------------------------- 1 | $end) { 42 | throw new ValidatorException('Start cannot be greater than the end time'); 43 | } 44 | 45 | return $data; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/Validator/Rule/AlphaDashRule.php: -------------------------------------------------------------------------------- 1 | getMessage(); 38 | if (!isset($data[$propertyName]) && $default === null) { 39 | $message = (empty($message)) ? sprintf('%s must exist!', $propertyName) : $message; 40 | throw new ValidatorException($message); 41 | } 42 | 43 | $rule = '/^[A-Za-z0-9\-\_]+$/'; 44 | if (preg_match($rule, $data[$propertyName])) { 45 | return $data; 46 | } 47 | 48 | $message = (empty($message)) ? sprintf('%s must be a email', $propertyName) : $message; 49 | throw new ValidatorException($message); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /app/Validator/TestValidator.php: -------------------------------------------------------------------------------- 1 | push('hi, this is home.index'); 33 | } 34 | 35 | /** 36 | * Message command is: 'home.echo' 37 | * 38 | * @param string $data 39 | * @MessageMapping() 40 | */ 41 | public function echo(string $data): void 42 | { 43 | Session::current()->push('(home.echo)Recv: ' . $data); 44 | } 45 | 46 | /** 47 | * Message command is: 'home.ar' 48 | * 49 | * @param string $data 50 | * @MessageMapping("ar") 51 | * 52 | * @return string 53 | */ 54 | public function autoReply(string $data): string 55 | { 56 | return '(home.ar)Recv: ' . $data; 57 | } 58 | 59 | /** 60 | * Message command is: 'help' 61 | * 62 | * @param string $data 63 | * @MessageMapping("help", root=true) 64 | * 65 | * @return string 66 | */ 67 | public function help(string $data): string 68 | { 69 | return '(home.ar)Recv: ' . $data; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /app/WebSocket/ChatModule.php: -------------------------------------------------------------------------------- 1 | push($request->getFd(), "Opened, welcome!(FD: $fd)"); 41 | 42 | $fullClass = Session::current()->getParserClass(); 43 | $className = basename($fullClass); 44 | 45 | $help = << App\WebSocket\Chat\HomeController::index() 59 | TXT; 60 | 61 | server()->push($fd, $help); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /app/WebSocket/EchoModule.php: -------------------------------------------------------------------------------- 1 | push("Opened, welcome #{$fd}!"); 36 | } 37 | 38 | /** 39 | * @OnMessage() 40 | * @param Server $server 41 | * @param Frame $frame 42 | */ 43 | public function onMessage(Server $server, Frame $frame): void 44 | { 45 | $server->push($frame->fd, 'Recv: ' . $frame->data); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/WebSocket/Middleware/DemoMiddleware.php: -------------------------------------------------------------------------------- 1 | before '; 36 | 37 | CLog::info('before handle'); 38 | 39 | $resp = $handler->handle($request); 40 | 41 | $resp->setData($start . $resp->getData() . ' after>'); 42 | 43 | CLog::info('after handle'); 44 | 45 | return $resp; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/WebSocket/Middleware/GlobalWsMiddleware.php: -------------------------------------------------------------------------------- 1 | before '; 36 | 37 | CLog::info('before handle'); 38 | 39 | $resp = $handler->handle($request); 40 | 41 | $resp->setData($start . $resp->getData() . ' after>'); 42 | 43 | CLog::info('after handle'); 44 | 45 | \server()->log(__METHOD__, [], 'error'); 46 | 47 | return $resp; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /app/WebSocket/Test/TestController.php: -------------------------------------------------------------------------------- 1 | push('hi, this is test.index'); 41 | } 42 | 43 | /** 44 | * Message command is: 'test.index' 45 | * 46 | * @param Message $msg 47 | * 48 | * @return void 49 | * @MessageMapping("close") 50 | */ 51 | public function close(Message $msg): void 52 | { 53 | $data = $msg->getData(); 54 | /** @var Connection $conn */ 55 | $conn = Session::current(); 56 | 57 | $fd = is_numeric($data) ? (int)$data : $conn->getFd(); 58 | 59 | $conn->push("hi, will close conn $fd"); 60 | 61 | // disconnect 62 | $conn->getServer()->disconnect($fd); 63 | } 64 | 65 | /** 66 | * Message command is: 'test.req' 67 | * 68 | * @param Request $req 69 | * 70 | * @return void 71 | * @MessageMapping("req") 72 | */ 73 | public function injectRequest(Request $req): void 74 | { 75 | $fd = $req->getFd(); 76 | 77 | Session::current()->push("(your FD: $fd)message data: " . json_encode($req->getMessage()->toArray())); 78 | } 79 | 80 | /** 81 | * Message command is: 'test.msg' 82 | * 83 | * @param Message $msg 84 | * 85 | * @return void 86 | * @MessageMapping("msg") 87 | */ 88 | public function injectMessage(Message $msg): void 89 | { 90 | Session::current()->push('message data: ' . json_encode($msg->toArray())); 91 | } 92 | 93 | /** 94 | * Message command is: 'echo' 95 | * 96 | * @param string $data 97 | * @MessageMapping(root=true) 98 | */ 99 | public function echo(string $data): void 100 | { 101 | Session::current()->push('(echo)Recv: ' . $data); 102 | } 103 | 104 | /** 105 | * Message command is: 'echo' 106 | * 107 | * @param Request $req 108 | * @param Response $res 109 | * @MessageMapping(root=true) 110 | */ 111 | public function hi(Request $req, Response $res): void 112 | { 113 | $fd = $req->getFd(); 114 | $ufd = (int)$req->getMessage()->getData(); 115 | 116 | if ($ufd < 1) { 117 | Session::current()->push('data must be an integer'); 118 | return; 119 | } 120 | 121 | $res->setFd($ufd)->setContent("Hi #{$ufd}, I am #{$fd}"); 122 | } 123 | 124 | /** 125 | * Message command is: 'bin' 126 | * 127 | * @MessageMapping("bin", root=true, opcode=2) 128 | * @param string $data 129 | * 130 | * @return string 131 | */ 132 | public function binary(string $data): string 133 | { 134 | // Session::current()->push('Binary: ' . $data, \WEBSOCKET_OPCODE_BINARY); 135 | return 'Binary: ' . $data; 136 | } 137 | 138 | /** 139 | * Message command is: 'ping' 140 | * 141 | * @MessageMapping("ping", root=true) 142 | */ 143 | public function pong(): void 144 | { 145 | Session::current()->push('pong!', WEBSOCKET_OPCODE_PONG); 146 | } 147 | 148 | /** 149 | * Message command is: 'test.ar' 150 | * 151 | * @MessageMapping("ar") 152 | * @param string $data 153 | * 154 | * @return string 155 | */ 156 | public function autoReply(string $data): string 157 | { 158 | return '(home.ar)Recv: ' . $data; 159 | } 160 | 161 | /** 162 | * Message command is: 'test.ar' 163 | * 164 | * @MessageMapping("stop-worker") 165 | */ 166 | public function testDie(): void 167 | { 168 | $wid = \server()->getPid('workerId'); 169 | 170 | \vdump($wid); 171 | 172 | \server()->stopWorker($wid); 173 | } 174 | } 175 | -------------------------------------------------------------------------------- /app/WebSocket/TestModule.php: -------------------------------------------------------------------------------- 1 | push("Opened, welcome!(FD: $fd)"); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /app/bean.php: -------------------------------------------------------------------------------- 1 | [ 26 | 'logFile' => '@runtime/logs/notice-%d{Y-m-d-H}.log', 27 | ], 28 | 'applicationHandler' => [ 29 | 'logFile' => '@runtime/logs/error-%d{Y-m-d}.log', 30 | ], 31 | 'logger' => [ 32 | 'flushRequest' => false, 33 | 'enable' => false, 34 | 'json' => false, 35 | ], 36 | 'httpServer' => [ 37 | 'class' => HttpServer::class, 38 | 'port' => 18306, 39 | 'listener' => [ 40 | // 'rpc' => bean('rpcServer'), 41 | // 'tcp' => bean('tcpServer'), 42 | ], 43 | 'process' => [ 44 | // 'monitor' => bean(\App\Process\MonitorProcess::class) 45 | // 'crontab' => bean(CrontabProcess::class) 46 | ], 47 | 'on' => [ 48 | // SwooleEvent::TASK => bean(SyncTaskListener::class), // Enable sync task 49 | SwooleEvent::TASK => bean(TaskListener::class), // Enable task must task and finish event 50 | SwooleEvent::FINISH => bean(FinishListener::class) 51 | ], 52 | /* @see HttpServer::$setting */ 53 | 'setting' => [ 54 | 'task_worker_num' => 12, 55 | 'task_enable_coroutine' => true, 56 | 'worker_num' => 6, 57 | // static handle 58 | // 'enable_static_handler' => true, 59 | // 'document_root' => dirname(__DIR__) . '/public', 60 | ] 61 | ], 62 | 'httpDispatcher' => [ 63 | // Add global http middleware 64 | 'middlewares' => [ 65 | \App\Http\Middleware\FavIconMiddleware::class, 66 | \Swoft\Http\Session\SessionMiddleware::class, 67 | // \Swoft\Whoops\WhoopsMiddleware::class, 68 | // Allow use @View tag 69 | \Swoft\View\Middleware\ViewMiddleware::class, 70 | ], 71 | 'afterMiddlewares' => [ 72 | \Swoft\Http\Server\Middleware\ValidatorMiddleware::class 73 | ] 74 | ], 75 | 'db' => [ 76 | 'class' => Database::class, 77 | 'dsn' => 'mysql:dbname=test;host=127.0.0.1', 78 | 'username' => 'root', 79 | 'password' => 'swoft123456', 80 | 'charset' => 'utf8mb4', 81 | ], 82 | 'db2' => [ 83 | 'class' => Database::class, 84 | 'dsn' => 'mysql:dbname=test2;host=127.0.0.1', 85 | 'username' => 'root', 86 | 'password' => 'swoft123456', 87 | 'charset' => 'utf8mb4', 88 | // 'dbSelector' => bean(DbSelector::class) 89 | ], 90 | 'db2.pool' => [ 91 | 'class' => Pool::class, 92 | 'database' => bean('db2'), 93 | ], 94 | 'db3' => [ 95 | 'class' => Database::class, 96 | 'dsn' => 'mysql:dbname=test2;host=127.0.0.1', 97 | 'username' => 'root', 98 | 'password' => 'swoft123456', 99 | 'charset' => 'utf8mb4', 100 | ], 101 | 'db3.pool' => [ 102 | 'class' => Pool::class, 103 | 'database' => bean('db3') 104 | ], 105 | 'migrationManager' => [ 106 | 'migrationPath' => '@database/Migration', 107 | ], 108 | 'redis' => [ 109 | 'class' => RedisDb::class, 110 | 'host' => '127.0.0.1', 111 | 'port' => 6379, 112 | 'database' => 0, 113 | 'option' => [ 114 | 'prefix' => 'swoft:' 115 | ] 116 | ], 117 | 'user' => [ 118 | 'class' => ServiceClient::class, 119 | 'host' => '127.0.0.1', 120 | 'port' => 18307, 121 | 'setting' => [ 122 | 'timeout' => 0.5, 123 | 'connect_timeout' => 1.0, 124 | 'write_timeout' => 10.0, 125 | 'read_timeout' => 0.5, 126 | ], 127 | 'packet' => bean('rpcClientPacket') 128 | ], 129 | 'user.pool' => [ 130 | 'class' => ServicePool::class, 131 | 'client' => bean('user'), 132 | ], 133 | 'rpcServer' => [ 134 | 'class' => ServiceServer::class, 135 | 'listener' => [ 136 | 'http' => bean('httpServer'), 137 | ] 138 | ], 139 | 'wsServer' => [ 140 | 'class' => WebSocketServer::class, 141 | 'port' => 18308, 142 | 'listener' => [ 143 | 'rpc' => bean('rpcServer'), 144 | // 'tcp' => bean('tcpServer'), 145 | ], 146 | 'on' => [ 147 | // Enable http handle 148 | SwooleEvent::REQUEST => bean(RequestListener::class), 149 | // Enable task must add task and finish event 150 | SwooleEvent::TASK => bean(TaskListener::class), 151 | SwooleEvent::FINISH => bean(FinishListener::class) 152 | ], 153 | 'debug' => 1, 154 | // 'debug' => env('SWOFT_DEBUG', 0), 155 | /* @see WebSocketServer::$setting */ 156 | 'setting' => [ 157 | 'task_worker_num' => 6, 158 | 'task_enable_coroutine' => true, 159 | 'worker_num' => 6, 160 | 'log_file' => alias('@runtime/swoole.log'), 161 | // 'open_websocket_close_frame' => true, 162 | ], 163 | ], 164 | // 'wsConnectionManager' => [ 165 | // 'storage' => bean('wsConnectionStorage') 166 | // ], 167 | // 'wsConnectionStorage' => [ 168 | // 'class' => \Swoft\Session\SwooleStorage::class, 169 | // ], 170 | /** @see \Swoft\WebSocket\Server\WsMessageDispatcher */ 171 | 'wsMsgDispatcher' => [ 172 | 'middlewares' => [ 173 | \App\WebSocket\Middleware\GlobalWsMiddleware::class 174 | ], 175 | ], 176 | /** @see \Swoft\Tcp\Server\TcpServer */ 177 | 'tcpServer' => [ 178 | 'port' => 18309, 179 | 'debug' => 1, 180 | ], 181 | /** @see \Swoft\Tcp\Protocol */ 182 | 'tcpServerProtocol' => [ 183 | // 'type' => \Swoft\Tcp\Packer\JsonPacker::TYPE, 184 | 'type' => \Swoft\Tcp\Packer\SimpleTokenPacker::TYPE, 185 | // 'openLengthCheck' => true, 186 | ], 187 | /** @see \Swoft\Tcp\Server\TcpDispatcher */ 188 | 'tcpDispatcher' => [ 189 | 'middlewares' => [ 190 | \App\Tcp\Middleware\GlobalTcpMiddleware::class 191 | ], 192 | ], 193 | 'cliRouter' => [// 'disabledGroups' => ['demo', 'test'], 194 | ], 195 | ]; 196 | -------------------------------------------------------------------------------- /bin/bootstrap.php: -------------------------------------------------------------------------------- 1 | addPsr4('Swoft\\Cache\\', 'vendor/swoft/cache/src/'); 15 | -------------------------------------------------------------------------------- /bin/swoft: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 300000, 9 | ]); 10 | 11 | // Run application 12 | (new \App\Application())->run(); 13 | -------------------------------------------------------------------------------- /composer.cn.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "swoft/swoft", 3 | "type": "project", 4 | "keywords": [ 5 | "php", 6 | "swoole", 7 | "swoft" 8 | ], 9 | "description": "Modern High performance AOP and Coroutine PHP Framework", 10 | "license": "Apache-2.0", 11 | "require": { 12 | "php": ">7.1", 13 | "ext-pdo": "*", 14 | "ext-redis": "*", 15 | "ext-json": "*", 16 | "ext-mbstring": "*", 17 | "swoft/db": "~2.0.0", 18 | "swoft/i18n": "~2.0.0", 19 | "swoft/view": "~2.0.0", 20 | "swoft/task": "~2.0.0", 21 | "swoft/redis": "~2.0.0", 22 | "swoft/framework": "~2.0.0", 23 | "swoft/http-server": "~2.0.0", 24 | "swoft/rpc-client": "~2.0.0", 25 | "swoft/rpc-server": "~2.0.0", 26 | "swoft/websocket-server": "~2.0.0" 27 | }, 28 | "require-dev": { 29 | "swoft/swoole-ide-helper": "dev-master", 30 | "phpunit/phpunit": "^7.5 || ^8.0", 31 | "swoft/devtool": "~2.0.0" 32 | }, 33 | "autoload": { 34 | "psr-4": { 35 | "App\\": "app/" 36 | }, 37 | "files": [ 38 | "app/Helper/Functions.php" 39 | ] 40 | }, 41 | "autoload-dev": { 42 | "psr-4": { 43 | "AppTest\\Testing\\": "test/testing", 44 | "AppTest\\Unit\\": "test/unit" 45 | } 46 | }, 47 | "scripts": { 48 | "post-root-package-install": [ 49 | "@php -r \"file_exists('.env') || copy('.env.example', '.env');\"" 50 | ], 51 | "test": "./vendor/bin/phpunit -c phpunit.xml", 52 | "check-cs": "./bin/php-cs-fixer fix --dry-run --diff --diff-format=udiff", 53 | "cs-fix": "./bin/php-cs-fixer fix" 54 | }, 55 | "repositories": { 56 | "packagist": { 57 | "type": "composer", 58 | "url": "https://mirrors.aliyun.com/composer/" 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /composer.dev.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "swoft/swoft", 3 | "type": "project", 4 | "keywords": [ 5 | "php", 6 | "swoole", 7 | "swoft" 8 | ], 9 | "description": "Modern High performance AOP and Coroutine PHP Framework, base on Swoole", 10 | "license": "Apache-2.0", 11 | "require": { 12 | "php": ">7.1", 13 | "ext-pdo": "*", 14 | "ext-json": "*", 15 | "swoft/component": "dev-master as 2.0", 16 | "swoft/ext": "dev-master as 2.0" 17 | }, 18 | "require-dev": { 19 | "swoft/swlib": "~2.0.0", 20 | "swoft/swoole-ide-helper": "dev-master", 21 | "phpunit/phpunit": "^7.5 || ^8.0" 22 | }, 23 | "autoload": { 24 | "psr-4": { 25 | "App\\": "app/" 26 | }, 27 | "files": [ 28 | "app/Helper/Functions.php" 29 | ] 30 | }, 31 | "autoload-dev": { 32 | "psr-4": { 33 | "SwoftTest\\": "./test/" 34 | } 35 | }, 36 | "scripts": { 37 | "post-root-package-install": [ 38 | "@php -r \"file_exists('.env') || copy('.env.example', '.env');\"" 39 | ], 40 | "test": "./vendor/bin/phpunit -c phpunit.xml", 41 | "cs-fix": "./vendor/bin/php-cs-fixer fix $1" 42 | }, 43 | "repositories": { 44 | "packagist": { 45 | "type": "composer", 46 | "url": "https://mirrors.aliyun.com/composer/" 47 | }, 48 | "0": { 49 | "type": "git", 50 | "url": "git@github.com:swoft-cloud/swoft-component.git" 51 | }, 52 | "1": { 53 | "type": "git", 54 | "url": "git@github.com:swoft-cloud/swoft-ext.git" 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "swoft/swoft", 3 | "type": "project", 4 | "keywords": [ 5 | "php", 6 | "swoole", 7 | "swoft" 8 | ], 9 | "description": "Modern High performance AOP and Coroutine PHP Framework", 10 | "license": "Apache-2.0", 11 | "require": { 12 | "php": ">7.1", 13 | "ext-pdo": "*", 14 | "ext-redis": "*", 15 | "ext-json": "*", 16 | "ext-simplexml": "*", 17 | "ext-libxml": "*", 18 | "ext-mbstring": "*", 19 | "swoft/cache": "~2.0.0", 20 | "swoft/db": "~2.0.0", 21 | "swoft/i18n": "~2.0.0", 22 | "swoft/view": "~2.0.0", 23 | "swoft/task": "~2.0.0", 24 | "swoft/redis": "~2.0.0", 25 | "swoft/framework": "~2.0.0", 26 | "swoft/http-server": "~2.0.0", 27 | "swoft/rpc-client": "~2.0.0", 28 | "swoft/rpc-server": "~2.0.0", 29 | "swoft/websocket-server": "~2.0.0", 30 | "swoft/tcp-server": "~2.0.0", 31 | "swoft/process": "~2.0.0", 32 | "swoft/apollo": "~2.0.0", 33 | "swoft/consul": "~2.0.0", 34 | "swoft/limiter": "~2.0.0", 35 | "swoft/breaker": "~2.0.0", 36 | "swoft/crontab": "~2.0.0", 37 | "swoft/session": "~2.0.0", 38 | "swoft/devtool": "~2.0.0" 39 | }, 40 | "require-dev": { 41 | "swoft/swlib": "~2.0.0", 42 | "swoft/swoole-ide-helper": "dev-master", 43 | "phpunit/phpunit": "^7.5 || ^8.0" 44 | }, 45 | "autoload": { 46 | "psr-4": { 47 | "App\\": "app/", 48 | "Database\\": "database/" 49 | }, 50 | "files": [ 51 | "app/Helper/Functions.php" 52 | ] 53 | }, 54 | "autoload-dev": { 55 | "psr-4": { 56 | "AppTest\\Testing\\": "test/testing", 57 | "AppTest\\Unit\\": "test/unit" 58 | } 59 | }, 60 | "scripts": { 61 | "post-root-package-install": [ 62 | "@php -r \"file_exists('.env') || copy('.env.example', '.env');\"" 63 | ], 64 | "phpstan": "./vendor/bin/phpstan analyze", 65 | "api-tests": "php test/run.php -c phpunit.xml --testsuite apiTests", 66 | "unit-tests": "php test/run.php -c phpunit.xml --testsuite unitTests", 67 | "check-cs": "./bin/php-cs-fixer fix --dry-run --diff --diff-format=udiff", 68 | "cs-fix": "./bin/php-cs-fixer fix" 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /config/app.php: -------------------------------------------------------------------------------- 1 | ['a', 'b'], 8 | 'warehouseCode' => $envVal ? explode(',', $envVal) : [], 9 | ]; 10 | -------------------------------------------------------------------------------- /config/base.php: -------------------------------------------------------------------------------- 1 | 'Swoft framework 2.0', 4 | 'debug' => env('SWOFT_DEBUG', 1), 5 | ]; 6 | -------------------------------------------------------------------------------- /config/db.php: -------------------------------------------------------------------------------- 1 | 'http://127.0.0.1' 4 | ]; 5 | -------------------------------------------------------------------------------- /config/dev/db.php: -------------------------------------------------------------------------------- 1 | __DIR__, 40 | ]; 41 | } 42 | 43 | /** 44 | * @return array 45 | */ 46 | public function metadata(): array 47 | { 48 | return []; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /database/Migration/Count.php: -------------------------------------------------------------------------------- 1 | schema->createIfNotExists('count', function (Blueprint $blueprint) { 33 | $blueprint->comment('user count comment ...'); 34 | 35 | $blueprint->increments('id')->comment('primary'); 36 | $blueprint->integer('user_id')->default('0')->comment('user table primary'); 37 | $blueprint->integer('create_time')->default('0')->comment('create time'); 38 | $blueprint->timestamp('update_time')->comment('update timestamp'); 39 | 40 | $blueprint->index(['user_id', 'create_time']); 41 | 42 | $blueprint->engine = 'Innodb'; 43 | $blueprint->charset = 'utf8mb4'; 44 | }); 45 | } 46 | 47 | /** 48 | * @throws DbException 49 | */ 50 | public function down(): void 51 | { 52 | $this->schema->dropIfExists('count'); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /database/Migration/Desc.php: -------------------------------------------------------------------------------- 1 | schema->createIfNotExists('desc', function (Blueprint $blueprint) { 33 | $blueprint->comment = 'user desc'; 34 | 35 | $blueprint->increments('id'); 36 | $blueprint->string('desc', 30); 37 | }); 38 | } 39 | 40 | /** 41 | * @throws DbException 42 | */ 43 | public function down(): void 44 | { 45 | $this->schema->dropIfExists('desc'); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.4' 2 | services: 3 | swoft: 4 | image: swoft/swoft 5 | # for local develop 6 | # command: php -S 127.0.0.1:13300 7 | container_name: swoft-srv 8 | environment: 9 | - APP_ENV=dev 10 | - TIMEZONE=Asia/Shanghai 11 | restart: always 12 | depends_on: 13 | - mysql 14 | - redis 15 | ports: 16 | - "18306:18306" 17 | - "18307:18307" 18 | - "18308:18308" 19 | volumes: 20 | - ./:/var/www/swoft 21 | # - ./:/var/www/swoft:delegated 22 | # - ./:/var/www/swoft:cached 23 | # - ./runtime/ng-conf:/etc/nginx 24 | # - ./runtime/logs:/var/log 25 | 26 | mysql: 27 | image: mysql 28 | container_name: mysql-srv 29 | environment: 30 | - MYSQL_ROOT_PASSWORD=123456 31 | ports: 32 | - "13306:3306" 33 | volumes: 34 | - ./runtime/data/mysql:/var/lib/mysql 35 | restart: always 36 | 37 | redis: 38 | container_name: redis-srv 39 | image: redis:4-alpine 40 | ports: 41 | - "16379:6379" 42 | sysctls: 43 | net.core.somaxconn: 65535 44 | restart: always 45 | -------------------------------------------------------------------------------- /phpstan.neon.dist: -------------------------------------------------------------------------------- 1 | includes: 2 | - phar://phpstan.phar/conf/bleedingEdge.neon 3 | parameters: 4 | level: max 5 | inferPrivatePropertyTypeFromConstructor: true 6 | checkMissingIterableValueType: false 7 | paths: 8 | - %currentWorkingDirectory%/app/ 9 | autoload_files: 10 | - %currentWorkingDirectory%/bin/bootstrap.php 11 | autoload_directories: 12 | - %currentWorkingDirectory%/vendor/swoft/swoole-ide-helper/output/namespace/ 13 | - %currentWorkingDirectory%/vendor/swoft/ 14 | dynamicConstantNames: 15 | - APP_DEBUG 16 | - SWOFT_DEBUG 17 | excludes_analyse: 18 | - test/* 19 | - runtime/* 20 | - resource/* 21 | ignoreErrors: 22 | # Variable type 23 | - '#^Call to an undefined method Swoft\\Contract\\ContextInterface::get\S+\(\)\.$#' 24 | - '#^Call to an undefined method Swoft\\Contract\\SessionInterface::\S+\(\)#' 25 | # - '#^Call to an undefined method Swoft\\Session\\SessionInterface::getFd\(\)#' 26 | - '#^Call to an undefined method Swoft\\Server\\Server::push\(\)\.$#' 27 | # - '#^Call to an undefined method Swoft\\Server\\Server::disconnect\(\)\.$#' 28 | - '#^Call to an undefined method\sPsr\\Http\\Message\\ServerRequestInterface::getUriPath\(\)#' 29 | - '#.+onstant APP_DEBUG not found.#' 30 | # - '#^Function view not found.#' 31 | # - '#^Call to static method \w+\(\) on an unknown class Swoft\\Cache\\Cache.#' 32 | # These are ignored for now 33 | - 34 | path: %currentWorkingDirectory%/app/Http/Controller/DbModelController.php 35 | message: '#^Method App\\Http\\Controller\\DbModelController::getId\(\) should return int but returns int\|null\.$#' 36 | - 37 | path: %currentWorkingDirectory%/app/Http/Controller/DbModelController.php 38 | message: '#^Argument of an invalid type App\\Model\\Entity\\User supplied for foreach, only iterables are supported\.$#' 39 | - 40 | path: %currentWorkingDirectory%/app/Http/Controller/DbTransactionController.php 41 | message: '#^Method App\\Http\\Controller\\DbTransactionController::getId\(\) should return int but returns int\|null\.$#' 42 | - 43 | path: %currentWorkingDirectory%/app/Http/Controller/RpcController.php 44 | message: '#^Unreachable statement - code above always terminates\.$#' 45 | - 46 | path: %currentWorkingDirectory%/app/Http/Controller/SelectDbController.php 47 | message: '#^Method App\\Http\\Controller\\SelectDbController::getId\(\) should return int but returns int\|null\.$#' 48 | - 49 | path: %currentWorkingDirectory%/app/Http/Controller/ValidatorController.php 50 | message: '#^Method App\\Http\\Controller\\ValidatorController::(validateAll|validateType|validatePassword|validateCustomer)\(\) should return array but returns array\|object\|null\.$#' 51 | - 52 | path: %currentWorkingDirectory%/app/Task/Task/SyncTask.php 53 | message: '#^Method App\\Task\\Task\\SyncTask::testNull\(\) should return bool but returns null\.$#' 54 | - 55 | path: %currentWorkingDirectory%/app/Validator/Rule/AlphaDashRule.php 56 | message: '#^Call to an undefined method object::getMessage\(\)\.$#' 57 | 58 | -------------------------------------------------------------------------------- /public/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swoft-cloud/swoft/334290debc7569b1b68e6b88b49c93b8c92088b3/public/.keep -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swoft-cloud/swoft/334290debc7569b1b68e6b88b49c93b8c92088b3/public/favicon.ico -------------------------------------------------------------------------------- /public/image/start-http-server.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swoft-cloud/swoft/334290debc7569b1b68e6b88b49c93b8c92088b3/public/image/start-http-server.jpg -------------------------------------------------------------------------------- /public/image/swoft-logo-mdl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swoft-cloud/swoft/334290debc7569b1b68e6b88b49c93b8c92088b3/public/image/swoft-logo-mdl.png -------------------------------------------------------------------------------- /resource/language/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swoft-cloud/swoft/334290debc7569b1b68e6b88b49c93b8c92088b3/resource/language/.keep -------------------------------------------------------------------------------- /resource/views/home/index.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | Swoft Framework 2.0 - PHP microservices coroutine framework 9 | 251 | 252 | 253 |
254 | 262 |
263 |

Swoft Framework 264 | 2.x 265 |

266 |
267 |
268 | 276 | 277 | 278 | -------------------------------------------------------------------------------- /resource/views/layouts/default.php: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | 12 | 13 | Demo for layout 14 | 15 | 16 | 17 | include('layouts/default/header') ?> 18 | 19 |
20 | 21 |
{_CONTENT_}
22 | include('layouts/default/footer') ?> 23 |
24 | 25 | 26 | -------------------------------------------------------------------------------- /resource/views/layouts/default/footer.php: -------------------------------------------------------------------------------- 1 |
2 | 16 |

This is footer

17 |
18 | view file: 
19 |     
20 |
21 | -------------------------------------------------------------------------------- /resource/views/layouts/default/header.php: -------------------------------------------------------------------------------- 1 |
2 | 29 |
30 | --------------------------------------------------------------------------------