{"id":13703814,"url":"https://github.com/bingcool/swoolefy","last_synced_at":"2026-04-26T13:01:31.191Z","repository":{"id":40499465,"uuid":"99567960","full_name":"bingcool/swoolefy","owner":"bingcool","description":"swoolefy是一个基于swoole实现的协程级、轻量级、高性能、开放性的API应用服务框架","archived":false,"fork":false,"pushed_at":"2026-04-22T01:54:46.000Z","size":8944,"stargazers_count":508,"open_issues_count":2,"forks_count":76,"subscribers_count":25,"default_branch":"master","last_synced_at":"2026-04-22T03:36:27.831Z","etag":null,"topics":["ioc","mvc","php","swoole","swoolefy"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bingcool.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2017-08-07T10:49:21.000Z","updated_at":"2026-04-02T07:58:19.000Z","dependencies_parsed_at":"2023-09-23T07:54:45.907Z","dependency_job_id":"2fdf717b-df6a-4ddf-bfc6-f5c0d49497b3","html_url":"https://github.com/bingcool/swoolefy","commit_stats":{"total_commits":1018,"total_committers":7,"mean_commits":"145.42857142857142","dds":0.08939096267190572,"last_synced_commit":"cfc297e2e7c781d24d1920387e1d61a72638039b"},"previous_names":[],"tags_count":105,"template":false,"template_full_name":null,"purl":"pkg:github/bingcool/swoolefy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bingcool%2Fswoolefy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bingcool%2Fswoolefy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bingcool%2Fswoolefy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bingcool%2Fswoolefy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bingcool","download_url":"https://codeload.github.com/bingcool/swoolefy/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bingcool%2Fswoolefy/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32297900,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-26T09:34:17.070Z","status":"ssl_error","status_checked_at":"2026-04-26T09:34:00.993Z","response_time":129,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ioc","mvc","php","swoole","swoolefy"],"created_at":"2024-08-02T21:01:00.373Z","updated_at":"2026-04-26T13:01:31.176Z","avatar_url":"https://github.com/bingcool.png","language":"PHP","funding_links":[],"categories":["目录","框架( Frameworks )"],"sub_categories":["框架 frameworks"],"readme":"# swoolefy\n```\n  ______                                _           _ _ _ _\n /  ____|                              | |         |  _ _ _|  _   _\n|  (__     __      __   ___     ___    | |   ___   | |       | | | |\n \\___  \\   \\ \\ /\\ / /  / _ \\   / _ \\   | |  / _ \\  | |_ _ _  | | | |\n ____)  |   \\ V  V /  | (_) | | (_) |  | | | ___/  |  _ _ _| | |_| |\n|_____ /     \\_/\\_/    \\___/   \\___/   |_|  \\___|  | |        \\__, |\n                                                   |_|           | |\n                                                              __ / |\n                                                             |_ _ /\n```  \n\n[![License](https://img.shields.io/packagist/l/bingcool/swoolefy.svg)](https://packagist.org/packages/bingcool/swoolefy)\n[![Latest Stable Version](https://img.shields.io/packagist/v/bingcool/swoolefy.svg)](https://packagist.org/packages/bingcool/swoolefy)\n[![PHP Version Require](https://img.shields.io/packagist/php-v/bingcool/swoolefy.svg)](https://packagist.org/packages/bingcool/swoolefy)\n[![Total Downloads](https://img.shields.io/packagist/dt/bingcool/swoolefy.svg)](https://packagist.org/packages/bingcool/swoolefy)\n\n---\n### 一、📖 简介    \nswoolefy是一个基于swoole实现的轻量级高性能的常驻内存型的协程级应用服务框架，\n高度支持httpApi，websocket，udp服务器，以及基于tcp实现可扩展的rpc服务，worker多进程消费模型  \n同时支持composer包方式安装部署项目。基于实用主义设计出发，swoolefy抽象Event事件处理类，\n实现与底层的回调的解耦，支持协程单例调度，同步|异步调用，全局事件注册，心跳检查，异步任务，多进程(池)，连接池等，\n内置```log、session、mysql、pgsql、redis、mongodb、kafka、amqp、uuid、route midelware、cache、queue、rateLimit、traceId```等常用组件等.    \n\n### 🎯 核心特性\n\n- ⚡ **高性能**: 基于 Swoole 协程，单机支持数万并发连接\n- 🔧 **易扩展**: 自定义进程、进程池、连接池机制\n- 🏗️ **多协议**: HTTP/WebSocket/TCP/UDP/MQTT 统一架构\n- 🎨 **易用性**: Laravel 风格的路由、中间件、ORM\n- 🔄 **热更新**: 文件修改自动重启 Worker，无需停机 (开发环境)\n- 👥 **多进程管理**:\n    - **守护进程 (Daemon)**: 常驻内存，自动拉起多个 Worker 进程，支持进程健康监控和动态扩缩容\n    - **Cron 计划任务**: 类似 Linux crontab，支持 local/fork/url 三种调度模式，定时执行业务逻辑\n- ⚛️ **协程并发**:\n    - **goApp()**: 一键创建协程单例，自动处理 DB/Redis/Curl 等组件的协程隔离\n    - **Parallel**: 限制最大并发数，防止瞬间创建大量协程拖垮下游服务\n    - **GoWaitGroup**: 类似 Go 语言的 WaitGroup，优雅的协程同步等待机制\n- 📦 **组件化**:\n    - **bingcool/library** 大量常用协程组件库 @see https://github.com/bingcool/library\n\n\n### 🏛️ 架构设计\n\n### 进程模型\n\n```\n┌─────────────────────────────────────────────────────┐\n│              Master Process (主进程)                 │\n│  - 管理 Reactor 线程                                  │\n│  - 接收并分发客户端连接                                 │\n└──────────────┬──────────────────────────────────────┘\n               │\n               ▼\n┌─────────────────────────────────────────────────────────┐\n│              Master Process (主进程)                     │\n│  - 管理 Reactor 线程                                      │\n│  - 接收并分发客户端连接                                     │\n└──────────────┬──────────────────────────────────────────┘\n               │\n               ▼\n┌─────────────────────────────────────────────────────────┐\n│              Manager Process (管理进程)                  │\n│  - 管理 Worker 进程池                                    │\n│  - 管理 Task 进程池                                      │\n│  - 管理自定义进程 (通过 addProcess 拉起)                   │\n│  - 进程重启和监控                                         │\n└──────────┬────────────────────┬─────────────────────────┘\n           │                    │\n           ├───────────┬────────┴──────────┐\n           │           │                    │\n    ┌──────▼──────┐ ┌──▼──────────┐ ┌──────▼──────────┐\n    │   Worker    │ │    Task     │ │  User Process   │\n    │  Processes  │ │  Processes  │ │  (MainProcess)  │\n    │  (业务处理)  │ │ (异步任务)   │ │  (管理进程)       │\n    │             │ │             │ │                 │\n    │ - onRequest │ │ - onTask    │ │ 通过 MainManager │\n    │ - onConnect │ │             │ │ 拉起多个 Worker  │\n    │ - onReceive │ │             │ │                 │\n    │             │ │             │ │ - Cron 任务管理   │\n    │ 协程池/组件池 │ │             │ │ - Daemon 常驻     │\n    │ - DB 连接池  │ │             │ │ - 动态进程管理    │\n    │ - Redis 池  │ │             │ │                  │\n    │ - Curl 池   │ │             │ │ run() -\u003e start() │\n    └─────────────┘ └─────────────┘ └──────┬──────────┘\n                                           │\n                          ┌────────────────┼───────────────┐\n                          │                │               │\n                   ┌──────▼─────┐   ┌──────▼─────┐ ┌──────▼─────┐\n                   │   Cron     │   │   Daemon   │ │   Script   │\n                   │  Workers   │   │  Workers   │ │  Workers   │\n                   │ (定时任务)  │   │ (常驻进程)   │ │ (脚本)      │\n                   │            │   │            │ │            │\n                   │ - 定时调度  │   │ - 消息消费   │ │ - 临时脚本  │\n                   │ - 任务队列  │   │ - 数据处理   │ │ - 数据迁移   │ \n                   │ - URL请求  │   │ - 实时计算   │ │ - 修复工具   │\n                   └────────────┘   └────────────┘ └────────────┘\n```\n\n**进程层级说明:**\n\n1. **Master Process**: 最高层级，管理 Reactor 线程和连接分发\n2. **Manager Process**: 第二层级，统一管理所有子进程\n3. **Worker/Task/User Process**: 第三层级，由 Manager 直接管理\n4. **Cron/Daemon/Script Workers**: 第四层级，由 User Process (MainProcess) 通过 `MainManager::start()` 拉起\n\n### http请求处理流程\n\n```\nClient Request\n     ↓\n┌────────────────────────┐\n│ Swoole HTTP Server     │\n│ (Reactor 线程接收)      │\n└───────────┬────────────┘\n            │\n            ↓\n┌────────────────────────┐\n│ Worker Process         │\n│ (onRequest 回调)        │\n└───────────┬────────────┘\n            │\n            ↓\n┌────────────────────────┐\n│ 1. App::__construct()  │\n│    - 加载配置           │\n│    - 初始化协程 ID       │\n└───────────┬────────────┘\n            │\n            ↓\n┌────────────────────────┐\n│ 2. App::run()          │\n│    - parseHeaders()    │\n│    - initCoreComponent()│\n│    - Application::setApp()│ ← 绑定到协程上下文\n│    - defer()           │ ← 注册清理钩子\n└───────────┬────────────┘\n            │\n            ↓\n┌────────────────────────┐\n│ 3. HttpRoute::dispatch()│\n│    - 加载路由配置         │\n│    - 匹配路由            │\n└───────────┬──────────── ┘\n            │\n            ↓\n┌────────────────────────────────┐\n│ 4. 执行中间件 (Middleware)       │\n│    - beforeHandle (前置中间件)   │\n│    - 验证/鉴权/CORS 等           │\n│    - 请求参数处理                │\n└───────────┬────────────────────┘\n            │\n            ↓\n┌────────────────────────────────┐\n│ 5. 调用控制器 Action             │\n│    - Controller::action()      │\n│    - 业务逻辑处理                │\n└───────────┬────────────────────┘\n            │\n            ↓\n┌─────────────────────────────────────┐\n│ 6. 执行业务 (Business Logic)         │\n│                                     │\n│  ┌─────────────────────────────┐   │\n│  │ goApp(function() {          │   │\n│  │     // 协程并发处理           │   │\n│  │     - DB 查询                │   │\n│  │     - Redis 操作             │   │\n│  │     - HTTP 请求              │   │\n│  │     - 文件 IO                │   │\n│  │ })                          │   │\n│  │                             │   │\n│  │ Parallel::run(50, $list,    │   │\n│  │     function($item) {       │   │\n│  │         // 限制并发数处理     │   │\n│  │     }                       │   │\n│  │ )                           │   │\n│  └─────────────────────────────┘   │\n│                                    │\n│  - 协程调度器自动切换                 │\n│  - IO 密集型任务异步执行              │\n│  - CPU 继续执行其他协程               │\n└───────────┬────────────────────────┘\n            │\n            ↓\n┌────────────────────────┐\n│ 7. 后置中间件            │\n│    - afterHandle       │\n│    - 响应格式化          │\n│    - 日志记录            │\n└───────────┬────────────┘\n            │\n            ↓\n┌────────────────────────┐\n│ 8. App::end()          │\n│    - handleLog()       │\n│    - pushComponentPools()│ ← 归还连接池\n│    - clearComponent()  │\n│    - response-\u003eend()   │\n└───────────┬────────────┘\n            │\n            ↓\nClient Response\n```\n\n\n---\n\n### 二、📦 版本选择\n#### 6.x 版本 (推荐 - 最新稳定版)\n\n**最低要求:**\n- PHP \u003e= 8.2\n- Swoole \u003e= 6.1 (推荐使用 Swoole 6.x 最新版本)\n\n**安装命令:**\n```bash\ncomposer require bingcool/swoolefy:^6.1\n```\n\n#### 4.9 LTS 版本 (长期维护版)\n\n**最低要求:**\n- PHP 7.3 ~ 7.4\n- Swoole 4.8.x (推荐 4.8.13+)\n\n**安装命令:**\n```bash\ncomposer require bingcool/swoolefy:^4.9\n```\n\n**选择哪个版本?**  \n1、如果确定项目是使用php81+的，那么直接选择 ```swoole \u003e 5.1.x，推荐直接使用 swoole-6.x.x+ 以上最新版本更好``` 安装，然后选择 ```bingcool/swoolefy:^6.1``` 作为项目分支安装最新稳定版本   \n\n2、如果确定项目是使用 ```php7.3 ~ php7.4``` 的，那么选择 swoole-v4.8+ 版本来进行编译安装(不能直接使用 swoole-cli-v4.8+ 了, 因为其内置的是php8.1，与你的项目的php7不符合)\n所有只能通过编译swoole源码的方式来生成swoole扩展，然后选择 ```bingcool/swoolefy:^4.9``` 作为项目分支稳定版本   \n\n3、依赖编译： ./configure --enable-openssl --enable-sockets --enable-swoole-curl --enable-swoole-pgsql --enable-swoole-stdext --enable-iouring     \n\n4、若不希望自己编译构建，也可以直接使用本目录下的Dockerfile来构建镜像:     \n```\n// 构建镜像\ndocker build --no-cache -t swoolefy-php83-swoole61:v1 -f ./php83-swoole61.Dockerfile .   \n\n// 启动容器(开发环境下 --security-opt seccomp=unconfined的作用是禁用这个默认配置，让容器内的进程可以使用所有系统调用比如io_uring)   \n// 生产环境下建议使用配置文件方式 --security-opt seccomp=./seccomp_profile.json     \n// @see https://github.com/moby/moby/blob/v28.3.3/profiles/seccomp/default.json      \ndocker run -d -it --security-opt seccomp=unconfined --name=swoolefy-php83-v6 swoolefy-php83-swoole61:v1\n\n```\n### 三、⚙️ 实现的功能特性    \n\n#### 基础特性\n- [x] 支持架手脚一键创建项目自动生成最小项目骨架         \n- [x] 支持swagger一键生成api文档     \n- [x] 支持分组路由, 路由中间件middleware, 前置路由组件, 后置路由组件middleware,多模块应用    \n- [x] 支持自定义注册不同根命名空间，快速多项目部署          \n- [x] 支持httpServer，实用轻量Api接口开发     \n- [x] 支持多协议websocketServer、udpServer、mqttServer      \n- [x] 支持基于tcp实现的rpc服务，开放式的系统接口，可自定义协议数据格式，并提供rpc-client协程组件\n- [x] 支持DI容器，组件IOC、配置化，Channel公共组件池            \n- [x] 支持协程单例注册,协程上下文变量寄存    \n- [x] 支持mysql、postgreSql、redis协程组件   \n- [x] 支持全局logger组件，包括system log, runtime log,  request log, sql log     \n- [x] 支持opentelemetry的trace链路追踪组件        \n- [x] 支持分布式锁组件       \n- [x] 支持滑动窗口的流量速率组件        \n- [x] 支持mysql协程连接池\n- [x] 支持redis协程池   \n- [x] 支持curl协程池   \n- [x] 支持protobuf buffer的数据接口结构验证，压缩传输等        \n- [x] 支持异步务管理TaskManager  \n- [x] 定时器管理TickManager  \n- [x] 内存表管理TableManager  \n- [x] 支持自定义进程管理ProcessManager，进程池管理PoolsManger\n- [x] 支持底层异常错误的所有日志捕捉,支持全局日志,包括debug、info、notice、warning、error等级       \n- [x] 支持自定义进程的redis，rabbitmq，kafka的订阅发布，消息队列等      \n- [x] 支持热更新reload worker 监控以及更新                 \n- [x] 支持定时的系统信息采集，并以订阅发布，udp等方式收集至存贮端    \n- [x] 支持命令行形式高度封装启动|停止控制的脚本，简单命令即可管理整个框架, 并对外提供控制启动|停止|重启|查看状态的api接口，可开发成可视化控制页面    \n\n##### 高级特性\n- [x] 支持cron计划任务模式. 类似crontab，支持local|fork|remote url三种方式      \n    \n    | 支持方式  |                          说明                           |\n    |:-----------------------------------------------------:|:---:|\n    | local |                     自定义进程内定时执行代码                      |\n    | fork  | 自定义进程定时拉起一个新的进程，由新的进程去执行任务，可异步，类似laravel的schedule计划任务 |\n    | url   |          自定义进程定时发起远程url请求，可设置callback回调处理结果           |\n\n- [x] 支持daemon模式.worker下后台daemon模式的多进程协程消费模型,包括进程自动拉起，进程数动态调整，进程健康状态监控     \n- [x] 支持console终端脚本模式. 跑完脚本自动退出，可用于修复数据、数据迁移等临时脚本功能      \n- [ ] 支持分布式服务注册（zk，etcd）       \n\n### 四、🔌 适配协程环境组件\n| 组件名称             | 安装                                                    | 说明                                                  |\n|------------------|-------------------------------------------------------|-----------------------------------------------------|\n| predis           | composer require predis/predis:~1.1.7                 | predis组件、或者Phpredis扩展                               |\n| mongodb          | composer require mongodb/mongodb:~1.3                 | mongodb组件，需要使用mongodb必须安装此组件                        |\n| rpc-client       | composer require bingcool/rpc-client:dev-master       | swoolefy的rpc客户端组件，当与rpc服务端通信时，需要安装此组件，支持在php-fpm中使用 |\n| cron-expression  | composer require dragonmantank/cron-expression:~3.3.0 | crontab计划任务组件，类似Linux的crobtab                       |  \n| redis lock       | composer require malkusch/lock                        | Redis锁组件                                            |\n| amqp             | composer require php-amqplib/php-amqplib:~3.7.0       | amqp php原生实现amqp协议客户端                               |  \n| ffmpeg           | composer require php-ffmpeg/php-ffmpeg:~1.4.0         | php proc-open 调用ffmpeg处理音视频                         |  \n| image            | composer require intervention/image:~3.11.0           | php 图像处理组件                                          |    \n| validate         | composer require vlucas/valitron                      | validate数据校验组件                                      |    \n| guzzlehttp       | composer require guzzlehttp/guzzle:~7.9.0             | guzzlehttp 组件                                       | \n| oauth 2.0        | composer require league/oauth2-server                 | oauth 2.0 授权认证组件                                    |  \n| php-standard-library        | composer require php-standard-library/php-standard-library                | php标准库(推荐)                                          |\n| bingcool/library | composer require bingcool/library                     | library组件库                                          |  \n\n### 五、📚 bingcool/library 是 swoolefy require 内置库，专为 swoole 协程实现的组件库        \n实现了包括：    \n- [x] Db ORM Model 组件(支持mysql、 postSql、 sqlite、 Oracle)\n- [x] DB Query Builder 链式操作查询组件      \n- [x] Kafka Producer Consumer组件\n- [x] Rabbitmq Queue组件  \n- [x] Rabbitmq Delay Queue 死信延迟队列组件    \n- [x] Redis Cache组件  \n- [x] Redis Queue队列组件   \n- [x] Redis Delay Queue延迟队列组件            \n- [x] RedisLock锁组件   \n- [x] RateLimit限流组件   \n- [x] Redis Public Subscribe组件    \n- [x] Db、Redis、 Curl协程连接池组件\n- [x] UUid 分布式自增id组件  \n- [x] OpenTelemetry 链路追踪组件      \n- [x] Curl基础组件    \n- [x] Jwt 组件   \n- [x] Validate 组件    \n- [x] Encrypt 加密解密组件   \n- [x] Captcha 验证码组件    \n- [x] Translation 国际化（I18N）    \n   \ngithub: https://github.com/bingcool/library    \n\n\n### 六、📥 安装 \n\n#### 1、先配置环境变量(必须设置)\n```\n// 独立物理机或者云主机配置系统环境变量\nvi /etc/profile\n\n在/etc/profile末尾添加一行，标识环境变量，下面是支持的4个环境,框架将通过这个环境变量区分环境，加载不同的配置\n\nexport SWOOLEFY_CLI_ENV='dev'  // 开发环境\nexport SWOOLEFY_CLI_ENV='test' // 测试环境\nexport SWOOLEFY_CLI_ENV='gra'  // 灰度环境\nexport SWOOLEFY_CLI_ENV='prd'  // 生产环境\n\n// 最后是配置生效\nsource /etc/profile\n\n```\n```\n// 如果是通过dockerfile 创建容器的, 可以根据不同环境生成的内置环境变量不同镜像，每个不同的环境镜像可以用在不同环境，代码将通过这个环境变量区分环境，加载不同的配置\nENV SWOOLEFY_CLI_ENV=dev\n\n```\n#### 2、创建项目\n```\n// 下载代码到到你的自定义目录，这里定义为myproject\ncomposer create-project bingcool/swoolefy:^6.0 myproject   \n```\n\n### 七、📝 添加项目入口启动文件 cli.php,并定义你的项目目录，命名为 App\n\n```php\n\u003c?php\n// 在myproject目录下添加cli.php, 这个是启动项目的入口文件\n\ndate_default_timezone_set('Asia/Shanghai');\ninclude __DIR__.'/vendor/autoload.php';\n\n$appName = ucfirst($_SERVER['argv'][2]);\n// 定义app name\ndefine('APP_NAME', $appName);\n// 启动目录\ndefined('START_DIR_ROOT') or define('START_DIR_ROOT', __DIR__);\n// 应用父目录\ndefined('ROOT_PATH') or define('ROOT_PATH',__DIR__);\n// 应用目录\ndefined('APP_PATH') or define('APP_PATH',__DIR__.'/'.$appName);\n\nregisterNamespace(APP_PATH);\n\n// 你的项目命名为App，对应协议为http协议服务器，支持多个项目的，只需要在这里添加好项目名称与对应的协议即可\ndefine('APP_META_ARR', [\n    'Test' =\u003e [\n        'protocol' =\u003e 'http',\n        'worker_port' =\u003e 9501,\n    ],\n    'App' =\u003e [\n        'protocol' =\u003e 'http',\n        'worker_port' =\u003e 9502,\n    ]\n]);\n// 定义服务端口\ndefine('WORKER_PORT', APP_META_ARR[$appName]['worker_port']);\ndefine('IS_WORKER_SERVICE', 0);\ndefine('IS_DAEMON_SERVICE', 0);\ndefine('IS_SCRIPT_SERVICE', 0);\ndefine('IS_CRON_SERVICE', 0);\ndefine('PHP_BIN_FILE','/usr/bin/php');\n\ndefine('WORKER_START_SCRIPT_FILE', str_contains($_SERVER['SCRIPT_FILENAME'], $_SERVER['PWD']) ? $_SERVER['SCRIPT_FILENAME'] : $_SERVER['PWD'].'/'.$_SERVER['SCRIPT_FILENAME']);\ndefine('WORKER_SERVICE_NAME', makeServerName($appName));\ndefine('WORKER_PID_FILE_ROOT', '/tmp/workerfy/log/'.WORKER_SERVICE_NAME);\ndefine('WORKER_CTL_LOG_FILE',WORKER_PID_FILE_ROOT.'/ctl.log'); \ndefine('SERVER_START_LOG_JSON_FILE', WORKER_PID_FILE_ROOT.'/start.json');\n\n// 启动前处理,比如加载.env\n//$beforeFunc = function () {\n//    try {\n//        \\Test\\LoadEnv::load('192.168.1.101:8848','swoolefy','test','nacos-test','123456');\n//    }catch (\\Throwable $exception) {\n//\n//    }\n//};\n\ninclude __DIR__.'/swoolefy';\n\n\n```\n\n### 八、📂 执行创建你定义的 App 项目\n\n```\n// 你定义的项目目录是App, 在myproject目录下执行下面命令行\n\nphp cli.php create App   \n或者  \nswoole-cli cli.php create App \n\n\n// 执行完上面命令行后，将会自动生成 App 项目目录以及内部子目录\nmyproject\n|—— App           // 应用项目目录\n|     |── Config       // 应用配置\n|     |   |__ component  // 协程单例组件\n|     |      |—— database.php  // 数据库相关组件\n|     |      |—— log.php       // 日志相关组件\n|     |      |—— cache.php     // 缓存组件，可以继续添加其他组件，命名自由\n|     │   ├── dc.php           // 环境配置项\n|     │   └── constants.php\n|     |   |—— app.php          // 应用层配置\n|     |\n|     ├── Controller\n|     │   └── IndexController.php  // 控制器层\n|     ├── Model\n|     │   └── ClientModel.php      // 数据模型层\n|     ├── Module        // 模块层\n|     ├── Protocol      // 协议配置\n|     │   ├── conf.php  // 全局配置\n|     │\n|     ├── Router\n|     │   └── api.php   // 路由文件，不同模块定义不同文件即可\n|     |—— Storage\n|     |   |—— Crontab   // cron service 的调度日志\n|     |   |—— Logs      // 日志文件目录\n|     |   |—— Sql       // sql 日志目录\n|     |—— Scripts\n|     |   |—— Kernel.php    // 计划任务定义\n|     |__ .env              // 自动生成环境变量文件\n|     │—— autoloader.php    // 自定义项目自动加载\n|     |—— Event.php         // 事件实现类\n|     |—— HttpServer.php    // http server\n|    \n|——— src            // 源码\n|——— cli.php        // http应用启动入口文件\n|——— cron.php       // 定时 worker 任务的多进程启动入口文件\n|——— daemon.php     // 守护进程 worker 的多进程启动入口文件\n|——— script.php     // 脚本启动入口文件\n|——— swag.php       // 生成 swagger 接口文档入口文件\n\n```\n\n### 九、🚀 启动 http应用项目\n\n**http应用启动命令行**\n\n```\n// 终端启动 ctl+c 停止进程\nphp cli.php start App\n或者    \nswoole-cli cli.php start App\n\n// 守护进程方式启动,添加-D参数控制\nphp cli.php start App --daemon=1\n或者  \nswooole-cli cli.php start App --daemon=1\n\n// 停止进程 \nphp cli.php stop App\n\n或者   \nswooole-cli cli.php stop App --force=1\n\n// 查看进程状态\nswooole-cli cli.php status App\n\n// 完全重启服务\nphp cli.php restart App    \n或者    \nswooole-cli cli.php restart App\n\n```\n\n**启动Cron定时计划任务服务**\n\n```\n// 创建生成Cron定时计划任务服务,默认生成WorkerCron目录\n\nphp script.php start App --c=gen:cron:service\n\n// 启动Cron服务, CTRL+C 停止进程\n\nphp cron.php start App\n\n// --daemon=1 以守护进程启动\n\nphp cron.php start App --daemon=1\n\n// 重启Cron服务\n\nphp cron.php restart App\n\n\n\n// 停止Cron服务，终端交互询问需要输入`yes` or `no` 再次确认是否需要停止服务\n\nphp cron.php stop App\n\n// --force=1 强制停止Cron服务，不询问直接停止服务\n\nphp cron.php stop App --force=1\n\n```\n\n**启动Daemon常驻进程服务**\n\n```\n// 创建生成Daemon常驻进程消费服务,默认生成WorkerDaemon目录\n\nphp script.php start App --c=gen:daemon:service\n\n// 启动Daemon服务，CTRL+C 停止进程\n\nphp daemon.php start App \n\n// --daemon=1 以守护进程启动\n\nphp daemon.php start App --daemon=1\n\n// 重启Daemon服务\n\nphp daemon.php restart App\n\n\n\n\n// 停止Daemon服务, 终端交互询问是否需要输入`yes` or `no` 再次确认是否需要停止服务\n\nphp daemon.php stop App\n\n// --force=1 强制停止Daemon服务，不询问直接停止服务\n\nphp daemon.php stop App --force=1\n\n\n```\n\n### 十、🌐 访问\n\n默认端口是9502,可以通过 http://localhost:9502 访问默认控制器\n```php\n\u003c?php\nnamespace App\\Controller;\n\nuse Swoolefy\\Core\\Application;\nuse Swoolefy\\Core\\Controller\\BController;\n\n// 默认生成的IndexController\nclass IndexController extends BController {\n\n    public function index() {\n        // 最简单的协程单例，goApp()即可创建一个协程,在单例中的db,redis等其他注册的组件都是单例的，不同协程单例相互隔离  \n        goApp(function() {\n            var_dump('this is a coroutine single app test');\n        });\n        \n        Application::getApp()-\u003eresponse-\u003ewrite('\u003ch1\u003eHello, Welcome to Swoolefy Framework! \u003ch1\u003e');\n    }\n}\n\n```\n\n至此一个最简单的http的服务就创建完成了，更多例子请参考项目下Test的demo\n\n\n### 十一、🧩 定义组件\n\n1、应用层配置文件：Config/app.php\n\n```php\n\u003c?php\nreturn [\n\n    // db|redis连接池\n    'component_pools' =\u003e [\n        // 取components的`DB`组件名称相对应\n        'db' =\u003e [\n            'max_pool_num' =\u003e 5, // db实例数\n            'max_push_timeout' =\u003e 2, // db实例进入channel池最长等待时间，单位s\n            'max_pop_timeout' =\u003e 1, // db实例出channel池最长等待时间，单位s.在规定时间内获取不到db对象，将降级为实时创建db实例\n            'max_life_timeout' =\u003e 10, // db实例的有效期，单位s.过期后将被掉弃，重新创建新DB实例\n            'enable_tick_clear_pool' =\u003e 0 // 是否每分钟定时清空pool，防止长时间一直占用链接，max_pool_num设置很大的时候需要设置，否则不需要设置\n        ],\n    \n        // 取components的`redis`组件名称相对应\n        'redis' =\u003e [\n            'max_pool_num' =\u003e 5,\n            'max_push_timeout' =\u003e 2,\n            'max_pop_timeout' =\u003e 1,\n            'max_life_timeout' =\u003e 10,\n            'enable_tick_clear_pool' =\u003e 0 // 是否每分钟定时清空pool，防止长时间一直占用链接，max_pool_num设置很大的时候需要设置，否则不需要设置\n        ]\n    ],\n    \n     // default_db\n    'default_db' =\u003e 'db',\n\n    // 加载组件配置\n    'components' =\u003e \\Swoolefy\\Core\\SystemEnv::loadComponent()\n    \n    // 其他配置\n    ......\n]\n\n```\n\n2、组件Component.php\n```php\n\u003c?php\n\n$dc = \\Swoolefy\\Core\\SystemEnv::loadDcEnv();\n\nreturn [\n    // 用户行为记录的日志\n    'log' =\u003e function($name) {\n        $logger = new Log($name);\n        $logger-\u003esetChannel('application');\n        if(SystemEnv::isDaemonService()) {\n            $logFilePath = LOG_PATH.'/daemon/info.log';\n        }else if (SystemEnv::isScriptService()) {\n            $logFilePath = LOG_PATH.'/script/info.log';\n        }else if (SystemEnv::isCronService()) {\n            $logFilePath = LOG_PATH.'/cron/info.log';\n        } else {\n            $logFilePath = LOG_PATH.'/cli/info.log';\n        }\n        $logger-\u003esetLogFilePath($logFilePath);\n        return $logger;\n    },\n\n    // 用户行为记录错误日志\n    'error_log' =\u003e function($name) {\n        $logger = new Log($name);\n        $logger-\u003esetChannel('application');\n        if(SystemEnv::isDaemonService()) {\n            $logFilePath = LOG_PATH.'/daemon/error.log';\n        }else if (SystemEnv::isScriptService()) {\n            $logFilePath = LOG_PATH.'/script/error.log';\n        }else if (SystemEnv::isCronService()) {\n            $logFilePath = LOG_PATH.'/cron/error.log';\n        } else {\n            $logFilePath = LOG_PATH.'/cli/error.log';\n        }\n        $logger-\u003esetLogFilePath($logFilePath);\n        return $logger;\n    },\n\n    // 系统捕捉抛出异常错误日志\n    'system_error_log' =\u003e function($name) {\n        $logger = new \\Swoolefy\\Util\\Log($name);\n        $logger-\u003esetChannel('application');\n        if(SystemEnv::isDaemonService()) {\n            $logFilePath = LOG_PATH.'/daemon/system_error.log';\n        }else if (SystemEnv::isScriptService()) {\n            $logFilePath = LOG_PATH.'/script/system_error.log';\n        }else if (SystemEnv::isCronService()) {\n            $logFilePath = LOG_PATH.'/cron/system_error.log';\n        } else {\n            $logFilePath = LOG_PATH.'/cli/system_error.log';\n        }\n        $logger-\u003esetLogFilePath($logFilePath);\n        return $logger;\n    }\n    \n    // Redis Cache\n    'redis' =\u003e function() use($dc) {\n        $redis = new \\Common\\Library\\Redis\\Redis();\n        $redis-\u003econnect($dc['redis']['host'], $dc['redis']['port']);\n        return $redis;\n    },\n    \n    // Predis Cache\n    'predis' =\u003e function() use($dc) {\n        $predis = new \\Common\\Library\\Redis\\predis([\n            'scheme' =\u003e $dc['predis']['scheme'],\n            'host'   =\u003e $dc['predis']['host'],\n            'port'   =\u003e $dc['predis']['port'],\n        ]);\n        return $predis;\n    }\n    \n```\n\n### 十二、💡 使用组件\n```php\nuse Swoolefy\\Core\\Application;\n\nclass TestController extends BController {\n    /**\n    * 控制器\n    */\n    public function test() {\n        // 获取组件，组件就是配置回调中定义的组件\n        $redis = Application::getApp()-\u003eredis;\n        //或者通过get指明组件名获取(推荐)\n        // $redis = Application::getApp()-\u003eget('redis');\n\n        // swoole hook 特性，这个过程会发生协程调度\n        $redis-\u003eset('name', swoolefy);\n\n        // predis组件\n        $predis = Application::getApp()-\u003epredis;\n        //或者通过get指明组件名获取(推荐)\n        // $predis = Application::getApp()-\u003eget('predis');\n        \n        // 这个过程会发生协程调度\n        $predis-\u003eset('predis','this is a predis instance');\n        $predis-\u003eget('predis');\n        \n        // PDO的mysql实例，这个过程会发生协程调度\n        $db = Application::getApp()-\u003edb;\n        // 或者\n        // $mysql = Application::getApp()-\u003eget('db');\n        // 添加一条数据\n        $sql = \"INSERT INTO `user` (`username` ,`sex`) VALUES (:username, :sex)\"; \n        $numRows = $db-\u003ecreateCommand($sql)-\u003einsert([\n            ':username'=\u003e'bingcool-test',\n            ':sex' =\u003e 1\n        ]);\n        var_dump($numRows)\n        \n        // DB Query查询\n         $db = Application::getApp()-\u003edb;\n         $db-\u003enewQuery()-\u003etable('user')-\u003ewhere([\n            'user_id' =\u003e 10000\n         ])-\u003eselect()\n         \n         // DB 插入单条数据\n         $data = [\n            'username'=\u003e'bingcool-test',\n            'sex' =\u003e 1\n         ]\n         $db = Application::getApp()-\u003edb;\n         $db-\u003enewQuery()-\u003etable('user')-\u003einsert($data);\n         \n         // DB 插入多条数据\n         $data = \n         [\n            [\n                'username'=\u003e'bingcool-test1111',\n                'sex' =\u003e 1\n            ],\n            [\n                'username'=\u003e'bingcool-test2222',\n                'sex' =\u003e 1\n            ]\n         ]\n         $db = Application::getApp()-\u003edb;\n         $db-\u003enewQuery()-\u003etable('user')-\u003einsertAll($data);\n         \n         \n        // 查询\n        $result = $db-\u003ecreateCommand('select * from user where id\u003e:id')-\u003equeryOne([':id'=\u003e100]);\n        var_dump($result);    \n\n        // pg实例    \n        $pg = Application::getApp()-\u003eget('pg');   \n        // 添加一条数据   \n        $sql = \"INSERT INTO `user` (username ,sex) VALUES (:username, :sex)\"; \n        $pg-\u003ecreateCommand($sql)-\u003einsert([\n            ':username'=\u003e'bingcool-test',\n            ':sex' =\u003e 1\n        ]);\n    }\n}\n\n```\n\n\n### 十三、⚙️ 默认协议层全局配置文件 Protocol/conf.php\n\n*配置项*\n\n开发者可以根据实际使用适当调整\n\n```php\n$dc = \\Swoolefy\\Core\\SystemEnv::loadDcEnv();\n\nreturn [\n    // 应用层配置\n    'app_conf'                 =\u003e \\Swoolefy\\Core\\SystemEnv::loadAppConf(), // 应用层配置\n    'application_index'        =\u003e '',\n    'event_handler'            =\u003e \\Test\\Event::class,\n    'exception_handler'        =\u003e \\Test\\Exception\\ExceptionHandle::class,\n    'response_formatter'       =\u003e \\Swoolefy\\Core\\ResponseFormatter::class,\n    'master_process_name'      =\u003e 'php-swoolefy-http-master',\n    'manager_process_name'     =\u003e 'php-swoolefy-http-manager',\n    'worker_process_name'      =\u003e 'php-swoolefy-http-worker',\n    'www_user'                 =\u003e '',\n    'host'                     =\u003e '0.0.0.0',\n    'port'                     =\u003e '9501',\n    'time_zone'                =\u003e 'PRC',\n    'swoole_process_mode'      =\u003e SWOOLE_PROCESS,\n    'include_files'            =\u003e [],\n    'runtime_enable_coroutine' =\u003e true,\n\n    // swoole setting\n\t'setting' =\u003e [\n        'admin_server'           =\u003e '0.0.0.0:9503',\n        'reactor_num'            =\u003e 1,\n        'worker_num'             =\u003e 4,\n        'max_request'            =\u003e 10000,\n        'task_worker_num'        =\u003e 2,\n        'task_tmpdir'            =\u003e '/dev/shm',\n        'daemonize'              =\u003e 0,\n        'dispatch_mode'          =\u003e 3,\n        'reload_async'           =\u003e true,\n        'enable_coroutine'       =\u003e 1,\n        'task_enable_coroutine'  =\u003e 1,\n        // 压缩\n        'http_compression'       =\u003e true,\n        // $level 压缩等级，范围是 1-9，等级越高压缩后的尺寸越小，但 CPU 消耗更多。默认为 1, 最高为 9\n        'http_compression_level' =\u003e 1,\n        'log_file'               =\u003e \\Swoolefy\\Core\\SystemEnv::loadLogFile('/tmp/' . APP_NAME . '/swoole_log.txt'),\n        'pid_file'               =\u003e \\Swoolefy\\Core\\SystemEnv::loadPidFile('/data/' . APP_NAME . '/log/server.pid'),\n\t],\n\n    'coroutine_setting' =\u003e [\n        'max_coroutine' =\u003e 50000\n    ],\n\n    // 是否内存化线上实时任务\n    'enable_table_tick_task' =\u003e true,\n\n    // 内存表定义\n    'table' =\u003e [\n        'table_process' =\u003e [\n             // 内存表建立的行数,取决于建立的process进程数,最小值64\n             'size' =\u003e 64,\n              // 定义字段\n              'fields'=\u003e [\n                     ['pid','int', 10],\n                     ['process_name','string', 56],\n                  ]\n               ]\n     ],\n\n    // 依赖于EnableSysCollector = true，否则设置没有意义,不生效\n    'enable_pv_collector'  =\u003e false,\n    'enable_sys_collector' =\u003e true,\n    'sys_collector_conf' =\u003e [\n        'type'           =\u003e SWOOLEFY_SYS_COLLECTOR_UDP,\n        'host'           =\u003e '127.0.0.1',\n        'port'           =\u003e 9504,\n        'from_service'   =\u003e 'http-app',\n        'target_service' =\u003e 'collectorService/system',\n        'event'          =\u003e 'collect',\n        'tick_time'      =\u003e 2,\n        'callback'       =\u003e function () {\n            $sysCollector = new \\Swoolefy\\Core\\SysCollector\\SysCollector();\n            return $sysCollector-\u003etest();\n        }\n    ],\n\n    // 热更新\n    'reload_conf'=\u003e [\n        'enable_reload'     =\u003e false, // 是否启用热文件更新功能       \n        'after_seconds'     =\u003e 3, // 检测到只要有文件更新，3s内不在检测，等待重启既可     \n        'monitor_path'      =\u003e APP_PATH, // 开发者自己定义目录\n        'reload_file_types' =\u003e ['.php', '.html', '.js'],\n        'ignore_dirs'       =\u003e [],\n        'callback'          =\u003e function () {}\n    ]\n];\n\n```\n### 十四、🛣️ 路由系统\n\n支持类似 Laravel 的分组路由和中间件:\n\n*Router/api.php*\n\n```php\n\n\u003c?php\nuse Swoolefy\\Http\\Route;\nuse Swoolefy\\Http\\RequestInput;\n\n// 直接路由-不分组\nRoute::get('/index/index', [\n    'beforeHandle' =\u003e function(RequestInput $requestInput) {\n        Context::set('name', 'bingcool');\n        $name = $requestInput-\u003egetPostParams('name');\n    },\n\n    // 这里需要替换长对应的控制器命名空间\n    'dispatch_route' =\u003e [\\Test\\Controller\\IndexController::class, 'index'],\n\n    'afterHandle' =\u003e function(RequestInput $requestInput) {\n\n    },\n    'afterHandle1' =\u003e function(RequestInput $requestInput) {\n\n    },\n]);\n\n// 分组路由\nRoute::group([\n    // 路由前缀\n    'prefix' =\u003e 'api',\n    // 路由中间件,多个按顺序执行\n    'middleware' =\u003e [\n        \\Test\\Middleware\\Route\\ValidLoginMiddleware::class,\n    ]\n], function () {\n\n    Route::get('/', [\n        // 前置路由,闭包函数形式\n        'beforeHandle' =\u003e function(RequestInput $requestInput) {\n            var_dump('beforeHandle');\n        },\n\n        // 前置路由,中间件类形式(推荐)\n        'beforeHandle2' =\u003e \\Test\\Middleware\\Route\\ValidLoginMiddleware::class,\n\n        // 前置路由,中间件数组类形式(推荐)\n        'beforeHandle3' =\u003e [\n            \\Test\\Middleware\\Route\\ValidLoginMiddleware::class,\n            \\Test\\Middleware\\Route\\ValidLoginMiddleware::class,\n        ],\n\n        // 控制器action\n        'dispatch_route' =\u003e [\\Test\\Controller\\IndexController::class, 'index'],\n\n        // 后置路由\n        'afterHandle1' =\u003e function(RequestInput $requestInput) {\n            var_dump('afterHandle');\n        },\n\n        // 前置路由,中间件类形式(推荐)\n        'afterHandle2' =\u003e \\Test\\Middleware\\Route\\ValidLoginMiddleware::class,\n\n        // 前置路由,中间件数组类形式(推荐)\n        'afterHandle3' =\u003e [\n            \\Test\\Middleware\\Route\\ValidLoginMiddleware::class,\n            \\Test\\Middleware\\Route\\ValidLoginMiddleware::class\n        ],\n    ]);\n});\n\n```\n\n### 十五、🗄️ 数据库操作\n```php\n\n$db = Application::getApp()-\u003eget('db');\n// 插入单条数据\n$db-\u003enewQuery()-\u003etable('tbl_users')-\u003einsert([\n            'user_name' =\u003e '李四-'.rand(1,9999),\n            'sex' =\u003e 0,\n            'birthday' =\u003e '1991-07-08',\n            'phone' =\u003e 12345678\n    ]);\n\n// 批量插入\n$db-\u003enewQuery()-\u003etable('tbl_users')-\u003einsertAll([\n            [\n                'user_name' =\u003e '李四-'.rand(1,9999),\n                'sex' =\u003e 0,\n                'birthday' =\u003e '1991-07-08',\n                'phone' =\u003e 12345678\n            ],\n            [\n                'user_name' =\u003e '李四-'.rand(1,9999),\n                'sex' =\u003e 0,\n                'birthday' =\u003e '1991-07-08',\n                'phone' =\u003e 12345678\n            ]\n    ]);\n\n\n// 查询列表\n$db-\u003enewQuery()-\u003etable('tbl_users')-\u003ewhere('id','\u003e', 1)-\u003efield(['id', 'user_name'])-\u003elimit(0,10)-\u003eselect();\n\n// 查询单条\n$db-\u003enewQuery()-\u003etable('tbl_users')-\u003ewhere(['id', '=', 100])-\u003efield(['id', 'user_name'])-\u003efind();\n\n.....还有很多其他链式操作\n\n```\n\n### 十六、⚡ 协程单例\n\n*协程单例*  \n```php\n\n// 协程单例使用goApp直接调用创建, 每个协程的DB，redis,kafka,mq的socket对象相互隔离，互不影响，代码通用\ngoApp(function() {\n    $db = Application::getApp()-\u003eget('db');\n    // 查询列表\n    $db-\u003enewQuery()-\u003etable('tbl_users')-\u003ewhere('id','\u003e', 1)-\u003efield(['id', 'user_name'])-\u003elimit(0,10)-\u003eselect();\n    // redis\n    $redis = Application::getApp()-\u003eget('redis');\n    $redis-\u003eset('name','bingcool');\n   \n    // 再开启一个协程单例\n    goApp(function() {\n        // $db1与父级协程的$db完全隔离，不是同一个对象\n        $db1 = Application::getApp()-\u003eget('db');\n    })\n})\n\n```\n\n*协程隔离示意图:*\n\n```php\n    协程 A (cid=1001)              协程 B (cid=1002)\n    ↓                              ↓\n    App Instance A                App Instance B\n    ↓                              ↓\n    containers['db'] A         containers['db'] B\n    ↓                              ↓\n    Redis Object A                Redis Object B\n    (独立 Socket 连接)              (独立 Socket 连接)\n\n```\n### 十七、⚡ 协程并发  \n#### Parallel 并发限制器\n\n```php\nuse Swoolefy\\Core\\Coroutine\\Parallel;\n\n// 场景：有 1000 个请求，限制每次并发 50 个\n$parallel = new Parallel(50);\n\nfor ($i = 0; $i \u003c 1000; $i++) {\n    $parallel-\u003eadd(function() use ($i) {\n        // 协程任务\n        $result = file_get_contents(\"http://api.example.com/data?id={$i}\");\n        return json_decode($result, true);\n    }, \"key_{$i}\");\n}\n\n// 长等待10s获取结果\n$results = $parallel-\u003erunWait(10.0);\n\n\n// 场景：少量的请求，通过add添加闭包\n$parallel = new Parallel();\n$parallel-\u003eadd(function() {\n    return file_get_contents(\"http://api.example.com/data\");\n}, \"key1\");\n\n$parallel-\u003eadd(function() {\n    return file_get_contents(\"http://api.example.com/data\");\n}, \"key2\");\n\n$parallel-\u003eadd(function() {\n    return file_get_contents(\"http://api.example.com/data\");\n}, \"key3\");\n\n// 最长等待10s获取结果\n$parallel-\u003erunWait(10.0)\n\n\n```\n\n#### Parallel::run 迭代并发\n\n```php\nuse Swoolefy\\Core\\Coroutine\\Parallel;\n\n// 分批处理大数据集(无需等待数据返回)\n$list = range(1, 10000);\n\nParallel::run(\n    100,           // 每批 100 个协程\n    $list,         // 数据数组\n    function($item) {\n        // 处理每个元素\n        echo \"Processing: {$item}\\n\";\n    },\n    0.01          // 每批间隔 0.01 秒\n);\n```\n\n#### GoWaitGroup\n\n```php\nuse Swoolefy\\Core\\Coroutine\\GoWaitGroup;\n\n$wg = new GoWaitGroup();\n\nfor ($i = 0; $i \u003c 10; $i++) {\n    $wg-\u003eadd();\n    go(function() use ($wg, $i) {\n        try {\n            // 并发任务\n            sleep(1);\n            echo \"Task {$i} done\\n\";\n        } finally {\n            $wg-\u003edone();\n        }\n    });\n}\n\n$wg-\u003ewait();  // 等待所有任务完成\n```\n\n### 十八、📄 swagger 接口文档生成\n\n在Test/Module/Order/Validation下，每个文件对应一个Controller的方法，可以使用php8的attribute注解定义好接口，然后执行 php swag.php Test 即可自动生成openapi.yaml文件\n在浏览器直接访问: http:127.0.0.1:9501/swagger.html\n\n```php\nnamespace Test\\Module\\Order\\Validation;\n\nuse OpenApi\\Attributes as OA;\nuse Test\\Module\\Swag;\n\nclass UserOrderValidation\n{\n    // Post请求的参数\n    #[OA\\Post(\n        path: '/user/user-order/userList',\n        summary:'订单保存',\n        description:'保存订单',\n        tags: [Swag::MODULE_TAG_ORDER], // 根据Swag.php的注册的tag值来设置，相同的tag的接口将汇集在同一个模块下\n        security: [['apiKeyAuth' =\u003e []], ['appId' =\u003e []]], //指定了在哪些接口上应用SecurityScheme中已经定义的安全方案\n        requestBody: new OA\\RequestBody(\n            required: true,\n            content: new OA\\MediaType(\n                mediaType: \"application/json\",// 或者application/x-www-form-urlencoded\n                schema: new OA\\Schema(\n                    type: 'object',\n                    required:['name'],\n                    properties: [\n                        // 字符串\n                        new OA\\Property(property: 'name', type: 'string', description:'名称'\n                        ),\n                        // 字符串\n                        new OA\\Property(property: 'email', type: 'string', description:'邮件'\n                        ),\n                        // 整型\n                        new OA\\Property(property: 'product_num', type: 'integer', description:'产品数量'\n                        ),\n                        // 数组 phone =\u003e [1111, 22222]\n                        new OA\\Property(property: 'phone', type: 'array', description:'电话', items: new OA\\Items(\n                            type: 'integer'\n                        )),\n\n                        // 一维关联数组(对象) address = ['sheng' =\u003e '广东省', 'city' =\u003e '深圳市'，'area'=\u003e'宝安区'],\n                        new OA\\Property(property: 'address', type: 'object', description:'居住地址',\n                            properties:[\n                                // sheng\n                                new OA\\Property(property: 'sheng', type: 'string', description:'省份'\n                                ),\n                                // city\n                                new OA\\Property(property: 'city', type: 'string', description:'城市'\n                                ),\n                                // area\n                                new OA\\Property(property: 'area', type: 'string', description:'县/区'\n                                ),\n                            ]\n                        ),\n\n                        // 二维关联数组 addressList =\u003e [\n                        //      ['sheng' =\u003e '广东省', 'city' =\u003e '深圳市'，'area'=\u003e'宝安区'],\n                        //      ['sheng' =\u003e '广东省', 'city' =\u003e '深圳市'，'area'=\u003e'宝安区']\n                        //  ]\n                        new OA\\Property(property: 'addressList', type: 'array', description:'地址列表', items: new OA\\Items(\n                            type: 'object',\n                            properties:[\n                                // sheng\n                                new OA\\Property(property: 'sheng', type: 'string', description:'省份'\n                                ),\n                                // city\n                                new OA\\Property(property: 'city', type: 'string', description:'城市'\n                                ),\n                                // area\n                                new OA\\Property(property: 'area', type: 'string', description:'县/区'\n                                ),\n                            ]\n                        )),\n                    ]\n                )\n            )\n        )\n    )]\n\n    #[OA\\Response(\n        response: 200,\n        description: '操作成功'\n    )]\n\n    public function userList(): array\n    {\n        return [\n            'rules' =\u003e [\n                    'name' =\u003e 'required|float|json',\n                    'order_ids' =\u003e 'required|array',\n                    'order_ids.*' =\u003e 'int'\n            ],\n\n            'messages' =\u003e [\n                    'name.required' =\u003e '名称必须',\n                    'name.json' =\u003e '名称必须json字符串',\n            ]\n        ];\n    }\n\n    /**\n     * @return array[]\n     */\n    #[OA\\Get(\n        path: '/user/user-order/userList1',\n        summary:'订单列表',\n        description:'获取订单列表内容111',\n        tags: [Swag::MODULE_TAG_ORDER],// 根据Swag.php的注册的tag值来设置，相同的tag的接口将汇集在同一个模块下\n        security: [['apiKeyAuth' =\u003e []], ['appId' =\u003e []]], //指定了在哪些接口上应用SecurityScheme中已经定义的安全方案\n    )]\n    // Get Query\n    #[OA\\QueryParameter(name: 'order_id', description: \"订单ID\", required: true, allowEmptyValue: false, allowReserved: true, schema: new OA\\Schema(type:'integer')\n    )]\n    // Get Query\n    #[OA\\QueryParameter(name: 'product_name', description: '产品名称', required: true, allowEmptyValue: true, allowReserved: true, schema: new OA\\Schema(type:'string')\n    )]\n\n    // Get Query array eg: ids[1]=22\u0026ids[2]=333\n    #[OA\\QueryParameter(name: 'product_ids', description: '产品名称', required: true, allowEmptyValue: true, allowReserved: true, schema: new OA\\Schema(\n        type:'array',\n        items: new OA\\Items(\n            type:'integer'\n        )\n    ))]\n    #[OA\\Response(\n        response: 200,\n        description: '操作成功'\n    )]\n    public function userList1(): array\n    {\n        return [\n            'rules' =\u003e [\n               \n            ],\n\n            'messages' =\u003e [\n            ]\n        ];\n    }\n}\n\n```\n\n\n### License\nMIT   \nCopyright (c) 2017-2026 zengbing huang    \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbingcool%2Fswoolefy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbingcool%2Fswoolefy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbingcool%2Fswoolefy/lists"}