文档菜单
文档首页
/ / /
PHP库手册

常见问题解答

本页内容

  • 常见扩展安装错误
  • PHP头文件未找到
  • 安装了多个PHP运行时
  • 在Windows上加载不兼容的DLL
  • 连接处理与持久性
  • 服务器选择失败

例如

/private/tmp/pear/install/mongodb/php_phongo.c:24:10: fatal error: 'php.h' file not found
#include <php.h>
^~~~~~~

此错误表示PHP的构建系统找不到必要的头文件。所有PHP扩展都需要头文件才能编译。此外,这些头文件必须与将用于扩展的PHP运行时相对应。通常,phpize 命令(由 pecl 调用)将确保扩展使用正确的头文件进行构建。

请注意,仅仅存在PHP运行时并不意味着头文件可用。在各个Linux发行版中,头文件通常在单独的 php-devphp-devel 软件包下发布。在macOS上,默认的PHP运行时不包括头文件,用户通常需要通过Homebrew 来安装PHP(和头文件)以构建扩展。

如果您的系统安装了多个版本的PHP,每个版本都将有其自己的 peclphpize 命令。此外,每个PHP运行时可能为每个SAPI(例如FPM、CLI)有单独的 php.ini 文件。如果已安装扩展但在运行时不可用,请检查您是否已使用正确的 pecl 命令并已修改适当的 php.ini 文件。

如果对PHP运行时使用的php.ini文件有任何疑问,您应该检查特定SAPI的phpinfo()输出。phpinfo()。此外,可以使用php_ini_loaded_file()php_ini_scanned_files()来确定PHP加载了哪些INI文件。

要调试未加载扩展的问题,您可以使用工具目录中提供的detect-extension脚本。您可以从命令行运行此脚本,或者将其包含在可通过您的web服务器访问的脚本中。该工具将指出潜在问题和系统安装说明。假设您已通过Composer安装了库,您可以从vendor目录调用该脚本

php vendor/mongodb/mongodb/tools/detect-extension.php

如果想要检查web服务器SAPI的配置,请将文件包含在可通过web服务器访问的脚本中,并在浏览器中打开它。请记住,为了正确格式化输出,将脚本包裹在<pre>标签中

<pre><?php require(...); ?></pre>

Windows的二进制文件适用于各种PHP版本、线程安全(TS或NTS)和架构(x86或x64)的组合。未选择正确的二进制文件将导致在尝试运行时加载扩展DLL时出错。

PHP Warning: PHP Startup: Unable to load dynamic library 'mongodb'

请确保您已下载与以下PHP运行时属性相对应的DLL

  • PHP版本 (PHP_VERSION)

  • 线程安全 (PHP_ZTS)

  • 架构 (PHP_INT_SIZE)

除了上述常量之外,这些属性还可以从phpinfo()中推断。如果您系统安装了多个PHP运行时,请确保您检查的是正确环境的phpinfo()输出。

上述detect-extension脚本也可以用来确定适合您PHP环境的适当DLL。

连接到MongoDB部署由libmongoc库和PHP扩展处理。当你构建一个MongoDB\Client 实例,PHP 库通过相同的连接字符串和选项创建了一个 MongoDB\Driver\Manager 实例。该扩展也使用这些构造函数参数来推导持久 libmongoc 客户端的哈希键。如果您之前使用密钥持久化了一个 libmongoc 客户端,则它将被重用。否则,将创建一个新的 libmongoc 客户端,并在 PHP 工作进程的生命周期内进行持久化。您可以在 PHP 扩展文档

每个 libmongoc 客户端都维护自己的连接到 MongoDB 部署及其拓扑视图。当您重用持久 libmongoc 客户端时,PHP 库可以避免建立新连接和重新发现拓扑的开销。这种方法通常可以提高性能,并且是驱动程序的默认行为。

持久 libmongoc 客户端将在 PHP 工作进程结束时才被释放。这意味着在 MongoDB\Driver\Manager 对象超出作用域后,连接到 MongoDB 部署可能会保持打开状态。虽然这通常不是连接到一个 MongoDB 部署的应用程序的问题,但在某些情况下可能会出现问题,以下列表中进行了描述

  • PHP-FPM 配置了 pm.max_requests=0,因此工作进程永远不会重启,并且 PHP 应用程序被多次部署,对其 MongoDB 连接字符串或选项进行了微小更改。这可能导致每个工作进程中的 libmongoc 客户端对象累积。

  • 应用程序偶尔会连接到后端组件中的单独 MongoDB 部署,其中请求延迟不是最重要的方面。

在第一种情况下,作为应用程序部署的一部分重启 PHP-FPM 允许应用程序释放任何未使用的 libmongoc 客户端,并仍然使用持久客户端进行最新的连接字符串。

第二种情况需要不同的解决方案。将 disableClientPersistence 驱动程序选项指定为 true 指示 PHP 库创建一个新的 libmongoc 客户端,并确保在相应的 MongoDB\Driver\Manager 离开作用域时释放它。

以下代码演示了如何在创建客户端时将 disableClientPersistence 选项设置为 true

<?php
$client = new MongoDB\Client(
uri: getenv('MONGODB_URI') ?: 'mongodb://127.0.0.1/',
uriOptions: [],
driverOptions: ['disableClientPersistence' => true],
);

在使用 disableClientPersistence 驱动程序选项之前请仔细考虑,因为放弃客户端持久性需要更多时间来建立与 MongoDB 部署的连接并发现其拓扑。

以下都是 服务器选择 失败的示例

No suitable servers found (`serverSelectionTryOnce` set):
[connection refused calling hello on 'a.example.com:27017']
[connection refused calling hello on 'b.example.com:27017']
No suitable servers found: `serverSelectionTimeoutMS` expired:
[socket timeout calling hello on 'example.com:27017']
No suitable servers found: `serverSelectionTimeoutMS` expired:
[connection timeout calling hello on 'a.example.com:27017']
[connection timeout calling hello on 'b.example.com:27017']
[TLS handshake failed: -9806 calling hello on 'c.example.com:27017']
No suitable servers found: `serverselectiontimeoutms` timed out:
[TLS handshake failed: certificate verify failed (64): IP address mismatch calling hello on 'a.example.com:27017']
[TLS handshake failed: certificate verify failed (64): IP address mismatch calling hello on 'b.example.com:27017']

这些错误通常表现为扩展的 MongoDB\Driver\Exception\ConnectionTimeoutException 异常。实际的异常消息来自 libmongoc,这是扩展使用的底层系统库。由于这些消息可以有多种形式,因此分解消息结构以更好地诊断应用程序中的错误是有帮助的。

消息通常以 "未找到合适的服务器" 开头。消息的下一部分表明了服务器选择失败的原因。默认情况下,扩展程序会避免服务器选择循环,而是根据 serverSelectionTryOnce 连接字符串选项进行单次尝试。如果扩展程序配置为使用循环,则类似于 "serverSelectionTimeoutMS 已过期" 的消息将告诉我们我们已经用完了其时间限制。

消息的最后部分告诉我们服务器选择失败的原因,并包括来自拓扑扫描器的直接错误,拓扑扫描器是负责连接和监控每个主机的服务。任何在监控期间最后发生错误的宿主都将包括在这个列表中。这些消息通常来自低级别的套接字或 TLS 函数。

以下内容并非旨在详尽无遗,但希望能帮助您找到分析服务器选择失败原因的方向

  • "连接被拒绝" 可能表明远程主机未在预期的端口上监听。

  • "连接超时" 可能表明存在路由或防火墙问题,或者可能是由于延迟导致的超时。

  • "套接字超时" 暗示某个时候已建立连接,但由于延迟而断开或超时。

  • "TLS 握手失败" 暗示与 TLS 或 OCSP 验证相关的问题,有时可能是 TLS 证书配置错误。

在连接失败的情况下,您可以使用 connect 工具尝试获取更多信息。此工具尝试使用套接字函数连接到连接字符串中的每个主机,以查看它是否能够建立连接、发送和接收数据。工具将连接字符串作为其唯一参数传递给 MongoDB 部署。假设您已通过 Composer 安装了库,您将从一个供应商目录调用脚本

php vendor/mongodb/mongodb/tools/connect.php mongodb://127.0.0.1:27017

如果服务器不接受连接,输出将类似于以下内容

Looking up MongoDB at mongodb://127.0.0.1:27017
Found 1 host(s) in the URI. Will attempt to connect to each.
Could not connect to 127.0.0.1:27017: Connection refused

注意

该工具仅支持 mongodb:// URI 架构。不支持使用 mongodb+srv 架构。

返回

升级