学完这篇你能拿到一张「什么场景该选 PHP、什么场景该选 Node.js」的判断清单,以及两边部署时最容易踩的坑和对应命令。
PHP 和 Node.js 都被拿来写后端,但它们的运行模型完全不同,很多争论其实是拿一种模型的标准去衡量另一种。下面按六个步骤把差异拆开,最后给一张选型表。
第一步:先看清运行模型,这一点最为关键
PHP 是「请求—执行—销毁」的短生命周期模型:Nginx 把请求交给 PHP-FPM 的进程池,每个请求结束后,全局变量、连接、内存都会被清空。Node 是「常驻进程 + 事件循环」:app.js 启动后一直活着,所有请求由同一个 JS 线程调度。
验证环境:
php -v && php -m # 看版本和已装扩展
node -v && npm -v
注意:Node 说「单线程」指的是 JS 执行线程,文件、DNS、部分加密等由 libuv 线程池处理,不等于只能处理一个请求;PHP-FPM 的并发上限由 pm.max_children 决定,经验值是「可用内存 ÷ 单进程实际占用」,设太大反而会把机器拖垮。
第二步:压测你的真实接口,别信直觉
先给结论:IO 密集型接口(查库、调外部 API)Node 在同等资源下能扛更高的并发连接数;纯 CPU 计算(图像处理、大量加解密、正则回溯)PHP 和 Node 都会把工作线程占满,Node 的影响更大,因为它会卡住所有请求。
压测命令:
wrk -t4 -c200 -d30s http://your-host/api/list
注意:Node 里一个同步 CPU 循环(pbkdf2Sync、超大 JSON.parse、灾难性正则)会让整个进程不再响应其他请求,必须拆到 worker_threads 或独立进程;PHP 里同样的代码只会拖慢当前这一个请求,但是会占满 FPM 进程池。
第三步:依赖与生态,两条不同的路
PHP 用 Composer 管依赖(Packagist),但也允许零依赖——直接上传文件就能运行,像 Clara BBS 这类无框架系统就是「上传 → 访问 install 向导 → 完成」,不需要 Composer、不需要命令行。
composer require monolog/monolog
npm init -y && npm i express
npm ci # CI 里用 lockfile 精确安装
注意:PHP 的 redis、gd 这类扩展是系统级安装,缺了就要改 Dockerfile 或面板配置,不是改 composer.json 能解决的;Node 的 native 模块(node-gyp 编译的)在切换 Node 大版本后需要 npm rebuild,否则会报 NODE_MODULE_VERSION 不匹配。
第四步:数据库与工程结构
PHP 短生命周期,连接用完即还,通常靠 FPM 的持久连接或外部连接池;Node 进程常驻,连接池(mysql2 的 pool、pg 的 Pool)在进程内长期存在,必须自己管泄漏和长事务。
php -i | grep -i pdo
node -e "console.log(process.versions)"
注意:Node 里放在模块顶层的数组、Map 做缓存会一直累积,不重启不会释放;PHP 每次请求都是干净的。调试「为什么数据不对」时,思路完全不同——PHP 先怀疑外部状态,Node 先怀疑进程内残留状态。
第五步:部署与运维成本
PHP 的部署成本明显更低:上传代码 + 配好 Nginx/PHP-FPM,改完文件刷新即生效,回滚就是覆盖文件。
systemctl reload php-fpm
Node 必须做进程守护 + 反向代理 + 端口管理:
pm2 start app.js -i max # cluster 模式吃满多核
pm2 logs && pm2 monit
注意:容器里跑 Node 要显式设 --max-old-space-size,否则容易在内存超限时被 OOM Kill,而且日志里看不到明确报错,只看到进程「无声消失」。
第六步:按场景做决定
- 内容型站点、论坛、CMS、后台管理系统,团队小、想少运维 → PHP。上面那类系统(版块、权限矩阵、内容审核、计划任务)在 PHP 生态里成熟方案最多,且计划任务这类能力往往一行注册就能用。
- 实时能力为主:WebSocket 聊天、协作编辑、SSE 推送、通知长连接 → Node,天然长驻进程。
- 前端团队想全栈同语言、接口聚合层(BFF)→ Node。
- 数据批处理、定时统计 → 两边都行,PHP CLI + cron 完全够用;Node 则要注意别和 Web 进程抢 CPU。
- 不必二选一:Nginx 按路径分流,
/api 反代到 Node,其余交给 PHP-FPM,这是很多中型站点的实际做法。
小结
- 差异的根源是运行模型:PHP 每请求销毁,Node 进程常驻,后面的坑几乎都由这一条派生。
- Node 擅长高并发 IO,怕 CPU 阻塞;PHP 擅长快速交付与低运维,怕进程池被占满。
- 依赖管理:PHP 靠 Composer + 系统扩展,Node 靠 npm + lockfile,两边都要把「版本固定」当纪律。
- 内存状态是最大认知差:Node 要主动清理进程内缓存,PHP 不用。
- 部署成本 PHP 更低,Node 必须做守护进程与内存上限配置。
- 选型看负载类型和团队,不看「谁更现代」;生产环境可以做按路径分流的混合架构。