我们有一个 Linux 环境,用于运行几个不同的应用程序,这些应用程序均使用 PHP 7.4 编写。它们由使用虚拟主机的单个 Nginx Web 服务器提供服务,并且均使用 FPM。
在我们的代码中,我们使用 JSON-RPC 客户端类 (@package JsonRPC, @author Frederic Guillot),它是 PHP CURL 的包装器。由于历史原因,Client.php 类在不同应用程序中存在不同的版本。这些显然是从文件系统中的不同物理位置加载的,假设它是/var/www/appA/classes/Client.php
和/var/www/appB/classes/Client.php
。
令我们大吃一惊的是,我们发现 FPM 有时会在从 appB 调用时提供来自 appA 的 Client.php 版本!我们发现这个问题是因为 appB 应用程序抛出了异常,从堆栈跟踪中我们可以看到 Client.php 是从 appA 下的路径加载的。在 Client.php 代码的一个版本中插入调试语句证实了这个问题。
问题的进一步证据是,当重新启动 FPM 服务时,问题消失,并加载了正确的版本。至少在一段时间内……在使用了其他版本的 Client.php 后,问题在几个小时后再次出现。
显然,如果这是真的,这似乎可能会带来巨大的安全问题!
一种假设是,两个应用程序接收到由同一个 FPM 工作进程按顺序服务的请求,并且缓存逻辑错误地发现 Client.php 已经被加载。
这两个版本使用相同的 PHP 命名空间,但在 PHP 代码中有所不同。这可能是 FPM 将它们混淆的原因吗?人们会认为,加载的文件上会有一个校验和,可以检测到文件确实不同。
关于如何处理 FPM 中的同名类,是否存在任何已知的限制?