Установите драйверы PHP для SQL Server на Windows

Используйте эту статью, чтобы установить драйверы SQLSRV и PDO_SQLSRV для PHP на Windows. Драйверы — это PHP-расширения, использующие драйвер Microsoft ODBC для SQL Server.

Перед началом убедитесь, что ваша версия PHP, архитектура и режим безопасности потоков поддерживаются в матрице поддержки. Среда выполнения PHP, используемая процессом, запущенным из командной строки, и среда выполнения, используемая веб-сервером, могут использовать разные файлы php.ini. Настраивайте и проверяйте каждую среду выполнения отдельно.

В конце процедуры оба sqlsrv_connect() и драйвер PDO sqlsrv должны быть доступны в соответствующем CLI или веб-приложении, и каждый API должен выполнить тестовый запрос. Успешная копия файла сама по себе не является завершенной установкой.

Выбор метода установки

Метод Используйте его, когда Что он устанавливает
Установщик PHP для расширений (PIE) Вам нужно, чтобы установщик выбрал сборку драйвера для исполняемого файла PHP Неверсионированные php_sqlsrv.dll и php_pdo_sqlsrv.dll, с попыткой автоматической настройки
Выпущенный ZIP-пакет Вам нужно самостоятельно выбирать, проверять или развертывать конкретные предварительно собранные файлы Версионные DLL, выбранные по малой версии PHP, режиму безопасности потоков и архитектуре

Используйте один метод для обоих расширений. Не держите одновременно активными записи конфигурации PIE и ZIP.

Установка необходимых компонентов

  1. Установите поддерживаемую PHP-сборку с сайта PHP for Windows. Добавьте каталог PHP в PATH.

  2. Установите Visual C++ Redistributable, необходимый для вашей PHP-сборки. Подберите архитектуру x64 или x86 в соответствии с PHP, как описано в требованиях PHP для Windows.

  3. Установите последний драйвер Microsoft ODBC для SQL Server.

  4. Выполните следующие команды для проверки среды выполнения PHP и конфигурационного файла:

    php --version
    php --ini
    

    Если Loaded Configuration File — (none), скопируйте php.ini-development в php.ini в каталоге PHP.

  5. В php.ini установите каталог расширений и включите расширения, необходимые для PHP-установщика расширений (PIE):

    extension_dir = "ext"
    extension=openssl
    extension=zip
    
  6. Убедитесь, что PHP может найти необходимые расширения:

    php --ri openssl
    php --ri zip
    

    Исправьте эти предварительные условия перед загрузкой PIE.

Установка через PIE

PIE устанавливает соответствующий предварительно скомпилированный драйвер для PHP runtime. В Windows это не требует компилятора C.

  1. Переключитесь на каталог, в который у вас есть права на запись, и скачайте последний архив PIE PHP (PHAR):

    curl.exe -fL --output pie.phar https://github.com/php/pie/releases/latest/download/pie.phar
    

    Оставшиеся команды PIE обращаются к файлу как .\pie.phar, поэтому запускайте их из этой же папки.

    Перед запуском PHAR проверьте его с помощью командного интерфейса GitHub (CLI):

    gh attestation verify --owner php .\pie.phar
    

    Подтвердите загрузку, прежде чем продолжить:

    dir pie.phar
    php .\pie.phar --version
    
  2. Устанавливайте каждый драйвер отдельно:

    php .\pie.phar install microsoft/sqlsrv
    php .\pie.phar install microsoft/pdo_sqlsrv
    
  3. Проверьте среду выполнения командной строки:

    php --ri sqlsrv
    php --ri pdo_sqlsrv
    php -m | findstr /I "sqlsrv pdo_sqlsrv"
    

PIE пытается включить расширения в конфигурации, используемой программой командной строки. Если PIE сообщает, что не смог включить расширение, добавьте записи расширения, специфичные для PIE.

Если ваш веб-сервер использует другую PHP-установку, установите оба драйвера для PHP-версии, архитектуры и режима безопасности потоков этой установки перед его настройкой. Если одна и та же PHP-установка использует другой php.ini для веб-сервера, включите установленные драйверы в этом файле. Проверьте веб-среду выполнения отдельно и перезапустите веб-сервер после изменения его конфигурации.

PIE меняет выбранную установленную версию PHP. Не настраивает IIS, не выбирает сайт IIS и не перезапускает существующие PHP-процессы.

Установить вручную ZIP-пакет релиза

Используйте этот метод, когда нужно выбрать файлы драйверов самостоятельно или когда PIE не подходит.

  1. Скачайте ZIP-файл Windows для опубликованной версии драйвера со страницы Microsoft Drivers for PHP for SQL Server releases.

  2. Запустите php -i | findstr /I "PHP Version Thread Safety Architecture extension_dir" и запишите версию PHP, режим безопасности потоков, архитектуру и каталог расширений.

  3. Из ZIP скопируйте обе совпадающие библиотеки динамических связей (DLL) в каталог расширений:

    php_sqlsrv_<php-version>_<ts-or-nts>_<x86-or-x64>.dll
    php_pdo_sqlsrv_<php-version>_<ts-or-nts>_<x86-or-x64>.dll
    

    Например, PHP 8.5 x64 потоково-безопасная среда выполнения использует php_sqlsrv_85_ts_x64.dll и php_pdo_sqlsrv_85_ts_x64.dll.

  4. Добавьте соответствующие имена расширений к php.ini, используемому средой выполнения:

    extension=php_sqlsrv_85_ts_x64.dll
    extension=php_pdo_sqlsrv_85_ts_x64.dll
    

    Замените 85, tsи x64 на значения для вашего PHP-runtime. Не смешивайте потокобезопасные и непотокобезопасные файлы, 32-битные и 64-битные файлы, а также файлы, созданные для другой минорной версии PHP.

  5. Проверьте среду выполнения с помощью php --ri sqlsrv, php --ri pdo_sqlsrv и php -m. Для веб-сервера ограничите доступ к диагностической странице перед созданием временной phpinfo() страницы. Проверьте загруженный конфигурационный файл и оба раздела драйверов, затем удалите страницу.

Настройте веб-сервер

Для IIS настройте предназначенное приложение php-cgi.exe как FastCGI, следуя рекомендациям по установке PHP для IIS. Убедитесь, что приложение FastCGI использует ту же папку PHP и ту же архитектуру, которые вы использовали для установки драйверов.

Для любого веб-сервера Windows:

  1. Ограничьте доступ к диагностической странице перед созданием временной phpinfo() страницы. Определите PHP-исполняемый файл веб-сервера и активную конфигурацию php.ini.

  2. Убедитесь, что оба драйвера установлены для веб-среды выполнения. Для отдельной установки PHP используйте PIE с исполняемым файлом PHP этой установки или скопируйте оба совпадающих DLL-файла из выпущенного ZIP-файла в каталог расширений. Добавьте записи драйверов в конфигурацию веб-среды выполнения, включая случаи, когда только php.ini отличается от CLI.

  3. Перезапустите веб-сервер или процессы FastCGI.

  4. Убедитесь, что на странице есть отдельные sqlsrv и pdo_sqlsrv разделы.

  5. Удалите страницу phpinfo() .

Протестируйте оба PHP-API

Сохраните эту программу как verify-php-drivers.php:

<?php
$failures = [];

if (!extension_loaded('sqlsrv') || !function_exists('sqlsrv_connect')) {
    $failures[] = 'SQLSRV is not available.';
}

if (!extension_loaded('pdo_sqlsrv') || !in_array('sqlsrv', PDO::getAvailableDrivers(), true)) {
    $failures[] = 'PDO_SQLSRV is not available.';
}

echo $failures === []
    ? "SQLSRV and PDO_SQLSRV are available." . PHP_EOL
    : implode(PHP_EOL, $failures) . PHP_EOL;

exit($failures === [] ? 0 : 1);

Сначала запустите её из командной строки:

php verify-php-drivers.php

Ожидаемые выходные данные:

SQLSRV and PDO_SQLSRV are available.

Если нужно проверить веб-среду выполнения, временно поместите файл в корень документа сайта и запросите его в браузере. Удалите его после тестирования. Эта программа проверяет PHP-API, не требуя и не раскрывая учетные данные базы данных.

Проверьте соединение с базой данных

Загрузка расширения — это только первая проверка установки. Протестируйте оба API с целевой базой данных, используемой приложением, чтобы тест также охватывал драйвер ODBC, сетевой путь, шифрование, аутентификацию, выполнение запросов, возвращаемые значения и очистку.

Устанавливайте временные переменные среды в PowerShell, отвечая на запросы. Введите имя сервера и базы данных в виде необработанных значений без кавычек или кодирования драйверов. Используйте диалог с учетными данными или запрос учетных данных для тестовой учетной записи с доступом к базе данных. Не включайте учетные данные в командную строку или записанную сессию терминала:

$env:SQL_SERVER_NAME = Read-Host "Server name (tcp:<server>,1433)"
$env:SQL_DATABASE = Read-Host "Database name"
$credential = Get-Credential -Message "Enter the database test account"
if ($null -eq $credential) {
    throw "Database test credentials are required."
}
$env:SQL_UID = $credential.UserName
$env:SQL_PWD = $credential.GetNetworkCredential().Password
Remove-Variable credential

Запрос учетных данных маскирует пароль. Среда содержит пароль в открытом тексте, чтобы PHP мог его прочитать. Используйте эти переменные только в тестовой сессии, не печатьте их и очищайте после тестирования.

Сохраните эту программу как test-php-drivers.php. Сохраняйте значения переменных окружения без изменений. Программа удваивает замыкающие скобки и добавляет внешние скобки перед передачей драйверу имени базы данных, имени пользователя и пароля. Такое кодирование сохраняет буквальные скобки и предотвращает разделение параметров подключения точками с запятой.

<?php
$serverName = getenv('SQL_SERVER_NAME');
$database = getenv('SQL_DATABASE');
$uid = getenv('SQL_UID');
$pwd = getenv('SQL_PWD');

if ($serverName === false || $serverName === ''
    || $database === false || $database === ''
    || $uid === false || $uid === ''
    || $pwd === false || $pwd === '') {
    fwrite(STDERR, "Set SQL_SERVER_NAME, SQL_DATABASE, SQL_UID, and SQL_PWD." . PHP_EOL);
    exit(1);
}

$database = '{' . str_replace('}', '}}', $database) . '}';
$uid = '{' . str_replace('}', '}}', $uid) . '}';
$pwd = '{' . str_replace('}', '}}', $pwd) . '}';

$connectionOptions = [
    "Database" => $database,
    "UID" => $uid,
    "PWD" => $pwd,
    "Encrypt" => 1,
    "TrustServerCertificate" => 0,
];

$sqlsrvConnection = sqlsrv_connect($serverName, $connectionOptions);
if ($sqlsrvConnection === false) {
    foreach (sqlsrv_errors() as $error) {
        fwrite(
            STDERR,
            "SQLSRV {$error['SQLSTATE']} ({$error['code']}): {$error['message']}" . PHP_EOL
        );
    }
    exit(1);
}

$sqlsrvStatement = sqlsrv_query($sqlsrvConnection, "SELECT 1 AS TEST_VALUE");
if ($sqlsrvStatement === false) {
    foreach (sqlsrv_errors() as $error) {
        fwrite(
            STDERR,
            "SQLSRV {$error['SQLSTATE']} ({$error['code']}): {$error['message']}" . PHP_EOL
        );
    }
    sqlsrv_close($sqlsrvConnection);
    exit(1);
}

$sqlsrvRow = sqlsrv_fetch_array($sqlsrvStatement, SQLSRV_FETCH_ASSOC);
if ($sqlsrvRow === false || $sqlsrvRow === null || (int) $sqlsrvRow['TEST_VALUE'] !== 1) {
    fwrite(STDERR, "SQLSRV returned an unexpected result." . PHP_EOL);
    sqlsrv_free_stmt($sqlsrvStatement);
    sqlsrv_close($sqlsrvConnection);
    exit(1);
}

echo "SQLSRV query: 1" . PHP_EOL;
sqlsrv_free_stmt($sqlsrvStatement);
sqlsrv_close($sqlsrvConnection);

$failed = false;
try {
    $pdoConnection = new PDO(
        "sqlsrv:server=$serverName;Database=$database;Encrypt=1;TrustServerCertificate=0",
        $uid,
        $pwd,
        [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
    );
    $pdoStatement = $pdoConnection->query("SELECT 1 AS TEST_VALUE");
    $pdoRow = $pdoStatement->fetch(PDO::FETCH_ASSOC);
    if ($pdoRow === false || (int) $pdoRow['TEST_VALUE'] !== 1) {
        throw new RuntimeException("PDO_SQLSRV returned an unexpected result.");
    }

    echo "PDO_SQLSRV query: 1" . PHP_EOL;
} catch (Throwable $exception) {
    fwrite(STDERR, $exception->getMessage() . PHP_EOL);
    $failed = true;
} finally {
    unset($pdoStatement);
    unset($pdoConnection);
}

exit($failed ? 1 : 0);

Запустите программу с тем же исполняемым файлом PHP, который вы проверили:

php test-php-drivers.php

Ожидаемые выходные данные:

SQLSRV query: 1
PDO_SQLSRV query: 1

Если проверка расширения пройдена, но эта программа завершается с ошибкой, используйте SQLSTATE и код собственной ошибки, чтобы определить владеющий слой. Не переустанавливайте расширения PHP из-за ошибки сети, сертификата, аутентификации или прав доступа к базе данных.

Удалите скрипт и временные переменные после тестирования:

Remove-Item .\verify-php-drivers.php, .\test-php-drivers.php
Remove-Item Env:\SQL_SERVER_NAME, Env:\SQL_DATABASE, Env:\SQL_UID, Env:\SQL_PWD

Troubleshooting

Симптом Что требуется проверить Исправление
Could not open input file: .\pie.phar Текущий каталог и папка загрузки Вернитесь в каталог с проверенным PHAR или скачайте и проверьте его снова
Unable to load dynamic library extension_dir, точное название DLL, минорная версия PHP, архитектура и режим безопасности потоков Выберите соответствующую DLL или перезапустите PIE с нужным исполняемым файлом PHP
The specified module could not be found Зависимости DLL драйвера Убедитесь, что существует DLL-файл расширения, установите соответствующий Visual C++ Redistributable и проверьте оставшиеся отсутствующие зависимости DLL
CLI загружает оба драйвера, но IIS — нет. Другой исполняемый файл PHP или php.ini Сравните php --ini с phpinfo(), настройте IIS runtime и перезапустите FastCGI
Module "sqlsrv" is already loaded Записи в PIE и ZIP, или повторяющиеся записи Оставьте одну запись SQLSRV и одну запись PDO_SQLSRV
Отчёты PDO could not find driver конфигурация PDO_SQLSRV Запустите php --ri pdo_sqlsrv и проверьте PDO::getAvailableDrivers()
PIE сообщает об успехе, но старая версия остаётся Версионные элементы ZIP-архива всё ещё активны Замените старые записи на неверсионные DLL-записи PIE и перезапустите все процессы PHP

Если оба расширения загружаются, PHP может вызывать их API. Фиксируйте ошибки SQLSRV или исключение PDO перед изменением файлов драйверов. Ошибки сети, аутентификации, шифрования, сертификатов и разрешения базы данных не исправляются переустановкой расширения PHP.