Aktualisieren Sie die PHP-Treiber für SQL Server

Aktualisieren Sie SQLSRV und PDO_SQLSRV gemeinsam, sodass beide Erweiterungen dieselbe Versionsfamilie verwenden. Die PHP-Treiber verwenden den Microsoft ODBC-Treiber für SQL Server, daher sollten Sie vor dem Upgrade die Systemanforderungen prüfen.

Ein Upgrade ändert nativen Code, der in PHP-Prozessen geladen wird. Eine gemischte Bereitstellung kann die vorherige Version weiterführen, beim PHP-Start ausfallen oder verschiedene Treiberversionen für die CLI und Webanwendung bereitstellen. Inventariere jede PHP-Laufzeit und bewahre die vorherigen Dateien und Konfigurationen auf, bis die Verifikation abgeschlossen ist.

Wählen Sie den Upgradepfad

Aktuelle Installation Zielinstallation Procedure
PIE PIE Führe PIE mit derselben PHP-Executable oder explizit php-config aus und verifiziere dann jede SAPI
Für Windows freigegebenes ZIP Von Windows erstellte ZIP-Datei Ersetzen Sie beide versionierten DLLs und aktualisieren Sie beide Konfigurationseinträge gleichzeitig
von Windows erstellte ZIP-Datei PIE Installieren Sie beide PIE-Pakete, ersetzen Sie versionierte DLL-Einträge durch PIE-Einträge und entfernen Sie Duplikate
Für Linux oder macOS veröffentlichtes Archiv PIE Installieren Sie beide PIE-Pakete, ersetzen Sie Archive-Filename-Einträge durch sqlsrv.so und pdo_sqlsrv.so, und behalten Sie die PDO-Ladereihenfolge bei
Linux oder macOS PIE Neue PHP-Minor-Version Installiere die neuen PHP-Entwicklungstools, baue beide Erweiterungen für diese PHP-Installation und konfiguriere jedes SAPI separat

Überschreibe die vorherigen Binärdateien nicht, bis du eine Rollback-Kopie hast. Aktualisieren Sie nicht nur eine Erweiterung, wenn die Anwendung beide APIs verwendet.

Vor dem Upgrade

  1. Notiere die PHP-ausführbare Datei, die Konfigurationsdatei, die Architektur, den Thread-Sicherheitsmodus und die aktuellen Treiberversionen.

    php --version
    php --ini
    php --ri sqlsrv
    php --ri pdo_sqlsrv
    
  2. Sichern Sie die php.ini-Datei und alle erweiterungsspezifischen .ini-Dateien, die sqlsrv oder pdo_sqlsrv laden.

  3. Überprüfe die Support-Matrix für die Ziel-PHP-Version und das Betriebssystem.

  4. Siehe die ODBC-Kompatibilitätstabelle unter Systemanforderungen. Installiere eine unterstützte ODBC-Version vor oder während des PHP-Treiber-Upgrades, wenn die Zieltreiberversion es verlangt.

  5. Planen Sie einen Neustart jedes Prozesses, der PHP lädt, einschließlich des Webservers, des PHP FastCGI Process Manager (PHP-FPM), Queue-Workern und langlebigen Befehlszeilen-Workern.

  6. Zeichnen Sie eine Basislinie von jeder Runtime auf:

    • Die von php --ri sqlsrv und php --ri pdo_sqlsrv angezeigte ExtensionVer.
    • Die Konfigurationsdatei wurde geladen und das Verzeichnis .ini wurde gescannt.
    • Das Erweiterungsverzeichnis und die Dateinamen des aktiven Treibers.
    • Ein erfolgreicher Anwendungs-Rauchtest, der jede API nutzt, auf der Ihre Anwendung angewiesen ist.
  7. Rollback vorbereiten:

    • Halte die vorherige PHP-Laufzeit verfügbar, falls du die PHP-Minor-Version änderst. Erfassen Sie die ausführbare Datei, die für jeden Webserver und Worker konfiguriert ist.
    • Bewahre Kopien der vorherigen SQLSRV- und PDO_SQLSRV Dateien auf.
    • Bewahre Kopien aller geänderten php.ini oder erweiterungsspezifischen .ini Dateien auf.
    • Notieren Sie die vorherige ODBC-Paketversion, falls das Upgrade sie ändert.
    • Definiere, wie der Betrieb oder die Worker gestoppt werden können, während native Erweiterungsdateien ersetzt werden.

Upgrade unter Windows mit PIE

Verwenden Sie den PHP Installer for Extensions (PIE) mit dem PHP-Executable, mit dem die Anwendung ausgeführt wird. Erstens: Laden Sie PIE herunter und überprüfen Sie es. Bevor Sie einen der Installationsbefehle ausführen, leiten Sie den Anwendungsverkehr um und stoppen Sie den Webserver, FastCGI-Prozesse und Worker, die diese PHP-Installation verwenden. Verhindern Sie, dass diese automatisch neu starten, bis sowohl Erweiterungen als auch deren Konfiguration bereit sind. Halte eine separate Kommandozeilensitzung für PIE.

Kommentieren Sie vorübergehend die vorhandenen SQLSRV- und PDO_SQLSRV-Erweiterungseinträge in der von PIE verwendeten CLI-Konfiguration. Andernfalls kann der PHP-Prozess, der PIE ausführt, die alten DLLs geladen halten und einen Austausch verhindern. PIEs erforderliche Erweiterungen aktiviert lassen.

Aus dem Verzeichnis mit pie.phar installieren Sie beide Pakete separat:

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

PIE installiert php_sqlsrv.dll und php_pdo_sqlsrv.dll. Ersetzen Sie in jeder aktiven Konfiguration versionierte ZIP-Einträge wie extension=php_sqlsrv_85_ts_x64.dll und extension=php_pdo_sqlsrv_85_ts_x64.dll durch:

extension=php_sqlsrv.dll
extension=php_pdo_sqlsrv.dll

Beide Einträge aktivieren und doppelte SQLSRV- und PDO_SQLSRV-Einträge entfernen, selbst wenn PIE meldet, dass die automatische Aktivierung erfolgreich war. Wenn der Webserver eine andere PHP-Installation verwendet, wiederhole das Upgrade und die Konfigurationsänderungen für diese Installation.

Starte jeden PHP-Prozess neu und führe dann php --ri sqlsrv und php --ri pdo_sqlsrv mit der entsprechenden ausführbaren Datei aus. Bestätigen Sie, dass ExtensionVer die Zielversion für beide Treiber meldet. Für eine Webanwendung sollte der Zugriff auf diagnostische Seiten eingeschränkt werden, bevor eine temporäre phpinfo() Seite erstellt wird. Verifiziere beide Werte und entferne dann die Seite.

Aktualisieren einer Windows-ZIP-Installation

  1. Laden Sie die Windows ZIP der Zielversion von der Seite Microsoft Drivers for PHP for SQL Server Releases herunter.

  2. Bestätigen Sie, dass die neuen Namen der Dynamic-Link-Bibliothek (DLL) mit der PHP-Minor-Version, der Architektur und dem Thread-Sicherheitsmodus übereinstimmen. Stoppe den PHP-Webserver oder die Worker-Prozesse, bevor du Dateien ersetzt.

  3. Ersetzen Sie beide Dateien php_sqlsrv_*.dll und php_pdo_sqlsrv_*.dll im PHP-Erweiterungsverzeichnis. Behalte die bestehenden extension= Einträge, falls die Dateinamen noch übereinstimmen. Ansonsten aktualisieren Sie sie gemeinsam.

  4. Installieren oder aktualisieren Sie den Microsoft ODBC-Treiber für SQL Server, wenn der Ziel-PHP-Treiber eine neuere unterstützte Version benötigt.

  5. Starte jeden PHP-Prozess, der die ersetzten DLLs verwendet, neu. Ein laufender Prozess hält die alte native Erweiterung geladen, bis er beendet wird.

Upgrade auf Linux oder macOS mit PIE

  1. Halte dich an die PIE-Einrichtung und die Plattformvoraussetzungen , falls PIE nicht installiert ist. Bestätigen Sie, dass die PHP-Entwicklungstools und das ODBC-Entwicklungspaket installiert sind. In einer interaktiven Sitzung kann PIE über den Plattform-Paketmanager zur Installation fehlender Build-Tools auffordern. In einer nicht-interaktiven Sitzung installieren Sie sie, bevor Sie PIE ausführen.

  2. Wähle die PHP-Installation vor dem Upgrade aus. Für eine versionierte Installation fügen Sie die Option von PIE --with-php-config zu beiden Installationsbefehlen hinzu. Zum Beispiel verwenden Sie pie install --with-php-config=/usr/bin/php-config8.4 microsoft/sqlsrv, wenn das vorgesehene Konfigurationswerkzeug /usr/bin/php-config8.4 ist. Wende dieselbe Option auf microsoft/pdo_sqlsrv an. Für versionierte ausführbare Dateien von Alpine verwenden Sie die Installationsbefehle von Alpine.

  3. Leiten Sie den Anwendungsverkehr ab und stoppen Sie den Webserver, PHP-FPM-Prozesse und Worker, die diese PHP-Installation verwenden. Verhindern Sie, dass diese automatisch neu starten, bis sowohl Erweiterungen als auch deren Konfiguration bereit sind. Halte eine separate Kommandozeilensitzung für PIE.

    Kommentieren Sie vorübergehend die vorhandenen SQLSRV- und PDO_SQLSRV-Erweiterungseinträge in der von PIE verwendeten CLI-Konfiguration. Lass die erforderlichen Erweiterungen von PIE aktiviert.

  4. Upgrade beide Pakete einzeln. Diese Befehle verwenden die Standard-PHP-Installation von PIE:

    pie install microsoft/sqlsrv
    pie install microsoft/pdo_sqlsrv
    
  5. Überprüfe jede aktive Konfiguration der von deiner Anwendung verwendeten PHP-Installation. Wenn eine frühere manuelle Installation Archiv-Dateinamen wie extension=SQLSRV_8.4_NTS.so und extension=PDO_SQLSRV_8.4_NTS.so verwendet, ersetzen Sie diese Einträge durch die von PIE installierten Dateinamen:

    extension=sqlsrv.so
    extension=pdo_sqlsrv.so
    

    Beide Treibereinträge wieder aktivieren und Duplikate entfernen. Belassen Sie PDO_SQLSRV in einer gescannten Konfigurationsdatei, die nach PDO geladen wird, wie unter Laden der Treiber unter Linux und macOS beschrieben. Wiederholen Sie diese Konfigurationsänderung für die Kommandozeilen-, PHP-FPM-, Webserver- und Worker-Konfigurationen, die Ihre Anwendung verwendet.

  6. Aktualisieren Sie den Microsoft ODBC-Treiber für SQL Server, wenn dies das Zielrelease verlangt.

  7. Neustarte jeden CLI-Worker, Warteschlangenworker, Webserver und PHP-FPM Service, der die aktualisierte PHP-Installation nutzt.

Neu starten und überprüfen

Das Ersetzen einer Erweiterungsdatei aktualisiert keinen PHP-Prozess, der bereits die alte Binärdatei geladen hat. Starten Sie den Webserver, PHP-FPM und alle langlebigen PHP-Worker neu, bevor Sie das Upgrade verifizieren.

  1. Überprüfen Sie die Kommandozeilen-Laufzeit:

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

    Unter Linux oder macOS ersetzen Sie den letzten Befehl durch php -m | grep -E 'sqlsrv|pdo_sqlsrv'.

  2. Für eine Webanwendung sollte der Zugriff auf diagnostische Seiten eingeschränkt werden, bevor eine temporäre phpinfo() Seite erstellt wird. Überprüfen Sie die geladene Konfigurationsdatei, das Erweiterungsverzeichnis und ExtensionVer für beide Treiber. Bestätige, dass ExtensionVer die Zielversion anzeigt, und entferne dann die Seite.

  3. Führe einen bestehenden Anwendungs-Rauchtest durch, der sowohl SQLSRV als auch PDO_SQLSRV prüft, falls deine Anwendung beide verwendet. Lasse die Verbindungskonfiguration während dieser Überprüfung unverändert, damit ein Upgrade-Test nicht auch eine nicht damit zusammenhängende Verbindungsänderung testet.

Wenn ein Treiber nicht lädt, vergleichen Sie die PHP-Minor-Version, Architektur, den Thread-Sicherheitsmodus, das Erweiterungsverzeichnis und die ODBC-Installation mit den vor dem Upgrade aufgezeichneten Werten.

Überprüfen Sie sowohl APIs als auch Versionen

Speichere dieses Programm als 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);

Führen Sie das Programm mit dem CLI-Executable und vorübergehend in jeder Web-Runtime aus. Bestätigen Sie, dass beide gemeldeten Versionen mit dem von Ihnen installierten Release übereinstimmen. Entfernen Sie die Webkopie nach der Überprüfung.

Dieses Programm überprüft die PHP-Erweiterungsschicht. Führen Sie anschließend den Smoke-Test der unveränderten Anwendung durch, um den ODBC-Ladevorgang, Verbindungsoptionen, Authentifizierung, Datenbankzugriff, zurückgegebene PHP-Typen und Reinigungsverhalten zu überprüfen.

Überprüfen Sie das Datenbankverhalten vor und nach dem Upgrade

Verwende vor und nach dem Upgrade dasselbe Programm und dieselben Verbindungseinstellungen. Das Beibehalten des unveränderten Tests trennt Treiberänderungen von Anwendungs- oder Verbindungskonfigurationsänderungen.

Setzen Sie die SQL_SERVER_NAME, SQL_DATABASE, SQL_UID, und SQL_PWD Umgebungsvariablen für ein Testkonto, indem Sie Prompts beantworten. Geben Sie die Rohwerte ein, ohne Shell-Quotes oder Treiberkodierung. Fügen Sie keine Zugangsdaten in eine Kommandozeile oder eine aufgezeichnete Terminalsitzung ein.

Unter Windows PowerShell geben Sie den Servernamen und den Datenbanknamen ein und verwenden Sie dann den Anmeldeinformationsdialog oder die Aufforderung für das Testkonto:

$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

Unter Linux oder macOS solltest du Bash verwenden. Deaktivieren Sie die Befehlsverfolgung, bevor Sie irgendwelche Werte lesen. Die Passwortaufforderung zeigt Ihre Eingabe nicht an:

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

Die Umgebung enthält das Klartext-Passwort, sodass PHP es lesen kann. Verwenden Sie diese Variablen nur in der Testsitzung, drucken Sie sie nicht aus und löschen Sie sie nach dem Test.

Speichere dieses Programm als test-driver-upgrade.php. Halte die Umgebungswerte unverändert. Das Programm verdoppelt schließende geschweifte Klammern und fügt äußere geschweifte Klammern hinzu, bevor Datenbankname, Benutzername und Passwort an den Treiber weitergegeben werden. Diese Kodierung bewahrt wörtliche Klammern und verhindert, dass Semikolons die Verbindungsoptionen trennen.

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

Führe das Programm vor dem Upgrade aus und speichere die Ausgabe eines erfolgreichen Durchlaufs. Führe die unveränderte Datei nach Neustart jedes PHP-Prozesses erneut aus:

php test-driver-upgrade.php

Beide Runs sollten Folgendes hervorbringen:

SQLSRV query: 1
PDO_SQLSRV query: 1

Wenn der Lauf nach dem Upgrade fehlschlägt, notieren Sie den genauen SQLSTATE oder die Ausnahme. Vergleichen Sie dann den Fehler mit der Basisversion, den Erweiterungsversionen, der aktiven Konfiguration, der ODBC-Version und dem Neustartstatus des Prozesses. Rolle beide PHP-Erweiterungen gleichzeitig zurück, wenn du die Diskrepanz im Bereitstellungsfenster nicht korrigieren kannst.

Nach der Verifizierung löschen Sie die Testdatei und löschen Sie die temporären Umgebungsvariablen. Führen Sie in PowerShell Folgendes aus:

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

Führen Sie unter Linux oder macOS Folgendes aus:

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

Rückgängigmachen eines erfolglosen Upgrades

  1. Stoppen Sie die betroffenen Webserver, PHP-FPM Pools und lang laufende Worker.

  2. Wenn du die PHP-Minor-Version geändert hast, stelle die vorherige PHP-Laufzeit wieder her und verweise jeden Webserver und Worker auf diese Installation.

  3. Stelle beide vorherigen Treiberdateien wieder her. Stellen Sie die vorherigen SQLSRV- und PDO_SQLSRV Konfigurationseinträge gemeinsam wieder her.

  4. Stelle das vorherige ODBC-Paket nur wieder her, wenn die neuere Version den Fehler verursacht hat und das ältere Paket weiterhin von der von dir wiederhergestellten PHP-Treiberversion unterstützt wird.

  5. Starte die Prozesse neu und führe die Baseline-Versionsprüfungen und Anwendungs-Rauchtests erneut durch.

  6. Bewahre die Protokolle zum fehlgeschlagenen Upgrade und den genauen PHP-Start- oder Verbindungsfehler auf. Sie helfen zu erkennen, ob der Fehler auf das PHP-Laden, den Betriebssystem-Loader, ODBC oder die Datenbankverbindung zurückzuführen ist.

Fehlerbehebung bei einem Upgrade

Symptom Wahrscheinliche Ursache Korrekturmaßnahme
PIE ist erfolgreich, bleibt ExtensionVer aber unverändert Ein alter versionierter Eintrag lädt weiterhin die vorherige Datei Ersetzen Sie den alten Eintrag, entfernen Sie Duplikate und starten Sie alle PHP-Prozesse neu
SQLSRV und PDO_SQLSRV melden unterschiedliche Versionen Nur eine Erweiterung wurde ersetzt oder eine SAPI hat eine veraltete Konfiguration Aktualisieren und konfigurieren Sie beide Erweiterungen gemeinsam in jeder Laufzeitumgebung
Die CLI meldet die Zielversion, aber die Website tut es nicht Das Web-SAPI verwendet eine andere PHP-Installation oder wurde nicht neu gestartet Vergleichen Sie Konfigurations- und Erweiterungsverzeichnisse und starten Sie dann den korrekten Prozess neu
Der PHP-Start meldet einen Architektur- oder Symbolfehler Die Erweiterung passt nicht zum PHP-Build Stellen Sie die vorherigen Dateien wieder her und erstellen oder wählen Sie dann Dateien für die korrekte PHP-Minor-Version, Architektur und den Thread-Sicherheitsmodus neu aus
Erweiterungen werden geladen, aber Verbindungen schlagen nach einer ODBC-Änderung fehl ODBC-Konfiguration, Zertifikatsverhalten, Authentifizierung oder Netzwerkzugriff wurden geändert Erfassen Sie den SQLSTATE und den nativen Fehler, bevor Sie zurückrollen oder die Verbindungseinstellungen ändern
Worker-Prozesse schlagen fehl, während neue Web-Anfragen erfolgreich sind Lang laufende Worker behalten weiterhin die vorherige Erweiterung oder Konfiguration Entleeren und starten Sie jeden Worker-Prozess neu