Installa i driver PHP per SQL Server su Windows

Usa questo articolo per installare i driver SQLSRV e PDO_SQLSRV per PHP su Windows. I driver sono estensioni PHP che utilizzano il driver Microsoft ODBC per SQL Server.

Prima di iniziare, verifica che la tua versione PHP, l'architettura e la modalità di sicurezza dei thread siano supportate nella matrice di supporto. Il runtime PHP usato da un processo da riga di comando e il runtime usato da un server web possono utilizzare diversi file php.ini. Configura e verifica ogni runtime separatamente.

Al termine della procedura, sia sqlsrv_connect() sia il driver PDO sqlsrv dovrebbero essere disponibili per la CLI o l'applicazione web prevista, e ogni API dovrebbe completare una query di test. Una copia di file riuscita da sola non è un'installazione completata.

Scegliere un metodo di installazione

Method Usarlo quando Cosa installa
Installatore PHP per Estensioni (PIE) Vuoi che l'installatore selezioni la build driver per l'eseguibile PHP Senza versione php_sqlsrv.dll e php_pdo_sqlsrv.dll, con configurazione automatica tentata
Pacchetto ZIP rilasciato Devi scegliere, ispezionare o distribuire tu stesso file precompilati esatti DLL suddivise per versione, selezionate in base alla versione secondaria di PHP, alla modalità di sicurezza dei thread e all'architettura

Usa un solo metodo per entrambe le estensioni. Non tenere attive contemporaneamente le voci di configurazione PIE e ZIP.

Installare i prerequisiti

  1. Installa una build PHP supportata dal sito PHP per Windows. Aggiungi la directory PHP a PATH.

  2. Installa il Visual C++ Redistributable richiesto dalla tua build PHP. Assicurati che la sua architettura x64 o x86 corrisponda a quella di PHP, come descritto nei requisiti PHP per Windows.

  3. Installa l'ultimo driver Microsoft ODBC per SQL Server.

  4. Esegui i seguenti comandi per confermare il runtime PHP e il file di configurazione:

    php --version
    php --ini
    

    Se il file di configurazione caricato è (none), copia php.ini-development in php.ini nella directory PHP.

  5. In php.ini, imposta la directory delle estensioni e abilita le estensioni richieste dall'Installer PHP per le Estensioni (PIE):

    extension_dir = "ext"
    extension=openssl
    extension=zip
    
  6. Conferma che PHP riesca a individuare le estensioni prerequisite:

    php --ri openssl
    php --ri zip
    

    Soddisfa questi prerequisiti prima di scaricare PIE.

Installa con PIE

PIE installa il driver precompilato corrispondente per il runtime PHP. Non richiede un compilatore C su Windows.

  1. Cambia in una directory su cui puoi scrivere e scarica l'ultimo archivio PIE PHP (PHAR):

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

    I restanti comandi PIE si riferiscono al file come .\pie.phar, quindi eseguili da questa stessa directory.

    Prima di eseguire il PHAR, verificalo con l'interfaccia a riga di comando (CLI) di GitHub:

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

    Conferma il download prima di continuare:

    dir pie.phar
    php .\pie.phar --version
    
  2. Installa ogni driver separatamente:

    php .\pie.phar install microsoft/sqlsrv
    php .\pie.phar install microsoft/pdo_sqlsrv
    
  3. Verifica il runtime della riga di comando:

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

PIE tenta di abilitare le estensioni nella configurazione usata dall'eseguibile a riga di comando. Se PIE segnala che non poteva abilitare un'estensione, aggiungi le voci dell'estensione specifiche di PIE.

Se il tuo server web utilizza un'altra installazione PHP, installa entrambi i driver per la versione PHP di quell'installazione, l'architettura e la modalità thread-safety prima di configurarlo. Se la stessa installazione PHP usa un altro php.ini per il server web, abilita i driver installati in quel file. Verifica separatamente il runtime web e riavvia il server web dopo aver cambiato la configurazione.

PIE modifica l'installazione PHP selezionata. Non configura IIS, non seleziona un sito IIS né riavvia processi PHP esistenti.

Installa manualmente un pacchetto ZIP rilasciato

Usa questo metodo quando devi selezionare tu stesso i file dei driver o quando il PIE non è adatto.

  1. Scarica il Windows ZIP per la versione rilasciata del driver dalla pagina Microsoft Drivers for PHP for SQL Server releases.

  2. Esegui php -i | findstr /I "PHP Version Thread Safety Architecture extension_dir" e registra la versione PHP, la modalità di sicurezza dei thread, l'architettura e la directory delle estensioni.

  3. Dal ZIP, copiare entrambe le librerie a collegamento dinamico corrispondenti (DLL) nella directory di estensione:

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

    Ad esempio, un runtime thread-safe PHP 8.5 x64 utilizza php_sqlsrv_85_ts_x64.dll e php_pdo_sqlsrv_85_ts_x64.dll.

  4. Aggiungi i nomi corrispondenti delle estensioni al php.ini usato dal runtime:

    extension=php_sqlsrv_85_ts_x64.dll
    extension=php_pdo_sqlsrv_85_ts_x64.dll
    

    Sostituisci 85, ts, e x64 con i valori per il tuo runtime PHP. Non mischiare file thread-safe e non thread-safe, file a 32 e 64 bit, o file costruiti per un'altra versione minore di PHP.

  5. Verifica il runtime con php --ri sqlsrv, php --ri pdo_sqlsrv, e php -m. Per un server web, limita l'accesso alla pagina diagnostica prima di creare una temporanea phpinfo() pagina. Verifica il file di configurazione caricato e entrambe le sezioni del driver, poi rimuovi la pagina.

Configura un server web

Per IIS, configura il php-cgi.exe previsto come applicazione FastCGI seguendo le indicazioni di installazione di PHP IIS. Conferma che l'applicazione FastCGI utilizza la stessa directory e architettura PHP che hai usato per installare i driver.

Per qualsiasi server web Windows:

  1. Limita l'accesso alla pagina diagnostica prima di creare una pagina temporanea phpinfo() . Identifica l'eseguibile PHP del server web e il file php.ini attivo php.ini.

  2. Assicurati che entrambi i driver siano installati per il runtime web. Per un'installazione PHP separata, usa PIE con l'eseguibile PHP di quell'installazione, oppure copia entrambe le DLL corrispondenti dal file ZIP rilasciato nella cartella delle estensioni di quell'installazione. Aggiungi le voci del driver alla configurazione del runtime web, anche quando solo il suo php.ini differisce dalla CLI.

  3. Riavvia il server web o i processi FastCGI.

  4. Conferma che la pagina contiene sezioni separate sqlsrv e pdo_sqlsrv separate.

  5. Rimuovi la phpinfo() pagina.

Testa entrambe le API PHP

Salva questo programma come 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);

Eseguilo prima dalla riga di comando:

php verify-php-drivers.php

Output previsto:

SQLSRV and PDO_SQLSRV are available.

Se devi verificare un runtime web, posiziona temporaneamente il file nella document root del sito e aprilo in un browser. Rimuovilo dopo il test. Questo programma verifica le API PHP senza richiedere o esporre le credenziali del database.

Testare una connessione a un database

Il caricamento delle estensioni è solo il primo controllo di installazione. Testa entrambe le API rispetto al target del database utilizzato dall'applicazione, così il test copre anche il driver ODBC, il percorso di rete, la crittografia, l'autenticazione, l'esecuzione delle query, i valori restituiti e la pulizia.

Imposta variabili di ambiente temporanee in PowerShell rispondendo ai prompt. Inserisci i nomi del server e del database come valori grezzi, senza virgolette o codifica dei driver. Usa la finestra di dialogo o il prompt delle credenziali per un account di test che possa collegarsi al database. Non includere credenziali in una riga di comando o in una sessione terminale registrata:

$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

Il prompt per le credenziali maschera la password. L'ambiente contiene la password in chiaro così PHP può leggerla. Usa queste variabili solo durante la sessione di test, non stamparle e cancellale dopo il test.

Salva questo programma come test-php-drivers.php. Mantieni invariati i valori dell'ambiente. Il programma raddoppia le parentesi di chiusura e aggiunge le parentesi esterne prima di passare il nome del database, il nome utente e la password al driver. Questa codifica preserva le parentesi graffe letterali e impedisce ai punti e virgola di separare le opzioni di connessione.

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

Esegui il programma con lo stesso eseguibile PHP che hai verificato:

php test-php-drivers.php

Output previsto:

SQLSRV query: 1
PDO_SQLSRV query: 1

Se il controllo dell'estensione passa ma questo programma fallisce, usa SQLSTATE e l'errore nativo per identificare il livello responsabile. Non reinstallare le estensioni PHP per errori di rete, certificato, autenticazione o autorizzazione del database.

Rimuovere lo script e le variabili temporanee dopo i test:

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

Sintomo Controlli da eseguire Correzione
Could not open input file: .\pie.phar Directory attuale e posizione di download Torna alla directory contenente il PHAR verificato, oppure scaricalo e verificalo di nuovo
Unable to load dynamic library extension_dir, nome DLL esatto, versione minore di PHP, architettura e modalità di sicurezza dei thread Seleziona la DLL corrispondente o riesegui il PIE con l'eseguibile PHP previsto
The specified module could not be found Dipendenze DLL dei driver Conferma che la DLL di estensione esiste, installa il Visual C++ Redistributable corrispondente e ispeziona eventuali dipendenze residue della DLL mancante
La CLI carica entrambi i driver ma IIS no Eseguibili PHP diversi o php.ini Confronta php --ini con phpinfo(), configura il runtime IIS e riavvia FastCGI
Module "sqlsrv" is already loaded Sia voci PIE che ZIP, oppure voci ripetute Tieni una voce SQLSRV e una PDO_SQLSRV voce
Report PDO could not find driver Configurazione di PDO_SQLSRV Esegui php --ri pdo_sqlsrv e controlla PDO::getAvailableDrivers()
PIE segnala che l'operazione è riuscita ma una vecchia versione rimane Voci ZIP versionate ancora attive Sostituire le vecchie voci con le voci DLL non versionate di PIE e riavviare ogni processo PHP

Se entrambe le estensioni si caricano, PHP può chiamare le loro API. Cattura gli errori SQLSRV o l'eccezione PDO prima di cambiare file driver. Gli errori di rete, autenticazione, crittografia, certificato e autorizzazione del database non vengono risolti reinstallando l'estensione PHP.