Troubleshoot de Microsoft-drivers voor PHP voor SQL Server

PHP-stuurprogramma downloaden

Diagnoseer en los veelvoorkomende problemen op wanneer je de Microsoft Drivers voor PHP voor SQL Server gebruikt om verbinding te maken met SQL Server, Azure SQL Database, Azure SQL Managed Instance en SQL database in Microsoft Fabric.

Voor algemene patronen voor fout- en waarschuwingsafhandeling, zie Afhandelingsfouten en waarschuwingen. Voor diagnostische vastlegging aan bestuurderszijde, zie Logging activiteiten.

Installatieproblemen

Uitbreiding niet geladen

Symptomen:

  • phpinfo()Vermeldt geen A-sectie sqlsrv of On.pdo_sqlsrv
  • PDOException: could not find driver bij het construeren van een PDO met de sqlsrv: DSN.
  • Fatal error: Uncaught Error: Call to undefined function sqlsrv_connect().

Mogelijke oorzaken en oplossingen:

  • Extensie niet ingeschakeld in php.ini. Controleer of zowel extension=sqlsrv als extension=pdo_sqlsrv niet gereageerd zijn. Op Windows gebruik je de volledige bestandsnaam (extension=php_sqlsrv_84_ts_x64.dll). Voor details, zie Laden van de drivers.
  • Verkeerde schroefdraadveiligheidsconstructie. De driver-binary moet overeenkomen met de threadveiligheid van je PHP-build (ts voor thread-safe, nts voor niet-thread-safe). Voer php -i | grep "Thread Safety" uit om te controleren. Download het bijpassende binaire account van de downloadpagina.
  • Microsoft ODBC-driver ontbreekt. De PHP-drivers omsluiten de Microsoft ODBC Driver for SQL Server. Installeer (of msodbcsql17) op Linux en macOS msodbcsql18 met je pakketbeheerder voordat je de extensies laadt. Installeer op Windows de ODBC-driver vanaf de downloadpagina.

Controleer een geslaagde installatie:

php -m | grep -i sqlsrv

Je zou beide pdo_sqlsrv en sqlsrv in de output moeten zien.

PECL-installatie mislukt op Linux of macOS

Symptomen:

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

Oplossen:

Installeer de ODBC-ontwikkelheaders voordat je start pecl install:

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

Probeer het dan opnieuw:

sudo pecl install sqlsrv
sudo pecl install pdo_sqlsrv

Als pecl het nog steeds faalt nadat de headers zijn geïnstalleerd, kan de bouw-toolchain onvolledig zijn. Installeer phpize, re2c, en een C++-compiler (build-essential op Debian en Ubuntu, gcc-c++ make op Red Hat en Fedora, build-base op Alpine).

Voor het volledige installatiepad, zie de installatiehandleiding voor Linux en macOS.

Meerdere PHP-versies geïnstalleerd

Symptomen:

phpinfo() op je webserver wordt één PHP-versie getoond, maar php -v op de commandoregel een andere, en de driver verschijnt in slechts één van die versies geladen.

Oplossen:

Elke PHP-versie heeft zijn eigen php.ini directory ext . Zoek het juiste configuratiebestand uit php --ini de omgeving waar de driver ontbreekt, en voeg daar de extension= regels toe. Herstart de webserver (Apache, Nginx + PHP-FPM of IIS) na elke php.ini wijziging.

Verbindingsproblemen

Kan geen verbinding maken met de server

Symptomen:

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

Mogelijke oorzaken en oplossingen:

  • De server is niet bereikbaar. Controleer of de servernaam en poort correct zijn. Test vanaf de PHP-host de ruwe TCP-connectiviteit.

    # Linux and macOS
    nc -vz <server>.database.windows.net 1433
    
    # Windows PowerShell
    Test-NetConnection -ComputerName <server>.database.windows.net -Port 1433
    
  • Firewall blokkeert uitgaande 1433. Bedrijfsfirewalls en cloud-NSG's blokkeren vaak uitgaande poort 1433. Voeg een uitzondering toe, of sta de Azure SQL Database IP-ranges toe voor jouw regio.

  • Azure SQL server firewall. Voeg het publieke IP van je cliënt toe aan de server-niveau firewallregels in het Azure-portaal.

  • Naamgegeven instantie. Voor een benoemde instantie controleer je of de SQL Server Browser-service op de server draait en dat UDP 1434 open is. Of verbind via poort in plaats van via instantienaam.

Aanmelden is mislukt

Symptomen:

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

Mogelijke oorzaken en oplossingen:

  • SQL-authenticatiemodus uitgeschakeld. Lokale SQL Server-instanties gebruiken standaard alleen Windows-authenticatie. Schakel mixed mode authenticatie in in SQL Server Management Studio in onder Server properties>Security en start vervolgens de SQL Server-service opnieuw op.
  • Azure SQL credentials format. Azure SQL vereist de volledig gekwalificeerde gebruikersnaam (user@servername) bij verbinding met tools die het niet automatisch toevoegen.
  • Gebruiker niet gekoppeld aan de database. Controleer of de login een gebruikersmapping heeft in de doeldatabase en dat de gebruiker de vereiste rechten heeft.
  • Ik geef de voorkeur aan Microsoft Entra ID. Voor Azure SQL, Azure SQL Managed Instance en SQL database in Fabric gebruik je Microsoft Entra-authenticatie (Authentication=ActiveDirectoryMsi, Authentication=ActiveDirectoryServicePrincipal, of een toegangstoken) in plaats van SQL-logins. Zie Verbinding maken met behulp van Microsoft Entra-verificatie.

Ongeldige waarde gespecificeerd voor verbindingsreeks-attribuut 'Authentication'

Symptomen:

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

Oorzaak:

De ODBC-driver meldt de fout, maar het echte probleem is aan welke driver PDO_SQLSRV gebonden. Als de DSN geen Driver= trefwoord bevat en de host zowel ODBC 17 als ODBC 18 heeft geïnstalleerd, kan PDO_SQLSRV binden naar de oudere versie. Oudere ODBC 17.x-builds kennen geen nieuwere Authentication waarden zoals ActiveDirectoryServicePrincipal of ActiveDirectoryDefault, en vereisen zelfs ActiveDirectoryMsi ODBC 17.3.1.1 of een latere versie.

Oplossen:

Pind de driver in het 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]);

De haakjesvorm ({ODBC Driver 18 for SQL Server}) ontwijkt de spaties in de bestuurdersnaam. Het foutbericht zelf noemt altijd de driver die het heeft gemeld, dus het voorvoegsel [Microsoft][ODBC Driver 17 for SQL Server] in de fout is de snelste manier om de verkeerde drivergrens te bevestigen.

Ongeldig trefwoord 'UID' werd gespecificeerd in de DSN-string

Symptomen:

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

Oorzaak:

PDO_SQLSRV handhaaft een toestaanlijst met DSN-zoekwoorden en accepteert UID geen PWD of staat niet in het DSN. PDO reserveert de tweede en derde constructorargumenten voor die argumenten, en vertaalt PDO_SQLSRV ze intern naar ODBC UID/PWD .

Oplossen:

Verplaats de gebruikersnaam (en wachtwoord, voor SQL-authenticatie) naar de PDO-constructor:

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

De SQLSRV-procedurele driver accepteert UID daarentegen en PWD geeft in de verbindingsopties-array aan sqlsrv_connect().

PDO_SQLSRV negeert AccessToken in de optie-array stilletjes

Symptoom:

Je hebt een Microsoft Entra toegangstoken (bijvoorbeeld van az account get-access-token --resource https://database.windows.net/, , of ClientSecretCredential), en je geeft die door aan PDO_SQLSRV zoals ['AccessToken' => $token] in het vierde constructor-argumentManagedIdentityCredential. De verbindingspoging mislukt met een verwarrende fout zoals Windows logins are not supported in this version of SQL Server of Login failed for user '', alsof er geen inloggegevens zijn opgegeven.

Oorzaak:

Het vierde constructorargument van PDO is gereserveerd voor driver-specifieke attribuutconstanten (gehele getalsleutels zoals PDO::ATTR_ERRMODE). PDO laat string-keyed entries AccessTokenzoals , zodat PDO_SQLSRV het token nooit ziet. De verbinding valt dan terug op Windows Integrated authenticatie, die de server weigert.

Oplossen:

Ga AccessToken naar de DSN-string. Reserveer de opties-array voor PDO::ATTR_* constanten.

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

Voor aanvullende voorbeelden van Microsoft Entra authenticatie, waaronder het DSN-formulier voor PDO_SQLSRV, zie Connect using Microsoft Entra authentication.

Voor SQLSRV procedureel hoort AccessToken het in de connection-info array die aan sqlsrv_connect()wordt doorgegeven, wat de ruwe JWT SQL_COPT_SS_ACCESS_TOKEN voor jou inpakt:

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

TLS-certificaatfouten

Symptomen:

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

Oplossingen:

Geef de voorkeur aan een vertrouwd certificaat. Gebruik TrustServerCertificate=true alleen voor lokale ontwikkeling tegen een server die jij beheert.

Voor ontwikkeling op basis van een zelfondertekend certificaat:

<?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 Schakelt de validatie van servercertificaten uit. Neem die setting nooit mee naar productie, enscenering of gedeelde omgevingen.

Voor een productiehostnaam die niet overeenkomt met de certificaat Common Name (bijvoorbeeld bij verbinding via een luisteraar), specificeer het daadwerkelijke certificaatonderwerp:

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

Verbindingstijd is verlopen

Symptomen:

SQLSTATE[HYT00]: Login timeout expired

Mogelijke oorzaken en oplossingen:

  • LoginTimeout Niet ingesteld of te laag ingesteld voor cold failover. Stel een expliciet LoginTimeout (in seconden) in in de DSN wanneer je verbinding maakt met Azure SQL. Failover-group failovers en cold-start databases kunnen langer duren dan een korte client-side timeout toelaat. Zie Verbindingsopties voor de optiereferentie.
  • Budget voor idle reconnect ingekort. Als je en ConnectRetryIntervalzetConnectRetryCount, zorg er dan voor LoginTimeout >= ConnectRetryCount * ConnectRetryInterval. Anders beëindigt de inlogtimeout de herverbindingslus voortijdig. Zie Idle verbindingsveerkracht.
<?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,
]);

Problemen met de uitvoering van query's

Stille storingen met PDO

Symptoom:

A PDO::exec() of PDOStatement::execute() call keert terug, false maar geeft geen uitzondering.

Oplossen:

Bij PHP 8.0 en latere versies is PDO::ERRMODE_EXCEPTIONde standaard PDO-foutmodus . Als een aanroep terugkeert false zonder te gooien, verandert de applicatie de modus naar PDO::ERRMODE_SILENT of PDO::ERRMODE_WARNING. Zet het terug naar uitzonderingsmodus zodat fouten uitzonderingen veroorzaken:

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

Als je de modus niet globaal kunt wijzigen, controleer $conn->errorInfo() dan (of $stmt->errorInfo()) na elk gesprek. De array bevat [SQLSTATE, driver code, driver message].

Ongeldige objectnaam

Symptomen:

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

Mogelijke oorzaken en oplossingen:

  • Verkeerde databasecontext. Controleer het met een korte zoekopdracht:

    <?php
    $stmt = $conn->query("SELECT DB_NAME()");
    echo $stmt->fetchColumn();
    
  • Ontbrekende schema-kwalificatie. Gebruik volledig gekwalificeerde namen om te voorkomen dat je afhankelijk bent van het standaardschema van de beller:

    SELECT * FROM dbo.Products;
    
  • hoofdlettergevoeligheid. Databases die zijn gemaakt met een hoofdlettergevoelige rangrangatie behandelen products en Products als verschillende objecten. Stem exact overeen met het geval in de tabeldefinitie.

Verkeerd aantal parameters

Symptomen:

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

Oplossen:

Voor PDO_SQLSRV moet het aantal ? placeholders overeenkomen met het aantal waarden dat je doorgeeft aan execute(), en elke ? kaart bindt een enkele scalar (geen array). Voor benoemde parameters moet elke :name in de SQL in de array voorkomen en omgekeerd.

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

Voor SQLSRV geeft u de parameterarray door aan sqlsrv_query() of 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));
}

Voor een bredere introductie tot parameterbinding, zie Perform parameterized queries.

PDO geëmuleerd bereidt maskerfouten voor

Symptomen:

Een instructie draait succesvol op één verbinding, maar geeft een syntaxisfout op een andere verbinding die dezelfde querytekst gebruikt.

Oorzaak:

PDO_SQLSRV ondersteunt zowel geëmuleerde als native prepared statements. Geëmuleerd bereidt parameters voor (PDO::ATTR_EMULATE_PREPARES = true) interpoleert parameters aan de clientzijde. Native bereidt () voor enfalse stuurt de query en parameters apart naar de server. Het gedrag verschilt voor TOP (?), tabelwaardige parameters en enkele randgevallen in typecoercion.

Oplossen:

Ik geef de voorkeur aan inheemse bereidingen in productie. Ingesteld PDO::ATTR_EMULATE_PREPARES => false op het verbindingsmoment zodat het gedrag consistent is tussen omgevingen:

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

Voor details over wanneer je elke modus moet gebruiken, zie PDO::p repare.

Datatypeproblemen

Unicode-tekens verschijnen als ? of vervormd

Symptomen:

Rijen die PHP schrijft bevatten vraagtekens of vervangende tekens in plaats van de oorspronkelijke niet-ASCII-tekens. Lezen geven onverstaanbare tekst terug.

Mogelijke oorzaken en oplossingen:

  • Het kolomtype is VARCHAR, niet NVARCHAR. varchar-kolommen gebruiken een codepagina, geen Unicode. Gebruik nvarchar voor geïnnationaliseerde tekst.

  • Ontbrekende UTF-8 coderingshint op PDO_SQLSRV. Wanneer je SQL Server-kolom nvarchar is en je PHP-data UTF-8, laat dan de driver converteren tussen UTF-8 (client) en UTF-16 (server):

    <?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,
        ]
    );
    
  • SQLSRV-driver: vraag expliciet UTF-8 aan. SQLSRV_ENC_CHAR is de standaard 8-bits systeemcodepagina, niet UTF-8. Voor UTF-8 met SQLSRV zet "CharacterSet" => "UTF-8" je op de verbinding en geef je de literal 'UTF-8' door aan SQLSRV_PHPTYPE_STRING bij fetch of bind. Zie Verzenden en ophalen UTF-8 gegevens.

Fouten bij data-tijdconversie

Symptomen:

SQLSTATE[22007]: Invalid character value for cast specification

Oplossen:

Bind PDO_SQLSRV geen rauw DateTime object. PDO stringifiseert gebonden waarden voordat ze binden, en PHP's DateTime heeft geen __toString() methode, dus execute([new DateTime(...)]) verhoogt Object of class DateTime could not be converted to string. Formatteren eerst de waarde, of geef een ISO 8601-string door (YYYY-MM-DD HH:MM:SS[.fff]), niet een locale-formatteerde string.

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

Om datetime-kolommen als DateTime objecten op te halen in plaats van strings op PDO_SQLSRV, stel je het statement-attribuut in:

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

Voor details, zie Datetime-objecten ophalen (PDO_SQLSRV).

Decimale opmaakproblemen

Symptomen:

Waarden tussen -1 en 1 missen een leidende nul, of geld- en kleingeldwaarden tonen een onverwacht aantal decimalen.

Oplossen:

PDO_SQLSRV haalt altijd decimale en numerieke waarden op als strings met hun exacte precisie en schaal. Stel PDO::SQLSRV_ATTR_FORMAT_DECIMALS in om een leidende nul toe te voegen aan waarden tussen -1 en 1:

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

PDO::SQLSRV_ATTR_DECIMAL_PLACES geldt alleen voor geld- en kleingeldwaarden . Het stelt de getoonde schaal in van 0 tot 4 en kan de getoonde waarde afronden. Het beïnvloedt geen decimale of numerieke waarden .

Voor details, zie Format decimalals and money (PDO_SQLSRV) of Format decimals and money (SQLSRV).

Transactieproblemen

Datawijzigingen blijven niet behouden

Symptomen:

Rijen die je invoegt of bijwerkt in PHP verschijnen niet wanneer je een query vanuit een andere sessie indient.

Oorzaak:

PDO::beginTransaction() opent een expliciete transactie die een expliciet commit()vereist. Als het PHP-script eindigt zonder aan te roepen commit(), rolt PDO de transactie terug tijdens het opruimen van de verbinding.

Oplossen:

Altijd koppelen beginTransaction() met commit(), en gebruik try/catch om bij fout terug te rollen:

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

Voor SQLSRV gebruik sqlsrv_begin_transaction, sqlsrv_commit, en sqlsrv_rollback.

Deadlockfouten

Symptomen:

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

Oplossen:

Behandel tijdelijke deadlock-fouten met retry-logica. Wrap de hele transactie (niet alleen de falende statement) zodat eerdere statements opnieuw worden afgespeeld op de verse transactie. Voor een productiegericht herkansingpatroon, zie het voorbeeld op de PHP-driverlandingspagina.

Terugkerende deadlocks wijzen op een ontwerpprobleem. Leg de deadlock-grafiek vast en analyseer welke statements en locktypes betrokken zijn. Veelvoorkomende oplossingen zijn onder andere herordeningsoperaties zodat concurrerende transacties in dezelfde volgorde vergrendelingen verkrijgen, het verminderen van de transactiescope en het toevoegen van indexen om de duur van de vergrendeling te verkorten. Voor een volledige begeleiding, zie de Deadlocks-gids.

Problemen met verbindingsveerkracht

Opnieuw verbinden gebeurt niet

Symptomen:

Een idle-verbinding blijft verbroken na een failover van de Azure SQL Database, ook al zet ConnectRetryCount je en ConnectRetryInterval.

Mogelijke oorzaken en oplossingen:

  • Actieve server-side cursor. Idle-verbindingbestendigheid maakt alleen de idle-verbindingen weer verbinding. Een open server-side cursor of een lopende transactie houdt de verbinding actief. Vrijmaak serverzijde cursors door gebruik te maken sqlsrv_free_stmt() van of $stmt = null; (PDO) vóór het failover-venster, of schakel over naar een client-side gepufferde cursor. Zie Idle verbindingsveerkracht.
  • Niet-herstelbare sessie-status. Sommige sessie-toestanden kunnen niet worden hersteld, waaronder tijdelijke tabellen, globale en lokale cursors, transactiecontext, applicatiesloten, EXECUTE AS/REVERTOLE-automatiseringshandles, voorbereide XML-handles en trace-vlaggen. Elk van deze sessietoestanden voorkomt automatische herverbinding.
  • LoginTimeout te klein. Als ConnectRetryCount * ConnectRetryInterval > LoginTimeout, stopt de driver met opnieuw proberen wanneer LoginTimeout bereikt is. Verhoging LoginTimeout om het volledige herkansingsbudget te dekken.

Prestatieproblemen

Voor diagnose en remediëring van trage queries, cold starts, grote resultatensets en bulk inserts, zie Performance tuning.

Schakel driverdiagnostiek in

Wanneer aanroepen op applicatieniveau error_log() niet genoeg informatie opleveren, zet dan de logging aan de bestuurderszijde in. Het rapporteert elke ODBC-oproep die de chauffeur doet.

PDO_SQLSRV

Installeer pdo_sqlsrv.log_severityphp.ini en start de webserver op. Deze instelling is alleen leesbaar bij initialisatie:

[pdo_sqlsrv]
pdo_sqlsrv.log_severity = 1

Waarden zijn 0 (uit, de standaard), -1 (fouten, waarschuwingen en meldingen), 1 (fouten), 2 (waarschuwingen) en 4 (meldingen).

SQLSRV

Schakel logging tijdens runtime in met 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);

Logboekvermeldingen gaan naar het bestand dat door error_log in php.iniis geconfigureerd. Voor de volledige lijst van subsystemen en ernst, zie Logging activiteit.

Container- en CI-problemen

Ontbrekende systeembibliotheken op Linux

Symptomen:

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

Oplossen:

Installeer de runtime-afhankelijkheden voordat je de PHP-driver installeert:

Distribution Opdracht Installeren
Ubuntu en Debian sudo apt-get install unixodbc libgssapi-krb5-2
Red Hat en Fedora sudo dnf install unixODBC krb5-libs
Alpine apk add unixodbc gcompat

Installeer msodbcsql18 daarna vanuit de Microsoft package repository. Voor distributie-specifieke pakketrepositories en versies, zie de ODBC-driverinstallatiegids.

Docker-imagebuilds slagen, maar verbindingen falen tijdens runtime

Symptomen:

Het image bouwt op en PHP start, maar PDO::__construct() geeft een ODBC driver-not-found foutmelding.

Oplossen:

Controleer of de ODBC-driver in de runtime-image is geïnstalleerd, niet alleen in de bouwfase. Installeer msodbcsql18 en unixodbc-dev zit in dezelfde fase die naar productie wordt gestuurd. Bij een meerfasige bouw installeer je ze in de laatste fase. Een eenfasige Debian-gebaseerde installatie ziet er als volgt uit:

# 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/*