SQL Server için PHP için Microsoft Sürücülerini Sorun Gider

PHP sürücüsünü indirme

SQL Server, Azure SQL Veritabanı, Azure SQL Managed Database ve SQL database'e bağlanırken Microsoft Drivers for PHP for SQL Server kullanırken yaygın sorunları teşhis edin ve çözün Microsoft Fabric.

Genel hata ve uyarı işleme kalıpları için Hataları ve uyarıları ile ilgili konulara bakınız. Sürücü tarafı tanı yakalaması için bkz. Kayıt etkinliği.

Kurulum sorunları

Uzantı yüklenmedi

Belirtiler:

  • phpinfo() A sqlsrv veya pdo_sqlsrv bölümü listelenmiyor.
  • PDOException: could not find driver DSN ile bir A PDOsqlsrv: oluştururken.
  • Fatal error: Uncaught Error: Call to undefined function sqlsrv_connect().

Olası nedenler ve çözümler:

  • Uzantı php.iniiçinde etkinleştirilmedi . Her ikisinin extension=sqlsrv de yorumsuz extension=pdo_sqlsrv 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 kartı, PHP derinizin iş parçacığı güvenliğiyle eşleşmeli (ts iş parçacığı güvenli için, nts iş parçacığı güvenli olmayan için). Denetlemek için komutunu çalıştırın php -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 kurun msodbcsql18 .msodbcsql17 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

Her ikisini pdo_sqlsrv de çıkışta sqlsrv görmelisiniz.

Linux veya macOS'ta PECL kurulumu başarısız olur

Belirtiler:

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

Düzeltme:

Çalıştırmadan pecl installö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

Sonra tekrar dene:

sudo pecl install sqlsrv
sudo pecl install pdo_sqlsrv

Başlıklar pecl takıldığından sonra yine arızalanırsa, yapım aleti zinciri eksik olabilir. phpizeKurulum, re2c, ve bir C++ derleyicisi (build-essentialDebian ve Ubuntu'da, gcc-c++ make Red Hat ve Fedora üzerinde, build-base Alpine'de).

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 kendi php.ini dizini ext vardır. Sürücü eksik olan ortamda doğru yapılandırma dosyasını php --ini bulun ve oraya satırları extension= 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 1433
    
  • Firewall, 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ı ile geçer. 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. Giriş cihazının hedef veritabanında bir kullanıcı eşlemesi olup olmadığını 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 Authentication yeni değerleri bilmiyor ve ActiveDirectoryServicePrincipalActiveDirectoryDefaultActiveDirectoryMsi hatta ODBC 17.3.1.1 veya daha sonraki sürümleri gerektiriyor.

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 kelimelerinin izin listesini zorunlu kılar ve DSN'de kabul UID etmez PWD . 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ü UID kabul eder ve PWD bağlantı seçeneklerinde diziyi kabul eder.sqlsrv_connect()

PDO_SQLSRV, seçenekler dizisinde AccessToken'ı sessizce görmezden gelir

Belirti:

Bir Microsoft Entra erişim belirteciniz var (örneğin, , ManagedIdentityCredential, az account get-access-token --resource https://database.windows.net/veya 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 kafa karıştırıcı bir hata ile Windows logins are not supported in this version of SQL Server başarısız Login failed for user ''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:

DSN dizisine geç AccessToken . Opsiyon dizisini sabitler PDO::ATTR_* 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ürü için, AccessToken ham JWT'yi SQL_COPT_SS_ACCESS_TOKEN sizin için saran bağlantı-bilgi dizisine girersqlsrv_connect():

<?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 .

Kendi kendine imzalanmış sertifikaya karşı geliştirme için:

<?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 ortamı asla üretime, sahneleme veya paylaşılan ortamlara taşıma.

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:

  • LoginTimeout Soğuk failover için çok düşük ya da ayarlama. Azure SQL'e bağlanırken DSN'de bir açıkça LoginTimeout (saniyeler için) bir ayarla alın. Failover-grup failover'ları ve soğuk başlatma veritabanları, kısa bir istemci tarafı zaman aşımından daha uzun sürebilir. Seçenek referansı için Bağlantı seçeneklerine bakınız.
  • Boşta yeniden bağlantı bütçesi kısaltıldı. Eğer ve ConnectRetryIntervalayarlıyorsanızConnectRetryCount, LoginTimeout >= ConnectRetryCount * ConnectRetryIntervalemin olun. Aksi takdirde giriş süresi yeniden bağlantı döngüsünü erken bitirir. 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 arızalar

Belirti:

A PDO::exec() veya PDOStatement::execute() çağrı geri gelir false ama istisna olmaz.

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ıklar istisnalar yaratacak şekilde istisna moduna geri döndürün:

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

Modu küresel olarak değiştiremiyorsan, her aramadan sonra kontrol $conn->errorInfo() et.$stmt->errorInfo() Dizi içerir [SQLSTATE, driver code, driver message].

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 nitelendirmesi. 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ığı. Küçük harf duyarlı bir derleme ile oluşturulan veritabanları, ve Products farklı nesneler olarak ele alırproducts. 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 ? tutucu sayısı, verdiğiniz execute()değer sayısıyla eşleşmelidir ve her biri ? tek bir skaler (bir dizi değil) bağlar. 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 veya sqlsrv_prepare()adresine sqlsrv_query() iletin :

<?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 () parametreleri istemci tarafında interpolasyon yaparPDO::ATTR_EMULATE_PREPARES = true. Yerel () sorgu ve parametreleri ayrı ayrı sunucuya gönderirfalse. Davranış, TOP (?)tablo değerli parametreler ve tür zorlamasında bazı uç durumlar için farklılık gösterir.

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 dair detaylar için PDO::p repare adresine bakınız.

Veri tipi problemleri

Unicode karakterler ise ? garab veya bozuk şekilde görünür

Belirtiler:

PHP'nin yazdığı satırlar, orijinal ASCII olmayan karakterler yerine soru işaretleri veya yedek karakterler içerir. Okuduklar, bozuk metni geri döner.

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_CHAR varsayılan 8-bit sistem kod sayfasıdır, UTF-8 değildir. SQLSRV ile UTF-8 için, "CharacterSet" => "UTF-8" bağlantıyı ayarlayın ve literali 'UTF-8' on SQLSRV_PHPTYPE_STRING fetch veya bind ile 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 da bir nesneye bağlama DateTime . PDO, bağlanmadan önce bağlı değerleri stringifize eder ve PHP'nin DateTime yöntemi __toString() yoktur, bu yüzden execute([new DateTime(...)])Object of class DateTime could not be converted to stringartırır. Önce değeri biçimlendirin veya bir ISO 8601 dizisi (YYYY-MM-DD HH:MM:SS[.fff]), yerel biçimlendirilmiş bir diziyi değil iletebilirsiniz.

<?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ğerler önde sıfır eksiktir veya para ve küçük para değerleri beklenmedik sayıda ondalık oranı gösterir.

Düzeltme:

PDO_SQLSRV her zaman ondalık ve sayısal değerleri tam hassasiyet ve ölçekli dizide getirir. -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.

Detaylar için bkz. Formatlama ondalık ve para (PDO_SQLSRV) veya Biçim ondalık ve para (SQLSRV).

İş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 çağrı commit()yapmadan biterse, PDO bağlantı temizleme sırasında işlemi geri alır.

Düzeltme:

Her zaman ile eşleştirin beginTransaction() ve hata durumunda geri almak için kullanıncatchtry/:commit()

<?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_commitve sqlsrv_rollback.sqlsrv_begin_transaction

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 (sadece başarısız ifadeyi değil) sararak önceki ifadeler taze işlemde tekrar oynanır. Ü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. Deadlock grafiğini yakalayın ve hangi ifadeler ile 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ğlantı olmuyor

Belirtiler:

Boşta bir bağlantı, Azure SQL Veritabanı failover sonrası bozuk kalır, ConnectRetryCount ve ayarlarsanız ConnectRetryIntervalbile .

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. Sunucu tarafı imleci veya sqlsrv_free_stmt()$stmt = null; (PDO) kullanarak failover penceresinden önce serbest bırakın veya istemci tarafı tamponlu bir imleciye 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ğer ConnectRetryCount * ConnectRetryInterval > LoginTimeout, sürücü ulaşıldığında LoginTimeout tekrar denemeyi durdurur. Yeniden deneme bütçesinin tamamını karşılamak için artırın LoginTimeout .

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

Web sunucusunu kurup pdo_sqlsrv.log_severityphp.ini yeniden başlat. 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 php.initarafından error_log 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. Kurulum msodbcsql18 ve unixodbc-dev üretime gönderilen aynı aşamada. Çok aşamalı bir yapıda, onları son aşamaya takın. 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/*