不一定能直接装成功。workerman 不依赖 psr-4 自动加载,需手动引入 autoload.php 并编写 start.php 入口;要求 php 7.2+、启用 pcntl/posix 扩展,且不支持 windows 生产环境。

composer require workerman/workerman 能直接装成功吗
不一定。很多人执行 composer require workerman/workerman 后发现项目跑不起来,甚至 php start.php start 报错说找不到类——根本原因是 Workerman 不依赖 autoloader 的常规 PSR-4 加载逻辑,它需要手动引入启动文件,且对 PHP 版本、扩展有硬性要求。
常见错误现象:Class 'Workerman\Worker' not found,或启动时提示 pcntl_fork() is disabled。
- 必须用 PHP 7.2+(推荐 8.0+),低于 7.2 会因语法报错
- Linux/macOS 环境下必须启用
pcntl和posix扩展(Windows 只能开发调试,不支持生产) -
composer require只装包,不会自动创建start.php或配置进程管理,得自己写入口文件 - 如果项目已存在
autoload-dev或自定义加载规则,可能干扰 Workerman 自身的require_once加载链
workerman/start.php 入口文件怎么写才不崩
Workerman 的启动逻辑非常轻量,但极容易因路径、命名空间或启动方式写错而失败。它不走 Laravel 那套容器和服务注册,所有 Worker 实例靠 new Worker() 显式创建,靠 Worker::runAll() 统一调度。
最简可用示例(保存为 start.php,和 vendor/ 同级):
<?php
use Workerman\Worker;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker('text://0.0.0.0:1234');
$worker->onMessage = function($connection, $data) {
$connection->send('Hello ' . $data);
};
Worker::runAll();
-
require_once必须放在use之后、实例化之前,否则类找不到 -
Worker构造函数第一个参数是监听协议+地址,text://是纯文本协议,别写成http://(那是 WebServer 的用法) - 不能在 CLI 以外环境(如 Web Server 的 PHP-FPM)里执行
start.php,否则pcntl_fork()会直接失败 - 修改代码后必须手动
php start.php stop && php start.php start,它不支持热重载
workerman 启动报 pcntl_fork() is disabled 怎么办
这是 Linux/macOS 下最典型的权限卡点:PHP 配置禁用了进程控制函数。Workerman 本质是多进程常驻服务,pcntl_fork() 是它 fork 子进程的核心,禁用等于直接废掉主干能力。
检查和修复步骤:
- 运行
php -m | grep pcntl,没输出说明扩展未启用 - 查
php --ini找到php.ini路径,打开后确认没有disable_functions = pcntl_fork,pcntl_waitpid,...这类配置 - 如果用了 Docker,基础镜像(如
php:8.2-cli)默认不含pcntl,需在 Dockerfile 中加docker-php-ext-install pcntl - 某些云主机或共享主机禁止
pcntl,这种环境下 Workerman 无法使用,别硬扛
workerman 在 systemd 或 supervisor 里怎么稳住不退出
Workerman 自带 start/stop 命令,但直接丢给进程管理器常会意外退出——因为它的守护进程逻辑和 systemd 的生命周期模型不兼容,子进程状态难追踪。
关键点在于:不要让 systemd 直接执行 php start.php start,而应使用 php start.php status 判断状态,并用 Type=forking + PIDFile 显式声明主进程 ID。
- Workerman 默认生成的 PID 文件路径是
/var/run/workerman.pid,需确保目录可写 - supervisor 配置中必须设
autostart=true和autorestart=unexpected,且startsecs≥5(它启动稍慢) - 如果用
php start.php restart,systemd 会认为原进程已死,但新进程没注册进 cgroup,导致后续 stop 失效 - 日志务必重定向:Workerman 默认输出到终端,systemd 下要配
StandardOutput=append:/var/log/workerman.log
真正麻烦的不是装不上,而是它不报错就静默退出——比如子进程异常终止、内存超限被 OOM killer 干掉、或者某个 onWorkerStart 里抛了未捕获异常。这些都不会打在屏幕,只留在 status 或系统日志里。










