Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
SQL Server, Azure SQL Veritabanı, Azure SQL Yönetilen Örneği ve Microsoft Fabric'teki SQL veritabanına bağlanmak için Microsoft PHP için SQL Server Sürücüleri'ni kullandığınızda ortaya çıkan yaygın sorunları tanılayın ve giderin.
Genel hata ve uyarı işleme yaklaşımları için Hataları ve uyarıları işleme bölümüne bakın. Sürücü tarafındaki tanılama kaydı için Günlük etkinliği bölümüne bakın.
Kurulum sorunları
Uzantı yüklenmedi
Belirtiler:
-
phpinfo(),sqlsrvveyapdo_sqlsrvbölümünü listelemiyor. -
PDOException: could not find driversqlsrv:DSN’si ile birPDOoluşturulurken. -
Fatal error: Uncaught Error: Call to undefined function sqlsrv_connect().
Olası nedenler ve çözümler:
-
Uzantı php.iniiçinde etkinleştirilmedi . Hem
extension=sqlsrvhem deextension=pdo_sqlsrviçin yorum satırı işaretinin kaldırılmış olduğunu doğrulayın. Windows'ta tam dosya adını (extension=php_sqlsrv_84_ts_x64.dll). kullanın. Detaylar için Sürücüleri yükleme bölümüne bakınız. -
Yanlış diş güvenlik yapısı. Sürücü ikili dosyası, PHP yapınızın iş parçacığı güvenliğiyle eşleşmelidir (
tsiş parçacığı güvenli sürüm için,ntsiş parçacığı güvenli olmayan sürüm için). Denetlemek için komutunu çalıştırınphp -i | grep "Thread Safety". Eşleşen ikili dosyayı indirme sayfasından indirin. -
Microsoft ODBC sürücüsü eksik. PHP sürücüleri, SQL Server için Microsoft ODBC Sürücüsünü sarar. Linux ve macOS'ta, uzantıları yüklemeden önce paket yöneticinizle
msodbcsql18(veyamsodbcsql17) kurun. Windows'ta, indirme sayfasından ODBC sürücüsünü yükleyin.
Başarılı bir kurulumu doğrulayın:
php -m | grep -i sqlsrv
Çıktıda hem pdo_sqlsrv hem de sqlsrv öğesini görmelisiniz.
Linux veya macOS'ta PECL veya PIE kurulumu başarısız oluyor
Belirtiler:
error: ‘SQL_HANDLE_DBC’ undeclared (first use in this function)
fatal error: 'sql.h' file not found
Düzeltme:
Sürücüleri yüklemeden önce ODBC geliştirme başlıklarını yükleyin:
-
Ubuntu ve Debian:
sudo apt-get install unixodbc-dev -
Red Hat, Fedora ve CentOS:
sudo dnf install unixODBC-devel -
Alpine:
apk add unixodbc-dev -
macOS:
brew install unixodbc
Apple silikonunda, başlıklar tek başına yeterli değil. Homebrew, unixODBC'yi varsayılan derleyici arama yolunda yer almayan /opt/homebrew altına kurar; bu nedenle, başlık dosyaları mevcut olsa bile derleme aynı hatayla başarısız olur. Tekrar denemeden önce derleyici bayraklarını ayarlayın:
export CPPFLAGS="-I/opt/homebrew/opt/unixodbc/include/"
export LDFLAGS="-L/opt/homebrew/lib/"
Sonra PIE ile tekrar dene:
pie install microsoft/sqlsrv
pie install microsoft/pdo_sqlsrv
Ya da PECL ile:
sudo pecl install sqlsrv
sudo pecl install pdo_sqlsrv
Üstbilgiler yüklendikten sonra kurulum hâlâ başarısız oluyorsa, derleme araç zinciri eksik olabilir.
phpize, re2c ve bir C++ derleyicisi yükleyin (build-essential Debian ve Ubuntu için, gcc-c++ make Red Hat ve Fedora için, build-base Alpine için). PIE, eksik derleme araçlarını Linux ve macOS'ta sizin için yüklemeyi teklif ediyor.
Tam kurulum yolu için Linux ve macOS için Kurulum eğitimine bakınız.
Birden fazla PHP sürümü kuruldu
Belirtiler:
phpinfo() web sunucunuzda bir PHP sürümü gösterilir, php -v ama komut satırında başka bir PHP sürümü görünür ve sürücü sadece birinde yüklü görünür.
Düzeltme:
Her PHP sürümünün kendine ait php.ini ve ext dizinleri vardır. Sürücünün eksik olduğu ortamda, php --ini ile doğru yapılandırma dosyasını bulun ve extension= satırlarını bu dosyaya ekleyin. Herhangi bir php.ini değişikliğinden sonra web sunucusunu (Apache, Nginx + PHP-FPM veya IIS) yeniden başlatın.
Bağlantı sorunları
Sunucuya bağlanamıyor
Belirtiler:
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
Olası nedenler ve çözümler:
Sunucuya ulaşılamıyor. Sunucu adı ve portun doğru olduğundan emin olun. PHP ana bilgisayarından ham TCP bağlantısını test edin.
# Linux and macOS nc -vz <server>.database.windows.net 1433 # Windows PowerShell Test-NetConnection -ComputerName <server>.database.windows.net -Port 1433Firewall, giden 1433'ü engelliyor. Kurumsal güvenlik duvarları ve bulut NSG'leri genellikle çıkış portu 1433'ü engeller. Bir istisna ekleyin veya bölgeniz için Azure SQL Veritabanı IP aralıklarına izin verin.
Azure SQL server firewall. Müşterinizin genel IP'sini Azure portalındaki sunucu düzeyindeki firewall kurallarına ekleyin.
Isimli örnek. Isimlendirilmiş bir örnek için, SQL Server Browser servisinin sunucuda çalıştığını ve UDP 1434'ün açık olduğunu doğrulayın. Ya da örnek adıyla değil, port üzerinden bağlanın.
Oturum açılamadı
Belirtiler:
SQLSTATE[28000]: [Microsoft][ODBC Driver 18 for SQL Server][SQL Server]Login failed for user '<user_id>'.
Olası nedenler ve çözümler:
- SQL kimlik doğrulama modu devre dışı bırakıldı. Yerel SQL Server örnekleri varsayılan olarak yalnızca Windows Kimlik Doğrulaması kullanır. SQL Server Management Studio'da Server properties>Security altında karma mod kimlik doğrulamasını etkinleştirin ve ardından SQL Server hizmetini yeniden başlatın.
-
Azure SQL credentials format. Azure SQL, otomatik olarak eklenmeyen araçlardan bağlanırken tam nitelikli kullanıcı adı (
user@servername) gerektirir. - Kullanıcı veritabanına eşlenmedi. Oturum açma hesabının hedef veritabanında bir kullanıcı eşlemesi olduğunu ve kullanıcının gerekli izinlere sahip olduğunu doğrulayın.
-
Microsoft Entra ID'yi tercih edin. Azure SQL, Azure SQL Yönetilen Örneği ve Fabric'teki SQL veritabanı için, SQL girişleri yerine Microsoft Entra kimlik doğrulaması (
Authentication=ActiveDirectoryMsi,Authentication=ActiveDirectoryServicePrincipal, veya erişim tokenı) kullanın. Bkz . Microsoft Entra kimlik doğrulamayı kullanarak bağlanma.
'Authentication' bağlantı dizesi özniteliği için geçersiz değer belirtildi
Belirtiler:
SQLSTATE[08001]: [Microsoft][ODBC Driver 17 for SQL Server]Invalid value specified for connection string attribute 'Authentication'
Sebep:
ODBC sürücüsü hatayı bildiriyor, ancak asıl sorun hangi sürücünün PDO_SQLSRV bağlı olduğudur. DSN anahtar Driver= kelime içermiyorsa ve ana bilgisayarda hem ODBC 17 hem de ODBC 18 kuruluysa, PDO_SQLSRV eski sürüme bağlanabilir. Eski ODBC 17.x derlemeleri, ActiveDirectoryServicePrincipal veya ActiveDirectoryDefault gibi daha yeni Authentication değerlerini tanımaz ve ActiveDirectoryMsi bile ODBC 17.3.1.1 ya da daha sonraki bir sürümü gerektirir.
Düzeltme:
Sürücüyü DSN'de sabitleyin:
<?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]);
Parantez içindeki form ({ODBC Driver 18 for SQL Server}) sürücü adındaki boşluklardan kaçar. Hata mesajı her zaman bildiren sürücünün adını verir, bu yüzden hatadaki önek [Microsoft][ODBC Driver 17 for SQL Server] yanlış sürücü sınırını doğrulamanın en hızlı yoludur.
DSN dizisinde geçersiz anahtar kelime 'UID' belirtildi
Belirtiler:
SQLSTATE[IMSSP]: An invalid keyword 'UID' was specified in the DSN string.
Sebep:
PDO_SQLSRV, DSN anahtar sözcükleri için bir izin verilenler listesi uygular ve DSN içinde UID veya PWD kabul etmez. PDO, ikinci ve üçüncü yapıcı argümanlarını bunlara ayırır ve PDO_SQLSRV bunları dahili olarak ODBC'ye UID/PWD çevirir.
Düzeltme:
Kullanıcı adını (ve SQL kimlik doğrulaması için şifreyi) PDO yapıcısına taşıyın:
<?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);
Buna karşılık, SQLSRV prosedürel sürücüsü, sqlsrv_connect() öğesine geçirilen bağlantı seçenekleri dizisinde UID ve PWD değerlerini kabul eder.
PDO_SQLSRV, seçenekler dizisinde AccessToken'ı sessizce görmezden gelir
Belirti:
Bir Microsoft Entra erişim belirteciniz var (örneğin, , az account get-access-token --resource https://database.windows.net/, ManagedIdentityCredentialveya ClientSecretCredential), ve bunu dördüncü yapıcı argümanında olduğu gibi PDO_SQLSRV'ye ['AccessToken' => $token] iletiyorsunuz. Bağlantı girişimi, sanki hiçbir kimlik bilgisi sağlanmamış gibi, Windows logins are not supported in this version of SQL Server ya da Login failed for user '' gibi kafa karıştırıcı bir hatayla başarısız olur.
Sebep:
PDO'nun dördüncü yapıcı argümanı, sürücüye özgü öznitelik sabitleri (tamsayı PDO::ATTR_ERRMODEanahtarları gibi) için ayrılmıştır. PDO, , AccessTokengibi dize anahtarlı girişleri sessizce bırakır, böylece PDO_SQLSRV tokenı asla görmez. Bağlantı daha sonra Windows Entegre kimlik doğrulamasına geri dönüyor ve sunucu bunu reddediyor.
Düzeltme:
AccessToken öğesini DSN dizesine taşıyın. Seçenekler dizisini PDO::ATTR_* sabitleri için ayırın.
<?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,
]);
Ek Microsoft Entra kimlik doğrulama örnekleri için, PDO_SQLSRV için DSN formu da dahil olmak üzere, bkz. Connect using Microsoft Entra authentication.
SQLSRV prosedürel kullanımında, AccessToken, sqlsrv_connect()'e geçirilen bağlantı bilgileri dizisinde yer alır; sqlsrv_connect() ham JWT'yi sizin için SQL_COPT_SS_ACCESS_TOKEN içine sarar:
<?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 sertifika hataları
Belirtiler:
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
Çözümler:
Güvenilir bir sertifikayı tercih edin. Sadece kontrol ettiğiniz bir sunucuya karşı yerel geliştirme için kullanın TrustServerCertificate=true .
Kendinden imzalanmış bir sertifika ile geliştirme yaparken:
<?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 sunucu sertifikası doğrulamasını devre dışı bırakır. Bu ayarı asla üretim, hazırlık veya paylaşılan ortamlarda kullanma.
Sertifika Ortak Adı ile eşleşmeyen bir üretim ana adı için (örneğin, bir dinleyici üzerinden bağlanırken), gerçek sertifika konusunu belirtin:
<?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,
]);
Bağlantı zaman aşımına uğradı
Belirtiler:
SQLSTATE[HYT00]: Login timeout expired
Olası nedenler ve çözümler:
-
LoginTimeoutsoğuk yük devretme için ayarlanmamış veya çok düşük ayarlanmış. Azure SQL'e bağlanırken, DSN'de açık birLoginTimeoutdeğeri (saniye cinsinden) ayarlayın. Yük devretme grubu yük devretmeleri ve soğuk başlatılan veritabanları, istemci tarafında ayarlanan kısa bir zaman aşımı süresinin izin verdiğinden daha uzun sürebilir. Seçenek başvurusu için Bağlantı seçenekleri bölümüne bakın. -
Boşta yeniden bağlantı bütçesi kısaltıldı.
ConnectRetryCountveConnectRetryIntervalayarlarsanız,LoginTimeout >= ConnectRetryCount * ConnectRetryIntervalolduğundan emin olun. Aksi takdirde giriş zaman aşımı, yeniden bağlanma döngüsünü erken sonlandırır. Bkz. Boşta bağlantı dayanıklılığı.
<?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,
]);
Sorgu yürütme sorunları
PDO ile sessiz hatalar
Belirti:
Bir PDO::exec() veya PDOStatement::execute() çağrısı false döndürür, ancak bir özel durum fırlatmaz.
Düzeltme:
PHP 8.0 ve daha sonraki sürümlerde varsayılan PDO hata modu PDO::ERRMODE_EXCEPTION. Bir çağrı atma olmadan dönerse false , uygulama modu PDO::ERRMODE_SILENT veya PDO::ERRMODE_WARNINGolarak değiştirir. Başarısızlıklarda istisna fırlatılması için bunu yeniden istisna moduna alın:
<?php
$conn = new PDO($dsn, $user, $password, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);
Modu küresel olarak değiştiremiyorsan, her çağrıdan sonra $conn->errorInfo()'i (veya $stmt->errorInfo()'i) kontrol et. Dizi, [SQLSTATE, driver code, driver message] içerir.
Geçersiz nesne adı
Belirtiler:
SQLSTATE[42S02]: [Microsoft][ODBC Driver 18 for SQL Server][SQL Server]Invalid object name 'Products'.
Olası nedenler ve çözümler:
Yanlış veritabanı bağlamı. Hızlı bir sorgulamayla doğrulayın:
<?php $stmt = $conn->query("SELECT DB_NAME()"); echo $stmt->fetchColumn();Eksik şema niteleyicisi. Arayanın varsayılan şemasına bağlı olmamak için tam nitelikli isimler kullanın:
SELECT * FROM dbo.Products;Büyük/küçük harf duyarlılığı. Büyük/küçük harf duyarlı bir harmanlama ile oluşturulan veritabanları,
productsveProductsöğelerini farklı nesneler olarak değerlendirir. Tablo tanımındaki tam durumu eşleştirin.
Yanlış sayıda parametre
Belirtiler:
SQLSTATE[HY093]: Invalid parameter number
SQLSTATE[07002]: COUNT field incorrect or syntax error
Düzeltme:
PDO_SQLSRV için, ? yer tutucularının sayısı, execute() öğesine geçirdiğiniz değerlerin sayısıyla eşleşmelidir ve her ?, yalnızca tek bir skaler değeri bağlar (dizi değil). Adlandırılmış parametreler için, SQL'deki her :name bir dizide görünmelidir ve tam tersi de geçerlidir.
<?php
$stmt = $conn->prepare(
"SELECT * FROM dbo.Products WHERE CategoryID = ? AND ListPrice > ?"
);
$stmt->execute([1, 50.0]);
foreach ($stmt as $row) {
// ...
}
SQLSRV için parametre dizisini sqlsrv_query() veya sqlsrv_prepare() öğesine geçirin:
<?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));
}
Parametre bağlamaya daha geniş bir giriş için bkz. Parametrelerli sorgular gerçekleştir.
PDO emülasyonu maske hatalarını hazırlayır
Belirtiler:
Bir ifade bir bağlantıda başarıyla çalışır ancak aynı sorgu metnini kullanan başka bir bağlantıda sözdizimi hatası verir.
Sebep:
PDO_SQLSRV hem emüle edilen hem de yerel hazırlanmış ifaları destekler. Emulated, PDO::ATTR_EMULATE_PREPARES = true parametreleri istemci tarafında enterpole eder. Native, sorgu ile parametreleri sunucuya ayrı ayrı göndermeye hazırlanır (false). Davranış, TOP (?), tablo değerli parametreler ve tür zorlamasındaki bazı uç durumlar için farklıdır.
Düzeltme:
Üretimdeki yerli preparatları tercih edin. Bağlantı PDO::ATTR_EMULATE_PREPARES => false zamanında ayarlanır ki davranış ortamlar arasında tutarlı olsun:
<?php
$conn = new PDO($dsn, null, null, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_EMULATE_PREPARES => false,
]);
Her modun ne zaman kullanılacağına ilişkin ayrıntılar için PDO::prepare'e bakın.
Veri tipi problemleri
Unicode karakterleri ? olarak veya bozuk görünür
Belirtiler:
PHP'nin yazdığı satırlar, orijinal ASCII olmayan karakterler yerine soru işaretleri veya yedek karakterler içerir. Okuma işlemleri bozuk metin döndürür.
Olası nedenler ve çözümler:
Sütun tipi VARCHAR'dır, NVARCHAR değil. varchar sütunları Unicode değil, bir kod sayfası kullanır. Uluslararasılaştırılmış metin için nvarchar kullanın.
PDO_SQLSRV üzerinde eksik UTF-8 kodlama ipucu. SQL Server sütununuz nvarchar ve PHP verileriniz UTF-8 olduğunda, sürücüye UTF-8 (istemci) ile UTF-16 (sunucu) arasında dönüştürmeyi söyleyin:
<?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 sürücüsü: UTF-8'i açıkça talep edin.
SQLSRV_ENC_CHARvarsayılan 8-bit sistem kod sayfasıdır, UTF-8 değildir. SQLSRV ile UTF-8 için, bağlantıda"CharacterSet" => "UTF-8"değerini ayarlayın ve getirme veya bağlama sırasında'UTF-8'değişmeziniSQLSRV_PHPTYPE_STRINGöğesine geçirin. Bkz. UTF-8 verisini gönder ve al.
Tarih saati dönüşüm hataları
Belirtiler:
SQLSTATE[22007]: Invalid character value for cast specification
Düzeltme:
PDO_SQLSRV'de ham bir DateTime nesnesini bağlamayın. PDO, bağlamadan önce bağlı değerleri dizgeye dönüştürür ve PHP'de DateTime için __toString() yöntemi yoktur; bu yüzden execute([new DateTime(...)]), Object of class DateTime could not be converted to string hatasını tetikler. Önce değeri biçimlendirin veya yerel ayara göre biçimlendirilmiş bir dize değil, bir ISO 8601 dizesi (YYYY-MM-DD HH:MM:SS[.fff]) iletin.
<?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")]);
Datetime sütunlarını DateTime PDO_SQLSRV üzerinde diz yerine nesne olarak almak için ifade özniteliğini ayarlayın:
<?php
$stmt = $conn->prepare("SELECT EventDate FROM dbo.Events");
$stmt->setAttribute(PDO::SQLSRV_ATTR_FETCHES_DATETIME_TYPE, true);
$stmt->execute();
Detaylar için bkz. Tarih saati nesnelerini (PDO_SQLSRV) al.
Ondalık biçimlendirme sorunları
Belirtiler:
-1 ile 1 arasındaki değerlerin başında sıfır eksiktir veya money ve smallmoney değerleri beklenmedik sayıda ondalık basamak görüntüler.
Düzeltme:
PDO_SQLSRV, ondalık ve sayısal değerleri her zaman tam kesinlik ve ölçekleriyle dize olarak alır. -1 ile 1 arasındaki değerlere önde bir sıfır eklemek için ayarlandı PDO::SQLSRV_ATTR_FORMAT_DECIMALS :
<?php
$conn->setAttribute(PDO::SQLSRV_ATTR_FORMAT_DECIMALS, true);
PDO::SQLSRV_ATTR_DECIMAL_PLACES sadece para ve küçük para değerleri için geçerlidir. Gösterilen ölçeği 0'dan 4'e kadar ayarlar ve gösterilen değeri yuvarlayabilir.
Ondalık veya sayısal değerleri etkilemez.
Ayrıntılar için Ondalık sayıları ve para birimini biçimlendirme (PDO_SQLSRV) veya Ondalık sayıları ve para birimini biçimlendirme (SQLSRV) konusuna bakın.
İşlem sorunları
Veri değişiklikleri devam etmiyor
Belirtiler:
PHP'de eklediğiniz veya güncellettiğiniz satırlar, başka bir oturumdan sorgu aldığınızda görünmüyor.
Sebep:
PDO::beginTransaction() açık bir işlem açıyor ve bu işlem açıkça bir commit()işlem gerektiriyor. PHP betiği commit() çağrılmadan sona ererse, PDO bağlantı temizliği sırasında işlemi geri alır.
Düzeltme:
beginTransaction() öğesini her zaman commit() ile eşleştirin ve hata durumunda geri almak için try/catch kullanın:
<?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 için sqlsrv_begin_transaction, sqlsrv_commit ve sqlsrv_rollback kullanın.
Kilitlenme hataları
Belirtiler:
SQLSTATE[40001]: [Microsoft][ODBC Driver 18 for SQL Server][SQL Server]Transaction (Process ID 62) was deadlocked
Düzeltme:
Geçici deadlock hatalarını yeniden deneme mantığı ile yönetin. Tüm işlemi (yalnızca başarısız olan komutu değil) sarmalayın; böylece önceki komutlar yeni işlemde yeniden yürütülebilsin. Üretim odaklı bir yeniden deneme deseni için PHP sürücü açılış sayfasındaki örneği görün.
Tekrarlayan kilitlenmeler bir tasarım sorununu gösterir. Kilitlenme grafiğini yakalayın ve hangi ifadelerin ve kilit türlerinin dahil olduğunu analiz edin. Yaygın çözümler arasında, rakip işlemlerin aynı sırada kilitler elde etmesi için yeniden sıralama, işlem kapsamını azaltmak ve kilit süresini azaltmak için indeksler eklemek yer alır. Tam bir rehber için Deadlocks rehberine bakınız.
Bağlantı dayanıklılığı sorunları
Yeniden bağlanma gerçekleşmiyor
Belirtiler:
Boştaki bir bağlantı, ConnectRetryCount ve ConnectRetryInterval ayarlamış olsanız bile Azure SQL Veritabanı yük devretmesinden sonra kopuk kalır.
Olası nedenler ve çözümler:
-
Aktif sunucu tarafı imleç. Boşta bağlantı dayanıklılığı sadece boşta bağlantıları yeniden bağlar. Açık sunucu tarafı imleç veya bekleyen bir işlem bağlantıyı aktif tutar. Yük devretme penceresinden önce
sqlsrv_free_stmt()ya da$stmt = null;(PDO) kullanarak sunucu taraflı imleçleri serbest bırakın veya tamponlu bir istemci taraflı imlece geçin. Bkz. Boşta bağlantı dayanıklılığı. -
Kurtarılamayan seans durumu. Bazı oturum durumları yeniden kurulamaz; geçici tablolar, küresel ve yerel imleçler, işlem bağlamı, uygulama kilitleri,
EXECUTE AS/REVERTOLE otomasyon tutamaçları, hazırlanmış XML tutamaçları ve iz bayrakları dahil. Bu oturum durumlarından herhangi biri otomatik yeniden bağlanmayı engeller. -
LoginTimeoutÇok küçüktü. EğerConnectRetryCount * ConnectRetryInterval > LoginTimeoutise,LoginTimeout'e ulaşıldığında sürücü yeniden denemeyi durdurur.LoginTimeoutöğesini, yeniden deneme bütçesinin tamamını kapsayacak şekilde artırın.
Performans sorunları
Yavaş sorgulamalar, soğuk başlatmalar, büyük sonuç setleri ve toplu eklemelerin teşhisi ve düzeltilmesi için bkz. Performans ayarlama.
Sürücü teşhisini etkinleştir
Uygulama düzeyindeki error_log() çağrılar yeterli bilgi sağlamadığında, sürücü tarafı loglamayı açın. Sürücünün yaptığı her ODBC çağrısını rapor ediyor.
PDO_SQLSRV
php.ini içinde pdo_sqlsrv.log_severity ayarlayın ve web sunucusunu yeniden başlatın. Bu ayar yalnızca başlatma sırasında okunabilir:
[pdo_sqlsrv]
pdo_sqlsrv.log_severity = 1
Değerler 0 (kapalı, varsayılan olarak), -1 (hatalar, uyarılar ve bildirimler), 1 (hatalar), 2 (uyarılar) ve 4 (bildirimlerdir).
SQLSRV
Çalışma zamanında kayıtları etkinleştirin :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);
Log girişleri, içinde error_logtarafından php.ini yapılandırılan dosyaya gider. Alt sistemler ve ciddiyetlerin tam listesi için Kayıt faaliyetleri sayfasına bakınız.
Konteyner ve CI sorunları
Linux'ta eksik sistem kütüphaneleri
Belirtiler:
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
Düzeltme:
PHP sürücüsünü yüklemeden önce çalışma zamanı bağımlılıklarını yükleyin:
| Distribution | Yükle komutu |
|---|---|
| Ubuntu ve Debian | sudo apt-get install unixodbc libgssapi-krb5-2 |
| Red Hat ve Fedora | sudo dnf install unixODBC krb5-libs |
| Alpine | apk add unixodbc gcompat |
Sonra Microsoft paket deposundan kurunmsodbcsql18. Dağıtıma özgü paket depoları ve sürümleri için ODBC sürücü kurulum rehberine bakınız.
Docker imajı derlemeleri başarılı oluyor ama bağlantılar çalışma zamanında başarısız oluyor
Belirtiler:
Görüntü oluşturulur ve PHP başlar, ancak PDO::__construct() ODBC sürücüsü bulunamadı hatası verir.
Düzeltme:
ODBC sürücüsünün sadece yapım aşamasında değil , çalışma zamanı görüntüsünde kurulduğunu doğrulayın.
msodbcsql18 ve unixodbc-dev öğelerini üretime alınan aynı aşamada yükleyin. Çok aşamalı bir derlemede, onları son aşamada yükleyin. Tek aşamalı Debian tabanlı bir kurulum şöyle görünü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/*