Mettre à jour les pilotes PHP pour SQL Server

Mettez à jour SQLSRV et PDO_SQLSRV ensemble afin que les deux extensions utilisent la même famille de versions. Les pilotes PHP utilisent le pilote Microsoft ODBC pour SQL Server, donc vérifiez les exigences système avant de faire une mise à jour.

Une mise à jour modifie le code natif chargé dans les processus PHP. Un déploiement mixte peut continuer à exécuter la version précédente, échouer au démarrage de PHP, ou exposer différentes versions de pilotes à la CLI et à l’application web. Inventoriez chaque exécution PHP et conservez les fichiers précédents et la configuration précédente jusqu’à la fin de la vérification.

Choisissez la voie de mise à niveau

Installation actuelle Installation cible Procedure
PIE PIE Exécutez PIE avec le même exécutable PHP ou un chemin explicite php-config, puis vérifiez chaque SAPI
ZIP publié par Windows ZIP publié par Windows Remplacer les deux DLL versionnées et mettre à jour les deux entrées de configuration ensemble
Windows ZIP extrait PIE Installez les deux paquets PIE, remplacez les entrées DLL versionnées par des entrées PIE, et supprimez les doublons
Archive publiée pour Linux ou macOS PIE Installez les deux paquets PIE, remplacez les entrées des fichiers d’archive par sqlsrv.so et pdo_sqlsrv.so, et préservez l’ordre de chargement PDO
Linux ou macOS PIE Nouvelle version mineure de PHP Installez les nouveaux outils de développement PHP, construisez les deux extensions pour cette installation PHP, et configurez chaque SAPI séparément

Ne réécrasez pas les binaires précédents tant que vous n’avez pas une copie de sauvegarde pour restauration. Ne mettez pas à jour une seule des extensions lorsque l’application utilise les deux API.

Avant la mise à niveau

  1. Enregistrer l’exécutable PHP, le fichier de configuration, l’architecture, le mode de sécurité des threads et les versions actuelles des pilotes logiciels.

    php --version
    php --ini
    php --ri sqlsrv
    php --ri pdo_sqlsrv
    
  2. Sauvegardez le php.ini fichier ainsi que tous les fichiers spécifiques .ini à l’extension qui chargent sqlsrv ou pdo_sqlsrv.

  3. Vérifiez la matrice de support pour la version cible de PHP et le système d’exploitation.

  4. Consultez la table de compatibilité ODBC dans les exigences système. Installez une version ODBC prise en charge avant ou pendant la mise à niveau du pilote PHP lorsque la version cible du pilote l’exige.

  5. Prévoyez un redémarrage de chaque processus qui charge PHP, y compris le serveur web, le gestionnaire de processus PHP FastCGI (PHP-FPM), les workers de file d’attente et les workers en ligne de commande de longue durée.

  6. Enregistrez une référence de chaque exécution :

    • Les ExtensionVer affichés par php --ri sqlsrv et php --ri pdo_sqlsrv.
    • Fichier de configuration chargé et répertoire .ini analysé.
    • Le répertoire d’extension et les noms de fichiers des pilotes actifs.
    • Un test de fumée d’application réussi qui utilise chaque API dont votre application dépend.
  7. Préparez une restauration :

    • Gardez l’ancien environnement d’exécution PHP disponible si vous changez la version mineure de PHP. Enregistrez l’exécutable configuré pour chaque serveur web et worker.
    • Conservez des copies des fichiers SQLSRV et PDO_SQLSRV précédents.
    • Conservez des copies de chaque fichier modifié php.ini ou fichier spécifique à l’extension .ini.
    • Enregistrez la version précédente du package ODBC si la mise à jour la modifie.
    • Définissez comment arrêter le trafic ou les processus worker pendant que les fichiers d’extension natifs sont remplacés.

Mise à niveau sous Windows avec PIE

Utilisez l’installateur PHP pour les extensions (PIE) avec l’exécutable PHP qui sert l’application. D’abord, téléchargez et vérifiez PIE. Avant d’exécuter l’une ou l’autre commande d’installation, redirigez le trafic de l’application et arrêtez le serveur web, les processus FastCGI et les travailleurs utilisant cette installation PHP. Empêchez-les de redémarrer automatiquement tant que les extensions et leur configuration ne sont pas prêtes. Gardez une session en ligne de commande séparée pour PIE.

Mettez temporairement en commentaire les entrées d’extension SQLSRV et PDO_SQLSRV existantes dans la configuration CLI utilisée par PIE. Sinon, le processus PHP exécutant PIE peut garder les anciennes DLL chargées et empêcher leur remplacement. Gardez activées les extensions requises de PIE.

Depuis le répertoire contenant pie.phar, installez les deux paquets séparément :

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

PIE installe php_sqlsrv.dll et php_pdo_sqlsrv.dll. Dans chaque configuration active, remplacez les entrées ZIP versionnées telles que extension=php_sqlsrv_85_ts_x64.dll et extension=php_pdo_sqlsrv_85_ts_x64.dll par :

extension=php_sqlsrv.dll
extension=php_pdo_sqlsrv.dll

Activez les deux entrées, et supprimez les entrées en double de SQLSRV et PDO_SQLSRV même si le PIE indique que l’activation automatique a réussi. Si le serveur web utilise une installation PHP différente, répétez la mise à jour et les changements de configuration pour cette installation.

Redémarrez chaque processus PHP, puis exécutez php --ri sqlsrv et php --ri pdo_sqlsrv avec l’exécutable correspondant. Confirmez que ExtensionVer indique la version cible pour les deux pilotes. Pour une application web, restreignez l’accès à la page de diagnostic avant de créer une page temporaire phpinfo(). Vérifiez les deux valeurs, puis supprimez la page.

Mettre à jour une installation Windows ZIP

  1. Téléchargez le Windows ZIP de la version cible depuis la page Microsoft Drivers for PHP for SQL Server releases.

  2. Confirmez que les nouveaux noms de bibliothèques de liens dynamiques (DLL) correspondent à la version mineure de PHP, à l’architecture et au mode de sécurité des threads. Arrêtez le serveur web PHP ou les processus de travail avant de remplacer les fichiers.

  3. Remplacez les fichiers php_sqlsrv_*.dll et php_pdo_sqlsrv_*.dll dans le répertoire d’extension PHP. Conservez les entrées existantes extension= si les noms de fichiers correspondent toujours. Sinon, mettez-les à jour ensemble.

  4. Installez ou mettez à jour le pilote Microsoft ODBC pour SQL Server si le pilote PHP cible nécessite une version plus récente prise en charge.

  5. Redémarrez tous les processus PHP qui utilisent les DLL remplacées. Un processus en cours d’exécution maintient l’ancienne extension native chargée jusqu’à ce qu’il se termine.

Mise à jour sur Linux ou macOS avec PIE

  1. Suivez la configuration de PIE et les prérequis de la plateforme si PIE n’est pas installé. Confirmez que les outils de développement PHP et le package de développement ODBC sont installés. Lors d’une session interactive, PIE peut inviter à installer des outils de compilation manquants via le gestionnaire de paquets de la plateforme. Dans une session non interactive, installez-les avant d’exécuter PIE.

  2. Sélectionnez l’installation PHP avant de faire la mise à jour. Pour une installation versionnée, ajoutez l’option PIE --with-php-config aux deux commandes d’installation. Par exemple, utilisez pie install --with-php-config=/usr/bin/php-config8.4 microsoft/sqlsrv lorsque l’outil de configuration prévu est /usr/bin/php-config8.4. Appliquez la même option à microsoft/pdo_sqlsrv. Pour les exécutables versionnés d’Alpine, utilisez les commandes d’installation Alpine.

  3. Redirigez le trafic de l'application et arrêtez le serveur web, les processus PHP-FPM et les travailleurs qui utilisent cette installation PHP. Empêchez-les de redémarrer automatiquement tant que les extensions et leur configuration ne sont pas prêtes. Gardez une session en ligne de commande séparée pour PIE.

    Commentez temporairement les entrées d’extension SQLSRV et PDO_SQLSRV existantes dans la configuration CLI utilisée par PIE. Gardez activées les extensions requises de PIE.

  4. Mettez à jour les deux paquets séparément. Ces commandes utilisent l’installation PHP par défaut de PIE :

    pie install microsoft/sqlsrv
    pie install microsoft/pdo_sqlsrv
    
  5. Vérifiez chaque configuration active pour l’installation PHP utilisée par votre application. Si une installation manuelle précédente utilise des noms de fichiers d’archive tels que extension=SQLSRV_8.4_NTS.so et extension=PDO_SQLSRV_8.4_NTS.so, remplacez ces entrées par les noms de fichiers installés par PIE :

    extension=sqlsrv.so
    extension=pdo_sqlsrv.so
    

    Réactivez les deux entrées de pilotes et supprimez les doublons. Conservez PDO_SQLSRV dans un fichier de configuration analysé qui se charge après PDO, comme décrit dans Charger les pilotes sur Linux et macOS. Répétez ce changement de configuration pour les configurations en ligne de commande, PHP-FPM, serveur web et workers que votre application utilise.

  6. Mettez à jour le pilote Microsoft ODBC pour SQL Server lorsque la version prévue l’exige.

  7. Redémarrez chaque processus CLI, processus de file d’attente, serveur web et service PHP-FPM qui utilisent l’installation PHP mise à jour.

Redémarrer et vérifier

Remplacer un fichier d’extension ne met pas à jour un processus PHP qui avait déjà chargé l’ancien binaire. Redémarrez le serveur web, PHP-FPM et tous les processus PHP de longue durée avant de vérifier la mise à jour.

  1. Vérifiez l’environnement d’exécution en ligne de commande :

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

    Sous Linux ou macOS, remplacez la dernière commande par php -m | grep -E 'sqlsrv|pdo_sqlsrv'.

  2. Pour une application web, restreignez l’accès de la page de diagnostic avant de créer une page temporaire phpinfo(). Vérifiez le fichier de configuration chargé, le répertoire d’extension et les ExtensionVer pour les deux pilotes. Confirmez que ExtensionVer indique la version cible, puis retirez la page.

  3. Effectuez un test de fumée d’application existante qui exerce à la fois SQLSRV et PDO_SQLSRV si votre application utilise les deux. Gardez la configuration de la connexion inchangée pendant cette vérification afin qu’un test de mise à niveau ne teste pas aussi un changement de connexion sans rapport.

Si un pilote ne se charge pas, comparez la version mineure de PHP, son architecture, le mode de sécurité des threads, le répertoire d’extension et l’installation ODBC avec les valeurs enregistrées avant la mise à niveau.

Vérifier à la fois les API et les versions

Enregistrez ce programme comme 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);

Exécutez le programme avec l’exécutable CLI et, temporairement, via chaque environnement d’exécution web. Confirmez que les deux versions rapportées correspondent à la version que vous avez installée. Supprimez la copie web après vérification.

Ce programme vérifie la couche d’extension PHP. Exécutez ensuite le test de fumée inchangé de l’application pour vérifier le chargement ODBC, les options de connexion, l’authentification, l’accès à la base de données, les types PHP retournés et le comportement de nettoyage.

Vérifier le comportement de la base de données avant et après la mise à jour

Utilisez le même programme et les mêmes réglages de connexion avant et après la mise à jour. Maintenir le test inchangé sépare les changements de pilote des changements d’application ou de configuration de connexion.

Définissez les variables d’environnement SQL_SERVER_NAME, SQL_DATABASE, SQL_UID et SQL_PWD pour un compte test en répondant aux invites. Entrez les valeurs brutes, sans guillemets de shell ni encodage de pilote. N’incluez pas les identifiants dans une ligne de commande ou une session de terminal enregistrée.

Sur Windows PowerShell, saisissez le nom du serveur et celui de la base de données, puis utilisez la boîte de dialogue ou l’invite des identifiants pour le compte de 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

Sur Linux ou macOS, utilisez Bash. Désactivez le traçage des commandes avant de lire toute valeur. La demande de mot de passe n’affiche pas ce que vous saisissez :

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’environnement contient le mot de passe en clair pour que PHP puisse le lire. Utilisez ces variables uniquement pendant la session de test, ne les imprimez pas, et effacez-les après le test.

Enregistrez ce programme sous le nom test-driver-upgrade.php. Gardez les valeurs d’environnement inchangées. Le programme double les accolades fermantes et ajoute des accolades externes avant de transmettre le nom de la base de données, le nom d’utilisateur et le mot de passe au pilote. Ce codage préserve les accolades littérales et empêche les points-virgules de séparer les options de connexion.

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

Exécutez le programme avant la mise à jour et enregistrez la sortie obtenue avec succès. Exécutez à nouveau le fichier non modifié après avoir relancé chaque processus PHP :

php test-driver-upgrade.php

Les deux séries devraient produire :

SQLSRV query: 1
PDO_SQLSRV query: 1

Si l’exécution post-mise à niveau échoue, conservez le SQLSTATE exact ou l’exception. Ensuite, comparez l’échec avec la référence de base, les versions d’extension, la configuration active, la version ODBC et le statut de redémarrage du processus. Restaurez les deux extensions PHP ensemble lorsque vous ne pouvez pas corriger l’incompatibilité dans la fenêtre de déploiement.

Après vérification, supprimez le fichier de test et effacez les variables d’environnement temporaires. Dans PowerShell, exécutez :

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

Sur Linux ou macOS, exécutez :

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

Annuler une mise à niveau infructueuse

  1. Arrêtez les serveurs web affectés, les pools PHP-FPM et les workers de longue durée.

  2. Si vous avez modifié la version mineure de PHP, restaurez l’ancien runtime PHP et redirigez chaque serveur web et chaque worker vers cette installation.

  3. Restaurez les deux fichiers de pilotes précédents. Restaurez ensemble les entrées de configuration SQLSRV et PDO_SQLSRV précédentes.

  4. Restaurez l’ancien package ODBC seulement si la version récente a causé la panne et que l’ancien package reste supporté par la version du pilote PHP que vous avez restaurée.

  5. Redémarrez les processus et relancez les vérifications de version de base ainsi que les tests de fumée de l’application.

  6. Conservez les journaux de mise à jour ratés et l’erreur exacte de démarrage ou de connexion de PHP. Ils aident à identifier si la défaillance concerne le chargement PHP, le chargeur du système d’exploitation, ODBC ou la connexion à la base de données.

Détecter un problème lors d’une mise à niveau

Symptôme Cause la plus probable Mesure corrective
PIE réussit mais ExtensionVer reste inchangé Une ancienne entrée versionnée charge toujours le fichier précédent Remplacez l’ancienne entrée, supprimez les doublons, et redémarrez tous les processus PHP
SQLSRV et PDO_SQLSRV rapportent des versions différentes Une seule extension a été remplacée ou une SAPI a une configuration obsolète Mettre à jour et configurer les deux extensions ensemble à chaque exécution
CLI rapporte la version cible mais pas le site web Le web SAPI utilise une autre installation PHP ou n’a pas été redémarré Comparez les répertoires de configuration et d’extension, puis redémarrez le processus correct
Le démarrage de PHP signale une erreur d’architecture ou de symbole L’extension ne correspond pas au build PHP Restaurez les fichiers précédents, puis reconstruisez ou sélectionnez les fichiers pour la bonne version mineure PHP, l’architecture et le mode de sécurité des threads
Les extensions se chargent mais les connexions échouent après un changement ODBC Configuration ODBC, comportement des certificats, authentification ou accès réseau modifié Récupérez l’état SQLSTATE et l’erreur native avant d’annuler la transaction ou de modifier les paramètres de connexion
Les processus travailleurs échouent tandis que de nouvelles requêtes web réussissent Les workers de longue durée conservent toujours l’extension ou la configuration précédente Videz et redémarrez chaque processus worker