Installeer de PHP-drivers voor SQL Server op Windows

Gebruik dit artikel om de SQLSRV- en PDO_SQLSRV-drivers voor PHP op Windows te installeren. De drivers zijn PHP-extensies die de Microsoft ODBC Driver voor SQL Server gebruiken.

Controleer voordat je begint of je PHP-versie, architectuur en thread-safety-modus worden ondersteund in de supportmatrix. De PHP-runtime die door een commandoregelproces wordt gebruikt en de runtime die door een webserver wordt gebruikt, kunnen verschillende php.ini bestanden gebruiken. Configureer en verifieer elke runtime apart.

Aan het einde van de procedure zouden zowel sqlsrv_connect() als de PDO-driver sqlsrv beschikbaar moeten zijn voor de bedoelde CLI of webapplicatie, en elke API moet een testquery uitvoeren. Een succesvolle bestandskopie alleen is geen voltooide installatie.

Een installatiemethode kiezen

Method Gebruik deze wanneer Wat wordt geïnstalleerd
PHP Installer voor Extensies (PIE) Je wilt dat de installer de driverbuild voor het PHP-uitvoerbare bestand selecteert zonder versie php_sqlsrv.dll en php_pdo_sqlsrv.dll, waarbij automatische configuratie is geprobeerd
Vrijgegeven ZIP-pakket Je moet exact vooraf gebouwde bestanden zelf kiezen, inspecteren of deployen Geversioneerde DLL's geselecteerd op basis van PHP-minorversie, thread-safety-modus en architectuur

Gebruik één methode voor beide extensies. Houd de PIE- en ZIP-configuratie-items niet tegelijk actief.

Vereiste onderdelen installeren

  1. Installeer een ondersteunde PHP-build vanaf de PHP for Windows-site. Voeg de PHP-map toe aan PATH.

  2. Installeer de Visual C++ Redistributable die vereist is voor je PHP-build. Stem de x64- of x86-architectuur af op PHP, zoals beschreven in de PHP voor Windows-vereisten.

  3. Installeer de nieuwste Microsoft ODBC-driver voor SQL Server.

  4. Voer de volgende commando's uit om de PHP-runtime en het configuratiebestand te controleren:

    php --version
    php --ini
    

    Als het geladen configuratiebestand(none) is, kopieer php.ini-development dan naar php.ini in de PHP-map.

  5. In php.ini, stel je de extensiemap in en schakel je de extensies in die vereist zijn door de PHP Installer for Extensions (PIE):

    extension_dir = "ext"
    extension=openssl
    extension=zip
    
  6. Controleer of PHP de vereiste extensies kan vinden:

    php --ri openssl
    php --ri zip
    

    Los deze vereisten op voordat je PIE downloadt.

Installeer met PIE

PIE installeert de bijbehorende precompileerde driver voor de PHP-runtime. Het vereist geen C-compiler op Windows.

  1. Ga naar een map waar je schrijfrechten hebt, en download het nieuwste PIE PHP-archief (PHAR):

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

    De overige PIE-commando's verwijzen naar het bestand als .\pie.phar, dus voer ze uit vanuit dezezelfde map.

    Controleer de PHAR voordat je deze uitvoert met de GitHub-commandoregelinterface (CLI):

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

    Bevestig de download voordat je verdergaat:

    dir pie.phar
    php .\pie.phar --version
    
  2. Installeer elke driver apart:

    php .\pie.phar install microsoft/sqlsrv
    php .\pie.phar install microsoft/pdo_sqlsrv
    
  3. Controleer de runtime van de commandoregel:

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

PIE probeert de extensies in te schakelen in de configuratie die door het opdrachtregelprogramma wordt gebruikt. Als PIE meldt dat het geen extensie kon inschakelen, voeg dan de PIE-specifieke extensie-vermeldingen toe.

Als je webserver een andere PHP-installatie gebruikt, installeer dan beide drivers voor de PHP-versie, architectuur en thread-safety-modus van die installatie voordat je de webserver configureert. Als dezelfde PHP-installatie een andere php.ini voor de webserver gebruikt, schakel dan de geïnstalleerde drivers in dat bestand in. Controleer de webruntime afzonderlijk en herstart de webserver nadat je de configuratie hebt gewijzigd.

PIE wijzigt de geselecteerde PHP-installatie. Er wordt geen IIS geconfigureerd, geen IIS-site geselecteerd en geen bestaande PHP-processen opnieuw gestart.

Installeer handmatig een vrijgegeven ZIP-pakket

Gebruik deze methode wanneer je zelf de driverbestanden moet selecteren of wanneer PIE niet geschikt is.

  1. Download de Windows ZIP voor de uitgebrachte driverversie op de Microsoft Drivers for PHP for SQL Server releases-pagina.

  2. Voer php -i | findstr /I "PHP Version Thread Safety Architecture extension_dir" uit en registreer de PHP-versie, thread-safety-modus, architectuur en extensiemap.

  3. Kopieer vanuit de ZIP beide bijpassende dynamic-link-bibliotheken (DLL's) naar de extensiemap:

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

    Bijvoorbeeld, een PHP 8.5 x64 thread-safe runtime gebruikt php_sqlsrv_85_ts_x64.dll en php_pdo_sqlsrv_85_ts_x64.dll.

  4. Voeg de bijpassende extensienamen toe aan de php.ini die door de runtime wordt gebruikt:

    extension=php_sqlsrv_85_ts_x64.dll
    extension=php_pdo_sqlsrv_85_ts_x64.dll
    

    Vervang 85, ts, en x64 door de waarden voor je PHP-runtime. Meng geen thread-veilige en niet-threadveilige bestanden, 32-bit en 64-bit bestanden, of bestanden die voor een andere PHP-minor versie zijn gemaakt.

  5. Controleer de runtime met php --ri sqlsrv, php --ri pdo_sqlsrv, en php -m. Voor een webserver beperk de toegang tot diagnostische pagina's voordat u een tijdelijke phpinfo() pagina aanmaakt. Controleer het geladen configuratiebestand en beide driversecties, en verwijder daarna de pagina.

Configureer een webserver

Voor IIS configureer je de gewenste php-cgi.exe als een FastCGI-applicatie door de PHP IIS-installatierichtlijnen te volgen. Bevestig dat de FastCGI-applicatie dezelfde PHP-map en architectuur gebruikt als die je gebruikte om de drivers te installeren.

Voor elke Windows-webserver:

  1. Beperk de toegang tot diagnostische pagina's voordat je een tijdelijke phpinfo() pagina aanmaakt. Identificeer het uitvoerbare PHP-bestand van de webserver en de actieve php.ini.

  2. Zorg ervoor dat beide drivers geïnstalleerd zijn voor de webruntime. Voor een aparte PHP-installatie gebruik je PIE met het PHP-uitvoerbare bestand van die installatie, of kopieer je beide overeenkomende DLL's van de uitgebrachte ZIP naar de extensiemap. Voeg de driververmeldingen toe aan de configuratie van de webruntime, ook wanneer alleen zijn php.ini verschilt van de CLI.

  3. Herstart de webserver of FastCGI-processen.

  4. Bevestig dat de pagina afzonderlijke sqlsrv- en pdo_sqlsrv-secties bevat.

  5. Verwijder de phpinfo() pagina.

Test beide PHP-API's

Sla dit programma op als 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);

Voer het eerst uit vanaf de opdrachtregel:

php verify-php-drivers.php

Verwachte uitvoer:

SQLSRV and PDO_SQLSRV are available.

Als je een webruntime moet verifiëren, plaats het bestand dan tijdelijk in de documentwortel van de site en vraag het op in een browser. Verwijder het na testen. Dit programma verifieert de PHP-API's zonder database-inloggegevens te vereisen of bloot te stellen.

Test een databaseverbinding

Het laden van extensies is slechts de eerste installatiecontrole. Test beide API's op de doeldatabase die de applicatie gebruikt, zodat de test ook de ODBC-driver, het netwerkpad, encryptie, authenticatie, query-uitvoering, teruggegeven waarden en opschoning dekt.

Stel tijdelijke omgevingsvariabelen in PowerShell in door vragen te beantwoorden. Voer de server- en databasenamen in als ruwe waarden, zonder aanhalingstekens of drivercodering. Gebruik het dialoogvenster voor referenties of de prompt voor een testaccount waarmee verbinding kan worden gemaakt met de database. Voeg geen inloggegevens toe in een commandoregel of opgenomen terminalsessie:

$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

Het aanmeldingsvenster maskeert het wachtwoord. De omgeving bevat het platte tekstwachtwoord zodat PHP het kan lezen. Gebruik deze variabelen alleen tijdens de testsessie, print ze niet uit en maak ze na het testen schoon.

Sla dit programma op als test-php-drivers.php. Houd de omgevingswaarden ongewijzigd. Het programma verdubbelt sluitaccolades en voegt buitenste beugels toe voordat de databasenaam, gebruikersnaam en wachtwoord aan het stuurprogramma worden doorgegeven. Deze codering behoudt letterlijke accolades en voorkomt dat puntkomma's verbindingsopties scheiden.

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

Voer het programma uit met hetzelfde PHP-uitvoerbare bestand dat je hebt geverifieerd:

php test-php-drivers.php

Verwachte uitvoer:

SQLSRV query: 1
PDO_SQLSRV query: 1

Als de extensiecontrole slaagt maar dit programma faalt, gebruik dan de SQLSTATE en de native error om de bezittende laag te identificeren. Installeer de PHP-extensies niet opnieuw voor een netwerk-, certificaat-, authenticatie- of databasemachtigingsfout.

Verwijder het script en de tijdelijke variabelen na testen:

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

Symptom Wat u moet controleren Repareren
Could not open input file: .\pie.phar Huidige directory en downloadlocatie Ga terug naar de map met de geverifieerde PHAR, of download en verifieer deze opnieuw
Unable to load dynamic library extension_dir, exacte DLL-naam, PHP-minorversie, architectuur en thread-safety-modus Selecteer de bijbehorende DLL of voer PIE opnieuw uit met het bedoelde PHP-uitvoerbare bestand
The specified module could not be found Driver-DLL-afhankelijkheden Bevestig dat de extensie DLL bestaat, installeer de bijbehorende Visual C++ Redistributable en inspecteer eventuele resterende ontbrekende DLL-afhankelijkheid
CLI laadt beide drivers, maar IIS doet dat niet Een ander PHP-executable of php.ini Vergelijk php --ini met phpinfo(), configureer de IIS-runtime en start FastCGI opnieuw op
Module "sqlsrv" is already loaded Zowel PIE- als ZIP-items, of herhaalde items Houd één SQLSRV-invoer en één PDO_SQLSRV vermelding
PDO meldt could not find driver PDO_SQLSRV configuratie Voer php --ri pdo_sqlsrv uit en controleer PDO::getAvailableDrivers()
PIE meldt succes, maar een oude versie blijft bestaan Geversioneerde ZIP-items zijn nog steeds actief Vervang oude vermeldingen door de niet-geversioneerde DLL-vermeldingen van PIE en start elk PHP-proces opnieuw

Als beide extensies geladen zijn, kan PHP hun API's aanroepen. Leg SQLSRV-fouten of de PDO-uitzondering vast voordat je de driverbestanden verandert. Netwerk-, authenticatie-, encryptie-, certificaat- en database-permissiefouten worden niet opgelost door de PHP-extensie opnieuw te installeren.