PHP NTS 和 TS 版本如何选择
核心概念
线程安全版本
全称:Thread Safe,简称 TS 或 ZTS。
是什么:这个版本的 PHP 在编译时,其内部变量和数据结构都经过了特殊处理,以确保当它在多线程环境下运行时,每个线程的变量都是隔离的,不会互相干扰。
为什么需要:主要是为了与使用多线程模式的 Web 服务器集成。最典型的例子就是 IIS 和 Apache 的 worker MPM 或 winnt MPM 模式。在这些模式下,服务器会创建一个主进程,然后生成多个工作线程来处理并发请求。如果 PHP 不是线程安全的,多个线程同时操作相同的全局变量就会导致数据混乱和程序崩溃。
非线程安全版本
全称:Non Thread Safe,简称 NTS。
是什么:这个版本的 PHP 在编译时,没有进行上述的线程安全处理。它假设自己运行在一个单进程、单线程的环境中。
为什么需要:当 PHP 与使用多进程模式的 Web 服务器集成时,线程安全就不是必须的了。最典型的例子是 Nginx + PHP-FPM 的组合。PHP-FPM 本身是一个进程管理器,它会生成多个独立的 PHP 子进程来处理请求。每个进程都是独立的,拥有自己的内存空间,互不干扰,因此不需要考虑线程安全问题。
主要区别对比
| 特性 | 线程安全版本 | 非线程安全版本 |
|---|---|---|
| 全称 | Thread Safe (TS/ZTS) | Non Thread Safe (NTS) |
| 运行模式 | 为多线程环境设计 | 为多进程/单线程环境设计 |
| 性能 | 稍低(因为需要额外的锁和检查来保证线程安全) | 稍高(没有线程安全带来的开销) |
| 稳定性 | 在多线程环境下更稳定 | 在多进程环境下同样稳定 |
| 适用服务器 | Apache (mod_php, worker/winnt MPM), IIS | Nginx + PHP-FPM, Apache (event/prefork MPM + PHP-FPM) |
| 扩展兼容性 | 必须使用 TS 版本的扩展 | 必须使用 NTS 版本的扩展 |
如何选择?
选择哪个版本非常简单,主要取决于你的 PHP 运行方式,也就是 SAPI。
选择 NTS 的情况
如果你的环境是以下任何一种(绝大多数现代场景),请选择 NTS 版本:
Nginx + PHP-FPM:这是目前最主流、性能最好的组合。PHP-FPM 是进程管理器,所以用 NTS。
Apache + PHP-FPM:即使你使用 Apache,但如果配置为使用 PHP-FPM(而不是 mod_php),也应该选择 NTS。Apache 的
event或preforkMPM 配合 PHP-FPM 是很常见的配置。命令行脚本:如果你只是在命令行下运行 PHP 脚本(例如,通过
php script.php),不涉及 Web 服务器,那么 NTS 是更好的选择,因为它性能稍高。
简单总结:只要你是用 PHP-FPM,就无脑选 NTS。
选择 TS 的情况
如果你的环境是以下任何一种(较旧的或特定场景),请选择 TS 版本:
Apache + mod_php:如果你将 PHP 作为 Apache 的一个模块(
mod_php)来运行,并且 Apache 使用的是worker或winntMPM(多线程模型),那么必须使用 TS 版本。- 注意:Apache 的
preforkMPM(多进程模型)理论上可以用 NTS,但为了统一和避免混淆,官方 Windows 版的 Apache 集成包通常都提供 TS 版本的 PHP。
- 注意:Apache 的
IIS:在 Windows 上使用 IIS 作为 Web 服务器时,需要通过 FastCGI 或其它方式运行 PHP,由于 IIS 的应用程序池默认是多线程的,所以需要使用 TS 版本。
特殊需求:你明确需要在 PHP 代码中创建和管理线程(例如使用
pthreads扩展,但请注意该扩展已过时,现代替代品是parallel),那么你需要 TS 版本的 PHP。
实践指南和检查方法
查看当前 PHP 是 TS 还是 NTS
在命令行或一个 PHP 文件中执行:
1 | php -i | grep "Thread Safety" |
或者创建一个 PHP 文件,内容为:
1 |
|
在输出的信息中搜索 “Thread Safety” 这一项。
如果显示
enabled,说明是 TS 版本。如果显示
disabled,说明是 NTS 版本。
下载时如何区分?
在 Windows 上从官方下载 PHP 时,压缩包名称会明确标注:
php-8.x.x-Win32-vs16-x64.zip-> TS 版本php-8.x.x-Win32-vs16-x64-nts.zip-> NTS 版本
在 Linux 上,使用包管理器安装时,通常也会区分,例如:
php(可能是 NTS)php-zts(TS 版本)
具体取决于你使用的发行版和软件源。
扩展(DLL/so文件)也必须匹配
这是一个非常重要的点:你安装的 PHP 扩展必须与你的 PHP 主程序版本(TS 或 NTS)严格匹配。
如果你用的是 NTS 的 PHP,就必须加载 NTS 版本的扩展(
.dll或.so文件)。如果你用的是 TS 的 PHP,就必须加载 TS 版本的扩展。
混用会导致 PHP 无法启动,并报错。
最终结论
对于当今绝大多数 Web 应用(使用 Nginx + PHP-FPM 或 Apache + PHP-FPM),直接选择 NTS 版本。它性能稍好,且是这些环境下的标准选择。
只有当你在一个明确要求线程安全的环境中(如旧版 Apache mod_php 多线程模式、IIS),才选择 TS 版本。






