SQLSRV和PDO_SQLSRV驱动都是PHP扩展。 PHP 在 PHP 进程启动时加载这些文件,读取 php.ini 并读取任何额外的 .ini 文件。
加载和安装是分开的。 复制或构建该扩展会在磁盘上放置一个文件。 在活动配置包含正确条目并且 PHP 进程重启之前,PHP 不能使用 SQLSRV 或 PDO_SQLSRV。
防护网页诊断页面
在创建临时 phpinfo() 页面之前,先配置网页服务器只允许 localhost 请求或经过身份验证的管理员。 在你删除页面之前,保持这个限制。
phpinfo() 可以暴露环境变量、凭证和服务器配置。 验证后立即删除该页面。
理解 PHP 配置作用域
每个PHP服务器应用程序接口(SAPI)可以使用不同的可执行文件和配置:
| Runtime | 典型配置源 | 如何识别 |
|---|---|---|
| 命令行接口 (CLI) | 由php --ini报告的php.ini和扫描目录 |
使用完全相同的可执行文件运行 php --ini |
| IIS FastCGI | 在 IIS FastCGI 应用中配置的 PHP 可执行文件 | 使用临时 phpinfo() 页面 |
| Apache 模块 | Apache 的 PHP 模块配置 | 使用临时 phpinfo() 页面 |
| PHP-FPM | FPM 可执行文件、池、php.ini 和扫描目录 |
使用 -i 运行版本化的FPM二进制文件,或使用临时 phpinfo() 页面 |
| 长期运行的工作进程 | 启动工作进程的执行文件和环境 | 检查工作服务,更改后重启它 |
当 IIS、Apache 或 PHP-FPM 使用其他 PHP 安装或扫描目录时,更改 CLI 配置不会影响它们。
查找PHP配置
用你的应用程序使用的PHP可执行文件执行以下命令:
php --ini
php -i | findstr /I "PHP Version Thread Safety Architecture extension_dir"
在 Linux 或 macOS 上,请替换 findstr 为 grep:
php -i | grep -E "PHP Version|Thread Safety|extension_dir"
file "$(php -r 'echo PHP_BINARY;')"
该 file 命令用于识别所选可执行文件的架构。 对于通用macOS可执行文件,请遵循 显式架构选择。
加载的配置文件和在以下位置扫描其他 .ini 文件这两个值标识命令行进程所使用的配置。 网页服务器或 PHP FastCGI进程管理器(PHP-FPM) 进程可能使用不同的PHP可执行文件或配置文件。 使用临时 phpinfo() 页面来识别该过程的值。
编辑文件前,请记录:
- PHP 可执行文件路径和版本。
- 已加载
php.ini。 - 附加扫描目录
.ini - 扩展目录。
- 线程安全模式和架构。
- 每一个你都必须重新启动的进程。
备份你更改的每个配置文件。
在 Windows 上安装驱动程序
对于使用 PHP 扩展安装程序(PIE)进行的安装,首先 下载并验证 PIE。 从包含 pie.phar的目录中执行以下命令,并使用应加载驱动程序的 PHP 可执行文件:
php .\pie.phar install microsoft/sqlsrv
php .\pie.phar install microsoft/pdo_sqlsrv
PIE 安装 php_sqlsrv.dll 和 php_pdo_sqlsrv.dll。 如果 PIE 无法自动启用扩展,则移除当前活动的 php.ini 中所有现有的 SQLSRV 和 PDO_SQLSRV 条目,然后添加:
extension=php_sqlsrv.dll
extension=php_pdo_sqlsrv.dll
每位司机只填写一条条目。 更改配置后重启 PHP 进程。
对于 ZIP 安装,将与 PHP 小版本、架构和线程安全模式匹配的动态链接库(DLL)复制到 extension_dir 目录中。 PHP 8.5 x64 线程安全运行时使用以下文件名:
php_sqlsrv_85_ts_x64.dll
php_pdo_sqlsrv_85_ts_x64.dll
将这两个文件名添加到 PHP 进程使用的 php.ini 中:
extension=php_sqlsrv_85_ts_x64.dll
extension=php_pdo_sqlsrv_85_ts_x64.dll
将 85、ts 和 x64 替换为你的 PHP 运行时的值。 不要混用线程安全和非线程安全文件、32位和64位文件,或者为另一个PHP小版本编写的文件。
在 Linux 和 macOS 上加载驱动程序
通过 PIE安装驱动。 更多信息请参见 Linux和macOS安装教程。 PIE 安装扩展文件,并尝试通过使用平台的 PHP 配置工具或在额外的php.ini文件或标准.ini中添加extension=条目来启用它们。 如果PIE报告无法启用扩展,自己添加条目并验证激活配置。
手动安装时,选择与你的PHP版本、架构、线程安全模式以及操作系统原生库相匹配的预构建 .so 文件。 查看 预构建的 Linux 和 macOS 要求;如果环境不匹配,就用 PIE。
例如,PHP 8.4 非线程安全文件名为 SQLSRV_8.4_NTS.so 和 PDO_SQLSRV_8.4_NTS.so。 将它们放入 php -i | grep extension_dir 返回的目录中。 将它们重命名为 sqlsrv.so 和 pdo_sqlsrv.so,以使用以下条目,或者在条目中改为使用完全相同的包文件名。 将这些条目添加到你当前的PHP配置中,按照本节描述的加载顺序:
extension=sqlsrv.so
extension=pdo_sqlsrv.so
PHP 数据对象(PDO)必须在PDO_SQLSRV前加载。 PHP 会先读取 php.ini,然后按字母顺序扫描额外的 .ini 文件。 如果你的发行版从某个已扫描文件加载 pdo.so,请将 PDO_SQLSRV 条目放入后续扫描文件中,例如当 PDO 使用 10-pdo.ini 时,可放入 30-pdo_sqlsrv.ini。 在那种情况下不要在php.ini中放置PDO_SQLSRV条目。
选择扩展条目
使用与驱动安装方式相符的条目:
| 平台与方法 | SQLSRV 条目 | PDO_SQLSRV条目 |
|---|---|---|
| 带PIE的Windows | extension=php_sqlsrv.dll |
extension=php_pdo_sqlsrv.dll |
| Windows 创建的 ZIP | 精确版本的 DLL 名称,例如 extension=php_sqlsrv_85_ts_x64.dll |
精确版本的 DLL 名称,例如 extension=php_pdo_sqlsrv_85_ts_x64.dll |
| Linux或macOS带PIE | extension=sqlsrv.so |
extension=pdo_sqlsrv.so |
| Linux 或 macOS 发布的归档包,重命名后的文件 | extension=sqlsrv.so |
extension=pdo_sqlsrv.so |
| Linux 或 macOS 发布的归档,原始文件 | 精确的归档文件名,例如 extension=SQLSRV_8.4_NTS.so |
精确的归档文件名,例如 extension=PDO_SQLSRV_8.4_NTS.so |
不要同时为同一扩展配置短名和版本化名称。 PHP 可以报告模块已加载,或者升级后继续加载较旧的文件。
重启PHP以加载驱动程序
更改扩展文件或配置文件后,重启进程。 重启 Web 服务器、PHP-FPM、队列工作者以及其他加载驱动的长期运行 PHP 进程。
SQLSRV 和 PDO_SQLSRV 扩展可以独立加载,但当你的应用同时使用两个驱动时,请同时安装并验证这两个扩展。 PDO内置于许多PHP软件包中。 如果 PDO 不是内置的,PDO_SQLSRV前先启用 PDO 扩展。
验证已加载的驱动程序
对于命令行运行时,运行:
php --ri sqlsrv
php --ri pdo_sqlsrv
php -m | findstr /I "sqlsrv pdo_sqlsrv"
在Linux或macOS上,请使用:
php --ri sqlsrv
php --ri pdo_sqlsrv
php -m | grep -E "sqlsrv|pdo_sqlsrv"
对于网页服务器,在创建包含 的临时页面前,先<?php phpinfo(); ?>。 确认已加载的配置文件、extension_dir和单独的sqlsrv和pdo_sqlsrv部分。 验证后删除页面。
还要运行PHP层面的检查,确保验证涵盖两个API,而不仅仅是模块名称。 将此程序保存为 verify-php-drivers.php:
<?php
$checks = [
'SQLSRV extension' => extension_loaded('sqlsrv'),
'SQLSRV API' => function_exists('sqlsrv_connect'),
'PDO_SQLSRV extension' => extension_loaded('pdo_sqlsrv'),
'PDO_SQLSRV API' => class_exists('PDO')
&& in_array('sqlsrv', PDO::getAvailableDrivers(), true),
];
$failed = false;
foreach ($checks as $name => $passed) {
echo $name . ': ' . ($passed ? 'loaded' : 'missing') . PHP_EOL;
$failed = $failed || !$passed;
}
exit($failed ? 1 : 0);
使用应用程序所用的每个 PHP 可执行文件来运行该程序:
php verify-php-drivers.php
预期输出:
SQLSRV extension: loaded
SQLSRV API: loaded
PDO_SQLSRV extension: loaded
PDO_SQLSRV API: loaded
对于网页运行时,将文件暂时放在文档根目录中,并通过浏览器访问该文件。 验证后删除。 这个程序不会打开数据库连接,也不会打印配置值。
完成CLI和Web运行时检查后删除 verify-php-drivers.php 。
排查驱动加载问题
| 问题 | 检查原因 | 纠正措施 |
|---|---|---|
Unable to load dynamic library |
错误的文件名、 extension_dirPHP 小版本、架构或线程安全模式 |
与所选驱动文件比较 php -i ,并暂时使用绝对路径来隔离路径错误 |
Windows上的 The specified module could not be found |
驱动程序DLL或其依赖不可用 | 确认 DLL 是否在 extension_dir 中,安装匹配的 Visual C++ 运行时,并检查任何剩余缺失的 DLL 依赖 |
undefined symbol 或者在 Linux 或 macOS 上出现共享库错误 |
扩展和PHP构建不匹配,或者缺少ODBC依赖 | 使用预期的 php-config 重新构建,然后检查报告缺失的库 |
Module "sqlsrv" is already loaded |
重复条目或两个扫描文件 | 搜索已加载的php.ini和扫描目录,然后保留一个条目 |
could not find driver 来自PDO |
PDO_SQLSRV没有加载,或者PDO在它之后加载 | 检查 php --ri pdo_sqlsrv 并将 PDO_SQLSRV 条目移到 PDO 之后 |
| CLI 可以正常工作,但网页请求失败 | 不同的 SAPI 配置,或未重启的进程 | 比较CLI和 phpinfo() 配置值,编辑网页配置,然后重启网页进程 |
升级后仍保留旧的 ExtensionVer |
配置中仍然引用一个较旧版本的文件 | 用所选方法安装的文件替换旧条目,删除重复文件,重启所有PHP进程 |
PHP 控制扩展发现和加载顺序。 PIE或手动复制提供扩展文件。 操作系统加载器解析本机依赖项。 扩展加载后,Microsoft ODBC 驱动程序接管数据库协议。