本文目录导读:

- 使用 PHP 内置的异步框架
- 使用 systemd 服务(传统PHP + Nginx/Apache)
- 使用 Supervisor 管理
- 编写守护进程脚本(纯PHP)
- 使用 Docker 容器化
- 使用 PHP 内置服务器 + 进程管理
- 使用 ReactPHP 事件循环
- 生产环境部署建议
- 选择建议
- 注意事项
将PHP脚本变成服务(常驻内存运行)有几种常见方案,我会按推荐程度从高到低介绍:
使用 PHP 内置的异步框架
Swoole(最推荐)
// server.php
<?php
use Swoole\Http\Server;
use Swoole\Http\Request;
use Swoole\Http\Response;
$server = new Server("0.0.0.0", 9501);
$server->on("start", function(Server $server) {
echo "Swoole HTTP server started\n";
});
$server->on("request", function(Request $request, Response $response) {
$response->header("Content-Type", "text/plain");
$response->end("Hello from Swoole!\n");
});
$server->start();
运行:
php server.php
Workerman
<?php
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker("websocket://0.0.0.0:2346");
$worker->onMessage = function(TcpConnection $connection, $data) {
$connection->send("Hello: $data\n");
};
Worker::runAll();
运行:
php worker.php start
使用 systemd 服务(传统PHP + Nginx/Apache)
# /etc/systemd/system/php-app.service [Unit] Description=PHP Application Service After=network.target [Service] Type=simple User=www-data Group=www-data WorkingDirectory=/var/www/myapp ExecStart=/usr/bin/php -S 0.0.0.0:8080 -t /var/www/myapp Restart=always RestartSec=3 [Install] WantedBy=multi-user.target
启用服务:
# 启动服务 sudo systemctl enable php-app sudo systemctl start php-app # 查看状态 sudo systemctl status php-app
使用 Supervisor 管理
# /etc/supervisor/conf.d/php-app.conf [program:php-app] command=/usr/bin/php /path/to/your/script.php directory=/path/to/app autostart=true autorestart=true startretries=3 stderr_logfile=/var/log/php-app.err.log stdout_logfile=/var/log/php-app.out.log user=www-data
编写守护进程脚本(纯PHP)
<?php
// daemon.php
class Daemon {
private $pidfile;
private $logfile;
public function __construct($pidfile, $logfile) {
$this->pidfile = $pidfile;
$this->logfile = $logfile;
}
public function start() {
if ($this->isRunning()) {
echo "Already running\n";
return;
}
$pid = pcntl_fork();
if ($pid == -1) {
die("Could not fork\n");
} elseif ($pid) {
// Parent process
exit;
} else {
// Child process
posix_setsid();
$this->run();
}
}
private function run() {
// 主循环
while (true) {
$this->log("Working...");
sleep(5);
}
}
private function isRunning() {
if (file_exists($this->pidfile)) {
$pid = file_get_contents($this->pidfile);
if (posix_kill($pid, 0)) {
return true;
}
}
return false;
}
private function log($message) {
file_put_contents($this->logfile,
date('Y-m-d H:i:s') . " - $message\n", FILE_APPEND);
}
}
$daemon = new Daemon('/tmp/myapp.pid', '/var/log/myapp.log');
$daemon->start();
使用 Docker 容器化
# Dockerfile FROM php:8.2-cli WORKDIR /app COPY . /app RUN docker-php-ext-install pcntl CMD ["php", "server.php"]
# docker-compose.yml
version: '3'
services:
php-app:
build: .
ports:
- "9501:9501"
restart: always
使用 PHP 内置服务器 + 进程管理
# 使用 nohup 后台运行 nohup php -S 0.0.0.0:8080 > /var/log/php-server.log 2>&1 & # 或者使用 timeout 并配合 crontab 自动重启
使用 ReactPHP 事件循环
<?php
require_once __DIR__ . '/vendor/autoload.php';
use React\EventLoop\Factory;
use React\Http\Server;
use Psr\Http\Message\ServerRequestInterface;
use React\Http\Message\Response;
$loop = Factory::create();
$server = new Server($loop, function (ServerRequestInterface $request) {
return new Response(
200,
['Content-Type' => 'text/plain'],
"Hello World!\n"
);
});
$socket = new React\Socket\Server(8080, $loop);
$server->listen($socket);
echo "Server running on port 8080\n";
$loop->run();
生产环境部署建议
使用 Open Swoole 生产配置
# swoole.ini [swoole] swoole.display_errors = Off swoole.enable_coroutine = On
结合 PHP-FPM + Nginx
# nginx.conf
upstream php_websocket {
server 127.0.0.1:9501;
}
server {
listen 80;
location / {
proxy_pass http://php_websocket;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
}
}
选择建议
- WebSocket/长连接: 使用 Swoole/Workerman
- HTTP API: 使用 Swoole HTTP server
- 传统应用: 使用 PHP-FPM + 进程管理
- 简单定时任务: 使用 cron + PHP CLI
- 微服务架构: 使用 Docker + Swoole
注意事项
- 内存泄漏: 长期运行要注意内存管理
- 错误处理: 必须有完善的错误捕获机制
- 日志记录: 记录运行日志便于排查问题
- 自动重启: 配置进程管理软件自动重启
- 性能监控: 监控内存和CPU使用情况
选择哪种方案取决于你的具体需求(性能要求、部署环境、维护成本等),对于现代PHP应用,推荐使用 Swoole 或 Workerman 方案,性能最好且功能最完善。