Zainstaluj sterowniki PHP dla SQL Server na Windows

Użyj tego artykułu, aby zainstalować SQLSRV i PDO_SQLSRV sterowniki do PHP na Windows. Sterowniki to rozszerzenia PHP wykorzystujące Microsoft ODBC Driver for SQL Server.

Zanim zaczniesz, upewnij się, że wersja PHP, architektura oraz tryb bezpieczeństwa wątków są obsługiwane w matrycy zgodności. Środowisko uruchomieniowe PHP używane przez proces wiersza poleceń oraz środowisko uruchomieniowe używane przez serwer WWW mogą używać różnych plików php.ini. Konfiguruj i weryfikuj każde środowisko uruchomienia osobno.

Na końcu procedury zarówno sqlsrv_connect(), jak i sterownik PDO sqlsrv powinny być dostępne dla zamierzonego interfejsu CLI lub aplikacji internetowej, a każde API powinno wykonać zapytanie testowe. Sama udana kopia pliku nie jest zakończoną instalacją.

Wybieranie metody instalacji

Metoda Użyj go, gdy Instalowane składniki
Instalator PHP dla rozszerzeń (PIE) Chcesz, aby instalator wybrał wersję sterownika pasującą do pliku wykonywalnego PHP Niewersjonowane php_sqlsrv.dll i php_pdo_sqlsrv.dll, z próbą automatycznej konfiguracji
Udostępniony pakiet ZIP Musisz sam wybrać, sprawdzić lub wdrożyć dokładnie określone, wstępnie zbudowane pliki Wersjonowane biblioteki DLL wybrane według pomocniczej wersji PHP, trybu bezpieczeństwa wątków oraz architektury

Używaj jednej metody dla obu rozszerzeń. Nie trzymaj aktywnych wpisów konfiguracji PIE i ZIP jednocześnie.

Instalowanie wymagań wstępnych

  1. Zainstaluj wspieraną wersję PHP z witryny PHP for Windows. Dodaj katalog PHP do PATH.

  2. Zainstaluj Visual C++ Redistributable wymagany przez twoją wersję PHP. Dopasuj jego architekturę x64 lub x86 do PHP, jak opisano w wymaganiach PHP for Windows.

  3. Zainstaluj najnowszy sterownik Microsoft ODBC dla SQL Server.

  4. Wykonaj następujące polecenia, aby potwierdzić środowisko uruchomieniowe PHP i plik konfiguracyjny:

    php --version
    php --ini
    

    Jeśli Załadowany plik konfiguracyjny ma wartość (none), skopiuj php.ini-development do php.ini w katalogu PHP.

  5. W php.ini, ustaw katalog rozszerzeń i włącz rozszerzenia wymagane przez PHP Installer for Extensions (PIE):

    extension_dir = "ext"
    extension=openssl
    extension=zip
    
  6. Sprawdź, czy PHP potrafi zlokalizować wymagane rozszerzenia:

    php --ri openssl
    php --ri zip
    

    Popraw te wymagania wstępne przed pobraniem PIE.

Zainstaluj przy użyciu PIE

PIE instaluje odpowiadający prekompilowany sterownik dla środowiska uruchomieniowego PHP. Nie wymaga kompilatora C na Windows.

  1. Zmień katalog, do którego masz uprawnienia zapisu, i pobierz najnowsze archiwum PIE PHP (PHAR):

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

    Pozostałe polecenia PIE odwołują się do pliku jako .\pie.phar, więc uruchamiaj je z tego samego katalogu.

    Zanim uruchomisz PHAR, sprawdź go za pomocą interfejsu wiersza poleceń GitHub (CLI):

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

    Potwierdź pobranie przed kontynuacją:

    dir pie.phar
    php .\pie.phar --version
    
  2. Zainstaluj każdy sterownik osobno:

    php .\pie.phar install microsoft/sqlsrv
    php .\pie.phar install microsoft/pdo_sqlsrv
    
  3. Sprawdź środowisko uruchomieniowe wiersza poleceń:

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

PIE próbuje włączyć rozszerzenia w konfiguracji używanej przez program wiersza poleceń. Jeśli PIE raportuje, że nie mogło włączyć rozszerzenia, dodaj wpisy rozszerzeń specyficzne dla PIE.

Jeśli Twój serwer WWW korzysta z innej instalacji PHP, zainstaluj oba sterowniki dla wersji PHP, architektury i trybu bezpieczeństwa wielowątkowego tej instalacji przed konfiguracją. Jeśli ta sama instalacja PHP używa innego php.ini dla serwera WWW, włącz zainstalowane rozszerzenia w tym pliku. Zweryfikuj środowisko uruchomieniowe web osobno i zrestartuj serwer web po zmianie jego konfiguracji.

PIE zmienia wybraną instalację PHP. Nie konfiguruje IIS, nie wybiera witryny IIS ani nie restartuje istniejących procesów PHP.

Ręcznie zainstaluj opublikowany pakiet ZIP

Używaj tej metody, gdy musisz samodzielnie wybrać pliki sterownika lub gdy PIE nie jest odpowiednie.

  1. Pobierz plik ZIP dla systemu Windows dla wydanej wersji sterownika ze strony wydań Microsoft Drivers for PHP for SQL Server.

  2. Uruchom php -i | findstr /I "PHP Version Thread Safety Architecture extension_dir" i zanotuj wersję PHP, tryb bezpieczeństwa wątków, architekturę oraz katalog rozszerzeń.

  3. Z pliku ZIP skopiuj obie pasujące biblioteki DLL do katalogu rozszerzenia:

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

    Na przykład środowisko uruchomieniowe PHP 8.5 x64 bezpieczne dla wątków używa php_sqlsrv_85_ts_x64.dll i php_pdo_sqlsrv_85_ts_x64.dll.

  4. Dodaj odpowiadające nazwy rozszerzeń do php.ini używanego przez środowisko uruchomieniowe:

    extension=php_sqlsrv_85_ts_x64.dll
    extension=php_pdo_sqlsrv_85_ts_x64.dll
    

    Zastąp 85, ts i x64 wartościami dla twojego środowiska wykonawczego PHP. Nie mieszaj plików bezpiecznych dla wątków i niebezpiecznych dla wątków, plików 32-bitowych i 64-bitowych ani plików stworzonych dla innej pomocniczej wersji PHP.

  5. Zweryfikowaj czas działania z php --ri sqlsrv, php --ri pdo_sqlsrv, oraz php -m. Dla serwera WWW należy ograniczyć dostęp do strony diagnostycznej przed utworzeniem tymczasowej phpinfo() strony. Zweryfikuj załadowany plik konfiguracyjny oraz obie sekcje sterowników, a następnie usuń stronę.

Konfiguruj serwer WWW

Dla IIS skonfiguruj docelowe php-cgi.exe jako aplikację FastCGI, stosując się do wytycznych dotyczących instalacji PHP IIS. Sprawdź, czy aplikacja FastCGI używa tego samego katalogu i architektury PHP, których użyto do zainstalowania sterowników.

Dla dowolnego serwera WWW Windows:

  1. Ogranicz dostęp do strony diagnostycznej przed utworzeniem tymczasowej phpinfo() strony. Zidentyfikuj wykonywalny plik PHP serwera WWW i aktywną konfigurację php.ini.

  2. Upewnij się, że oba sterowniki są zainstalowane dla środowiska uruchomieniowego sieci Web. Dla osobnej instalacji PHP użyj PIE z plikiem wykonywalnym PHP tej instalacji lub skopiuj oba pasujące pliki DLL z wydanego ZIP-a do katalogu rozszerzeń tej instalacji. Dodaj wpisy sterowników do konfiguracji środowiska uruchomieniowego web, w tym wtedy, gdy tylko jego php.ini różni się od CLI.

  3. Zrestartuj serwer WWW lub procesy FastCGI.

  4. Upewnij się, że strona zawiera osobne sekcje sqlsrv i pdo_sqlsrv.

  5. Usuń phpinfo() stronę.

Przetestuj oba API PHP

Zapisz ten program jako 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);

Najpierw uruchom go z linii poleceń:

php verify-php-drivers.php

Oczekiwane dane wyjściowe:

SQLSRV and PDO_SQLSRV are available.

Jeśli musisz zweryfikować środowisko uruchomieniowe sieci Web, tymczasowo umieść plik w katalogu głównym dokumentów witryny i otwórz go w przeglądarce. Usuń go po testach. Program ten weryfikuje interfejsy API PHP bez konieczności udostępniania lub ujawniania danych uwierzytelniających do bazy danych.

Przetestuj połączenie bazy danych

Ładowanie rozszerzenia to tylko pierwszym sprawdzeniem instalacji. Przetestuj oba interfejsy API względem docelowej bazy danych, której używa aplikacja, aby test obejmował także sterownik ODBC, ścieżkę sieciową, szyfrowanie, uwierzytelnianie, wykonywanie zapytań, zwracane wartości oraz czyszczenie.

Ustaw tymczasowe zmienne środowiskowe w PowerShell, odpowiadając na prompty. Wprowadź nazwę serwera i bazy danych jako surowe wartości, bez cudzysłowów czy kodowania sterowników. Użyj okna dialogowego lub monitu poświadczeń dla konta testowego, które może połączyć się z bazą danych. Nie umieszczaj danych uwierzytelniających w wierszu poleceń ani w nagranej sesji terminalowej:

$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

Monit o dane logowania maskuje hasło. Środowisko zawiera hasło w tekstie jawnym, aby PHP mógł je odczytać. Używaj tych zmiennych tylko podczas sesji testowej, nie drukuj ich i usuwaj po testach.

Zapisz ten program jako test-php-drivers.php. Zachowaj wartości środowiska bez zmian. Program podwaja zamykające się klamry i dodaje zewnętrzne klamry przed przekazaniem nazwy bazy danych, nazwy użytkownika i hasła do sterownika. To kodowanie zachowuje dosłowne nawiasy klamrowe i zapobiega rozdzielaniu opcji połączeń przez średniki.

<?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);

Uruchom program z tym samym plikiem wykonywalnym PHP, który zweryfikowałeś:

php test-php-drivers.php

Oczekiwane dane wyjściowe:

SQLSRV query: 1
PDO_SQLSRV query: 1

Jeśli test rozszerzenia przejdzie, ale ten program zakończy się niepowodzeniem, użyj SQLSTATE i błędu natywnego do zidentyfikowania warstwy będącej właścicielem. Nie instaluj ponownie rozszerzeń PHP w przypadku błędu sieciowego, certyfikatu, uwierzytelniania lub uprawnień bazy danych.

Usuń skrypt i zmienne tymczasowe po testach:

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

Objaw Co należy sprawdzić? Napraw.
Could not open input file: .\pie.phar Aktualny katalog i miejsce pobierania Wróć do katalogu zawierającego zweryfikowany PHAR lub pobierz i zweryfikowaj go ponownie
Unable to load dynamic library extension_dir, dokładną nazwę DLL, wersję minor PHP, architekturę oraz tryb bezpieczeństwa wątków Wybierz odpowiadające DLL lub ponownie uruchom PIE z zamierzonym plikiem wykonywalnym PHP
The specified module could not be found Zależności biblioteki DLL sterownika Potwierdź, że plik DLL rozszerzenia istnieje, zainstaluj odpowiadający pakiet redystrybucyjny Visual C++ i sprawdź wszelkie pozostałe brakujące zależności DLL
CLI ładuje oba sterowniki, ale IIS nie Różny plik wykonywalny PHP lub php.ini Porównaj phpinfo() z php --ini, konfiguruj runtime IIS i restartuj FastCGI
Module "sqlsrv" is already loaded Zarówno wpisy PIE i ZIP, jak i powtarzające się wpisy Zachowaj jeden wpis SQLSRV i jeden PDO_SQLSRV
PDO zgłasza could not find driver Konfiguracja PDO_SQLSRV Uruchom php --ri pdo_sqlsrv i sprawdź PDO::getAvailableDrivers()
PIE informuje o sukcesie, ale stara wersja pozostaje Wersjonowane wpisy ZIP nadal aktywne Zamień stare wpisy na niezwersowane wpisy DLL PIE i restartuj każdy proces PHP

Jeśli oba rozszerzenia się załadują, PHP może wywołać ich API. Przed zmianą plików sterowników uchwyć błędy SQLSRV lub wyjątek PDO. Błędy sieciowe, uwierzytelniania, szyfrowania, certyfikatów i uprawnień do bazy danych nie są naprawiane przez ponowną instalację rozszerzenia PHP.