webman目录结构与生命周期遵循约定优于配置原则:app/存核心逻辑,config/管配置,public/为文档根,runtime/存临时文件,support/提供底层类;进程独立启动与销毁,请求创建独立$request对象,控制器可复用或每次新建,变量生命周期依php原生机制。

如果您刚刚接触Webman框架,面对项目文件夹中众多目录和配置项感到困惑,则可能是由于不了解其标准化结构与各组件的运行时行为。以下是理解Webman目录结构与核心生命周期的关键解析步骤:
一、标准目录结构说明
Webman采用约定优于配置的设计理念,所有目录位置与用途均有明确规范,便于开发者快速定位功能模块并维护代码一致性。该结构在项目初始化后即固定,不依赖运行时动态生成。
1、app/ 目录存放应用核心逻辑,包含控制器(controller)、模型(model)、视图(view)、中间件(middleware)及进程管理(process)子目录。
2、config/ 目录集中管理全部配置文件,如数据库连接、路由规则、中间件注册及应用级开关(例如 controller_reuse)。
3、public/ 目录为Web服务器文档根路径,仅暴露入口文件(start.php)及静态资源(CSS、JS、图片等),保障其余代码不被直接访问。
4、runtime/ 目录用于存储运行时产生的临时文件,包括日志(log)、缓存(cache)、会话(session)及PID文件,需确保Web服务器用户具有写权限。
5、support/ 目录提供框架底层辅助类,如 Request、Response、Container、Event 等,不建议直接修改,应通过继承或扩展方式复用。
二、进程生命周期解析
每个Webman工作进程独立启动、独立持有资源、独立响应请求,其生命周期从 start.php 启动命令触发开始,至收到 stop/reload/restart 信号后主动退出结束。进程间不共享内存或变量实例。
1、进程启动时加载全部配置与类定义,执行 config/bootstrap.php 中的初始化逻辑。
2、进程持续监听事件循环,接收来自Workerman的连接与请求,不因单个请求失败而中断整体服务。
3、进程内所有静态属性、全局变量、数据库连接、单例对象均被该进程独占,多个进程各自初始化一次。
4、当执行 php start.php reload 时,主进程 fork 新进程并优雅关闭旧进程,实现零停机更新。
三、请求生命周期解析
每次HTTP请求进入后,Webman会创建一个独立的 $request 对象,该对象贯穿整个请求处理链,最终随请求结束被PHP垃圾回收机制自动销毁,不残留于内存中。
1、请求抵达后,Router 根据 path 和 method 匹配对应控制器方法,并注入新构建的 Request 实例。
Webman 2.2.0版本强化了 TCP/UDP 服务支持,优化路由组管理,并增强异步任务处理能力。结合协程与连接池技术,Webman 能轻松应对高并发场景,适用于网站、接口服务、即时通讯、物联网及游戏开发,兼具高性能、灵活扩展与稳定可靠,是多场景 PHP 服务开发的理想选择。
2、中间件按注册顺序依次执行,可读取或修改 $request 与 $response 对象,但不可跨请求保留状态。
3、控制器方法返回值交由 Response 组件封装,经输出缓冲与头信息设置后发送至客户端。
4、请求结束后,$request 及其内部临时变量(含 new 创建的对象)立即解除引用,等待下一轮GC回收。
四、控制器生命周期控制
控制器实例是否复用由 config/app.php 中的 controller_reuse 配置项决定,该设置直接影响内存占用与数据隔离性,需根据业务场景谨慎选择。
1、当 controller_reuse = false 时,每个请求均新建控制器实例,构造函数每次执行,适合有状态操作或需强隔离的场景。
2、当 controller_reuse = true 时,控制器实例在进程生命周期内常驻,构造函数仅首次调用,后续请求复用同一实例。
3、启用复用时,禁止在构造函数中初始化可变状态(如数组、对象引用),否则将导致跨请求数据污染。
4、若需在复用模式下获取新实例,应使用 Container::make() 显式创建,而非依赖自动注入。
五、变量与对象生命周期遵循PHP原生机制
Webman未修改PHP默认内存管理策略,所有局部变量、函数参数、方法内 new 出的对象,在作用域结束时自动解除引用;仅静态属性、全局变量、长生命周期对象(如复用控制器、容器单例)会延续至进程退出。
1、控制器方法中声明的 $foo = new Foo() 在方法返回后立即失去引用,无需手动 unset。
2、若将对象赋值给控制器的实例属性(如 $this->cache),且控制器被复用,则该对象将持续存在直至进程终止。
3、使用 Container::get() 获取的类实例在容器内单例保存,同进程内多次调用返回同一对象。
4、使用 Container::make() 获取的类实例每次均为全新对象,不参与容器级复用,适用于带构造参数的场景。










