<?php
/**
* Workerman Worker::$user 配置示例
* 演示进程用户配置和安全最佳实践
*/
use Workerman\Worker;
require_once __DIR__ . '/vendor/autoload.php';
// 创建一个 HTTP 服务器
$worker = new Worker('http://0.0.0.0:8080');
// 设置进程数
$worker->count = 4;
// 设置进程名称
$worker->name = 'UserConfigDemo';
// ============================================
// 【Worker::$user 配置】
// ============================================
// 属性: Worker::$user
// 类型: string
// 默认值: 当前用户
//
// 安全说明:
// - 以 root 启动后,子进程切换到此用户运行
// - 降低安全风险
// - 遵循最小权限原则
// - 仅在 Linux/Unix 系统有效,Windows 无效
//
// 使用场景:
// 1. 需要监听 80/443 端口(需 root 启动)
// 2. 生产环境部署提高安全性
// 3. 限制进程权限
// ============================================
// 设置运行用户(取消下面的注释以启用)
// Linux 常用用户: www-data, nobody, www
// $worker->user = 'www-data';
// 启动回调 - 显示当前运行用户
$worker->onWorkerStart = function($worker) {
// 获取当前用户信息
$processUser = posix_getpwuid(posix_geteuid());
$userName = $processUser['name'];
$userUid = $processUser['uid'];
echo "========================================\n";
echo "Worker 进程已启动\n";
echo "进程ID: " . posix_getpid() . "\n";
echo "当前用户: {$userName} (UID: {$userUid})\n";
echo "配置用户: " . ($worker->user ?: '未设置(使用当前用户)') . "\n";
echo "========================================\n";
};
// HTTP 请求处理
$worker->onMessage = function($connection, $request) {
// 获取当前进程用户信息
$processUser = posix_getpwuid(posix_geteuid());
$response = [
'message' => 'Worker::$user 配置示例',
'process_info' => [
'pid' => posix_getpid(),
'user' => $processUser['name'],
'uid' => $processUser['uid'],
'gid' => $processUser['gid'],
],
'security_note' => [
'说明' => '以 root 启动后,子进程切换到配置的用户运行',
'优势' => '降低安全风险,遵循最小权限原则',
'平台' => 'Linux/Unix 有效,Windows 无效'
],
'usage' => [
'配置方式' => '$worker->user = "www-data";',
'启动方式' => 'sudo php user_config_demo.php start',
'注意事项' => '需要 root 权限启动才能切换用户'
]
];
$connection->send(json_encode($response, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
};
// 运行
Worker::runAll();
运行:
php user_config_demo.php start
解释:
● Read(user_config_demo.php)
⎿ Read 88 lines
● 📖 完整代码解释
第 1-9 行:引入和初始化
<?php
use Workerman\Worker;
require_once __DIR__ . '/vendor/autoload.php';
require_once - 加载 Composer 自动加载文件,导入所有依赖库
第 11-12 行:创建 Worker 实例
$worker = new Worker('http://0.0.0.0:8080');
含义:
8080 - 监听端口号
第 14-15 行:设置进程数
$worker->count = 4;
含义:
通常设置为 CPU 核心数,充分利用多核性能
第 17-18 行:设置进程名称
$worker->name = 'UserConfigDemo';
含义:
方便识别和管理进程
第 20-41 行:Worker::$user 配置说明
// $worker->user = 'www-data';
这是核心配置!详细说明:
属性: Worker::$user
类型: 字符串(string)
默认值: 当前启动脚本的用户
工作原理:
安全优势:
隔离保护:限制进程对系统文件的访问权限
使用场景:
平台限制:
❌ Windows 系统:不支持(会被忽略)
第 43-56 行:启动回调函数
$worker->onWorkerStart = function($worker) {
$processUser = posix_getpwuid(posix_geteuid());
$userName = $processUser['name'];
$userUid = $processUser['uid'];
echo "当前用户: {$userName} (UID: {$userUid})\n";
// ...
};
含义:
$processUser['uid'] - 用户ID(数字,如 33)
作用:
帮助调试和确认配置
第 58-84 行:HTTP 请求处理
$worker->onMessage = function($connection, $request) {
$processUser = posix_getpwuid(posix_geteuid());
$response = [
'message' => 'Worker::$user 配置示例',
'process_info' => [
'pid' => posix_getpid(), // 进程ID
'user' => $processUser['name'], // 用户名
'uid' => $processUser['uid'], // 用户ID
'gid' => $processUser['gid'], // 组ID
],
// ...
];
$connection->send(json_encode($response, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
};
含义:
$connection->send() - 发送响应给客户端
返回的信息:
使用方法:如何配置和启动
第 86-87 行:启动 Worker
Worker::runAll();
含义:
进入事件循环,持续运行
🔍 实际运行流程
php user_config_demo.php start
流程:
以当前用户(如 qq230)启动
主进程和子进程都以 qq230 运行
访问 http://127.0.0.1:8080/ 显示:
{
"process_info": {
"user": "qq230",
"uid": 1000
}
}
Root 启动 + Worker::$user 配置
// 取消第 41 行注释
$worker->user = 'www-data';
sudo php user_config_demo.php start
流程:
🛡️ 安全示例对比
不安全的做法(不推荐)
sudo php user_config_demo.php start
安全的做法(推荐)
$worker->user = 'www-data'; // 配置降权用户
sudo php user_config_demo.php start
📝 关键函数说明
| 函数 | 作用 |
|---|---|
| posix_geteuid() | 获取当前进程的有效用户ID |
| posix_getpwuid($uid) | 根据UID获取用户信息数组 |
| posix_getpid() | 获取当前进程ID |
| $worker->onWorkerStart | 子进程启动时的回调 |
| $worker->onMessage | 收到消息/请求时的回调 |
| Worker::runAll() | 启动所有Worker进程 |
完整解释完毕!这个脚本演示了如何安全地配置 Workerman 的进程用户,是生产环境部署的最佳实践。