Felsök Microsoft-drivrutinerna för PHP för SQL Server

Ladda ned PHP-drivrutin

Diagnostisera och lösa vanliga problem när du använder Microsoft Drivers för PHP för SQL Server för att ansluta till SQL Server, Azure SQL Database, Azure SQL Managed Instance och SQL Database i Microsoft Fabric.

För allmänna mönster för hantering av fel och varningar, se Hantering av fel och varningar. För diagnostik på förarsidan, se Loggning av aktivitet.

Installationsproblem

Tillägget har inte lästs in

Symtom:

  • phpinfo() har inte någon sqlsrv- eller pdo_sqlsrv-sektion.
  • PDOException: could not find driver när man konstruerar en PDO med sqlsrv:-DSN:en.
  • Fatal error: Uncaught Error: Call to undefined function sqlsrv_connect().

Möjliga orsaker och lösningar:

  • Tillägg inte aktiverat i php.ini. Kontrollera att både extension=sqlsrv och extension=pdo_sqlsrv är avkommenterade. På Windows, använd hela filnamnet (extension=php_sqlsrv_84_ts_x64.dll). Mer information finns i Inläsning av drivrutiner.
  • Fel trådsäkerhetskonstruktion. Drivrutinsbinären måste matcha trådsäkerheten i din PHP-version (ts för trådsäker version, nts för icke-trådsäker version). Kör php -i | grep "Thread Safety" för att kontrollera. Ladda ner den matchande binären från nedladdningssidan.
  • Microsoft ODBC-drivrutin saknas. PHP-drivrutinerna omsluter Microsoft ODBC-drivrutinen för SQL Server. På Linux och macOS, installera msodbcsql18 (eller msodbcsql17) med din pakethanterare innan du laddar tilläggen. På Windows, installera ODBC-drivrutinen från nedladdningssidan.

Verifiera en lyckad installation:

php -m | grep -i sqlsrv

Du bör se både pdo_sqlsrv och sqlsrv i utdata.

PECL-installationen misslyckas på Linux eller macOS

Symtom:

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

Lösningen

Installera ODBC-utvecklingsheaders innan du kör:pecl install

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

Försök sedan igen:

sudo pecl install sqlsrv
sudo pecl install pdo_sqlsrv

Om pecl fortfarande misslyckas när huvudfilerna har installerats kan verktygskedjan för kompilering vara ofullständig. Installera phpize, re2c, och en C++-kompilator (build-essential på Debian och Ubuntu, gcc-c++ make på Red Hat och Fedora, build-base på Alpine).

För hela installationsvägen, se installationsguide för Linux och macOS.

Flera PHP-versioner installerade

Symtom:

phpinfo() på din webbserver visar en PHP-version, men php -v på kommandoraden visar en annan, och drivrutinen verkar vara laddad i bara en av dem.

Lösningen

Varje PHP-version har sina egna kataloger php.ini och ext. Leta reda på rätt konfigurationsfil med php --ini inifrån den miljö som saknar drivrutinen och lägg till raderna extension= där. Starta om webbservern (Apache, Nginx + PHP-FPM eller IIS) efter varje php.ini ändring.

Anslutningsproblem

Kan inte ansluta till servern

Symtom:

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

Möjliga orsaker och lösningar:

  • Servern är inte nåbar. Kontrollera att servernamnet och porten är korrekta. Från PHP-värden, testa rå TCP-anslutning.

    # Linux and macOS
    nc -vz <server>.database.windows.net 1433
    
    # Windows PowerShell
    Test-NetConnection -ComputerName <server>.database.windows.net -Port 1433
    
  • Brandvägg blockerar utgående 1433. Företagsbrandväggar och moln-NSG:er blockerar ofta utgående port 1433. Lägg till ett undantag, eller tillåt Azure SQL Database IP-intervall för din region.

  • Azure SQL server firewall. Lägg till din klients publika IP i servernivåns brandväggsregler i Azure-portalen.

  • Namngiven instans. För en namngiven instans, kontrollera att SQL Server Browser-tjänsten körs på servern och att UDP 1434 är öppen. Eller koppla upp via port istället för efter instansnamn.

Inloggningen misslyckades

Symtom:

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

Möjliga orsaker och lösningar:

  • SQL-autentiseringsläge inaktiverat. Lokala SQL Server-instanser använder som standard endast Windows-autentisering. Aktivera mixed mode-autentisering i SQL Server Management Studio under Server properties>Security och starta sedan om SQL Server-tjänsten.
  • Azure SQL credentials format. Azure SQL kräver det fullt kvalificerade användarnamnet (user@servername) när man ansluter från verktyg som inte automatiskt lägger till det.
  • Användaren är inte mappad till databasen. Verifiera att inloggningen har en användarmappning i måldatabasen och att användaren har de nödvändiga behörigheterna.
  • Föredrar Microsoft Entra ID. För Azure SQL, Azure SQL Managed Instance och SQL-databas i Fabric, använd Microsoft Entra-autentisering (Authentication=ActiveDirectoryMsi, Authentication=ActiveDirectoryServicePrincipal, eller en åtkomsttoken) istället för SQL-inloggningar. Se Ansluta med Microsoft Entra-autentisering.

Ogiltigt värde angivet för attributet 'Authentication i reťazec pripojenia

Symtom:

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

Orsak:

ODBC-drivrutinen rapporterar felet, men det verkliga problemet är vilken drivrutin PDO_SQLSRV bunden till. Om ett DSN inte innehåller ett Driver=-nyckelord och värddatorn har både ODBC 17 och ODBC 18 installerade, kan PDO_SQLSRV koppla till den äldre versionen. Äldre ODBC 17.x-versioner känner inte till nyare Authentication värden som ActiveDirectoryServicePrincipal eller ActiveDirectoryDefault, och kräver till och med ActiveDirectoryMsi ODBC 17.3.1.1 eller en senare version.

Lösningen

Fäst drivrutinen i DSN:n:

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

Den parenteserade formen ({ODBC Driver 18 for SQL Server}) undviker mellandragen i förarnamnet. Felmeddelandet i sig namnger alltid drivrutinen som rapporterade det, så prefixet [Microsoft][ODBC Driver 17 for SQL Server] i felet är det snabbaste sättet att bekräfta fel drivrutinsgräns.

Ogiltigt nyckelord 'UID' specificerades i DSN-strängen

Symtom:

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

Orsak:

PDO_SQLSRV använder en lista över tillåtna DSN-nyckelord och accepterar inte UID eller PWD i DSN-strängen. PDO reserverar argumenten för den andra och tredje konstruktören för dessa, och PDO_SQLSRV översätter dem internt till ODBC UID/PWD .

Lösningen

Flytta användarnamnet (och lösenordet, för SQL-autentisering) till PDO-konstruktorn:

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

Den procedurbaserade SQLSRV-drivrutinen accepterar däremot UID och PWD i arrayen med anslutningsalternativ som skickas till sqlsrv_connect().

PDO_SQLSRV ignorerar tyst AccessToken i optionsmatrisen

Symptom:

Du har en Microsoft Entra access-token (till exempel från az account get-access-token --resource https://database.windows.net/, , eller ManagedIdentityCredential), och du skickar den till PDO_SQLSRV som ClientSecretCredential i det fjärde konstruktörargumentet['AccessToken' => $token]. Anslutningsförsöket misslyckas med ett förvirrande fel, som Windows logins are not supported in this version of SQL Server eller Login failed for user '', som om inga inloggningsuppgifter angavs.

Orsak:

PDO:s fjärde konstruktörargument är reserverat för drivrutinsspecifika attributkonstanter (heltalsnycklar såsom PDO::ATTR_ERRMODE). PDO släpper tyst strängnyckelposter som AccessToken, så PDO_SQLSRV ser aldrig tokenen. Anslutningen återgår sedan till Windows Integrerad autentisering, som servern avvisar.

Lösningen

Flytta AccessToken till DSN-strängen. Reservera optionsarrayen för PDO::ATTR_* konstanter.

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

För ytterligare exempel på Microsoft Entra autentisering, inklusive DSN-formuläret för PDO_SQLSRV, se Connect using Microsoft Entra authentication.

För procedurkod för SQLSRV ska AccessToken finnas i arrayen med anslutningsinformation som skickas till sqlsrv_connect(), vilket paketerar den råa JWT:n i SQL_COPT_SS_ACCESS_TOKEN åt dig:

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

Fel i TLS-certifikat

Symtom:

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

Lösningar:

Föredra ett betrodd certifikat. Använd TrustServerCertificate=true endast för lokal utveckling mot en server som du kontrollerar.

För utveckling mot ett självsignerat certifikat:

<?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 Inaktiverar validering av servercertifikat. Ta aldrig med den miljön in i produktion, iscensättning eller delade miljöer.

För ett produktionsvärdnamn som inte matchar certifikatets gemensamma namn (till exempel när man ansluter via en lyssnare), ange det faktiska certifikatämnet:

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

Tidsgräns för anslutning

Symtom:

SQLSTATE[HYT00]: Login timeout expired

Möjliga orsaker och lösningar:

  • LoginTimeout ej inställd eller inställd för lågt för kall redundansväxling. Ange LoginTimeout uttryckligen (i sekunder) i DSN:en vid anslutning till Azure SQL. Växlingar i redundansgrupper och kallstartade databaser kan ta längre tid än vad en kort tidsgräns på klientsidan medger. Se anslutningsalternativ för referensen till alternativ.
  • Trunkerad budget för återanslutning vid inaktivitet. Om du sätter ConnectRetryCount och ConnectRetryInterval, se till att LoginTimeout >= ConnectRetryCount * ConnectRetryInterval. Annars avslutas återanslutningsslingan i förtid av tidsgränsen för inloggning. Se Vilolägesanslutningsresiliens.
<?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,
]);

Problem med förfrågningsexekvering

Tysta fel med PDO

Symptom:

Ett PDO::exec()- eller PDOStatement::execute()-anrop returnerar false men kastar inget undantag.

Lösningen

Med PHP 8.0 och senare är PDO::ERRMODE_EXCEPTION standardläget för PDO-felhantering. Om ett anrop återvänder false utan att kasta har applikationen ändrat läget till PDO::ERRMODE_SILENT eller PDO::ERRMODE_WARNING. Återställ den till undantagsläge så att fel utlöser undantag:

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

Om du inte kan ändra läget globalt, kontrollera $conn->errorInfo() (eller $stmt->errorInfo()) efter varje samtal. Matrisen innehåller [SQLSTATE, driver code, driver message].

Ogiltigt objektnamn

Symtom:

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

Möjliga orsaker och lösningar:

  • Fel databaskontext. Verifiera med en snabb fråga:

    <?php
    $stmt = $conn->query("SELECT DB_NAME()");
    echo $stmt->fetchColumn();
    
  • Saknad schema-kvalificerare. Använd fullt kvalificerade namn för att undvika att behöva använda uppringarens standardschema:

    SELECT * FROM dbo.Products;
    
  • Skiftlägeskänslighet. Databaser skapade med en kasuskänslig sortering behandlar products och Products som olika objekt. Matcha det exakta fallet i tabelldefinitionen.

Fel antal parametrar

Symtom:

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

Lösningen

För PDO_SQLSRV måste antalet ? platshållare matcha antalet värden du skickar till execute(), och varje ? binder en enda skalär (inte en array). För namngivna parametrar måste varje :name i SQL visas i matrisen och vice versa.

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

För SQLSRV, skicka parameterarrayen till sqlsrv_query() eller 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));
}

För en bredare introduktion till parameterbindning, se Utför parameteriserade frågor.

PDO-emulerad förbereder maskfel

Symtom:

Ett uttalande körs framgångsrikt på en anslutning men kastar ett syntaxfel på en annan anslutning som använder samma frågetext.

Orsak:

PDO_SQLSRV stöder både emulerade och inbyggda förberedda satser. Emulerade prepare-satser (PDO::ATTR_EMULATE_PREPARES = true) interpolerar parametrar på klientsidan. Native förbereder (false) att skicka frågan och parametrarna separat till servern. Beteendet skiljer sig åt för TOP (?), tabellvärdesparametrar och vissa gränsfall vid typkonvertering.

Lösningen

Föredrar inhemska förberedelser i produktion. Ställ PDO::ATTR_EMULATE_PREPARES => false in vid anslutningstid så att beteendet är konsekvent över miljöer:

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

För information om när du ska använda varje läge, se PDO::prepare.

Datatypproblem

Unicode-tecken visas som ? eller förvrängda

Symtom:

Rader som PHP skriver innehåller frågetecken eller ersättningstecken istället för de ursprungliga icke-ASCII-tecknen. Avläsningar ger förvrängd text.

Möjliga orsaker och lösningar:

  • Kolumntypen är VARCHAR, inte NVARCHAR. varchar-kolumner använder en kodsida, inte Unicode. Använd nvarchar för internationaliserad text.

  • Saknar UTF-8-kodningstips på PDO_SQLSRV. När din SQL Server-kolumn är nvarchar och din PHP-data är UTF-8, be drivrutinen konvertera mellan UTF-8 (klient) och 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-drivrutin: begär explicit UTF-8. SQLSRV_ENC_CHAR är standardkodsidan för 8-bitars systemet, inte UTF-8. För UTF-8 med SQLSRV, ställ in "CharacterSet" => "UTF-8" för anslutningen och skicka literalen 'UTF-8' till SQLSRV_PHPTYPE_STRING vid hämtning eller bindning. Se Skicka och hämta UTF-8-data.

Fel vid konvertering av datum och tid

Symtom:

SQLSTATE[22007]: Invalid character value for cast specification

Lösningen

I PDO_SQLSRV ska du inte binda ett rått DateTime-objekt. PDO stringifierar bundna värden innan bindning, och PHP DateTime har ingen __toString() metod, så execute([new DateTime(...)]) höjer Object of class DateTime could not be converted to string. Formatera värdet först, eller skicka en ISO 8601-sträng (YYYY-MM-DD HH:MM:SS[.fff]), inte en lokalformaterad sträng.

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

För att hämta datetime-kolumner som DateTime objekt istället för strängar på PDO_SQLSRV, sätt attributet statement:

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

För detaljer, se Hämta datumtidsobjekt (PDO_SQLSRV).

Decimalformateringsproblem

Symtom:

Värden mellan -1 och 1 saknar en inledande nolla, eller så visar värdena på pengar och småpengar ett oväntat antal decimaler.

Lösningen

PDO_SQLSRV hämtar alltid decimala och numeriska värden som strängar med exakt precision och skala. Markera PDO::SQLSRV_ATTR_FORMAT_DECIMALS för att lägga till en inledande nolla före värden mellan -1 och 1:

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

PDO::SQLSRV_ATTR_DECIMAL_PLACES gäller endast pengar och småpenningvärden . Den sätter deras visade skala från 0 till 4 och kan avrunda det visade värdet. Det påverkar inte decimala eller numeriska värden.

För detaljer, se Formatera decimaltal och pengar (PDO_SQLSRV) eller Formatera decimaler och pengar (SQLSRV).

Transaktionsproblem

Dataförändringar kvarstår inte

Symtom:

Raderna du infogar eller uppdaterar i PHP visas inte när du frågar från en annan session.

Orsak:

PDO::beginTransaction() öppnar en explicit transaktion som kräver en explicit commit(). Om PHP-skriptet avslutas utan att anropa commit(), rullar PDO tillbaka transaktionen under anslutningsrensningen.

Lösningen

Para alltid beginTransaction() ihop med commit(), och använd try/catch för att rulla tillbaka vid fel:

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

För SQLSRV, använd sqlsrv_begin_transaction, sqlsrv_commit, och sqlsrv_rollback.

Dödlägesfel

Symtom:

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

Lösningen

Hantera tillfälliga deadlock-fel med retry-logik. Omslut hela transaktionen (inte bara den sats som misslyckas) så att tidigare satser körs om i den nya transaktionen. För ett produktionsorienterat återförsöksmönster, se exemplet på PHP-drivrutinens landningssida.

Återkommande dödlägen indikerar ett designproblem. Samla in deadlockdiagrammet och analysera vilka instruktioner och låstyper som ingår. Vanliga lösningar inkluderar omordningsoperationer så att konkurrerande transaktioner får lås i samma sekvens, minska transaktionsomfattningen och lägga till index för att förkorta låsets varaktighet. För en fullständig genomgång, se Deadlocks-guiden.

Problem med anslutningsresiliens

Återanslutning sker inte

Symtom:

En inaktiv anslutning förblir bruten efter en Azure SQL Database-failover, även om du sätter ConnectRetryCount och ConnectRetryInterval.

Möjliga orsaker och lösningar:

  • Aktiv markör på serversidan. Vilolägesresiliens för anslutningar återkopplar bara lediga anslutningar. En öppen markör på serversidan eller en väntande transaktion håller anslutningen aktiv. Frigör server-side-markörer genom att använda sqlsrv_free_stmt() or $stmt = null; (PDO) före failover-fönstret, eller byt till en buffrad kursör på klientsidan. Se Vilolägesanslutningsresiliens.
  • Sessionstillstånd som inte kan återställas. Vissa sessionstillstånd kan inte återställas, inklusive temporära tabeller, globala och lokala markörer, transaktionskontext, applikationslås, EXECUTE AS/REVERTOLE-automationshandtag, förberedda XML-handtag och spårflaggor. Något av dessa sessionstillstånd förhindrar automatisk återanslutning.
  • LoginTimeout för liten. Om ConnectRetryCount * ConnectRetryInterval > LoginTimeout slutar drivrutinen att göra nya försök när LoginTimeout nås. Höj LoginTimeout så att den täcker hela försöksbudgeten.

Prestandaproblem

Information om diagnostisering och åtgärdande av långsamma frågor, kallstarter, stora resultatuppsättningar och massinfogningar finns i Performance tuning.

Aktivera drivrutinsdiagnostik

När applikationsnivåanrop error_log() inte ger tillräckligt med information, slå på loggning på förarsidan. Den rapporterar varje ODBC-samtal som föraren gör.

PDO_SQLSRV

Sätt pdo_sqlsrv.log_severity in php.ini och starta om webbservern. Denna inställning är endast läsbar vid initialisering:

[pdo_sqlsrv]
pdo_sqlsrv.log_severity = 1

Värden är 0 (av, standard), -1 (fel, varningar och meddelanden), 1 (fel), 2 (varningar) och 4 (meddelanden).

SQLSRV

Aktivera loggning vid körning med 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);

Loggposter går till filen konfigurerad av error_log i php.ini. För hela listan över delsystem och allvarlighetsgrader, se Loggningsaktivitet.

Problem med containrar och CI

Saknade systembibliotek på Linux

Symtom:

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

Lösningen

Installera runtime-beroendena innan du installerar PHP-drivrutinen:

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

Installera msodbcsql18 sedan från Microsoft paketförråd. För distributionsspecifika paketarkiv och versioner, se ODBC:s drivrutinsinstallationsguide.

Byggning av Docker-avbildningar lyckas, men anslutningar misslyckas under körning

Symtom:

Avbilden byggs och PHP startar, men PDO::__construct() ger ett ODBC-drivrutinsfelmeddelande.

Lösningen

Verifiera att ODBC-drivrutinen är installerad i runtime-avbilden, inte bara i byggsteget. Installera msodbcsql18 och unixodbc-dev i samma fas som skickas till produktion. I en flerstegsbyggnation, installera dem i slutsteget. En enstegsinstallation baserad på Debian ser ut så här:

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