Aggiorna i driver PHP per SQL Server

Aggiorna SQLSRV e PDO_SQLSRV insieme in modo che entrambe le estensioni usino la stessa famiglia di versioni. I driver PHP utilizzano il driver Microsoft ODBC per SQL Server, quindi controlla i requisiti di sistema prima di aggiornare.

Un aggiornamento modifica il codice nativo caricato nei processi PHP. Un deployment misto può continuare a eseguire la versione precedente, fallire all'avvio di PHP o esporre versioni di driver diverse alla CLI e all'applicazione web. Inventariare ogni runtime PHP e conservare i file e le configurazioni precedenti fino al termine della verifica.

Scegli il percorso di aggiornamento

Installazione attuale Installazione di destinazione Procedure
PIE PIE Esegui PIE con lo stesso eseguibile PHP o php-config esplicito, poi verifica ogni SAPI
ZIP rilasciato da Windows Windows ha estratto ZIP Sostituire entrambe le DLL versionate e aggiornare insieme entrambe le voci di configurazione
ZIP rilasciato da Windows PIE Installare entrambi i pacchetti PIE, sostituire le voci DLL versionate con voci PIE e rimuovere i duplicati
Archivio delle versioni rilasciate per Linux o macOS PIE Installare entrambi i pacchetti PIE, sostituire le voci del nome file d'archivio con sqlsrv.so e pdo_sqlsrv.so, e preservare l'ordine di caricamento PDO
Linux o macOS PIE Nuova versione minore di PHP Installa i nuovi strumenti di sviluppo PHP, compila entrambe le estensioni per quell'installazione PHP e configura ogni SAPI separatamente

Non sovrascrivere i binari precedenti finché non hai una copia di rollback. Non aggiornare solo un'estensione quando l'applicazione usa entrambe le API.

Prima di aggiornare

  1. Registra l'eseguibile PHP, il file di configurazione, l'architettura, la modalità di sicurezza dei thread e le versioni attuali dei driver.

    php --version
    php --ini
    php --ri sqlsrv
    php --ri pdo_sqlsrv
    
  2. Fai il backup del file php.ini e di eventuali file .ini specifici dell'estensione che caricano sqlsrv o pdo_sqlsrv.

  3. Controlla la matrice di supporto per la versione PHP di destinazione e il sistema operativo.

  4. Controlla la tabella di compatibilità ODBC nei requisiti di sistema. Installa una versione ODBC supportata prima o durante l'aggiornamento del driver PHP quando la versione target del driver lo richiede.

  5. Pianifica un riavvio di ogni processo che carica PHP, inclusi il server web, PHP FastCGI Process Manager (PHP-FPM), i worker delle code e i worker da riga di comando a lunga esecuzione.

  6. Registra una baseline da ciascun runtime:

    • ExtensionVer è mostrato da php --ri sqlsrv e php --ri pdo_sqlsrv.
    • File di configurazione caricato e directory .ini analizzata.
    • La directory di estensione e i nomi dei file dei driver attivi.
    • Uno smoke test riuscito dell'applicazione che utilizza ogni API da cui la tua applicazione dipende.
  7. Prepara un rollback:

    • Mantieni disponibile il runtime PHP precedente se cambi la versione minore di PHP. Registra l'eseguibile configurato per ogni server web e worker.
    • Conserva copie dei precedenti file SQLSRV e PDO_SQLSRV.
    • Conserva copie di ogni file modificato php.ini o specifico dell'estensione .ini.
    • Registra la versione precedente del pacchetto ODBC se l'aggiornamento la modifica.
    • Definisci come fermare il traffico o i processi worker mentre vengono sostituiti i file di estensione nativi.

Aggiornamento su Windows con PIE

Usa il PHP Installer for Extensions (PIE) con l'eseguibile PHP che serve l'applicazione. Prima di tutto, scarica e verifica PIE. Prima di eseguire uno dei comandi di installazione, drena il traffico dell'applicazione e ferma il server web, i processi FastCGI e i worker che utilizzano questa installazione PHP. Impedire che si riavviino automaticamente finché sia le estensioni che la loro configurazione non saranno pronte. Tieni una sessione separata in riga di comando per PIE.

Commenta temporaneamente le voci esistenti delle estensioni SQLSRV e PDO_SQLSRV nella configurazione CLI usata da PIE. Altrimenti, il processo PHP che esegue PIE può mantenere cariche le vecchie DLL e impedirne la sostituzione. Mantieni abilitate le estensioni prerequisito di PIE.

Dalla directory che contiene pie.phar, installa entrambi i pacchetti separatamente:

php .\pie.phar install microsoft/sqlsrv
php .\pie.phar install microsoft/pdo_sqlsrv

PIE installa php_sqlsrv.dll e php_pdo_sqlsrv.dll. In ogni configurazione attiva, sostituire le voci ZIP versionate come extension=php_sqlsrv_85_ts_x64.dll e extension=php_pdo_sqlsrv_85_ts_x64.dll con:

extension=php_sqlsrv.dll
extension=php_pdo_sqlsrv.dll

Abilita entrambe le voci e rimuovi le voci duplicate di SQLSRV e PDO_SQLSRV anche se PIE segnala che l'abilitazione automatica è riuscita. Se il server web utilizza un'installazione PHP diversa, ripeti l'aggiornamento e le modifiche di configurazione per quell'installazione.

Riavvia ogni processo PHP, poi esegui php --ri sqlsrv e php --ri pdo_sqlsrv con l'eseguibile corrispondente. Conferma che ExtensionVer riporta la versione target per entrambi i driver. Per un'applicazione web, limita l'accesso alla pagina diagnostica prima di creare una pagina temporanea phpinfo() . Verifica entrambi i valori, poi rimuovi la pagina.

Aggiorna un'installazione di Windows ZIP

  1. Scarica il Windows ZIP della versione target dalla pagina Microsoft Drivers for PHP for SQL Server releases.

  2. Conferma che i nuovi nomi delle librerie a collegamento dinamico (DLL) corrispondano alla versione minore di PHP, all'architettura e alla modalità di sicurezza dei thread. Ferma il server web PHP o i processi worker prima di sostituire i file.

  3. Sostituisci entrambi i file php_sqlsrv_*.dll e php_pdo_sqlsrv_*.dll nella directory delle estensioni PHP. Mantieni le voci esistenti extension= se i nomi dei file corrispondono ancora. Altrimenti, aggiornali insieme.

  4. Installa o aggiorna il driver Microsoft ODBC per SQL Server se il driver PHP di destinazione richiede una versione supportata più recente.

  5. Riavvia ogni processo PHP che utilizza le DLL sostituite. Un processo in esecuzione mantiene caricata la vecchia estensione nativa finché non termina.

Aggiorna su Linux o macOS con PIE

  1. Segui la configurazione PIE e i prerequisiti della piattaforma se PIE non è installato. Conferma che gli strumenti di sviluppo PHP e il pacchetto ODBC siano installati. In una sessione interattiva, PIE può chiedere di installare gli strumenti di build mancanti tramite il gestore di pacchetti della piattaforma. In una sessione non interattiva, installali prima di eseguire PIE.

  2. Seleziona l'installazione PHP prima di aggiornare. Per un'installazione versionata, aggiungi l'opzione PIE --with-php-config a entrambi i comandi di installazione. Ad esempio, usare pie install --with-php-config=/usr/bin/php-config8.4 microsoft/sqlsrv quando lo strumento di configurazione previsto è /usr/bin/php-config8.4. Applica la stessa opzione a microsoft/pdo_sqlsrv. Per gli eseguibili versionati di Alpine, usa i comandi di installazione di Alpine.

  3. Drena il traffico dell'applicazione e ferma il server web, i processi PHP-FPM e i worker che utilizzano questa installazione PHP. Impedire che si riavviino automaticamente finché sia le estensioni che la loro configurazione non saranno pronte. Tieni una sessione separata in riga di comando per PIE.

    Commenta temporaneamente le voci esistenti delle estensioni SQLSRV e PDO_SQLSRV nella configurazione CLI usata da PIE. Mantieni abilitate le estensioni prerequisito di PIE.

  4. Aggiorna entrambi i pacchetti separatamente. Questi comandi utilizzano l'installazione PHP predefinita di PIE:

    pie install microsoft/sqlsrv
    pie install microsoft/pdo_sqlsrv
    
  5. Controlla ogni configurazione attiva per l'installazione PHP usata dalla tua applicazione. Se una precedente installazione manuale utilizza nomi file di archivio come extension=SQLSRV_8.4_NTS.so e extension=PDO_SQLSRV_8.4_NTS.so, sostituisci quelle voci con i nomi di file installati da PIE:

    extension=sqlsrv.so
    extension=pdo_sqlsrv.so
    

    Riabilita entrambe le voci del driver e rimuovi i duplicati. Tieni PDO_SQLSRV in un file di configurazione analizzato dal sistema che si carica dopo PDO, come descritto in Carica i driver su Linux e macOS. Ripeti questo cambiamento di configurazione per le configurazioni a riga di comando, PHP-FPM, server web e worker che la tua applicazione utilizza.

  6. Aggiorna il driver Microsoft ODBC per SQL Server quando richiesto dalla versione di destinazione.

  7. Riavvia ogni worker CLI, worker della coda, server web e servizio PHP-FPM che utilizzano l'installazione aggiornata di PHP.

Riavvia e verifica

Sostituire un file di estensione non aggiorna un processo PHP che ha già caricato il vecchio binario. Riavvia il server web, PHP-FPM e eventuali processi worker PHP a lunga esecuzione prima di verificare l'aggiornamento.

  1. Verifica il runtime della riga di comando:

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

    Su Linux o macOS, sostituisci l'ultimo comando con php -m | grep -E 'sqlsrv|pdo_sqlsrv'.

  2. Per un'applicazione web, limita l'accesso alla pagina diagnostica prima di creare una phpinfo() pagina temporanea. Verifica il file di configurazione caricato, la directory di estensione caricata e ExtensionVer caricato per entrambi i driver. Conferma che ExtensionVer riporta la versione target, poi rimuovi la pagina.

  3. Esegui un smoke test dell'applicazione esistente che eserciti sia SQLSRV che PDO_SQLSRV se la tua applicazione utilizza entrambi. Mantieni la configurazione della connessione invariata durante questo controllo così che un test di aggiornamento non verifichi anche una modifica di connessione non correlata.

Se un driver non si carica, confronta la versione minore di PHP, l'architettura, la modalità thread-safety, la cartella di estensione e l'installazione ODBC con i valori registrati prima dell'aggiornamento.

Verifica sia le API che le versioni

Salva questo programma come verify-driver-upgrade.php:

<?php
$results = [
    'SQLSRV' => [
        'loaded' => extension_loaded('sqlsrv') && function_exists('sqlsrv_connect'),
        'version' => phpversion('sqlsrv'),
    ],
    'PDO_SQLSRV' => [
        'loaded' => extension_loaded('pdo_sqlsrv')
            && in_array('sqlsrv', PDO::getAvailableDrivers(), true),
        'version' => phpversion('pdo_sqlsrv'),
    ],
];

$failed = false;
foreach ($results as $name => $result) {
    $version = $result['version'] === false ? 'unknown' : $result['version'];
    echo "$name: " . ($result['loaded'] ? 'loaded' : 'missing') . ", version $version" . PHP_EOL;
    $failed = $failed || !$result['loaded'] || $result['version'] === false;
}

exit($failed ? 1 : 0);

Esegui il programma con l'eseguibile della CLI e, temporaneamente, in ciascun runtime web. Conferma che entrambe le versioni riportate corrispondano a quella che hai installato. Rimuovi la copia web dopo la verifica.

Questo programma verifica lo strato delle estensioni PHP. Esegui il test di fumo dell'applicazione invariato successivamente per verificare il caricamento ODBC, le opzioni di connessione, l'autenticazione, l'accesso al database, i tipi di PHP restituiti e il comportamento di pulizia.

Verifica il comportamento del database prima e dopo l'aggiornamento

Usa le stesse impostazioni di programma e connessione prima e dopo l'aggiornamento. Mantenere il test invariato separa le modifiche al driver da quelle dell'applicazione o della configurazione della connessione.

Imposta le variabili di ambiente SQL_SERVER_NAME, SQL_DATABASE, SQL_UID e SQL_PWD per un account di test rispondendo ai prompt. Inserisci i valori grezzi, senza virgolette di shell o codifica del driver. Non includere credenziali in una riga di comando o in una sessione terminale registrata.

Su Windows PowerShell, inserisci il nome del server e il nome del database, poi usa la finestra di dialogo o il prompt delle credenziali per l'account di test:

$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

Su Linux o macOS, usa Bash. Disabilita il tracciamento dei comandi prima di leggere qualsiasi valore. Il prompt della password non visualizza ciò che digiti:

set +x
IFS= read -r -p 'Server name (tcp:<server>,1433): ' SQL_SERVER_NAME
IFS= read -r -p 'Database name: ' SQL_DATABASE
IFS= read -r -p 'User name: ' SQL_UID
IFS= read -r -s -p 'Password: ' SQL_PWD
printf '\n'
export SQL_SERVER_NAME SQL_DATABASE SQL_UID SQL_PWD

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-driver-upgrade.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 prima dell'aggiornamento e salva l'output corretto. Esegui di nuovo il file non modificato dopo aver riavviato ogni processo PHP:

php test-driver-upgrade.php

Entrambe le esecuzioni dovrebbero produrre:

SQLSRV query: 1
PDO_SQLSRV query: 1

Se l'esecuzione post-aggiornamento fallisce, mantenere il valore esatto di SQLSTATE o l'eccezione. Poi confronta il guasto con la baseline, le versioni di estensione, la configurazione attiva, la versione ODBC e lo stato del riavvio del processo. Ripristina entrambe le estensioni PHP insieme quando non puoi correggere la discrepanza entro la finestra di distribuzione.

Dopo la verifica, elimina il file di test e cancella le variabili temporanee dell'ambiente. In PowerShell eseguire:

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

In Linux o macOS eseguire:

rm verify-driver-upgrade.php test-driver-upgrade.php
unset SQL_SERVER_NAME SQL_DATABASE SQL_UID SQL_PWD

Ripristina un upgrade non riuscito

  1. Fermate i server web interessati, i pool di PHP-FPM e i worker a lunga esecuzione.

  2. Se hai cambiato la versione minore di PHP, ripristina il runtime PHP precedente e punta ogni server web e worker a quell'installazione.

  3. Ripristina entrambi i file driver precedenti. Ripristina insieme le precedenti voci di configurazione SQLSRV e PDO_SQLSRV.

  4. Ripristina il pacchetto ODBC precedente solo se la versione più recente ha causato il guasto e il pacchetto più vecchio rimane supportato dalla versione del driver PHP che hai ripristinato.

  5. Riavvia i processi e riesegui i controlli della versione di riferimento e gli smoke test dell'applicazione.

  6. Conserva i log degli aggiornamenti falliti e l'errore esatto di avvio o connessione di PHP. Aiutano a identificare se l'errore appartiene al caricamento PHP, al loader del sistema operativo, a ODBC o alla connessione al database.

Risolvere i problemi relativi a un aggiornamento

Sintomo Causa possibile Azione correttiva
Il PIE riesce ma ExtensionVer rimane invariato Una vecchia voce versionata carica ancora il file precedente Sostituisci la vecchia voce, rimuovi i duplicati e riavvia tutti i processi PHP
SQLSRV e PDO_SQLSRV riportano versioni diverse Solo un'estensione è stata sostituita o una SAPI ha una configurazione obsoleta Aggiorna e configura entrambe le estensioni insieme in ogni runtime
CLI riporta la versione target ma il sito no Il web SAPI utilizza un'altra installazione PHP o non è stato riavviato Confronta le directory di configurazione ed estensione, poi riavvia il processo corretto
L'avvio di PHP segnala un errore di architettura o di simbolo L'estensione non corrisponde alla build PHP Ripristina i file precedenti, poi ricostruisci o seleziona i file per la corretta versione minore PHP, architettura e modalità di sicurezza dei thread
Le estensioni si caricano ma le connessioni non funzionano dopo una modifica ODBC La configurazione ODBC, il comportamento dei certificati, l'autenticazione o l'accesso alla rete sono cambiati Acquisisci l'errore SQLSTATE e nativo prima di eseguire il rollback o modificare le impostazioni di connessione
I processi worker falliscono mentre le nuove richieste web hanno successo I worker a esecuzione prolungata mantengono ancora l'estensione o la configurazione precedente Svuota e riavvia ogni processo di lavoro