Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Diagnosztizáld és oldd meg a gyakori problémákat, amikor a Microsoft Drivers for PHP for SQL Server segítségével csatlakozol az SQL Server-hez, Azure SQL Database-hez, Azure SQL Managed Instance-hoz és SQL database-hez Microsoft Fabric.
Általános hiba- és figyelmeztetéskezelési mintákért lásd: Kezelési hibák és figyelmeztetések. Az illesztőprogram-oldali diagnosztikai adatok rögzítésével kapcsolatban lásd: Naplózási tevékenység.
Telepítési problémák
A kiterjesztés nincs betöltve
Tünetek:
-
phpinfo()nem sorol felsqlsrvvagypdo_sqlsrvszakaszt. -
PDOException: could not find driveregyPDOlétrehozásakor asqlsrv:DSN használatával. -
Fatal error: Uncaught Error: Call to undefined function sqlsrv_connect().
Lehetséges okok és megoldások:
-
A kiterjesztés nincs engedélyezve a php.ini fájlban. Ellenőrizd, hogy a
extension=sqlsrvés aextension=pdo_sqlsrvegyaránt nincs kikommentelve. Windows-on használd a teljes fájlnevet (extension=php_sqlsrv_84_ts_x64.dll). Részletekért lásd: A driverek betöltése. -
Rossz menetes biztonsági build. Az illesztőprogram bináris fájljának meg kell egyeznie a PHP-build szálbiztonsági beállításával (
tsszálbiztoshoz,ntsnem szálbiztoshoz). Futtassaphp -i | grep "Thread Safety"az ellenőrzéshez. Töltsd le a megfelelő bináris fájlt a letöltési oldalról. -
Microsoft ODBC drivere hiányzik. A PHP illesztőprogramok a Microsoft ODBC Driver for SQL Server köré épülnek. Linuxon és macOS-en telepíts
msodbcsql18(vagymsodbcsql17) a csomagkezelőddel, mielőtt betöltöd a bővítményeket. Windows-on telepítsd az ODBC illezőprogramot a letöltési oldalról.
Ellenőrizd a sikeres telepítést:
php -m | grep -i sqlsrv
A kimenetben mind a pdo_sqlsrv-nak, mind a sqlsrv-nek meg kell jelennie.
A PECL vagy PIE telepítés megbukik Linuxon vagy macOS-en
Tünetek:
error: ‘SQL_HANDLE_DBC’ undeclared (first use in this function)
fatal error: 'sql.h' file not found
Javítás:
Telepítsd az ODBC fejlesztői fejléceket az illesztőprogramok telepítése előtt:
-
Ubuntu és Debian:
sudo apt-get install unixodbc-dev -
Red Hat, Fedora és CentOS:
sudo dnf install unixODBC-devel -
Alpine:
apk add unixodbc-dev -
macOS:
brew install unixodbc
Apple siliconon a fejlécek önmagukban nem elegendőek. A Homebrew az unixODBC-t a /opt/homebrew alá telepíti, ami nem része a fordító alapértelmezett keresési útvonalának, ezért a build ugyanazzal a hibával meghiúsul, még akkor is, ha a fejlécfájlok is jelen vannak. Állítsd be a fordító zászlókat, mielőtt újra próbálkozol:
export CPPFLAGS="-I/opt/homebrew/opt/unixodbc/include/"
export LDFLAGS="-L/opt/homebrew/lib/"
Majd próbálkozz újra PIE-vel:
pie install microsoft/sqlsrv
pie install microsoft/pdo_sqlsrv
Vagy a PECL-rel:
sudo pecl install sqlsrv
sudo pecl install pdo_sqlsrv
Ha a telepítés még mindig kudarcot vall a fejlécek telepítése után, az építőeszköz-lánc hiányos lehet. Telepítsd phpize, re2c, és egy C++ fordítót (build-essential Debianon és Ubuntun, gcc-c++ make Red Haten és Fedorán, build-base Alpine-on). A PIE felajánlja, hogy telepítheti a hiányzó build-eszközöket Linuxon és macOS-en.
A teljes telepítési útvonalért lásd a Linux és macOS telepítési útmutatóját.
Több PHP verzió telepítve
Tünetek:
phpinfo() a webszerveren egy adott PHP-verziót mutat, de php -v a parancssorban egy másikat, és az illesztőprogram csak az egyikben tűnik betöltöttnek.
Javítás:
Minden PHP verziónak megvan a maga php.ini és ext a könyvtára. Keresd meg a megfelelő konfigurációs fájlt php --ini abban a környezetben, ahol hiányzik az illesztőprogram, és add hozzá a extension= sorokat oda. Indítsd újra a webszervert (Apache, Nginx + PHP-FPM vagy IIS) bármilyen php.ini változás után.
Csatlakozási problémák
Nem tudok csatlakozni a szerverhez
Tünetek:
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
Lehetséges okok és megoldások:
A szerver nem elérhető. Ellenőrizd, hogy a szerver neve és a port helyes-e. A PHP hosztról teszteld a nyers TCP kapcsolatot.
# Linux and macOS nc -vz <server>.database.windows.net 1433 # Windows PowerShell Test-NetConnection -ComputerName <server>.database.windows.net -Port 1433A tűzfal blokkolja a 1433-as kimenő vonalat. Vállalati tűzfalak és felhőalapú NSG-k gyakran blokkolják a 1433-as kimenő portot. Adj meg kivételt, vagy engedélyezd az Azure SQL Database IP tartományokat a régiódban.
Azure SQL server firewall. Csatolja az ügyfele nyilvános IP-címét a szerverszintű tűzfal szabályaihoz az Azure portálban.
Elnevezett példány. Elnevezett példány esetén ellenőrizd, hogy az SQL Server Browser szolgáltatás fut-e a kiszolgálón, és hogy az 1434-es UDP-port nyitva van-e. Vagy csatlakozzon port használatával példánynév helyett.
A bejelentkezés sikertelen
Tünetek:
SQLSTATE[28000]: [Microsoft][ODBC Driver 18 for SQL Server][SQL Server]Login failed for user '<user_id>'.
Lehetséges okok és megoldások:
- Az SQL hitelesítési mód letiltva. A helyi SQL Server példányok alapértelmezetten csak a Windows hitelesítést használják. Engedélyezze a vegyes módú hitelesítést az SQL Server Management Studio-ban a Server properties>Security alatt, majd indítsa újra az SQL Server szolgáltatást.
-
Azure SQL credentials format. Az Azure SQL-hez a teljes minősítésű felhasználónév (
user@servername) szükséges, amikor olyan eszközökből csatlakozunk, amelyek nem csatolják automatikusan hozzá. - A felhasználó nincs adatbázishoz rendelve. Ellenőrizd, hogy a bejelentkezésnek van felhasználói leképezése a cél adatbázisban, és hogy a felhasználónak megvannak a szükséges jogosultságai.
-
Preferálom a Microsoft Entra ID-t. Azure SQL, Azure SQL Managed Instance és SQL database Fabric-ben használjunk Microsoft Entra hitelesítést (
Authentication=ActiveDirectoryMsi,Authentication=ActiveDirectoryServicePrincipal, vagy access tokent) SQL bejelentkezések helyett. Lásd : Csatlakozás Microsoft Entra-hitelesítéssel.
Érvénytelen érték a kapcsolati karakterlánc attribútumához 'Authentication'
Tünetek:
SQLSTATE[08001]: [Microsoft][ODBC Driver 17 for SQL Server]Invalid value specified for connection string attribute 'Authentication'
Ok:
Az ODBC-illesztőprogram jelzi a hibát, de a valódi probléma az, hogy a PDO_SQLSRV melyik illesztőprogramhoz van kötve. Ha a DSN nem tartalmaz Driver= kulcsszót, és a hoszt telepítve van ODBC 17 és ODBC 18 is, akkor PDO_SQLSRV kapcsolódhat a régebbi verzióhoz. A régebbi ODBC 17.x kiadások nem ismerik az újabb Authentication értékeket, például a ActiveDirectoryServicePrincipal vagy a ActiveDirectoryDefault értéket, és még a ActiveDirectoryMsi is csak az ODBC 17.3.1.1-es vagy újabb verziótól érhető el.
Javítás:
Rögzítse az illesztőprogramot a DSN-ben:
<?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]);
A zárójeles alak ({ODBC Driver 18 for SQL Server}) kilép a meghajtó nevében lévő közközökből. Maga a hibaüzenet mindig megnevezi azt az illesztőprogramot, amely jelezte a hibát, így a hibaüzenetben szereplő [Microsoft][ODBC Driver 17 for SQL Server] előtag a leggyorsabb módja annak megerősítésére, hogy nem a megfelelő illesztőprogram kapcsolódott hozzá.
A DSN stringben az érvénytelen 'UID' kulcsszó volt megadva
Tünetek:
SQLSTATE[IMSSP]: An invalid keyword 'UID' was specified in the DSN string.
Ok:
A PDO_SQLSRV csak az engedélyezett DSN-kulcsszavakat fogadja el, és nem fogadja el a DSN-ben a UID vagy a PWD elemet. A PDO a második és harmadik konstruktorargumentumot erre a célra fenntartja, a PDO_SQLSRV pedig ezeket belsőleg ODBC UID/PWD értékekre fordítja.
Javítás:
Mozgasd át a felhasználónevet (és jelszót az SQL hitelesítéshez) a PDO konstruktorba:
<?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);
Az SQLSRV eljárásalapú illesztőprogram ezzel szemben elfogadja a sqlsrv_connect() függvénynek átadott kapcsolódási beállításokat tartalmazó tömbben a UID és PWD elemeket.
PDO_SQLSRV csendben figyelmen kívül hagyja az AccessToken-t az opciók tömbjében
Tünet:
Van egy Microsoft Entra hozzáférési tokened (például , az account get-access-token --resource https://database.windows.net/ManagedIdentityCredential, vagy ClientSecretCredential), és azt továbbítod PDO_SQLSRV-nek, mint ['AccessToken' => $token] a negyedik konstruktor érvelésben. A kapcsolódási kísérlet egy félreérthető hibaüzenettel, például Windows logins are not supported in this version of SQL Server vagy Login failed for user '' üzenettel meghiúsul, mintha nem adtak volna meg hitelesítő adatokat.
Ok:
A PDO negyedik konstruktorparamétere az illesztőprogram-specifikus attribútumkonstansok számára van fenntartva (egész szám típusú kulcsok, például PDO::ATTR_ERRMODE). A PDO csendben dobja el a string-kulcsos bejegyzéseket, mint AccessTokenpéldául , így PDO_SQLSRV soha nem látja a tokent. A kapcsolat ezután visszakerül a Windows integrált hitelesítésre, amit a szerver elutasít.
Javítás:
Helyezze át a(z) AccessToken elemet a DSN-karakterláncba. Tartsd fenn az opciótömböt a PDO::ATTR_* konstansok számára.
<?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,
]);
További Microsoft Entra hitelesítési példákért, beleértve a DSN űrlapot PDO_SQLSRV lásd: Kapcsolódj Microsoft Entra hitelesítés segítségével.
Az SQLSRV procedurális API esetén a AccessToken a sqlsrv_connect() függvénynek átadott kapcsolatinformációs tömbbe tartozik, amely helyetted a nyers JWT-t SQL_COPT_SS_ACCESS_TOKEN-be ágyazza be:
<?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 tanúsítvány hibák
Tünetek:
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
Megoldások:
Inkább megbízható tanúsítványt preferálok.
TrustServerCertificate=true Csak helyi fejlesztésre használd egy olyan szerver ellen, amit te irányítasz.
Önként aláírt tanúsítvány elleni fejlesztéshez:
<?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,
]);
Figyelmeztetés
TrustServerCertificate=true Letiltja a szerver tanúsítvány ellenőrzését. Soha ne vigye ezt a környezetet a gyártásba, a színpadi vagy megosztott környezetbe.
Ha az éles hosztnév nem egyezik meg a tanúsítvány Common Name (CN) mezőjével (például ha figyelőn keresztül csatlakozik), adja meg a tanúsítvány tényleges alanyát:
<?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,
]);
Kapcsolati időkorlát
Tünetek:
SQLSTATE[HYT00]: Login timeout expired
Lehetséges okok és megoldások:
-
LoginTimeoutNem állítva vagy túl alacsonyan a hideg failoverhez. Állíts be egy explicitLoginTimeoutértéket (másodpercben) a DSN-ben az Azure SQL-hez való csatlakozáskor. A feladatátvételi csoportok feladatátvétele és a hidegen indított adatbázisok több időt vehetnek igénybe, mint amennyit egy rövid ügyféloldali időtúllépés lehetővé tesz. Az opció hivatkozásáért lásd a Csatlakozási opciókat . -
Alapjárati újrakapcsolás költségvetése lerövidítve. Ha beállítod
ConnectRetryCountésConnectRetryInterval, győződj megLoginTimeout >= ConnectRetryCount * ConnectRetryIntervalróla. Ellenkező esetben a bejelentkezési időkorlát korán véget vet a visszakapcsolási ciklusnak. Lásd: Tétlen kapcsolati rezisztens.
<?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,
]);
Lekérdezés végrehajtási problémái
Csendes hibák a PDO használata során
Tünet:
A PDO::exec() vagy PDOStatement::execute() hívás false értéket ad vissza, de nem dob kivételt.
Javítás:
A PHP 8.0-s és újabb verziókban az alapértelmezett PDO hibamód a PDO::ERRMODE_EXCEPTION. Ha egy hívás visszatér false küldés nélkül, az alkalmazás megváltoztatja a módot vagy PDO::ERRMODE_SILENTPDO::ERRMODE_WARNING-re. Állítsuk vissza kivételmódba, hogy a hibák kivételt váltsanak ki:
<?php
$conn = new PDO($dsn, $user, $password, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);
Ha nem tudod globálisan megváltoztatni a módot, ellenőrizd $conn->errorInfo() (vagy $stmt->errorInfo()) minden hívás után. A tömb tartalmazza [SQLSTATE, driver code, driver message].
Érvénytelen objektumnév
Tünetek:
SQLSTATE[42S02]: [Microsoft][ODBC Driver 18 for SQL Server][SQL Server]Invalid object name 'Products'.
Lehetséges okok és megoldások:
Rossz adatbázis kontextus. Ellenőrizd egy gyors lekérdezéssel:
<?php $stmt = $conn->query("SELECT DB_NAME()"); echo $stmt->fetchColumn();Hiányzik a séma kvalifikátor. Használj teljesen minősített neveket, hogy ne a hívó alapértelmezett sémájától függj:
SELECT * FROM dbo.Products;Kiszámíthatóság érzékenysége. A kis- és nagybetűket megkülönböztető rendezéssel létrehozott adatbázisok a(z)
productsésProductselemeket különböző objektumokként kezelik. Egyeztess pontosan a táblázat definíciójában szereplő esetet.
Rossz számú paraméter
Tünetek:
SQLSTATE[HY093]: Invalid parameter number
SQLSTATE[07002]: COUNT field incorrect or syntax error
Javítás:
PDO_SQLSRV esetén a ? helykitöltők számának egyeznie kell a execute() számára átadott értékek számával, és minden ? egyetlen skalár értéket köt hozzá (nem tömböt). A nevelt paraméterekhez az SQL-ben minden :name szereplőnek meg kell jelennie a tömbben, és fordítva.
<?php
$stmt = $conn->prepare(
"SELECT * FROM dbo.Products WHERE CategoryID = ? AND ListPrice > ?"
);
$stmt->execute([1, 50.0]);
foreach ($stmt as $row) {
// ...
}
SQLSRV esetén adja át a paramétertömböt a(z) sqlsrv_query() vagy sqlsrv_prepare() függvénynek:
<?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));
}
A paraméterkötés szélesebb körű bevezetéséért lásd: Paraméterezett lekérdezések végrehajtása.
A PDO emulált előkészíti a maszkhibákat
Tünetek:
Egy utasítás sikeresen lefut az egyik kapcsolatban, de egy másik, ugyanazt a lekérdezésszöveget használó kapcsolatban szintaktikai hibát eredményez.
Ok:
PDO_SQLSRV támogatja mind az emulált, mind a natív előkészített állításokat. Az emulált előkészített utasítások (PDO::ATTR_EMULATE_PREPARES = true) kliensoldalon interpolálják a paramétereket. A natív előkészíti (false) a lekérdezést és a paramétereket külön elküldi a szervernek. A viselkedés eltér a TOP (?), a táblázatértékű paraméterek és a típuskonverzió egyes szélső esetei esetében.
Javítás:
Előnyben részesítem a termelés során lévő őshonos készítményeket. A csatlakozási időre állítsuk PDO::ATTR_EMULATE_PREPARES => false be, hogy a viselkedés konzisztens legyen a környezetek között:
<?php
$conn = new PDO($dsn, null, null, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_EMULATE_PREPARES => false,
]);
Az egyes módok használatának részleteiről lásd: PDO::prepare.
Adattípus-problémák
Unicode karakterek úgy jelennek meg, mint ? vagy zavaros módon
Tünetek:
A PHP által írt sorok kérdőjeleket vagy helyettesítő karaktereket tartalmaznak az eredeti nem ASCII karakterek helyett. Az olvasási műveletek értelmezhetetlen szöveget eredményeznek.
Lehetséges okok és megoldások:
Az oszlop típusa VARCHAR, nem NVARCHAR. a varchar oszlopok kódlapot használnak, nem Unicode-ot. Használd a nvarchart nemzetköziített szöveghez.
Hiányzik az UTF-8 kódolási tipp PDO_SQLSRV-n. Ha az SQL Server oszlopod nvarchar, és a PHP adataid UTF-8, mondd meg a drivernek, hogy konvertáljon UTF-8 (kliens) és UTF-16 (szerver) között:
<?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 illesztőprogram: az UTF-8 explicit kérése.
SQLSRV_ENC_CHARaz alapértelmezett 8 bites rendszerkód oldal, nem az UTF-8. UTF-8 SQLSRV használatakor állítsd be a(z)"CharacterSet" => "UTF-8"értéket a kapcsolaton, és lekéréskor vagy kötéskor add át a(z)'UTF-8'literált a(z)SQLSRV_PHPTYPE_STRINGszámára. Lásd: UTF-8 adatok küldése és letöltése.
Dátumidő-átalakítási hibák
Tünetek:
SQLSTATE[22007]: Invalid character value for cast specification
Javítás:
A PDO_SQLSRV esetében ne kössön nyers DateTime objektumot. A PDO a kötött értékeket a kötés előtt karakterlánccá alakítja, a PHP DateTime pedig nem rendelkezik __toString() metódussal, ezért a execute([new DateTime(...)])Object of class DateTime could not be converted to string kivételt dob. Először formázd az értéket, vagy adj át egy ISO 8601 stringet (YYYY-MM-DD HH:MM:SS[.fff]), ne egy helyi formátumú stringet.
<?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")]);
Ha a datetime oszlopokat a PDO_SQLSRV-ben karakterláncok helyett DateTime objektumként szeretné lekérni, állítsa be a következő utasításattribútumot:
<?php
$stmt = $conn->prepare("SELECT EventDate FROM dbo.Events");
$stmt->setAttribute(PDO::SQLSRV_ATTR_FETCHES_DATETIME_TYPE, true);
$stmt->execute();
Részletekért lásd: Dátumidő objektumok (PDO_SQLSRV) lekérése.
Tizedes formázási problémák
Tünetek:
Az -1 és 1 közötti értékekből hiányzik egy vezető nulla, vagy a pénz és a kis pénz értékek váratlan számú tizedesszámot mutatnak.
Javítás:
PDO_SQLSRV mindig tizedes és numerikus értékeket hoz be láncsorként, pontosan a pontossággal és skálával. Állítsuk PDO::SQLSRV_ATTR_FORMAT_DECIMALS be úgy, hogy vezető nullát adjunk hozzá -1 és 1 közötti értékekhez:
<?php
$conn->setAttribute(PDO::SQLSRV_ATTR_FORMAT_DECIMALS, true);
PDO::SQLSRV_ATTR_DECIMAL_PLACES csak a pénzre és a kis pénz értékekre vonatkozik. A megjelenített skálát 0-tól 4-ig állítja be, és lehet, hogy a megjelenített értéket kerekíti. Nem befolyásolja a tizedes vagy numerikus értékeket.
Részletekért lásd: Tizedesjegyek és pénzösszegek formázása (PDO_SQLSRV) vagy Tizedesjegyek és pénzösszegek formázása (SQLSRV).
Tranzakciós problémák
Az adatváltozások nem maradnak fenn
Tünetek:
A PHP-ben beszúrt vagy frissített sorok nem jelennek meg, amikor egy másik munkamenetből lekérdezi őket.
Ok:
PDO::beginTransaction() egy explicit tranzakciót nyit meg, amely explicit commit() megkövetel. Ha a PHP szkript hívás commit()nélkül végződik, a PDO visszahúzza a tranzakciót a kapcsolat tisztítása során.
Javítás:
Mindig együtt használd a(z) beginTransaction() és commit() elemeket, és hiba esetén a try/catch használatával végezz visszagörgetést:
<?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;
}
SQLSRV esetén használd sqlsrv_begin_transaction, sqlsrv_commit, és sqlsrv_rollback.
Holtzárhibák
Tünetek:
SQLSTATE[40001]: [Microsoft][ODBC Driver 18 for SQL Server][SQL Server]Transaction (Process ID 62) was deadlocked
Javítás:
Kezeld az átmeneti deadlock hibákat újrapróbálkozás logikával. Csomagold be az egész tranzakciót (nem csak a hibás utasítást), hogy a korábbi utasítások újra lejátszódjanak az új tranzakción. A termelésorientált újrapróbálási mintához lásd a PHP driver landing oldalán található mintát.
Az ismétlődő holtpontok tervezési problémára utalnak. Rögzítsük a holtpontgráfot, és elemezzük, mely utasítások és zárolástípusok érintettek. Gyakori megoldások közé tartozik az átrendezési műveletek, hogy a versengő tranzakciók ugyanabban a sorrendben szerezzenek zárokat, a tranzakciós kör csökkentése, valamint indexek hozzáadása a zár időtartamának csökkentése érdekében. A teljes végigjátszásért lásd a Deadlocks útmutatót.
Kapcsolódási ellenállósági problémák
A visszakapcsolás nem történik meg
Tünetek:
Egy ürtelen kapcsolat hibás marad egy Azure SQL Database failover után, még akkor is, ha beállítod ConnectRetryCount és ConnectRetryInterval.
Lehetséges okok és megoldások:
-
Aktív szerveroldali kurzor. Az üresjárati kapcsolatok helyreállítása csak a tétlen kapcsolatokat csatlakoztatja újra. Egy nyitott szerveroldali kurzor vagy függőben lévő tranzakció aktívan tartja a kapcsolatot. Szabadítsa fel a szerveroldali kurzorokat a
sqlsrv_free_stmt()vagy$stmt = null;(PDO) használatával a feladatátvételi időszak előtt, vagy váltson kliensoldali pufferelt kurzorra. Lásd: Tétlen kapcsolati rezisztens. -
Nem helyreállítható munkamenetállapot. Bizonyos sessionállapotok nem állíthatók vissza, például ideiglenes táblák, globális és helyi kurzorok, tranzakciós kontextus, alkalmazászárak,
EXECUTE AS/REVERTOLE automatizálási handlek, előkészített XML handle és trace flagok. Ezek közül bármelyik ülésállapot megakadályozza az automatikus újracsatlakozást. -
LoginTimeouttúl kicsi. HaConnectRetryCount * ConnectRetryInterval > LoginTimeout, a meghajtó felhagy az újrapróbálkozással, amikor eléri a(z)LoginTimeoutértéket. NöveldLoginTimeoutértékét a teljes újrapróbálkozási költségvetés fedezéséhez.
Teljesítményproblémák
A lassú lekérdezések, hidegindítások, nagy eredménykészletek és tömeges beillesztések diagnosztizálásáért és helyreállításáért lásd: Teljesítmény hangolás.
Illesztőprogram-diagnosztika engedélyezése
Ha az alkalmazásszintű error_log() hívások nem adnak elegendő információt, kapcsold be a vezetőoldali naplózást. Naplózza az illesztőprogram által végrehajtott minden ODBC-hívást.
PDO_SQLSRV
Állítsa be a(z) pdo_sqlsrv.log_severity elemet a(z) php.ini helyen, majd indítsa újra a webkiszolgálót. Ez a beállítás csak inicializációkor olvasható:
[pdo_sqlsrv]
pdo_sqlsrv.log_severity = 1
Az értékek: 0 (kikapcsolva, az alapértelmezett), -1 (hibák, figyelmeztetések és értesítések), 1 (hibák), 2 (figyelmeztetések) és 4 (értesítések).
SQLSRV
Engedélyezd a naplózást futásidőben a következőkkel: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);
A naplóbejegyzések az php.ini fájlba kerülnek, amelyet a(z) error_log állít be. Az alrendszerek és súlyosságok teljes listájáért lásd: Logolási tevékenység.
Konténer- és CI problémák
Hiányzó rendszerkönyvtárak Linuxon
Tünetek:
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
Javítás:
Telepítse a futtatókörnyezeti függőségeket, mielőtt telepítené a PHP-illesztőprogramot:
| Disztribúció | Parancs telepítése |
|---|---|
| Ubuntu és Debian | sudo apt-get install unixodbc libgssapi-krb5-2 |
| Red Hat és Fedora | sudo dnf install unixODBC krb5-libs |
| Alpine | apk add unixodbc gcompat |
Ezután telepítsd msodbcsql18 a Microsoft csomagtárolóból. A disztribúcióspecifikus csomagtárakkal és verziókkal kapcsolatban lásd az ODBC illesztőprogram telepítési útmutatóját.
Docker képek építése sikeres, de a kapcsolatok futásidőben hibásodnak
Tünetek:
A kép beépül, és a PHP elindul, de PDO::__construct() ODBC driver-not-found hibát dob.
Javítás:
Ellenőrizd, hogy az ODBC illesztőprogram a futásidejű képben van telepítve, nem csak az építési szakaszban. Telepítsd msodbcsql18 be, unixodbc-dev és ugyanabban a szakaszban, ami a gyártásba kerül. Többfokozatú buildben a végső szakaszba szereld be őket. Egy egyfázisú Debian-alapú telepítés így néz ki:
# 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/*