Vyřešit problémy s Microsoft ovladači pro PHP pro SQL Server

Stáhnout ovladač PHP

Diagnostikujte a řešte běžné problémy, když použijete Microsoft ovladače pro PHP pro SQL Server k připojení k SQL Server, Azure SQL Database, Azure SQL Managed Instance a SQL databázi v Microsoft Fabric.

Pro obecné vzorce zpracování chyb a varování viz Manipulace s chybami a varováními. Pro diagnostické zaznamenání na straně řidiče viz Logovací aktivita.

Problémy s instalací

Rozšíření není načteno

Příznaky:

  • phpinfo() Neuvádí sekci A sqlsrv OR (nebo pdo_sqlsrv sekci).
  • PDOException: could not find driver při konstrukci a PDO s sqlsrv: DSN.
  • Fatal error: Uncaught Error: Call to undefined function sqlsrv_connect().

Možné příčiny a řešení:

  • Rozšíření není povoleno v php.ini. Ověřte, že obě extension=sqlsrv a nekomentované extension=pdo_sqlsrv jsou. Ve Windows použijte celý název souboru (extension=php_sqlsrv_84_ts_x64.dll). Podrobnosti najdete v článku Načítání ovladačů.
  • Špatná bezpečnostní konstrukce závitu. Binární ovladač musí odpovídat bezpečnosti vláken vašeho PHP buildu (ts pro thread-safe, nts pro non-thread-safe). Spusťte php -i | grep "Thread Safety" ke kontrole. Stáhněte si odpovídající binární soubor ze stránky ke stažení.
  • Chybí ovladač Microsoft ODBC. PHP ovladače obalují ovladač Microsoft ODBC pro SQL Server. Na Linuxu a macOS nainstalujte msodbcsql18 (nebo msodbcsql17) ve správci balíčků před načtením rozšíření. Na Windows nainstalujte ovladač ODBC ze stránky ke stažení.

Ověřte úspěšnou instalaci:

php -m | grep -i sqlsrv

Měli byste vidět obojí pdo_sqlsrv i sqlsrv ve výstupu.

Instalace PECL selže na Linuxu nebo macOS

Příznaky:

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

Oprava:

Před spuštěním pecl installnainstalujte vývojové hlavičky ODBC:

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

Pak to zkuste znovu:

sudo pecl install sqlsrv
sudo pecl install pdo_sqlsrv

Pokud pecl selže i po instalaci hlaviček, může být řetězec stavebních nástrojů neúplný. Nainstalujte phpize, re2c, a C++ kompilátor (build-essential na Debianu a Ubuntu, gcc-c++ make na Red Hat a Fedora, build-base na Alpine).

Pro kompletní instalační cestu viz Instalační tutoriál pro Linux a macOS.

Více nainstalovaných verzí PHP

Příznaky:

phpinfo() na vašem webovém serveru se zobrazí jedna verze PHP, ale php -v v příkazovém řádku se zobrazí jiná a ovladač se zobrazí načtený pouze v jedné z nich.

Oprava:

Každá verze PHP má svůj vlastní php.iniext adresář. Najděte správný konfigurační soubor php --ini přímo v prostředí, kde chybí ovladač, a přidejte tam řádky extension= . Po jakékoliv změně php.ini restartujte webový server (Apache, Nginx + PHP-FPM nebo IIS).

Problémy s připojením

Nelze se připojit k serveru

Příznaky:

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

Možné příčiny a řešení:

  • Server není dostupný. Zkontrolujte, že název serveru a port jsou správné. Z PHP hostitele testujte surové TCP připojení.

    # Linux and macOS
    nc -vz <server>.database.windows.net 1433
    
    # Windows PowerShell
    Test-NetConnection -ComputerName <server>.database.windows.net -Port 1433
    
  • Firewall blokuje odchozí 1433. Firemní firewally a cloudové NSG často blokují odchozí port 1433. Přidejte výjimku nebo povolte IP rozsahy Azure SQL Database pro váš region.

  • Azure SQL server firewall. Přidejte veřejnou IP adresu svého klienta do serverových firewallových pravidel v Azure portálu.

  • Jmenovaná instance. Pro pojmenovanou instanci ověřte, že služba SQL Server Browser běží na serveru a že je otevřený UDP 1434. Nebo se připojit podle portu místo podle názvu instance.

Přihlášení se nezdařilo.

Příznaky:

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

Možné příčiny a řešení:

  • Režim SQL autentizace zakázán. Lokální instance SQL Server automaticky používají pouze Windows Authentication. Povolte autentizaci v režimu smíšeného režimu v SQL Server Management Studio v sekci>Bezpečnost a poté restartujte službu SQL Server.
  • Azure SQL credentials format. Azure SQL vyžaduje plně kvalifikované uživatelské jméno (user@servername) při připojování z nástrojů, které jej nepřidávají automaticky.
  • Uživatel není přiřazen k databázi. Ověřte, že přihlášení má uživatele mapované v cílové databázi a že uživatel má požadovaná oprávnění.
  • Preferuji Microsoft Entra ID. Pro Azure SQL, Azure SQL Managed Instance a SQL databáze ve Fabric používají Microsoft Entra autentizaci (Authentication=ActiveDirectoryMsi, Authentication=ActiveDirectoryServicePrincipal, nebo access token) místo SQL přihlášení. Viz Připojení pomocí ověřování Microsoft Entra.

Neplatná hodnota určená pro atribut připojovací řetězec 'Authentication'

Příznaky:

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

Příčina:

Ovladač ODBC hlásí chybu, ale skutečný problém je, na který ovladač PDO_SQLSRV vázaný. Pokud DSN neobsahuje klíčové slovo Driver= a hostitel má nainstalované jak ODBC 17, tak ODBC 18, PDO_SQLSRV může navázat na starší verzi. Starší verze ODBC 17.x neznají novější Authentication hodnoty jako ActiveDirectoryServicePrincipal nebo ActiveDirectoryDefault, a dokonce ActiveDirectoryMsi vyžadují ODBC 17.3.1.1 nebo pozdější verzi.

Oprava:

Připněte ovladač do 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]);

Závorkový tvar ({ODBC Driver 18 for SQL Server}) uniká mezerám v jménu jezdce. Chybová zpráva sama o sobě vždy uvádí ovladač, který ji nahlásil, takže předpona [Microsoft][ODBC Driver 17 for SQL Server] v chybě je nejrychlejší způsob, jak potvrdit nesprávnou hranici ovladače.

V řetězci DSN bylo uvedeno neplatné klíčové slovo 'UID'

Příznaky:

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

Příčina:

PDO_SQLSRV vynucuje povolený seznam klíčových slov DSN a nepřijímá UID ani PWD v DSN. PDO si vyhrazuje argumenty druhého a třetího konstruktora pro tyto PDO_SQLSRV a interně je překládá do ODBC UID/PWD .

Oprava:

Přesunout uživatelské jméno (a heslo pro SQL autentizaci) do konstruktoru 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);

Naopak procedurální ovladač SQLSRV přijímá UID a PWD v poli možností spojení je předán do sqlsrv_connect().

PDO_SQLSRV tiše ignoruje AccessToken v poli možností

Příznaky:

Máte Microsoft Entra přístupový token (například z az account get-access-token --resource https://database.windows.net/, , nebo ClientSecretCredential), a předáte ho PDO_SQLSRV jako ['AccessToken' => $token] ve čtvrtém konstruktorovém ManagedIdentityCredentialargumentu. Pokus o spojení selže s matoucí chybou jako Windows logins are not supported in this version of SQL Server nebo Login failed for user '', jako by nebyly zadány žádné přihlašovací údaje.

Příčina:

Čtvrtý konstruktorský argument PDO je vyhrazen pro specifické atributové konstanty ovladače (celočíselné klíče jako PDO::ATTR_ERRMODE). PDO tiše opouští položky s řetězcovým klíčem, jako je AccessToken, takže PDO_SQLSRV token nikdy nevidí. Připojení se pak vrací zpět k Windows Integrated authentication, kterou server odmítá.

Oprava:

Přejděte AccessToken do řetězce DSN. Pole možností si vyhraďte pro PDO::ATTR_* konstanty.

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

Pro další příklady autentizace Microsoft Entra, včetně formuláře DSN pro PDO_SQLSRV, viz Připojit pomocí Microsoft Entra autentizace.

Pro procedurální SQLSRV patří AccessToken do pole connection info předaného do sqlsrv_connect(), které pro vás zabalí surový JWT SQL_COPT_SS_ACCESS_TOKEN :

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

Chyby TLS certifikátů

Příznaky:

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

Řešení:

Preferujte důvěryhodný certifikát. Používejte TrustServerCertificate=true pouze pro lokální vývoj na serveru, který ovládáte.

Pro vývoj proti samopodepsanému certifikátu:

<?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 Vypíná ověřování serverových certifikátů. Nikdy toto nastavení nepřenášejte do produkce, stagingu nebo sdílených prostředí.

Pro produkční hostitelské jméno, které neodpovídá Common Name certifikátu (například při připojení přes posluchač), uveďte skutečný subjekt certifikátu:

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

Časový limit připojení vypršel

Příznaky:

SQLSTATE[HYT00]: Login timeout expired

Možné příčiny a řešení:

  • LoginTimeout Nenastavil jsem ani nebyl příliš nízký pro studený failover. Nastavte explicitní LoginTimeout (během sekund) v DSN při připojení k Azure SQL. Failover-group failovery a cold-start databáze mohou trvat déle, než umožňuje krátký timeout na straně klienta. Viz možnosti připojení pro referenci možností.
  • Nečinné znovupřipojení rozpočtu zkráceno. Pokud nastavíte ConnectRetryCount a ConnectRetryInterval, ujistěte se, že LoginTimeout >= ConnectRetryCount * ConnectRetryInterval. Jinak timeout přihlášení ukončí smyčku opětovného připojení dříve. Viz odolnost nečinnosti spojení.
<?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émy s prováděním dotazů

Tichá selhání s PDO

Příznaky:

Volání PDO::exec() nebo PDOStatement::execute() se vrátí, false ale nehodí výjimku.

Oprava:

U verzí PHP 8.0 a novějších je výchozím chybovým režimem PDO::ERRMODE_EXCEPTIONPDO . Pokud volání vrátí false bez vyvolání, aplikace změní režim na PDO::ERRMODE_SILENT nebo PDO::ERRMODE_WARNING. Nastavte zpět do režimu výjimek, aby selhání vyvolala výjimky:

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

Pokud nemůžeš režim globálně změnit, zkontroluj $conn->errorInfo() (nebo $stmt->errorInfo()) po každém hovoru. Pole obsahuje [SQLSTATE, driver code, driver message].

Neplatný název objektu

Příznaky:

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

Možné příčiny a řešení:

  • Špatný kontext databáze. Ověřte si rychlým dotazem:

    <?php
    $stmt = $conn->query("SELECT DB_NAME()");
    echo $stmt->fetchColumn();
    
  • Chybí kvalifikace schématu. Používejte plně kvalifikovaná jména, abyste se vyhnuli závislosti na výchozím schématu volajícího:

    SELECT * FROM dbo.Products;
    
  • Rozlišování velkých a malých písmen. Databáze vytvořené pomocí třídění rozlišujících písmena (case-cutit) považují products a Products za různé objekty. Přesně odpovídat definici tabulky.

Špatný počet parametrů

Příznaky:

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

Oprava:

Pro PDO_SQLSRV musí počet ? zástupců odpovídat počtu hodnot, které předáte do execute(), a každý z nich ? je přiřazen k jednomu skaláru (nikoli poli). Pro pojmenované parametry musí každý :name v SQL být v poli a naopak.

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

Pro SQLSRV předáme pole parametrů do sqlsrv_query() nebo 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));
}

Pro širší úvod do vázání parametrů viz Provádět parametrizované dotazy.

Emulované PDO připravuje chyby masky

Příznaky:

Příkaz se úspěšně spustí na jednom spojení, ale na jiném spojení, které používá stejný dotaz, vyhodí syntaktickou chybu.

Příčina:

PDO_SQLSRV podporuje jak emulované, tak nativně připravené výroky. Emulovaný připravuje (PDO::ATTR_EMULATE_PREPARES = true) interpolaci parametrů na straně klienta. Nativní připravuje (false) odesílá dotaz a parametry samostatně serveru. Chování se liší pro TOP (?), tabulkové parametry a některé okrajové případy u typové nátlakové práce.

Oprava:

Preferuji domácí přípravky ve výrobě. Nastavte PDO::ATTR_EMULATE_PREPARES => false na čas připojení, aby chování bylo konzistentní napříč prostředím:

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

Podrobnosti o tom, kdy použít jednotlivé režimy, viz PDO::p repare.

Problémy s datovými typy

Unicode znaky se objevují jako ? nebo jsou zkreslené

Příznaky:

Řádky, které PHP zapisuje, obsahují otazníky nebo náhradní znaky místo původních ne-ASCII znaků. Čte a vrací zkreslený text.

Možné příčiny a řešení:

  • Typ sloupce je VARCHAR, ne NVARCHAR. Sloupce varchar používají kódovou stránku, ne Unicode. Používejte nvarchar pro internacionalizované texty.

  • Chybí nápověda k kódování UTF-8 na PDO_SQLSRV. Když je váš sloupec SQL Server nvarchar a vaše PHP data jsou UTF-8, řekněte ovladači, aby převedl mezi UTF-8 (klient) a 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 ovladač: explicitně požádat o UTF-8. SQLSRV_ENC_CHAR je výchozí 8bitová systémová kódová stránka, nikoli UTF-8. Pro UTF-8 se SQLSRV nastavte "CharacterSet" => "UTF-8" na spojení a předejte literál 'UTF-8' na SQLSRV_PHPTYPE_STRING on fetch nebo bind. Viz Odesílat a získat data UTF-8.

Chyby při převodu data a času

Příznaky:

SQLSTATE[22007]: Invalid character value for cast specification

Oprava:

Na PDO_SQLSRV nepřiplétejte surový DateTime objekt. PDO před vázáním stringuje hodnoty mezí a PHP nemá DateTime__toString() žádnou metodu, takže execute([new DateTime(...)]) zvyšuje Object of class DateTime could not be converted to string. Nejprve naformátujte hodnotu, nebo předejte řetězec ISO 8601 (YYYY-MM-DD HH:MM:SS[.fff]), nikoli řetězec formátovaný lokálně.

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

Pro načtení sloupců datetime jako DateTime objektů místo řetězců na PDO_SQLSRV nastavte atribut příkazu:

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

Podrobnosti viz Retrive datetime objects (PDO_SQLSRV).

Problémy s desetinným formátováním

Příznaky:

Hodnoty mezi -1 a 1 postrádají úvodní nulu, nebo hodnoty peněz a malých peněz ukazují neočekávaný počet desetinných míst.

Oprava:

PDO_SQLSRV vždy načítá desetinnéa číselné hodnoty jako řetězce s jejich přesnou přesností a měřítkem. Nastavte PDO::SQLSRV_ATTR_FORMAT_DECIMALS tak, aby se k hodnotám mezi -1 a 1 přidala vedoucí nula:

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

PDO::SQLSRV_ATTR_DECIMAL_PLACES Platí pouze pro peníze a hodnoty malých peněz . Nastaví jejich zobrazovanou škálu od 0 do 4 a může zaokrouhlit zobrazenou hodnotu. Neovlivňuje todesetinné ani číselné hodnoty.

Pro podrobnosti viz Formát desetinných čísel a peněz (PDO_SQLSRV) nebo Formát desetinných čísel a peněz (SQLSRV).

Transakční problémy

Změny dat nepřetrvávají

Příznaky:

Řádky, které vložíte nebo aktualizujete v PHP, se při dotazování z jiné relace nezobrazí.

Příčina:

PDO::beginTransaction() otevírá explicitní transakci, která vyžaduje explicitní commit(). Pokud PHP skript skončí bez volání commit(), PDO během čištění spojení transakci vrátí zpět.

Oprava:

Vždy spárujte beginTransaction() s commit(), a použijte try/catch k vrácení chyby:

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

Pro SQLSRV použijte sqlsrv_begin_transaction, sqlsrv_commit, a sqlsrv_rollback.

Chyby zablokování

Příznaky:

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

Oprava:

Řeší přechodné chyby mrtvého bloku pomocí logiky opakovaného pokusu. Obalte celou transakci (nejen příkaz failing), aby se dřívější příkazy přehrály na čerstvé transakci. Pro produkčně orientovaný vzor opakování se podívejte na ukázku na landing stránce ovladačů PHP.

Opakující se patové situace naznačují problém v návrhu. Zachyťte graf zablokování a analyzujte, které příkazy a typy zámků jsou zapojeny. Běžné opravy zahrnují přeuspořádání operací, aby konkurenční transakce získaly zámky ve stejné sekvenci, což omezuje rozsah transakcí a přidává indexy ke zkrácení doby zámku. Pro kompletní návod viz průvodce Deadlocks.

Problémy s odolností spojení

Obnovení kontaktu se nestane

Příznaky:

Nečinné spojení zůstává přerušené po failoveru Azure SQL Database, i když nastavíte ConnectRetryCount a ConnectRetryInterval.

Možné příčiny a řešení:

  • Aktivní kurzor na straně serveru. Odolnost nečinného připojení znovu připojuje pouze nečinná připojení. Otevřený kurzor na straně serveru nebo čekající transakce udržuje spojení aktivní. Uvolnit kurzory na straně serveru použitím sqlsrv_free_stmt() or $stmt = null; (PDO) před oknem failover, nebo přepnout na kurzor s bufferem na straně klienta. Viz odolnost nečinnosti spojení.
  • Stav relace neobnovitelný. Některé stavy relace nelze obnovit, včetně dočasných tabulek, globálních a lokálních kurzorů, transakčního kontextu, aplikačních zámků, EXECUTE AS/REVERT, automatizačních rukojetí OLE, připravených XML rukojetí a trasovacích příznaků. Jakýkoli z těchto stavů relace zabraňuje automatickému opětovnému připojení.
  • LoginTimeout Příliš malé. Pokud ConnectRetryCount * ConnectRetryInterval > LoginTimeout, ovladač přestane znovu zkoušet, jakmile LoginTimeout je dosaženo. Zvýšte, LoginTimeout abyste pokryli celý rozpočet na opakování.

Problémy s výkonem

Pro diagnostiku a nápravu pomalých dotazů, studených startů, velkých sad výsledků a hromadných vkladů viz Performance tuning.

Zapněte diagnostiku ovladačů

Když volání na úrovni error_log() aplikací neposkytují dostatek informací, zapněte logování na straně řidiče. Hlásí každý hovor ODBC, který řidič uskuteční.

PDO_SQLSRV

Nastavte pdo_sqlsrv.log_severity a php.ini restartujte webový server. Toto nastavení je čitelné pouze při inicializaci:

[pdo_sqlsrv]
pdo_sqlsrv.log_severity = 1

Hodnoty jsou 0 (vypnuto, výchozí -1 ), (chyby, varování a upozornění), 1 (chyby), 2 (varování) a 4 (oznámení).

SQLSRV

Povolte logování za běhu pomocí 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);

Záznamy v logu vedou do souboru nakonfigurovaného v error_log .php.ini Pro úplný seznam podsystémů a závažností viz Logovací aktivita.

Problémy s kontejnery a CI

Chybějící systémové knihovny na Linuxu

Příznaky:

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

Oprava:

Nainstalujte runtime závislosti před instalací PHP ovladače:

Distribuce Instalační příkaz
Ubuntu a Debian sudo apt-get install unixodbc libgssapi-krb5-2
Red Hat a Fedora sudo dnf install unixODBC krb5-libs
Alpský apk add unixodbc gcompat

Pak instaluj msodbcsql18 z Microsoft repozitáře balíčků. Pro repozitáře a verze balíčků specifických pro distribuci viz instalační průvodce ovladači ODBC.

Sestavení docker image uspěje, ale připojení selhává za běhu

Příznaky:

Obraz se nahromadí a spustí PHP, ale PDO::__construct() zobrazí chybu ODBC driver-not-found.

Oprava:

Ověřte, že ODBC ovladač je nainstalován v runtime obrazu, nejen ve fázi sestavování. Instalace msodbcsql18 a unixodbc-dev ve stejné fázi, která se odesílá do výroby. Při vícestupňové výstavbě je instalujte až ve finální fázi. Jednofázová instalace založená na Debianu vypadá takto:

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