核心概念

线程安全版本

  • 全称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), IISNginx + PHP-FPM, Apache (event/prefork MPM + PHP-FPM)
扩展兼容性必须使用 TS 版本的扩展必须使用 NTS 版本的扩展

如何选择?

选择哪个版本非常简单,主要取决于你的 PHP 运行方式,也就是 SAPI

选择 NTS 的情况

如果你的环境是以下任何一种(绝大多数现代场景),请选择 NTS 版本

  1. Nginx + PHP-FPM:这是目前最主流、性能最好的组合。PHP-FPM 是进程管理器,所以用 NTS。

  2. Apache + PHP-FPM:即使你使用 Apache,但如果配置为使用 PHP-FPM(而不是 mod_php),也应该选择 NTS。Apache 的 event 或 prefork MPM 配合 PHP-FPM 是很常见的配置。

  3. 命令行脚本:如果你只是在命令行下运行 PHP 脚本(例如,通过 php script.php),不涉及 Web 服务器,那么 NTS 是更好的选择,因为它性能稍高。

简单总结:只要你是用 PHP-FPM,就无脑选 NTS。

选择 TS 的情况

如果你的环境是以下任何一种(较旧的或特定场景),请选择 TS 版本

  1. Apache + mod_php:如果你将 PHP 作为 Apache 的一个模块(mod_php)来运行,并且 Apache 使用的是 worker 或 winnt MPM(多线程模型),那么必须使用 TS 版本。

    • 注意:Apache 的 prefork MPM(多进程模型)理论上可以用 NTS,但为了统一和避免混淆,官方 Windows 版的 Apache 集成包通常都提供 TS 版本的 PHP。
  2. IIS:在 Windows 上使用 IIS 作为 Web 服务器时,需要通过 FastCGI 或其它方式运行 PHP,由于 IIS 的应用程序池默认是多线程的,所以需要使用 TS 版本。

  3. 特殊需求:你明确需要在 PHP 代码中创建和管理线程(例如使用 pthreads 扩展,但请注意该扩展已过时,现代替代品是 parallel),那么你需要 TS 版本的 PHP。

实践指南和检查方法

查看当前 PHP 是 TS 还是 NTS

在命令行或一个 PHP 文件中执行:

1
php -i | grep "Thread Safety"

或者创建一个 PHP 文件,内容为:

1
2
3
<?php
phpinfo();
?>

在输出的信息中搜索 “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 版本。