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 sqlsrv ani pdo_sqlsrv.
  • PDOException: could not find driver při vytváření 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 jak extension=sqlsrv, tak extension=pdo_sqlsrv nejsou zakomentované. 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é. Na hostiteli PHP otestujte přímé připojení TCP.

    # 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í.
  • Upřednostňujte 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 pro ně vyhrazuje druhý a třetí argument konstruktoru a PDO_SQLSRV je interně 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);

Naproti tomu procedurální ovladač SQLSRV přijímá UID a PWD v poli voleb připojení předávaném funkci sqlsrv_connect().

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

Příznaky:

Máte přístupový token Microsoft Entra (například z az account get-access-token --resource https://database.windows.net/, ManagedIdentityCredential nebo ClientSecretCredential) a předáte ho do PDO_SQLSRV jako ['AccessToken' => $token] ve čtvrtém argumentu konstruktoru. 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řesuň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 se AccessToken používá v poli s informacemi o připojení předaném do sqlsrv_connect(); sqlsrv_connect() za vás nezpracovaný token JWT zabalí do 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 se samopodepsaným certifikátem:

<?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 není nastaveno nebo je nastaveno příliš nízko pro cold failover. Nastavte v DSN při připojení k Azure SQL explicitně zadanou hodnotu LoginTimeout (v sekundách). 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í.
  • Limit pro opětovné připojení při nečinnosti byl zkrácen. Pokud nastavíte ConnectRetryCount a ConnectRetryInterval, ujistěte se, že LoginTimeout >= ConnectRetryCount * ConnectRetryInterval. Jinak časový limit přihlášení předčasně ukončí cyklus opětovného připojování. Viz odolnost neaktivního připojení.
<?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í v PDO

Příznaky:

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

Oprava:

V PHP 8.0 a novějších verzích je výchozí chybový režim PDO PDO::ERRMODE_EXCEPTION. Pokud volání vrátí false bez vyvolání, aplikace změní režim na PDO::ERRMODE_SILENT nebo PDO::ERRMODE_WARNING. Přepněte to zpět do režimu výjimek, aby se při selhání vyvolaly 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í kvalifikátor 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é s řazením rozlišujícím malá a velká písmena považují objekty products a Products za odlišné. Dodržte přesně stejné rozlišení velkých a malých písmen jako v 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ástupných symbolů ? odpovídat počtu hodnot, které předáte do execute(), a každý prvek ? váže jednu skalární hodnotu (nikoli pole). 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. Native připravuje (false) a odesílá dotaz a parametry na server samostatně. 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::prepare.

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ů. Operace čtení vracejí nesmyslný 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 v SQL Serveru nvarchar a vaše data v PHP jsou ve formátu UTF-8, řekněte ovladači, aby prováděl převod 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,
        ]
    );
    
  • Ovladač SQLSRV: explicitně vyžadovat UTF-8. SQLSRV_ENC_CHAR je výchozí 8bitová systémová kódová stránka, nikoli UTF-8. Pro UTF-8 v SQLSRV nastavte u připojení "CharacterSet" => "UTF-8" a při načítání nebo svázání předejte do SQLSRV_PHPTYPE_STRING literál 'UTF-8'. 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 navázáním převádí navázané hodnoty na řetězce a DateTime v PHP nemá metodu __toString(), takže execute([new DateTime(...)]) vyvolá 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")]);

Chcete-li v PDO_SQLSRV načítat sloupce datetime jako DateTime objekty místo řetězců, 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 hodnoty typu desítkové ani číselné.

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 párujte beginTransaction() s commit() a používejte try/catch pro vrácení změn zpět při chybě:

<?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 selhávající příkaz), aby se dřívější příkazy zopakovaly v nové 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ých připojení obnovuje připojení pouze pro 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 neaktivního připojení.
  • Neobnovitelný stav relace. 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 opakovat pokusy, jakmile je dosaženo LoginTimeout. Zvyšte LoginTimeout, aby pokryl celý limit opakování.

Problémy s výkonem

Diagnostiku a řešení pomalých dotazů, studeného spuštění, velkých sad výsledků a hromadného vkládání najdete v tématu 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 v php.ini a 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 protokolu se zapisují do souboru nastaveného pomocí error_log v 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í image Dockeru proběhne úspěšně, ale připojení za běhu selhávají

Příznaky:

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

Oprava:

Ověřte, že je ovladač ODBC nainstalován v běhovém obrazu, nejen ve fázi sestavení. Nainstalujte msodbcsql18 a unixodbc-dev ve stejné fázi, která se nasazuje do produkce. 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/*