Dépanner les pilotes Microsoft pour PHP pour SQL Server

Télécharger le pilote PHP

Diagnostiquez et résolvez les problèmes courants lorsque vous utilisez les pilotes Microsoft pour PHP pour SQL Server afin de vous connecter à SQL Server, Azure SQL Database, Azure SQL Managed Instance et la base de données SQL dans Microsoft Fabric.

Pour des schémas généraux de gestion des erreurs et des avertissements, voir Gestion des erreurs et avertissements. Pour la capture de diagnostic côté conducteur, voir Journalisation des activités.

Problèmes d’installation

Extension non chargée

Symptômes :

  • phpinfo() Ne mentionne pas la section A sqlsrv ou pdo_sqlsrv Only.
  • PDOException: could not find driver lors de la construction de A PDO avec le sqlsrv: DSN.
  • Fatal error: Uncaught Error: Call to undefined function sqlsrv_connect().

Causes possibles et solutions :

  • L’extension n’est pas activée dans php.ini. Vérifiez que les deux extension=sqlsrv et extension=pdo_sqlsrv ne font pas de commentaire. Sous Windows, utilisez le nom complet du fichier (extension=php_sqlsrv_84_ts_x64.dll). Pour plus de détails, voir Chargement des pilotes.
  • Mauvais montage de sécurité filetage. Le binaire du pilote doit correspondre à la sécurité thread de votre build PHP (ts pour thread-safe, nts pour non-thread-safe). Exécutez php -i | grep "Thread Safety" pour vérifier. Téléchargez le binaire correspondant depuis la page de téléchargement.
  • Pilote Microsoft ODBC manquant. Les pilotes PHP enveloppent le pilote Microsoft ODBC pour SQL Server. Sous Linux et macOS, installez msodbcsql18 (ou msodbcsql17) avec votre gestionnaire de paquets avant de charger les extensions. Sous Windows, installez le pilote ODBC depuis la page de téléchargement.

Vérifiez une installation réussie :

php -m | grep -i sqlsrv

Vous devriez voir les deux pdo_sqlsrv et sqlsrv dans la sortie.

Échec de l’installation de PECL sur Linux ou macOS

Symptômes :

error: ‘SQL_HANDLE_DBC’ undeclared (first use in this function)
fatal error: 'sql.h' file not found

Correctif :

Installez les en-têtes de développement ODBC avant de lancer pecl install:

  • Ubuntu et Debian : sudo apt-get install unixodbc-dev
  • Red Hat, Fedora et CentOS : sudo dnf install unixODBC-devel
  • Alpine : apk add unixodbc-dev
  • macOS : brew install unixodbc

Puis réessayez :

sudo pecl install sqlsrv
sudo pecl install pdo_sqlsrv

Si pecl cela tombe toujours en panne après l’installation des en-têtes, la chaîne d’outils de construction peut être incomplète. Installez phpize, re2c, et un compilateur C++ (build-essential sur Debian et Ubuntu, gcc-c++ make sur Red Hat et Fedora, sur build-base Alpine).

Pour le chemin d’installation complet, consultez le tutoriel d’installation pour Linux et macOS.

Plusieurs versions de PHP installées

Symptômes :

phpinfo() dans votre serveur web, une version de PHP apparaît, mais php -v en ligne de commande en affiche une autre, et le pilote n’apparaît chargé que dans l’une d’elles.

Correctif :

Chaque version de PHP a son propre php.ini répertoire ext . Localiser le bon fichier php --ini de configuration depuis l’environnement qui manque le pilote, et ajouter les extension= lignes à cet endroit. Redémarrez le serveur web (Apache, Nginx + PHP-FPM ou IIS) après toute modification php.ini.

Problèmes de connexion

Impossible de se connecter au serveur

Symptômes :

SQLSTATE[08001]: [Microsoft][ODBC Driver 18 for SQL Server]TCP Provider: A connection attempt failed
SQLSTATE[HYT00]: [Microsoft][ODBC Driver 18 for SQL Server]Login timeout expired

Causes possibles et solutions :

  • Le serveur n’est pas joignable. Vérifiez que le nom du serveur et le port sont corrects. Depuis l’hôte PHP, testez la connectivité TCP brute.

    # Linux and macOS
    nc -vz <server>.database.windows.net 1433
    
    # Windows PowerShell
    Test-NetConnection -ComputerName <server>.database.windows.net -Port 1433
    
  • Le pare-feu bloque la sortie 1433. Les pare-feux d’entreprise et les NSG cloud bloquent souvent le port sortant 1433. Ajoutez une exception, ou autorisez les plages IP d’Azure SQL Database pour votre région.

  • Pare-feu Azure SQL server. Ajoutez l'IP publique de votre client aux règles de pare-feu au niveau serveur dans le portail Azure.

  • Instance nommée. Pour une instance nommée, vérifiez que le service SQL Server Browser fonctionne sur le serveur et que UDP 1434 est ouvert. Ou bien, connectez-vous par port au lieu du nom de l’instance.

Échec de la connexion

Symptômes :

SQLSTATE[28000]: [Microsoft][ODBC Driver 18 for SQL Server][SQL Server]Login failed for user '<user_id>'.

Causes possibles et solutions :

  • Mode d’authentification SQL désactivé. Les instances locales de SQL Server sont par défaut uniquement en authentification Windows. Activez l’authentification en mode mixte dans SQL Server Management Studio sous propriétés>du serveur Sécurité, puis redémarrez le service SQL Server.
  • Azure SQL credentials format. Azure SQL nécessite le nom d'utilisateur entièrement qualifié (user@servername) lors de la connexion à des outils qui ne l'ajoutent pas automatiquement.
  • L’utilisateur n’est pas mappé à la base de données. Vérifiez que la connexion possède une correspondance utilisateur dans la base de données cible et que l’utilisateur dispose des autorisations requises.
  • Je préfère Microsoft Entra ID. Pour Azure SQL, Azure SQL Managed Instance et la base de données SQL dans Fabric, utilisez l’authentification Microsoft Entra (Authentication=ActiveDirectoryMsi, Authentication=ActiveDirectoryServicePrincipal, ou un jeton d’accès) au lieu des connexions SQL. Consultez Se connecter à l’aide de l’authentification Microsoft Entra.

Valeur invalide spécifiée pour l'attribut de chaîne de connexion « Authentification »

Symptômes :

SQLSTATE[08001]: [Microsoft][ODBC Driver 17 for SQL Server]Invalid value specified for connection string attribute 'Authentication'

Cause :

Le pilote ODBC rapporte l’erreur, mais le vrai problème est de savoir quel pilote PDO_SQLSRV lié. Si le DSN n’inclut pas de Driver= mot-clé et que l’hôte a à la fois ODBC 17 et ODBC 18 installés, PDO_SQLSRV peut se lier à l’ancienne version. Les anciennes versions ODBC 17.x ne connaissent pas les valeurs plus récentes Authentication telles que ActiveDirectoryServicePrincipal ou ActiveDirectoryDefault, et nécessitent même ActiveDirectoryMsi ODBC 17.3.1.1 ou une version ultérieure.

Correctif :

Épinglez le pilote dans le DSN :

<?php
$dsn = "sqlsrv:Driver={ODBC Driver 18 for SQL Server};Server=$server;Database=$db;" .
       "Encrypt=true;Authentication=ActiveDirectoryMsi";
$conn = new PDO($dsn, null, null, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);

La forme entre crochets ({ODBC Driver 18 for SQL Server}) s’échappe des espaces dans le nom du conducteur. Le message d’erreur lui-même nomme toujours le pilote qui l’a signalé, donc le préfixe [Microsoft][ODBC Driver 17 for SQL Server] dans l’erreur est le moyen le plus rapide de confirmer la mauvaise répartition du pilote.

Le mot-clé invalide 'UID' était spécifié dans la chaîne DSN

Symptômes :

SQLSTATE[IMSSP]: An invalid keyword 'UID' was specified in the DSN string.

Cause :

PDO_SQLSRV impose une liste de permis de mots-clés DSN et n’accepte UID pas ou PWD ne l’accepte pas dans le DSN. PDO réserve les deuxième et troisième arguments constructeurs pour ceux-ci, et PDO_SQLSRV les traduit en ODBC UID/PWD en interne.

Correctif :

Transférez le nom d’utilisateur (et le mot de passe, pour l’authentification SQL) dans le constructeur PDO :

<?php
// SQL authentication.
$dsn = "sqlsrv:Driver={ODBC Driver 18 for SQL Server};Server=$server;Database=$db;Encrypt=true";
$conn = new PDO($dsn, $user, $password);

// User-assigned managed identity. Pass the identity's client ID as $username.
$dsn = "sqlsrv:Driver={ODBC Driver 18 for SQL Server};Server=$server;Database=$db;" .
       "Encrypt=true;Authentication=ActiveDirectoryMsi";
$conn = new PDO($dsn, $clientId, null);

Le pilote procédural SQLSRV, en revanche, accepte UID et PWD dans l’array d’options de connexion est transmis à sqlsrv_connect().

PDO_SQLSRV ignore silencieusement AccessToken dans le tableau des options

Symptôme :

Vous avez un jeton d’accès Microsoft Entra (par exemple, de az account get-access-token --resource https://database.windows.net/, , ou ClientSecretCredential), et vous le passez à PDO_SQLSRV comme ['AccessToken' => $token] dans l’argument du ManagedIdentityCredentialquatrième constructeur. La tentative de connexion échoue avec une erreur confuse telle que Windows logins are not supported in this version of SQL Server ou Login failed for user '', comme si aucune identification n’avait été fournie.

Cause :

Le quatrième argument constructeur de PDO est réservé aux constantes d’attribut spécifiques au pilote (clés entières telles que PDO::ATTR_ERRMODE). PDO laisse tomber silencieusement des entrées à clé de chaîne comme AccessToken, PDO_SQLSRV ne voit jamais le jeton. La connexion revient alors à l’authentification intégrée Windows, que le serveur rejette.

Correctif :

Passe AccessToken à la chaîne DSN. Réservez le tableau d’options pour les PDO::ATTR_* constantes.

<?php
$server = '<server>.database.windows.net';
$token  = getenv('SQL_ACCESS_TOKEN');   // raw JWT, no "Bearer " prefix

$dsn = "sqlsrv:Server=$server;Database=<database>;Encrypt=true;AccessToken=$token";
$conn = new PDO($dsn, null, null, [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);

Pour d’autres exemples d’authentification Microsoft Entra, y compris le formulaire DSN pour PDO_SQLSRV, voir Connect using Microsoft Entra authentication.

Pour SQLSRV procédural, AccessToken appartient à l’array connexion-info passé à sqlsrv_connect(), qui encapsule le JWT brut pour SQL_COPT_SS_ACCESS_TOKEN vous :

<?php
$server = '<server>.database.windows.net';
$token  = getenv('SQL_ACCESS_TOKEN');   // raw JWT, no "Bearer " prefix

$connectionInfo = [
    'Database'               => '<database>',
    'AccessToken'            => $token,
    'Encrypt'                => true,
    'TrustServerCertificate' => false,
    'Driver'                 => '{ODBC Driver 18 for SQL Server}',
];

$conn = sqlsrv_connect($server, $connectionInfo);
if ($conn === false) {
    print_r(sqlsrv_errors());
    exit(1);
}

Erreurs de certificat TLS

Symptômes :

SQLSTATE[08001]: SSL Provider: The certificate chain was issued by an authority that is not trusted
SQLSTATE[08001]: SSL Provider: The target principal name is incorrect

Solutions :

Privilégiez un certificat fiable. Utilisez-les TrustServerCertificate=true uniquement pour le développement local sur un serveur que vous contrôlez.

Pour le développement avec un certificat auto-signé :

<?php
$server   = 'localhost';
$database = '<database>';
$user     = '<user_id>';
$password = '<password>';

$dsn = "sqlsrv:Server=$server;Database=$database;Encrypt=true;TrustServerCertificate=true";
$conn = new PDO($dsn, $user, $password, [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);

Caution

TrustServerCertificate=true désactive la validation des certificats serveur. Ne jamais porter ce cadre en production, en mise en scène ou dans des environnements partagés.

Pour un nom d’hôte de production qui ne correspond pas au nom commun du certificat (par exemple, lors de la connexion via un auditeur), spécifiez le sujet réel du certificat :

<?php
$dsn = "sqlsrv:Server=<listener>;Database=<database>;Encrypt=true;HostNameInCertificate=*.database.windows.net;Authentication=ActiveDirectoryMsi";
$conn = new PDO($dsn, null, null, [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);

Délai d’expiration de la connexion

Symptômes :

SQLSTATE[HYT00]: Login timeout expired

Causes possibles et solutions :

  • LoginTimeout Pas réglé ou trop bas pour le basculement à froid. Définissez un explicite LoginTimeout (en quelques secondes) dans le DSN lors de la connexion à Azure SQL. Les basculements de basculement par groupe de basculement et les bases de données à démarrage à froid peuvent prendre plus de temps qu’un court délai client ne le permet. Voir Options de connexion pour la référence d’option.
  • Budget de reconnexion au ralenti tronqué. Si vous définissez ConnectRetryCount et ConnectRetryInterval, assurez-vous LoginTimeout >= ConnectRetryCount * ConnectRetryInterval. Sinon, le délai d’expiration de la connexion met fin anticipément à la boucle de reconnexion. Voir résilience de la connexion au repos.
<?php
$dsn = "sqlsrv:Driver={ODBC Driver 18 for SQL Server};Server=<server>.database.windows.net;Database=<database>;" .
       "Encrypt=true;LoginTimeout=90;ConnectRetryCount=5;ConnectRetryInterval=15;" .
       "Authentication=ActiveDirectoryMsi";
$conn = new PDO($dsn, null, null, [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);

Problèmes d’exécution des requêtes

Défaillances silencieuses avec PDO

Symptôme :

Un PDO::exec() OR PDOStatement::execute() revient false mais ne fait pas d’exception.

Correctif :

Avec PHP 8.0 et versions ultérieures, le mode d’erreur PDO par défaut est PDO::ERRMODE_EXCEPTION. Si un appel revient false sans être lancé, l’application a changé le mode en PDO::ERRMODE_SILENT ou PDO::ERRMODE_WARNING. Remettez-le en mode exception pour que les échecs lancent des exceptions :

<?php
$conn = new PDO($dsn, $user, $password, [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);

Si vous ne pouvez pas changer le mode globalement, vérifiez $conn->errorInfo() (ou $stmt->errorInfo()) après chaque appel. Le tableau contient [SQLSTATE, driver code, driver message].

Nom d’objet non valide

Symptômes :

SQLSTATE[42S02]: [Microsoft][ODBC Driver 18 for SQL Server][SQL Server]Invalid object name 'Products'.

Causes possibles et solutions :

  • Mauvais contexte de base de données. Vérifiez par une simple question :

    <?php
    $stmt = $conn->query("SELECT DB_NAME()");
    echo $stmt->fetchColumn();
    
  • Qualification de schéma manquante. Utilisez des noms entièrement qualifiés pour éviter de dépendre du schéma par défaut de l’appelant :

    SELECT * FROM dbo.Products;
    
  • Respect de la casse. Les bases de données créées avec une colation sensible aux cas et majuscules traitent products et Products comme des objets différents. Correspondez exactement au cas indiqué dans la définition du tableau.

Mauvais nombre de paramètres

Symptômes :

SQLSTATE[HY093]: Invalid parameter number
SQLSTATE[07002]: COUNT field incorrect or syntax error

Correctif :

Pour PDO_SQLSRV, le nombre de ? placeholders doit correspondre au nombre de valeurs que vous passez à execute(), et chacun ? lie un seul scalaire (et non un tableau). Pour les paramètres nommés, chaque :name dans le SQL doit apparaître dans le tableau et inversement.

<?php
$stmt = $conn->prepare(
    "SELECT * FROM dbo.Products WHERE CategoryID = ? AND ListPrice > ?"
);
$stmt->execute([1, 50.0]);
foreach ($stmt as $row) {
    // ...
}

Pour SQLSRV, passez le tableau de paramètres à sqlsrv_query() ou sqlsrv_prepare():

<?php
$stmt = sqlsrv_query(
    $conn,
    "SELECT * FROM dbo.Products WHERE CategoryID = ? AND ListPrice > ?",
    [1, 50.0]
);
if ($stmt === false) {
    die(print_r(sqlsrv_errors(), true));
}

Pour une introduction plus large à la liaison de paramètres, voir Effectuer des requêtes paramétrées.

L’émulation PDO prépare des erreurs de masque

Symptômes :

Une instruction s’exécute correctement sur une connexion mais génère une erreur de syntaxe sur une autre connexion qui utilise le même texte de requête.

Cause :

PDO_SQLSRV prend en charge à la fois les déclarations préparées émulées et natives. Les préparations émulées (PDO::ATTR_EMULATE_PREPARES = true) interpolent les paramètres côté client. Les préparations natives (false) envoient la requête et les paramètres séparément au serveur. Le comportement diffère pour TOP (?), paramètres à valeurs de table, et certains cas limites de coercition de type.

Correctif :

Je préfère les préparations natives en production. Réglez PDO::ATTR_EMULATE_PREPARES => false au moment de la connexion pour que le comportement soit cohérent dans tous les environnements :

<?php
$conn = new PDO($dsn, null, null, [
    PDO::ATTR_ERRMODE          => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_EMULATE_PREPARES => false,
]);

Pour plus de détails sur le moment d’utilisation de chaque mode, voir PDO ::p repare.

Problèmes de type de données

Les caractères Unicode apparaissent comme ? ou brouillés

Symptômes :

Les lignes écrites par PHP contiennent des points d’interrogation ou des caractères de remplacement au lieu des caractères originaux non ASCII. Les lectures rendent un texte brouillé.

Causes possibles et solutions :

  • Le type de colonne est VARCHAR, pas NVARCHAR. Les colonnes varchar utilisent une page de codes, pas Unicode. Utilisez nvarchar pour le texte internationalisé.

  • Il manque un indice d’encodage UTF-8 sur PDO_SQLSRV. Lorsque votre colonne SQL Server est nvarchar et que vos données PHP sont UTF-8, dites au pilote de convertir entre UTF-8 (client) et UTF-16 (serveur) :

    <?php
    $conn = new PDO(
        "sqlsrv:Server=<server>;Database=<database>;Encrypt=true",
        $user,
        $password,
        [
            PDO::ATTR_ERRMODE                    => PDO::ERRMODE_EXCEPTION,
            PDO::SQLSRV_ATTR_ENCODING            => PDO::SQLSRV_ENCODING_UTF8,
        ]
    );
    
  • Pilote SQLSRV : demande explicitement UTF-8. SQLSRV_ENC_CHAR est la page de code système 8 bits par défaut, et non UTF-8. Pour UTF-8 avec SQLSRV, on met "CharacterSet" => "UTF-8" sur la connexion et on passe le littéral 'UTF-8' à SQLSRV_PHPTYPE_STRING on fetch ou bind. Voir Envoyer et récupérer les données UTF-8.

Erreurs de conversion de date et d’heure

Symptômes :

SQLSTATE[22007]: Invalid character value for cast specification

Correctif :

Sur PDO_SQLSRV, ne liez pas un objet brut DateTime . PDO stringifie les valeurs liées avant la liaison, et celui de DateTime PHP n’a pas __toString() de méthode, donc execute([new DateTime(...)]) augmente Object of class DateTime could not be converted to string. Formatez d’abord la valeur, ou passez une chaîne ISO 8601 (YYYY-MM-DD HH:MM:SS[.fff]), et non une chaîne formatée localement.

<?php
$stmt = $conn->prepare("INSERT INTO dbo.Events (EventDate) VALUES (?)");
$stmt->execute([(new DateTime("2026-03-15 10:00:00"))->format("Y-m-d H:i:s.u")]);

Pour récupérer les colonnes de datetime sous forme DateTime d’objets au lieu de chaînes de caractères sur PDO_SQLSRV, définissez l’attribut de l’instruction :

<?php
$stmt = $conn->prepare("SELECT EventDate FROM dbo.Events");
$stmt->setAttribute(PDO::SQLSRV_ATTR_FETCHES_DATETIME_TYPE, true);
$stmt->execute();

Pour plus de détails, voir Récupérer les objets datetime (PDO_SQLSRV).

Problèmes de mise en forme décimale

Symptômes :

Les valeurs comprises entre -1 et 1 manquent de zéro en tête, ou bien les valeurs de monnaie et de monnaie petite montrent un nombre inattendu de décimales.

Correctif :

PDO_SQLSRV récupère toujours les valeurs décimales et numériques sous forme de chaînes avec leur précision et leur échelle exactes. On peut ajouter PDO::SQLSRV_ATTR_FORMAT_DECIMALS un zéro en tête aux valeurs comprises entre -1 et 1 :

<?php
$conn->setAttribute(PDO::SQLSRV_ATTR_FORMAT_DECIMALS, true);

PDO::SQLSRV_ATTR_DECIMAL_PLACES S’applique uniquement à l’argent et aux valeurs de la petite monnaie . Il fixe leur échelle affichée de 0 à 4 et peut arrondir la valeur affichée. Cela n’affecte pas les valeurs décimales ou numériques .

Pour plus de détails, voir Formater décimales et monnaie (PDO_SQLSRV) ou Formater décimales et monnaie (SQLSRV).

Problèmes de transaction

Les changements de données ne persistent pas

Symptômes :

Les lignes que vous insérez ou mettez à jour dans PHP n’apparaissent pas lorsque vous interrogez depuis une autre session.

Cause :

PDO::beginTransaction()ouvre une transaction explicite qui nécessite un .commit() Si le script PHP se termine sans appeler commit(), PDO annule la transaction lors du nettoyage de la connexion.

Correctif :

Associez toujours beginTransaction() avec commit(), et utilisezcatchtry/pour revenir en arrière en cas d’erreur :

<?php
try {
    $conn->beginTransaction();
    $conn->exec("INSERT INTO dbo.Orders (CustomerID, Total) VALUES (1, 100)");
    $conn->exec("UPDATE dbo.Inventory SET Stock = Stock - 1 WHERE ProductID = 5");
    $conn->commit();
} catch (PDOException $e) {
    $conn->rollBack();
    throw $e;
}

Pour SQLSRV, utilisez sqlsrv_begin_transaction, sqlsrv_commit, et sqlsrv_rollback.

Erreurs d’interblocage

Symptômes :

SQLSTATE[40001]: [Microsoft][ODBC Driver 18 for SQL Server][SQL Server]Transaction (Process ID 62) was deadlocked

Correctif :

Gérer les erreurs de blocage transitoire avec la logique de retentive. Emballez toute la transaction (pas seulement l’état en échec) pour que les relevés précédents se rejouent sur la nouvelle transaction. Pour un motif de réessai orienté production, consultez l’exemple sur la page d’accueil du pilote PHP.

Des blocages récurrents indiquent un problème de conception. Capturez le graphique des blocages et analysez quelles instructions et types de verrous sont impliqués. Les correctifs courants incluent le réordre des opérations afin que les transactions concurrentes acquèrent des verrous dans la même séquence, la réduction de la portée des transactions, et l’ajout d’indices pour diminuer la durée des verrous. Pour une solution complète, consultez le guide Deadlocks.

Problèmes de résilience des connexions

La reconnexion n’a pas lieu

Symptômes :

Une connexion inactive reste coupée après un basculement d’Azure SQL Database, même si vous avez défini ConnectRetryCount et ConnectRetryInterval.

Causes possibles et solutions :

  • Curseur actif côté serveur. La résilience des connexions inactives ne reconnecte que les connexions inactives . Un curseur ouvert côté serveur ou une transaction en attente maintient la connexion active. Libérez les curseurs côté serveur en utilisant sqlsrv_free_stmt() ou $stmt = null; (PDO) avant la fenêtre de basculement, ou basculez vers un curseur tamponné côté client. Voir résilience de la connexion au repos.
  • État de session non récupérable. Certains états de session ne peuvent pas être rétablis, y compris les tables temporaires, les curseurs globaux et locaux, le contexte des transactions, les verrous d’application, EXECUTE AS/REVERTles handles d’automatisation OLE, les handles XML préparés et les trace flags. Chacun de ces états de session empêche la reconnexion automatique.
  • LoginTimeout trop petit. Si ConnectRetryCount * ConnectRetryInterval > LoginTimeout, le conducteur cesse de réessayer lorsqu’il LoginTimeout est atteint. Augmentez LoginTimeout pour couvrir le budget complet des tentatives.

Problèmes de performances

Pour le diagnostic et la correction des requêtes lentes, des démarrages à froid, de grands ensembles de résultats et des inserts en masse, voir Réglage de performance.

Activer le diagnostic des pilotes

Lorsque les appels au niveau error_log() de l’application ne fournissent pas assez d’informations, activez la journalisation côté conducteur. Il rapporte chaque appel ODBC que le chauffeur fait.

PDO_SQLSRV

Installez-vous pdo_sqlsrv.log_severityphp.ini et redémarrez le serveur web. Ce réglage n’est lisible qu’à l’initialisation :

[pdo_sqlsrv]
pdo_sqlsrv.log_severity = 1

Les valeurs sont 0 (désactivé, par défaut), -1 (erreurs, avertissements et avis), 1 (erreurs), 2 (avertissements) et 4 (avis).

SQLSRV

Activez la journalisation à l’exécution avec sqlsrv_configure():

<?php
sqlsrv_configure("LogSubsystems", SQLSRV_LOG_SYSTEM_CONN | SQLSRV_LOG_SYSTEM_STMT);
sqlsrv_configure("LogSeverity", SQLSRV_LOG_SEVERITY_ERROR | SQLSRV_LOG_SEVERITY_WARNING);

Les entrées de journal vont dans le fichier configuré par error_log dans php.ini. Pour la liste complète des sous-systèmes et des sévérités, voir Activité de journalisation.

Problèmes de conteneurs et de CI

Bibliothèques système manquantes sur Linux

Symptômes :

error while loading shared libraries: libodbc.so.2: cannot open shared object file
error while loading shared libraries: libssl.so.1.1: cannot open shared object file

Correctif :

Installez les dépendances à l’exécution avant d’installer le pilote PHP :

Distribution Commande d'installation
Ubuntu et Debian sudo apt-get install unixodbc libgssapi-krb5-2
Red Hat et Fedora sudo dnf install unixODBC krb5-libs
Alpine apk add unixodbc gcompat

Ensuite, installez msodbcsql18 depuis le dépôt de paquets Microsoft. Pour les dépôts et versions spécifiques à chaque distribution, consultez le guide d’installation des pilotes ODBC.

Les builds d’image Docker réussissent mais les connexions échouent à l’exécution

Symptômes :

L’image se construit et PHP démarre, mais PDO::__construct() affiche une erreur ODBC driver-in-found.

Correctif :

Vérifiez que le pilote ODBC est installé dans l’image d’exécution, pas seulement à l’étape de compilation. Installé msodbcsql18 et unixodbc-dev dans la même phase que l’expédition en production. Dans une construction à plusieurs étapes, installez-les à l’étape finale. Une installation Debian à une seule étape ressemble à ceci :

# Pin to a specific PHP minor version in production, for example php:8.4.11-cli.
FROM php:8.4-cli
RUN apt-get update && apt-get install -y --no-install-recommends \
        curl gnupg2 apt-transport-https ca-certificates \
    && curl -sSL https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > /usr/share/keyrings/microsoft.gpg \
    && echo "deb [arch=amd64 signed-by=/usr/share/keyrings/microsoft.gpg] https://packages.microsoft.com/debian/12/prod bookworm main" > /etc/apt/sources.list.d/mssql-release.list \
    && apt-get update \
    && ACCEPT_EULA=Y apt-get install -y --no-install-recommends msodbcsql18 unixodbc-dev \
    # $PHPIZE_DEPS ships in the official php image and includes gcc, make, autoconf, and re2c.
    && apt-get install -y --no-install-recommends $PHPIZE_DEPS \
    && pecl install sqlsrv pdo_sqlsrv \
    && docker-php-ext-enable sqlsrv pdo_sqlsrv \
    && apt-get purge -y --auto-remove $PHPIZE_DEPS \
    && rm -rf /var/lib/apt/lists/*