Parametreli bir SELECT sorgusu için bir PDO nesnesini nasıl düzgün bir şekilde kullanabilirim


85

SELECTSorgu yapmak için PHP.net talimatlarını izlemeyi denedim, ancak bunu yapmanın en iyi yolunun ne olduğundan emin değilim.

SELECTMümkünse parametreleştirilmiş bir sorgu kullanmak istiyorum ID, namealanını parametreyle eşleşen bir tabloda döndürmek için . Bu, IDbenzersiz olacağı için bir döndürmelidir .

Sonra gibi bu kullanmak istiyorum IDbir için INSERTo başarılı olup olmadığını belirlemek gerekir bu yüzden, başka bir tabloya.

Ayrıca sorguları yeniden kullanım için hazırlayabileceğinizi okudum, ancak bunun nasıl yardımcı olduğundan emin değildim.

Yanıtlar:


158

Bunun gibi verileri seçersiniz:

$db = new PDO("...");
$statement = $db->prepare("select id from some_table where name = :name");
$statement->execute(array(':name' => "Jimbo"));
$row = $statement->fetch(); // Use fetchAll() if you want all results, or just iterate over the statement, since it implements Iterator

Aynı şekilde eklersiniz:

$statement = $db->prepare("insert into some_other_table (some_id) values (:some_id)");
$statement->execute(array(':some_id' => $row['id']));

PDO'yu hata durumunda istisnalar atacak şekilde yapılandırmanızı tavsiye ederim. Daha sonra PDOExceptionsorgulardan herhangi biri başarısız olursa bir alırsınız - Açıkça kontrol etmeye gerek yoktur. İstisnaları açmak için, $dbnesneyi oluşturduktan hemen sonra bunu çağırın :

$db = new PDO("...");
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

Yeni PDO'nuzun (...) olduğu PDOStatement'ı kastettiğinizi varsayıyorum, değil mi?
Joe Phillips

1
Hayır. PDO, bağlantı sınıfıdır (Muhtemelen bunun yerine PdoConnection olarak adlandırılmalıdır). Bağlantı, PdoStatements oluşturabilir. SetAttribute () öğesini tek tek ifadelerde değil, bağlantı nesnesinde çağırırsınız. (Alternatif olarak, bunu
kurucuya da iletebilirsiniz

1
bu yararlı olabilir:$db = new PDO('mysql:dbname=your_database;host=localhost', 'junior', '444');
Junior Mayhé

2
Satır için $statement->execute(array(':name' => "Jimbo"));, Jimbo kısmını açıklayabilir misin?
muttley91

1
@rar Önceki satırda, sorgu bir yer tutucuyla başlatılır :name. executeBurada arama , bir yer tutucu -> değer çiftleri ilişkisel dizisi ile yapılır. Dolayısıyla bu durumda, :nameyer tutucu Jimbo dizesiyle değiştirilecektir. Değer, gerçek sorgudan farklı bir kanala gönderildiği veya bu şekilde herhangi bir enjeksiyon saldırısını önlediği için, bunun basitçe bir dizi değiştirme yapmadığını unutmayın.
troelskn

16

Son zamanlarda PDO ile çalışıyorum ve yukarıdaki cevap tamamen doğru, ancak aşağıdakilerin de işe yaradığını belgelemek istedim.

$nametosearch = "Tobias";
$conn = new PDO("server", "username", "password");
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sth = $conn->prepare("SELECT `id` from `tablename` WHERE `name` = :name");
$sth->bindParam(':name', $nametosearch);
// Or sth->bindParam(':name', $_POST['namefromform']); depending on application
$sth->execute();

16
Hayır, hangi veritabanını kullanacağınızı seçmediğiniz için olmaz.
Rápli András

3
Bu aslında gerçekte şeklinde bir DSN olmalı "sunucu" dizesi, olmalıdır "{sürücü}: Dbname = {Db_name}; host = {sunucu}" küme ayracı değerlerini değiştirerek ne bağlantın ihtiyaçları
thorne51

12

İfadenizi hazırlamanıza yardımcı olması için bindParamveya bindValueyöntemlerini kullanabilirsiniz . $check->execute(array(':name' => $name));Özellikle birden çok değeri / değişkeni bağlıyorsanız, işleri ilk bakışta yapmak yerine daha net hale getirir .

Aşağıdaki net, okunması kolay örneği kontrol edin:

$q = $db->prepare("SELECT id FROM table WHERE forename = :forename and surname = :surname LIMIT 1");
$q->bindValue(':forename', 'Joe');
$q->bindValue(':surname',  'Bloggs');
$q->execute();

if ($q->rowCount() > 0){
    $check = $q->fetch(PDO::FETCH_ASSOC);
    $row_id = $check['id'];
    // do something
}

Birden fazla satır bekliyorsanız LIMIT 1, getirme yöntemini kaldırın ve şu şekilde değiştirin fetchAll:

$q = $db->prepare("SELECT id FROM table WHERE forename = :forename and surname = :surname");// removed limit 1
$q->bindValue(':forename', 'Joe');
$q->bindValue(':surname',  'Bloggs');
$q->execute();

if ($q->rowCount() > 0){
    $check = $q->fetchAll(PDO::FETCH_ASSOC);
    //$check will now hold an array of returned rows. 
    //let's say we need the second result, i.e. index of 1
    $row_id = $check[1]['id']; 
    // do something
}

Emin değil. Bana geçerli bir cevap gibi görünüyor. Sanırım 'isim' yerine 'myname' kullanmanın ve ayrıca tek bir parametre yerine birden çok parametrenin kullanılmasının fayda sağlayacağını düşünüyorum.
Joe Phillips

@GillianLoWong ne yapar $check = $q->fetch(PDO::FETCH_ASSOC); if (!empty($check)){ $row_id = $check['id']; // do something }?
Abdul

1
Merhaba @abdul, dizideki sayım / boş kontrolünü değiştirdim. Herhangi bir sonucun iade edilip edilmediğini görmesi gerekiyordu. Ancak pdo, herhangi bir satırın etkilenip etkilenmediğini / getirilip getirilmediğini kontrol etmenizi sağlayan rowCount () adlı bir işleve de sahiptir. Herhangi bir satırın seçilip seçilmediğini bile bilmiyorsanız, veri getirmenin bir anlamı yoktur, bu yüzden getirme ifadesini if ​​rowCount () ifadesine taşıdım. :)
Gilly

@Gillian La Wong, birden çok yerde sorgu için temiz bindValue sorgunuz için teşekkür ederiz. bu benim projemi kurtarıyor.
php-coder

6

Hepsi kullanıma hazır, biraz eksiksiz bir cevap burada:

    $sql = "SELECT `username` FROM `users` WHERE `id` = :id";
    $q = $dbh->prepare($sql);
    $q->execute(array(':id' => "4"));
    $done= $q->fetch();

 echo $done[0];

İşte $dbhüzerinde PDO'su db bağlantı birimini ve esaslı idtablodan usersaldığımız ettikusername kullanarakfetch();

Umarım bu birine yardımcı olur, tadını çıkarın!


Veya gerekli olmaktan fetchColumn()kaçınmak için kullanın [0]. Ayrıca, LIMIT 1SQL'de kullanmayı unutmayın .
rybo111

3

Yöntem 1: PDO sorgu yöntemini kullanın

$stmt = $db->query('SELECT id FROM Employee where name ="'.$name.'"');
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);

Satır Sayısını Alma

$stmt = $db->query('SELECT id FROM Employee where name ="'.$name.'"');
$row_count = $stmt->rowCount();
echo $row_count.' rows selected';

Yöntem 2: Parametreli İfadeler

$stmt = $db->prepare("SELECT id FROM Employee WHERE name=?");
$stmt->execute(array($name));
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

Yöntem 3: Bağlama parametreleri

$stmt = $db->prepare("SELECT id FROM Employee WHERE name=?");
$stmt->bindValue(1, $name, PDO::PARAM_STR);
$stmt->execute();
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

**bind with named parameters**
$stmt = $db->prepare("SELECT id FROM Employee WHERE name=:name");
$stmt->bindValue(':name', $name, PDO::PARAM_STR);
$stmt->execute();
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

or
$stmt = $db->prepare("SELECT id FROM Employee WHERE name=:name");
$stmt->execute(array(':name' => $name));
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

Daha fazla bilgi edinmek istiyorsanız bu bağlantıya bakın


4
Lütfen Yöntem 1'i kaldırın. Bu mysql enjeksiyonuna izin verir.
Tomahock

-2

tek sayfada satır içi kodlama kullanıyorsanız ve bu tam örnekle gitmek yerine oops kullanmıyorsanız, kesinlikle yardımcı olacaktır

//connect to the db
$dbh = new PDO('mysql:host=localhost;dbname=mydb', dbuser, dbpw); 

//build the query
$query="SELECT field1, field2
FROM ubertable
WHERE field1 > 6969";

//execute the query
$data = $dbh->query($query);
//convert result resource to array
$result = $data->fetchAll(PDO::FETCH_ASSOC);

//view the entire array (for testing)
print_r($result);

//display array elements
foreach($result as $output) {
echo output[field1] . " " . output[field1] . "<br />";
}

Bu kod parçacığı sorunu çözebilirken, soruyu neden veya nasıl yanıtladığını açıklamaz. Lütfen kodunuz için bir açıklamaya yer gerçekten Yayınınızla kalitesini artırmak için yardımcı olarak,. Gelecekte okuyucular için soruyu yanıtlayacağınızı ve bu kişilerin kod önerinizin nedenlerini bilmeyebileceklerini unutmayın. İşaretleyiciler / gözden geçirenler: Bunun gibi salt kod yanıtları için, olumsuz oy verin, silmeyin!
Scott Weldon

Öyleyse
Shiv Singh

Hayır, tam tersi. Bu gönderiye Düşük Kaliteli Gönderi Sırasında rastladım ve bu nedenle yorumumun son kısmı insanlara silmeleri için oy vermemelerini söylemekti . (Bunun yerine, olumsuz oy verme önerisi, gönderiniz düzenlendikten sonra kaldırılacak olan geçici olumsuz oylar gerektiriyordu.) Önceki yorumumda da belirtildiği gibi, yaptığınız kodu neden önerdiğinize dair bir açıklama eklemeniz daha iyi olacaktır. . Ayrıca, bu soru parametreleştirilmiş sorgular hakkında sorular sorar, ancak field > 6969parametreleştirilmiş olmaktan çok sabit kodlanmış görünür.
Scott Weldon
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.