Frissítse a SQL Server PHP drivereit

Frissítsd együtt az SQLSRV-t és a PDO_SQLSRV-t, hogy mindkét kiegészítés ugyanazt a kiadási családot használja. A PHP illezőprogramok a Microsoft ODBC Driver for SQL Server-t használják, ezért ellenőrizd a rendszerkövetelményeket frissítés előtt.

A frissítés megváltoztatja a PHP folyamatokba betöltött natív kódot. Egy vegyes telepítés továbbra is az előző kiadást futtathatja, meghibásodhat a PHP indításakor, vagy eltérő illesztőprogram-verziókat tehet elérhetővé a CLI és a webalkalmazás számára. Készíts leltárt az összes PHP-futtatókörnyezetről, és tartsd meg a korábbi fájlokat és konfigurációkat, amíg az ellenőrzés befejeződik.

Válaszd a fejlesztési útvonalat

Jelenlegi telepítés A cél telepítése Procedure
PIE PIE Futtasd a PIE-t ugyanazzal a PHP futtatható állománnyal vagy explicit php-config használatával, majd ellenőrizd az összes SAPI-t
Windows által kibocsátott ZIP Windows által kiadott ZIP Cseréld ki mindkét verziós DLL-t, és frissítsd mindkét konfigurációs bejegyzést együtt.
A Windows kicsomagolta a ZIP-et PIE Telepítsd mindkét PIE csomagot, cseréld le a verziózott DLL bejegyzéseket PIE bejegyzésekre, és távolítsd el a duplikátumokat
Linuxhoz vagy macOS-hez készült archívum PIE Telepítsd mindkét PIE csomagot, cseréld le az archív fájlnév-bejegyzéseket pdo_sqlsrv.so és sqlsrv.so értékekre, és őrizd meg a PDO betöltési sorrendet
Linux vagy macOS PIE Új PHP kisebb verzió Telepítsd az új PHP fejlesztő eszközöket, készítsd mindkét kiterjesztést ehhez a PHP telepítéshez, és konfiguráld külön mindegyik SAPI-t

Ne írd felül a korábbi binárokat, amíg nincs visszaállítási másolatod. Ne frissíts csak egy kiterjesztést, ha az alkalmazás mindkét API-t használja.

A frissítés előtt

  1. Rögzítse a PHP futtatható fájlt, konfigurációs fájlt, architektúrát, szálbiztonsági módot és a jelenlegi illesztőprogram-verziókat.

    php --version
    php --ini
    php --ri sqlsrv
    php --ri pdo_sqlsrv
    
  2. Készíts biztonsági mentést a php.ini fájlról és minden olyan kiterjesztésspecifikus .ini fájlról, amelyek betöltik a(z) sqlsrv vagy pdo_sqlsrv fájlt.

  3. Nézd meg a támogatási mátrixot a cél PHP verzióhoz és az operációs rendszerhez.

  4. Ellenőrizze az ODBC kompatibilitási táblázatot a Rendszerkövetelményekben. Telepíts támogatott ODBC verziót a PHP illesztőprogram frissítése előtt vagy alatt, amikor a célillesztőprogram kiadása ezt megköveteli.

  5. Tervezd meg minden olyan folyamat újraindítását, amely betölti a PHP-t, beleértve a webszervert, a PHP FastCGI Process Managert (PHP-FPM), a sorkezelőket és a hosszú ideig futó parancssori dolgozókat is.

  6. Minden futásidőből rögzíts egy alapvonalat:

    • A ExtensionVer megjelenítve: php --ri sqlsrv és php --ri pdo_sqlsrv által.
    • A konfigurációs fájl betöltve, a(z) .ini könyvtár beolvasva.
    • A bővítmény könyvtár és az aktív illesztőprogram fájlnevei.
    • Egy sikeres alkalmazás-füstteszt, amely minden API-t használ, amelyre az alkalmazásod támaszkodik.
  7. Készíts elő egy visszaállítást:

    • Tartsd elérhetővé a korábbi PHP futóidőt, ha megváltoztatod a PHP minor verziót. Rögzítse az egyes webszerverekhez és workerekhez beállított futtatható fájlt.
    • Tartsd meg a korábbi SQLSRV és PDO_SQLSRV fájlok másolatait.
    • Minden módosított php.ini vagy kiterjesztéshez tartozó .ini fájl másolatait tartsd meg.
    • Ha a frissítés megváltoztatja az ODBC csomagverziót, rögzítsd az előző ODBC csomagverziót.
    • Határozd meg, hogyan állítsd le a forgalmat vagy a munkafolyamatokat, miközben a natív bővítményfájlokat cserélik.

Frissítés Windows-on PIE-val

Használd a PHP Installer for Extensions (PIE) alkalmazást a PHP futtatható fájllal, amely az alkalmazást futtatja. Először töltsd le és ellenőrizd a PIE-t. A telepítési parancs futtatása előtt tereld el az alkalmazás forgalmát, és állítsd le a webszervert, a FastCGI folyamatokat és a PHP telepítést használó dolgozókat. Akadályozd meg, hogy automatikusan újrainduljanak, amíg mindkét kiterjesztés és a konfigurációjuk készen nem áll. Tarts külön parancssori munkamenetet a PIE-hez.

Ideiglenesen kommenteljük ki a meglévő SQLSRV és PDO_SQLSRV bővítmény bejegyzéseket a PIE által használt CLI konfigurációban. Ellenkező esetben a PIE-t futtató PHP folyamat betöltve tarthatja a régi DLL-eket, és megakadályozhatja a cserét. Tartsd bekapcsolva a PIE előfeltétel kiterjesztéseit.

A könyvtárból, amely pie.phartartalmazza, telepítsük mindkét csomagot külön-külön:

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

A PIE telepíti a php_sqlsrv.dll és php_pdo_sqlsrv.dll elemeket. Minden aktív konfigurációban cseréljük le a verziózott ZIP-bejegyzéseket, például a(z) extension=php_sqlsrv_85_ts_x64.dll és extension=php_pdo_sqlsrv_85_ts_x64.dll elemeket, a következőkre:

extension=php_sqlsrv.dll
extension=php_pdo_sqlsrv.dll

Engedélyezd mindkét bejegyzést, és távolítsd el a duplikált SQLSRV és PDO_SQLSRV bejegyzéseket, még akkor is, ha a PIE azt jelzi, hogy az automatikus engedélyezés sikeres volt. Ha a webszerver más PHP-telepítést használ, ismételd meg a frissítést és a konfigurációs módosításokat az adott telepítéshez.

Indítsd újra az összes PHP-folyamatot, majd futtasd a megfelelő futtatható fájllal a php --ri sqlsrv és php --ri pdo_sqlsrv parancsot. Erősítsd meg, hogy ExtensionVer mindkét illesztőprogram esetében a célverziót mutatja. Webalkalmazásnál korlátozza a diagnosztikai oldalhoz való hozzáférést, mielőtt ideiglenes phpinfo() oldalt létrehozna. Mindkét értéket ellenőrizd, majd távolítsd el az oldalt.

Frissíts egy Windows ZIP telepítést

  1. Töltse le a célverzió Windows ZIP-jét a Microsoft Drivers for PHP for SQL Server kiadások oldaláról.

  2. Győződjön meg róla, hogy az új dinamikus csatolású kódtár (DLL) nevei egyeznek a PHP kisebb verziójával, architektúrájával és szálbiztonsági módjával. Állítsd le a PHP webszervert vagy a worker folyamatokat, mielőtt fájlokat cserélnél.

  3. Cseréld le mind a php_sqlsrv_*.dll-, mind a php_pdo_sqlsrv_*.dll fájlt a PHP-bővítmények könyvtárában. Ha a fájlnevek még egyeznek, tartsák meg a meglévő extension= bejegyzéseket. Ellenkező esetben frissítsd őket együtt.

  4. Telepítse vagy frissítse a Microsoft ODBC Driver for SQL Server-t, ha a cél PHP illesztőprogramhoz újabb, támogatott verzió szükséges.

  5. Indíts újra minden PHP-folyamatot, amely a lecserélt DLL-eket használja. Egy futó folyamat a régi natív bővítményt betöltve tartja, amíg le nem áll.

Frissítés Linuxon vagy macOS-en PIE-val

  1. Ha a PIE nincs telepítve, kövesd a PIE beállítási útmutatót és a platform előfeltételeit. Ellenőrizze, hogy a PHP fejlesztő eszközök és az ODBC fejlesztőcsomag telepítve vannak. Egy interaktív szekcióban a PIE a platform csomagkezelőn keresztül kérheti a hiányzó build eszközök telepítését. Nem interaktív munkamenetben telepíteni kell őket a PIE futtatása előtt.

  2. Válaszd ki a PHP telepítést a frissítés előtt. Verziós telepítéshez mindkét telepítési parancshoz add hozzá a --with-php-config PIE opciót. Például használja a(z) pie install --with-php-config=/usr/bin/php-config8.4 microsoft/sqlsrv elemet, ha a kívánt konfigurációs eszköz a(z) /usr/bin/php-config8.4. Alkalmazd ugyanezt az opciót .microsoft/pdo_sqlsrv Az Alpine verziózott futtatható fájljaihoz használd az Alpine telepítési parancsokat.

  3. Vezesd el az alkalmazásforgalmat, és állítsd le a webszervert, a PHP-FPM folyamatokat és a dolgozókat, amelyek ezt a PHP telepítést használják. Akadályozd meg, hogy automatikusan újrainduljanak, amíg mindkét kiterjesztés és a konfigurációjuk készen nem áll. Tarts külön parancssori munkamenetet a PIE-hez.

    Ideiglenesen kommenteljük ki a meglévő SQLSRV és PDO_SQLSRV bővítmény bejegyzéseket a PIE által használt CLI konfigurációban. Tartsd bekapcsolva a PIE előfeltétel-kiterjesztéseit.

  4. Mindkét csomagot külön-külön frissítsd. Ezek a parancsok a PIE alapértelmezett PHP telepítését használják:

    pie install microsoft/sqlsrv
    pie install microsoft/pdo_sqlsrv
    
  5. Ellenőrizd az alkalmazásod által használt PHP-telepítés összes aktív konfigurációját. Ha egy korábbi manuális telepítés archív fájlneveket használ, mint például extension=SQLSRV_8.4_NTS.so és extension=PDO_SQLSRV_8.4_NTS.so, cserélje le ezeket a bejegyzéseket a PIE-val telepített fájlnevekre:

    extension=sqlsrv.so
    extension=pdo_sqlsrv.so
    

    Engedélyezd újra mindkét illesztőprogram-bejegyzést, és távolítsd el a duplikált bejegyzéseket. Tartsd a PDO_SQLSRV-t egy beolvasott konfigurációs fájlban, amely a PDO után töltődik be, ahogy azt a Az illesztőprogramok betöltése Linuxon és macOS rendszeren részben leírjuk. Ismételd meg ezt a konfigurációs változtatást a parancssori, PHP-FPM-, webszerver- és worker-konfigurációknál, amelyeket az alkalmazásod használ.

  6. Frissítse a Microsoft ODBC Driver for SQL Server-t, amikor a célverzió megköveteli.

  7. Indíts újra minden CLI-munkafolyamatot, sorfeldolgozó folyamatot, webszervert és PHP-FPM szolgáltatást, amely a frissített PHP-telepítést használja.

Indítsa újra és ellenőrizze

Egy kiterjesztési fájl cseréje nem frissíti azt a PHP folyamatot, amely már betöltötte a régi binárist. Indítsd újra a webszervert, a PHP-FPM-et és a hosszan futó PHP-munkafolyamatokat, mielőtt ellenőriznéd a frissítést.

  1. Ellenőrizd a parancssori futtatókörnyezetet:

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

    Linuxon vagy macOS-en cseréld le az utolsó parancsot erre: php -m | grep -E 'sqlsrv|pdo_sqlsrv'

  2. Webalkalmazásnál korlátozza a diagnosztikai oldal hozzáférését, mielőtt ideiglenes phpinfo() oldalt hozna létre. Ellenőrizd a betöltött konfigurációs fájlt, a bővítménykönyvtárat és a ExtensionVer elemet mindkét illesztőprogram esetében. Erősítsd meg, hogy ExtensionVer a célverziót jelzi, majd távolítsd el az oldalt.

  3. Futtass egy meglévő alkalmazás füsttesztjét, amely mind az SQLSRV-t, mind a PDO_SQLSRV-t teszteli, ha az alkalmazásod mindkettőt használja. Tartsd meg a kapcsolat konfigurációját változatlanul ebben az ellenőrzésben, hogy egy frissítési teszt ne teszteljen egy független kapcsolatváltozást is.

Ha egy illesztőprogram nem töltődik be, hasonlítsd össze a PHP alverzióját, architektúráját, szálbiztonsági módját, bővítménykönyvtárát és ODBC telepítését a frissítés előtti értékekkel.

Ellenőrizd az API-kat és a verziókat

Mentse el ezt a programot a következő néven: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);

Futtasd a programot a CLI futtatható fájllal, és ideiglenesen az összes webes futtatókörnyezetben. Erősítsd meg, hogy mindkét jelentett verzió egyezik a telepített kiadással. A webes másolatot az ellenőrzés után távolítsd el.

Ez a program ellenőrzi a PHP-bővítményréteget. Ezután futtatd a változatlan alkalmazási füsttesztet, hogy ellenőrizd az ODBC betöltését, a csatlakozási lehetőségeket, a hitelesítést, az adatbázis-hozzáférést, a visszaküldött PHP típusokat és a tisztítási viselkedést.

Ellenőrizd az adatbázis viselkedését a verziófrissítés előtt és után

Ugyanazt a programot és a csatlakozási beállításokat használd a frissítés előtt és után. A teszt változatlanul tartása elválasztja az illesztőprogram-változásokat az alkalmazás- vagy kapcsolat-konfigurációs változásoktól.

Állítsd be a tesztfiókhoz a SQL_SERVER_NAME, SQL_DATABASE, SQL_UID és SQL_PWD környezeti változókat a promptok megválaszolásával. Adja meg a nyers értékeket, shell idézőjelek vagy driver kódolás nélkül. Ne tegyél be hitelesítő adatokat parancssorba vagy rögzített terminálülésbe.

A Windows PowerShellben írd be a kiszolgáló nevét és az adatbázis nevét, majd a tesztfiók hitelesítő adatainak megadásához használd a hitelesítőadat-kérő párbeszédpanelt vagy parancssort:

$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

Linux vagy macOS esetén használja a Bash-t. Kapcsold ki a parancskövetést, mielőtt bármilyen értéket olvasnál. A jelszókérő prompt nem tükrözi a beviteledet:

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

A környezet tartalmazza a tiszta szöveges jelszót, így a PHP el tudja olvasni. Ezeket a változókat csak a tesztmunkamenetben használd, ne nyomtasd ki őket, és töröld őket a tesztelés után.

Mentsd el ezt a programot test-driver-upgrade.php. Tartsd változatlanul a környezeti értékeket. A program megduplázza a záró kapcsos zárójeleket, és hozzáadja a külső kapcsos zárójeleket, mielőtt átadja az adatbázis nevét, felhasználónevét és jelszavát az illesztőprogramnak. Ez a kódolás megőrzi a literális kapcsos zárójeleket, és megakadályozza, hogy a félvesszők elválasszák a csatlakozási lehetőségeket.

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

Indítsd a programot a frissítés előtt, és mentsd el a sikeres kimenetet. Futtassa újra a változatlan fájlt minden PHP-folyamat újraindítása után:

php test-driver-upgrade.php

Mindkét futtatásnak a következőket kell hoznia:

SQLSRV query: 1
PDO_SQLSRV query: 1

Ha a frissítés utáni futtatás meghibásodik, őrizd meg a pontos SQLSTATE vagy kivételt. Ezután hasonlítsuk össze a hibát az alapállapottal, a bővítési verziókkal, az aktív konfigurációval, az ODBC verzióval és a folyamat újraindításának állapotával. Vissza kell fordítani mindkét PHP bővítményt együtt, ha nem tudod kijavítani az eltérést a telepítési ablakon belül.

Ellenőrzés után töröld a tesztfájlt, és töröld az ideiglenes környezeti változókat. A PowerShellben futtassa a következőt:

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

Linux vagy macOS rendszeren futtassa a következőt:

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

Sikertelen frissítés visszaállítása

  1. Állítsd meg az érintett webszervereket, PHP-FPM poolokat és a hosszú ideje futó workereket.

  2. Ha megváltoztattad a PHP alverziót, állítsd vissza az előző PHP futtatókörnyezetet, és állíts vissza minden webszervert és workert arra a telepítésre.

  3. Állítsd vissza mindkét korábbi driver fájlt. Állítsd vissza a korábbi SQLSRV és PDO_SQLSRV konfigurációs bejegyzéseket együtt.

  4. A korábbi ODBC csomagot csak akkor állítsd vissza, ha az újabb verzió okozta a hibát, és a régebbi csomagot továbbra is támogatja az általad visszaállított PHP-illesztőprogram-verzió.

  5. Indítsd újra a folyamatokat, és futtasd meg az alapverziós ellenőrzéseket és az alkalmazás füsttesztjeit.

  6. Tartsd meg a sikertelen frissítési naplókat és a pontos PHP-indítási vagy csatlakozási hibaüzenetet. Segítenek azonosítani, hogy a hiba a PHP betöltésében, az operációs rendszer betöltőjében, az ODBC-ben vagy az adatbázis-kapcsolatban van-e.

A frissítés hibaelhárítása

Tünet Valószínű ok Helyesbítő intézkedés
A PIE sikerrel jár, de ExtensionVer változatlan marad Egy régi verziójú bejegyzés még mindig betölti az előző fájlt Cseréld ki a régi bejegyzést, távolítsd el a duplikátumokat, és indítsd újra az összes PHP folyamatot
Az SQLSRV és PDO_SQLSRV különböző verziókat jeleznek Csak egy kiterjesztést cseréltek le, vagy egy SAPI-nak elavult konfigurációja van Frissítsd és konfiguráld mindkét bővítményt együtt minden futtatókörnyezetben
A CLI jelzi a célverziót, de a weboldal nem jelzi a célverziót A webes SAPI egy másik PHP telepítést használ, vagy nem indították újra. Hasonlítsd össze a konfigurációs és bővítménykönyvtárakat, majd indítsd újra a megfelelő folyamatot
A PHP indításakor architektúra- vagy szimbólumhiba jelenik meg A kiterjesztés nem egyezik a PHP buildjével A korábbi fájlokat állítsd vissza, majd újraépítsd vagy válassz fájlokat a megfelelő PHP minor verzióhoz, architektúrához és szálbiztonsági módhoz
A bővítmények betöltődnek, de a kapcsolatok meghibásodnak egy ODBC váltás után ODBC konfiguráció, tanúsítvány viselkedése, hitelesítés vagy hálózati hozzáférés megváltozott Rögzítsd az SQLSTATE és a natív hibát, mielőtt visszatekered vagy megváltoztatnád a kapcsolatbeállításokat.
A háttérfolyamatok meghibásodnak, míg az új webes kérések sikeresek A régóta futó worker folyamatok továbbra is a korábbi bővítményt vagy konfigurációt használják Leállítani és újraindítani minden workerfolyamatot