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.
Başlarken'den çalışan bir bağlantınız olduktan sonra, bu rehberi kullanarak herhangi bir PHP API'si ile bir satır yazmak, commit etmek ve okumak için kullanın. Her program kendi kurulumu ve temizliği içerir. Bir API'den diğerine seçenekleri kopyalamak yerine iş akışını genişletmek için görev bağlantılarını kullanın.
Test bağlantısı hazırla
Mevcut bir SQL Server test veritabanı ve bağlanıp yerel geçici tablolar oluşturabilen bir giriş kullanın. Örnekler SQL kimlik doğrulaması kullanır. Desteklenen kimlik doğrulama seçenekleri ve şifresiz Azure ilk katılımı için Sunucuya Bağlanma bölümünü inceleyebilirsiniz.
Seçtiğiniz uzantıyı yükleyin ve PHP işleminin ortamında SQL_DATABASE, SQL_USER, SQL_PASSWORD ve SQL_SERVER ayarlayın.
SQL_SERVER açık bir port içerebilir, örneğin <server>,1433. Sunucu, istemci tarafından güvenilen ve o uç nokta için geçerli olan bir sertifika sunmalıdır. Şifreleri program ve kaynak kontrolü dışında tutun.
Gerçek veritabanı adı, kullanıcı adı ve şifreyi ortam değişkenlerinde sakla. Her program, PHP sürücüsünün ODBC tarzı bağlantı yönetimi için kapanış küme parantezlerini iki katına çıkarır ve bu değerleri bir kez küme parantezleri içine alır. Escaping, bağlantı değerlerinde özel karakterleri korur; bu sorgulama parametreleştirmesi değildir. Daha fazla bilgi için Sunucuya Bağlanma bölümünü inceleyin.
Transact-SQL (T-SQL) ifadeleri, yalnızca onu oluşturan bağlantıya görünebilen #PhpGuide, geçici bir tablo oluşturur. Programlar kalıcı bir uygulama tablosu oluşturmaz veya değiştirmez. İş akışı boyunca aynı bağlantıyı koruyun.
Bir kayıt yazın ve okuyun
Programlar bir tamsayı, UTF-8 metni ve parametreler aracılığıyla SQL NULL ekler. Tam olarak bir satırın etkilenmesi, işlemin onaylanması ve geri dönen değerlerin ve PHP tiplerinin doğrulanması gerekiyor. Son sorgu ayrıca hiçbir işlemin açık kalmadığını kontrol eder.
SQLSRV
Bu programın tamamını workflow-sqlsrv.php olarak kaydedin ve php workflow-sqlsrv.php çalıştırın.
<?php
$config = [];
foreach (['SQL_SERVER', 'SQL_DATABASE', 'SQL_USER', 'SQL_PASSWORD'] as $name) {
$value = getenv($name);
if ($value === false || $value === '') {
throw new RuntimeException("Set $name before running this example.");
}
$config[$name] = $value;
}
foreach (['SQL_DATABASE', 'SQL_USER', 'SQL_PASSWORD'] as $name) {
$config[$name] = '{' . str_replace('}', '}}', $config[$name]) . '}';
}
$conn = sqlsrv_connect($config['SQL_SERVER'], [
'Database' => $config['SQL_DATABASE'],
'UID' => $config['SQL_USER'],
'PWD' => $config['SQL_PASSWORD'],
'Encrypt' => true,
'TrustServerCertificate' => false,
'LoginTimeout' => 30,
'CharacterSet' => 'UTF-8',
]);
if ($conn === false) {
throw new RuntimeException(print_r(sqlsrv_errors(), true));
}
$stmt = null;
$inTransaction = false;
$failure = null;
try {
$stmt = sqlsrv_query($conn, 'CREATE TABLE #PhpGuide '
. '(Id int PRIMARY KEY, Title nvarchar(80), OptionalCount int NULL)');
if ($stmt === false) {
throw new RuntimeException(print_r(sqlsrv_errors(), true));
}
sqlsrv_free_stmt($stmt);
$stmt = null;
if (!sqlsrv_begin_transaction($conn)) {
throw new RuntimeException(print_r(sqlsrv_errors(), true));
}
$inTransaction = true;
$id = 1;
$title = "Caf\u{00E9}";
$optionalCount = null;
$params = [
[&$id, SQLSRV_PARAM_IN, SQLSRV_PHPTYPE_INT, SQLSRV_SQLTYPE_INT],
[&$title, SQLSRV_PARAM_IN, SQLSRV_PHPTYPE_STRING('UTF-8'), SQLSRV_SQLTYPE_NVARCHAR(80)],
[&$optionalCount, SQLSRV_PARAM_IN, SQLSRV_PHPTYPE_INT, SQLSRV_SQLTYPE_INT],
];
$stmt = sqlsrv_prepare($conn,
'INSERT INTO #PhpGuide (Id, Title, OptionalCount) VALUES (?, ?, ?)', $params);
if ($stmt === false || !sqlsrv_execute($stmt)) {
throw new RuntimeException(print_r(sqlsrv_errors(), true));
}
$affected = sqlsrv_rows_affected($stmt);
if ($affected === false) {
throw new RuntimeException(print_r(sqlsrv_errors(), true));
}
if ($affected !== 1) {
throw new RuntimeException('Expected exactly one inserted row.');
}
sqlsrv_free_stmt($stmt);
$stmt = null;
if (!sqlsrv_commit($conn)) {
throw new RuntimeException(print_r(sqlsrv_errors(), true));
}
$inTransaction = false;
$stmt = sqlsrv_query($conn,
'SELECT Id, Title, OptionalCount, @@TRANCOUNT AS TransactionCount FROM #PhpGuide');
if ($stmt === false) {
throw new RuntimeException(print_r(sqlsrv_errors(), true));
}
$row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
if ($row === false) {
throw new RuntimeException(print_r(sqlsrv_errors(), true));
}
if ($row !== ['Id' => 1, 'Title' => $title, 'OptionalCount' => null, 'TransactionCount' => 0]) {
throw new RuntimeException('Unexpected committed values, types, or transaction state.');
}
$end = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
if ($end === false) {
throw new RuntimeException(print_r(sqlsrv_errors(), true));
}
if ($end !== null) {
throw new RuntimeException('Expected exactly one result row.');
}
} catch (Throwable $error) {
$failure = $error;
if ($inTransaction && !sqlsrv_rollback($conn)) {
$failure = new RuntimeException(
'Rollback failed: ' . print_r(sqlsrv_errors(), true), 0, $error);
}
throw $failure;
} finally {
if (is_resource($stmt)) {
sqlsrv_free_stmt($stmt);
}
try {
$cleanup = sqlsrv_query($conn, 'DROP TABLE IF EXISTS #PhpGuide');
if ($cleanup === false) {
throw new RuntimeException(
'Cleanup failed: ' . print_r(sqlsrv_errors(), true), 0, $failure);
}
sqlsrv_free_stmt($cleanup);
} finally {
sqlsrv_close($conn);
}
}
echo "Inserted 1 row; read committed UTF-8 text and null; no open transaction.", PHP_EOL;
PDO_SQLSRV
Bu ayrı programı , workflow-pdo.phpolarak kaydedin ve çalıştırın php workflow-pdo.php.
<?php
$config = [];
foreach (['SQL_SERVER', 'SQL_DATABASE', 'SQL_USER', 'SQL_PASSWORD'] as $name) {
$value = getenv($name);
if ($value === false || $value === '') {
throw new RuntimeException("Set $name before running this example.");
}
$config[$name] = $value;
}
foreach (['SQL_DATABASE', 'SQL_USER', 'SQL_PASSWORD'] as $name) {
$config[$name] = '{' . str_replace('}', '}}', $config[$name]) . '}';
}
$server = $config['SQL_SERVER'];
$database = $config['SQL_DATABASE'];
$pdo = new PDO(
"sqlsrv:Server=$server;Database=$database;Encrypt=true;"
. "TrustServerCertificate=false;LoginTimeout=30",
$config['SQL_USER'],
$config['SQL_PASSWORD'],
[
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::SQLSRV_ATTR_ENCODING => PDO::SQLSRV_ENCODING_UTF8,
PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE => true,
]
);
$stmt = null;
$failure = null;
try {
$pdo->exec('CREATE TABLE #PhpGuide '
. '(Id int PRIMARY KEY, Title nvarchar(80), OptionalCount int NULL)');
$pdo->beginTransaction();
$title = "Caf\u{00E9}";
$stmt = $pdo->prepare(
'INSERT INTO #PhpGuide (Id, Title, OptionalCount) VALUES (?, ?, ?)');
$stmt->bindValue(1, 1, PDO::PARAM_INT);
$stmt->bindValue(2, $title, PDO::PARAM_STR);
$stmt->bindValue(3, null, PDO::PARAM_NULL);
$stmt->execute();
if ($stmt->rowCount() !== 1) {
throw new RuntimeException('Expected exactly one inserted row.');
}
$stmt = null;
$pdo->commit();
$stmt = $pdo->query(
'SELECT Id, Title, OptionalCount, @@TRANCOUNT AS TransactionCount FROM #PhpGuide');
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if ($row !== ['Id' => 1, 'Title' => $title, 'OptionalCount' => null, 'TransactionCount' => 0]) {
throw new RuntimeException('Unexpected committed values, types, or transaction state.');
}
if ($stmt->fetch(PDO::FETCH_ASSOC) !== false || $pdo->inTransaction()) {
throw new RuntimeException('Expected one result row and no open transaction.');
}
} catch (Throwable $error) {
$failure = $error;
if ($pdo->inTransaction()) {
try {
$pdo->rollBack();
} catch (PDOException $rollbackError) {
$failure = new RuntimeException(
'Rollback failed: ' . $rollbackError->getMessage(), 0, $error);
}
}
throw $failure;
} finally {
$stmt = null;
try {
$pdo->exec('DROP TABLE IF EXISTS #PhpGuide');
} catch (PDOException $cleanupError) {
throw new RuntimeException(
'Cleanup failed: ' . $cleanupError->getMessage(), 0, $failure ?? $cleanupError);
} finally {
$pdo = null;
}
}
echo "Inserted 1 row; read committed UTF-8 text and null; no open transaction.", PHP_EOL;
Her iki program için beklenen çıktı:
Inserted 1 row; read committed UTF-8 text and null; no open transaction.
Çıktı ancak kontroller ve temizlik başarılı olduktan sonra ortaya çıkar. Bağlantı, yazma, getirme, geri alma veya tablo temizleme hatası bunun yerine bir istisna ortaya çıkarır.
Seçenekleri anlayın
Değerler için T-SQL'e girdiyi birleştirmek yerine yer tutucular kullanın ? . Örnekler tablo ve sütun adlarını sabit tutar: bir değer parametresi bir tanımlayıcının yerini alamaz. Hazırlanmış ifadeler ayrıca aynı ifadeyi farklı değerlerle tekrar çalıştırmanıza olanak tanır. Daha fazla bilgi için bkz. Sorgu yürütme işlevlerini karşılaştırma.
| Seçenek | Reason |
|---|---|
| Açıkça tanımlanmış işlem yöntemleri | Örnek, yazmayı ya commit etmek ya da geri almak zorunda olan bir birim olarak ele alıyor. SQLSRV sqlsrv_begin_transaction, sqlsrv_commit, ve sqlsrv_rollback; kullanır; PDO kendi işlem yöntemlerini kullanır. |
| SQLSRV parametre tanımlayıcıları | Her tanımlayıcı yönü, PHP tipini ve SQL türünü belirtir. Referanslar, girdi değişkenlerini korur; bunlar arasında değişken de vardır null. |
PDO bindValue |
Bu ifade, her geçerli değeri açık bir PDO parametre tipiyle alır.
bindParam sonraki yürütmelerin değişkeni referans yoluyla okuması gerektiğinde uygundur. |
| UTF-8 artı nvarchar | PHP UTF-8 bayt sağlar; uzantı ve ODBC sürücüsü bunları SQL Unicode sütununa dönüştürür. Alınan metin, orijinal PHP dizesiyle bayt bayt eşleşmelidir. |
| PDO için açıkça sayısal veri alma | Sonuç karşılaştırması PHP tam sayıları bekler. PDO_SQLSRV özniteliği olmadan, bu SQL tam sayı sonuçları sürücünün varsayılan dize gösterimini kullanır. |
| Adlandırılmış getirme anahtarları |
SQLSRV_FETCH_ASSOC ve PDO::FETCH_ASSOC sütun adıyla indekslenmiş diziler döner. API sabitleri birbirinin yerine geçemez. |
PDO::exec tablo kurulumu için |
Tablo oluşturma ifadesini doğrudan çalıştırır. Bu yaklaşım, sunucu tarafından hazırlanmış bir deyim kapsamında geçici bir tablo oluşturmaktan kaçınır. |
| Yalnızca ileri yönlü sonuçlar | Programlar her satırı bir kez okuyor. Arabelleğe alınmış bir sonuç talep etmezler veya getirmenin başarılı olduğuna dair kanıt olarak SELECT satır sayısı kullanmazlar. |
SQLSRV, dizi fetch sonuna ulaştığında false ve fetch hatasında null döndürür. PDO'nun fetch yöntemi, sonunda false döndürür; istisna modu ayarlandığında, bir veritabanı getirme hatası fırlatılır. Her iki API'de de OptionalCount alanının kendisi PHP null içerir. O alan değeri, sonuç sonu işareti değildir.
Yazma işlemi doğrulama sorgusundan önce yapılır. Daha sonraki bir okuma başarısız olursa, daha önce commit edilmiş yazma işlemi geri alınamaz. Bu örnekte, satır sadece temizlik işleminin sildiği geçici bir tabloya aittir. Kalıcı tablolu bir uygulamada, başarısızlığı doğru şekilde bildirin ve belirsiz bir commit sonucundan sonra körü körüne eklemeyi tekrarlamayın.
Arızayı ve temizlemeyi yönetin
catch bloğu aktif bir işlemi geri alır ve başarısızlığı yeniden fırlatır.
finally bloğu ifadeyi serbest bırakır, geçici tabloyu siler ve bağlantıyı serbest bırakır. Temizlik hem başarı hem de başarısızlık yolunda çalışır. Geri alma veya tablo temizlemesi de başarısız olursa, program orijinal istisnayı önceki istisna olarak korur.
Komut satırı egzersizi için, yakalanmayan bir istisna, sıfır olmayan bir çıkış kodu ve bir hata mesajıyla PHP'yi durdurur. Bir web uygulamasında, isteği işleyen kodda yakalayın. Uygulama günlüğünüze tanı kaydetmeden önce hassas değerleri kaldırın ve uygun bir hata yanıtı döndürün. Bağlantı detaylarını, kimlik bilgilerini veya ham veritabanı hatalarını tarayıcıya açığa çıkarmayın.
| Failure | Denetlenecek şeyler |
|---|---|
| Uzatma fonksiyonu veya sürücü eksik | PHP sürecinin, eşleşen çalışma zamanı ve yapılandırma ile birlikte amaçlanan uzantıyı yüklediğini doğrulayın. Çalışan bir komut satırı PHP yapılandırması, web sunucunuzun bunu kullandığını kanıtlamaz. |
| Bağlantı veya sertifika hatası | Sorgu kodunu değiştirmeden önce uç noktayı, kimlik doğrulamayı, izinleri ve istemci sertifika güvenini kontrol edin. Sertifika doğrulamasını üretim çözümü olarak devre dışı bırakmayın. |
| Geçici tablo bulunamadı | Yapılandırma, yazma ve okumaları tek bir bağlantıda tutun. PDO kurulumunda, varsayılan hazırlanmış exec çağrısı ile değiştirmek yerine gösterilen query yolunu koruyun. |
| Beklenmedik değer veya PHP tipi | Getirme özelliklerini ve parametre açıklayıcılarını kontrol edin. Kesin doğrulamaları gevşek karşılaştırmalarla değiştirerek farkı gizlemeyin. |
| Yazma veya geri döndürme hatası | SQLSRV'nin hatalarını derhal yakalayın, ya da PDO istisnası. Rollback başarısızlıklarını da bildirin; rollback başarısız olursa yazmanın geri alındığını iddia etmeyin. |
| Bağlantı kaybından sonra temizleme hatası | Program sunucu tarafındaki düşüşü doğrulayamıyor. PHP handle serbest bırakmak, alt havuzlu fiziksel bağlantının hemen kapatıldığını kanıtlamaz. |
PHP uzantıları bağlama ve getirme API'lerini sağlar. ODBC sunucu ile iletişim kurar ve bağlantı havuzunu yönetir. SQL Server, geçici tablo kapsamını, işlemleri, kısıtlamaları ve işlenmiş verileri kontrol eder. Fiziksel bağlantının kapanmasına güvenmek yerine tabloyu açıkça bırakın.
Egzersizden sonra sil workflow-sqlsrv.php ve workflow-pdo.php artık ihtiyacın yoksa sile de. Test işlemini bitirdiğinizde credential ortamı değişkenlerini temizleyin. Her iki program da kaldırılacak kalıcı bir tablo bırakmaz.
Bu kılavuzlar SQL Server'ı hedefliyor. Azure SQL Veritabanı, Azure SQL Yönetilen Örneği, Azure Synapse Analytics, SQL database in Fabric ve Warehouse in Fabric için önce hedefin kimlik doğrulama ve T-SQL desteğini kontrol edin. Her iki Fabric ürünü de Microsoft Entra ID doğrulaması gerektirirken, Warehouse birden fazla aktif sonuç kümesinin (MARS) devre dışı bırakılması gerektirir. Bu SQL Server programları hizmete özgü işlem veya geçici tablo desteği sağlamaz.
Sonraki görevinizi seçin
İhtiyacınız olan davranış için iş akışını ilgili makaleyle genişletin.
| Görev | Guidance |
|---|---|
| Kimlik doğrulamayı seçin veya bağlantıları yönetin | Sunucuya bağlanılıyor. |
| Farklı değerlerle prepared statement'ı yeniden kullanın | Sorgu yürütme fonksiyonlarını karşılaştırın. |
| PDO doğrudan yürütmeyi veya hazırlanmış yürütmeyi seçin | Doğrudan ifade yürütme ve PDO_SQLSRV sürücüsünde hazırlanmış ifade yürütme. |
| Değerleri getir ve sonuç biçimlerini seç | Veri alınıyor. |
| Sonucu kaydırmak veya arabelleğe almak | Bir imleç tipi belirtmek ve satır seçmek. |
| Uygulama verilerini değiştir | Veri güncelleniyor. |
| PHP ve SQL tür dönüşümlerini kontrol edin | Veri türlerini dönüştürmek. |
| Arızaları teşhis et ve sürücü günlük kaydını etkinleştir | Hataları ve uyarıları işleme ve günlüğe kaydetme. |
| Hassas sütunları koruyun | SQL Server için PHP’ye yönelik Microsoft Sürücüleri ile Always Encrypted Kullanımı. |
| Üretim uygulamasını sertleştirin | SQL Server için Microsoft Drivers for PHP için güvenlik hususları. |