Bagaimana cara membuat kueri berparameter PDO dengan pernyataan LIKE?

107

Inilah usaha saya:

$query = $database->prepare('SELECT * FROM table WHERE column LIKE "?%"');

$query->execute(array('value'));

while ($results = $query->fetch()) 
{
    echo $results['column'];
}
Andrew G. Johnson
sumber

Jawaban:

124

Menemukannya tepat setelah saya memposting:

$query = $database->prepare('SELECT * FROM table WHERE column LIKE ?');
$query->execute(array('value%'));

while ($results = $query->fetch())
{
    echo $results['column'];
}
Andrew G. Johnson
sumber
1
@ Andrew: bagaimana jika multipel likedigunakan? bagaimana cara mengeksekusi array secara berurutan?
logan
Terima kasih. memiliki masalah yang sama dengan csharp + Mysql + ODBC menggunakan seperti itu tidak akan mengembalikan baris apapun menggunakan "pilih * dari tabel di mana kolom seperti '%?%';" tetapi akankah jika saya melakukan seperti yang Anda lakukan "pilih * dari tabel di mana kolom seperti?;" dan setel parameter string jadi: string frag = $ "% {searchFragment}%"; lalu gunakan frag untuk nilai parameter. Aneh
sdjuan
2
PDO harus keluar dari% itu dalam panggilan eksekusi. Jawaban Kaqai lebih baik
Peter Bagnall
Tampaknya perlu dicatat bahwa catatan kontribusi pengguna teratas pada halaman dokumentasi PDOStatement :: bindParam menawarkan pendekatan yang berbeda: Tambahkan tanda persen ke variabel sebelum mengikatnya.
Dan Robinson
Lihatlah solusi gavin, diambil dari halaman Akal Sehat Anda, di dekat bagian bawah utas ini. Sederhana. Logis.
RationalRabbit
85

Bagi mereka yang menggunakan parameter bernama, berikut adalah cara untuk menggunakan LIKEdengan %pencocokan parsial untuk database MySQL :

DI MANA nama_kolom SEPERTI CONCAT ('%',: hazardstring, '%')

di mana parameter bernama :dangerousstring .

Dengan kata lain, gunakan %tanda yang tidak dapat di- escape secara eksplisit dalam kueri Anda sendiri yang dipisahkan dan yang pasti bukan input pengguna.

Edit: Sintaks penggabungan untuk database Oracle menggunakan operator penggabungan:, ||jadi itu hanya akan menjadi:

DI MANA nama_kolom SUKA '%' || : tali berbahaya || '%'

Namun ada peringatan seperti yang disebutkan @bobince di sini bahwa:

The kesulitan datang ketika Anda ingin memungkinkan literal %atau _karakter dalam string pencarian, tanpa harus bertindak sebagai wildcard.

Jadi, itu hal lain yang harus diperhatikan saat menggabungkan suka dan parameterisasi.

Kzqai
sumber
6
+1 - ini sepertinya pendekatan yang baik bagi saya karena semua penggabungan terjadi di database setelah placeholder diganti, dan itu berarti placeholder bernama dapat digunakan. Perlu disebutkan bahwa sintaks di atas adalah untuk Oracle - di MySQL sintaksnya adalah LIKE CONCAT('%', :something, '%'). Referensi: stackoverflow.com/a/661207/201648
Aaron Newton
1
Ini sebenarnya tidak berhasil untuk saya, tetapi membawa saya ke jalur yang benar. Saya harus melakukan LIKE '%': sesuatu '%' agar bisa bekerja.
Christopher Smit
Saya tahu ini di luar topik tetapi saya dapat melakukan injeksi sql bahkan dengan menggunakan pernyataan ini, mengapa?
Thiago Dias
Ini tidak berhasil untuk saya, saya juga mengujinya dengan perintah SQL, SELECT * FROM calculation WHERE ( email LIKE '%' || luza || '%' OR siteLocation LIKE '%'|| luza ||'%' OR company LIKE '%' ||luza ||'%' )ini akan memberi saya kesalahan.
Luzan Baral
@Aaron and it means named placeholders can be used. Bagaimana ini bahkan menjadi masalah dengan placeholder bernama ketika Anda menggabungkan dalam PHP? Jelas penggabungan dalam PHP mendukung nama dan posisi dan lebih portabel karena Anda dapat menggunakan kueri yang sama untuk database apa pun. Saya tidak benar-benar mengerti mengapa begitu banyak orang berpikir ada apa perbedaan antara nama dan posisi placeholder.
Akal Sehat Anda
18
$query = $database->prepare('SELECT * FROM table WHERE column LIKE ?');
$query->bindValue(1, "%$value%", PDO::PARAM_STR);
$query->execute();

if (!$query->rowCount() == 0) 
{
    while ($results = $query->fetch()) 
    {
        echo $results['column'] . "<br />\n";
    }       
} 
else 
{
    echo 'Nothing found';
}
Jaket
sumber
1
Apakah ada keuntungan menggunakan ini dibandingkan jawaban yang diterima? Apakah menggunakan bindValuemelindungi dari serangan injeksi? Jawaban yang diterima pada dasarnya meniadakan nilai menggunakan ?placeholder dengan menggabungkan string pencarian menjadi %like in ye days of olde.
felwithe
Apa gunanya menggunakan negasi sebelum $ query-> rowCount () == 0? Apakah ini masuk akal?
ssi-anik
14

Anda juga bisa mencoba yang ini. Saya menghadapi masalah yang sama tetapi mendapat hasil setelah penelitian.

$query = $pdo_connection->prepare('SELECT * FROM table WHERE column LIKE :search');

$stmt= $pdo_connection->prepare($query);

$stmt->execute(array(':search' => '%'.$search_term.'%'));

$result = $stmt->fetchAll(PDO::FETCH_ASSOC);

print_r($result);
Vijaysinh Parmar
sumber
Saya mengedit postingan Anda untuk memasukkan kode ke dalam blok kode - Anda dapat membaca lebih lanjut tentang format postingan di stackoverflow.com/help/formatting . Beberapa pengguna lain memilih untuk memberi suara negatif pada jawaban Anda tanpa meninggalkan komentar, jadi saya tidak yakin tentang penyebab penurunan suara tersebut.
josliber
2
Untuk mengulangi, saya tidak memberikan suara untuk pertanyaan Anda; orang lain tidak memilih.
josliber
3

Ini bekerja:

search `table` where `column` like concat('%', :column, '%')
kjdion84.dll
sumber
2

Saya mendapatkan ini dari delusi php

$search = "%$search%";
$stmt  = $pdo->prepare("SELECT * FROM table WHERE name LIKE ?");
$stmt->execute([$search]);
$data = $stmt->fetchAll();

Dan itu berhasil untuk saya, sangat sederhana. Seperti yang dia katakan, Anda harus "menyiapkan literal lengkap kami terlebih dahulu" sebelum mengirimkannya ke kueri

gavin
sumber
0

PDO lolos "%" (Dapat menyebabkan injeksi sql) : Penggunaan kode sebelumnya akan memberikan hasil yang diinginkan saat ingin mencocokkan sebagian string TETAPI jika pengunjung mengetik karakter "%", Anda masih akan mendapatkan hasil meskipun tidak ' t memiliki apa pun yang disimpan di basis data (dapat menyebabkan suntikan sql)

Saya telah mencoba banyak variasi, semuanya dengan hasil yang sama PDO keluar dari "%" yang mengarah ke hasil pencarian yang tidak diinginkan / tidak bersemangat.

Saya pikir itu layak untuk dibagikan jika ada yang menemukan kata di sekitarnya, tolong bagikan

Ozkar R
sumber
1
Ini dari Manual: us3.php.net/manual/en/pdo.prepared-statements.php Ini adalah posting lain tentang subjek: stackoverflow.com/questions/22030451/ .. Saya benar-benar ingin mengetahui pendapat Anda tentang masalah ini.
Ozkar R
1
Solusi yang memungkinkan (Tidak diuji) Gunakan CONCAT , seperti: $ sql = "PILIH item_title FROM item WHERE item_title LIKE CONCAT ('%',?, '%')”; Referensi: blog.mclaughlinsoftware.com/2010/02/21/php-binding-a-wildcard
R
3
PDO tidak lolos%. Kode Anda yang salah. Untuk solusinya, Anda diharapkan membaca jawaban yang sudah disediakan di sini
Akal
Terima kasih atas saran Anda. Bagaimanapun kode yang diuji adalah kode dari manual, menggunakan placeholder untuk menghindari injeksi SQL, saya masih mendapatkan hasil yang sama Contoh # 6 Penggunaan placeholder PDO yang tidak valid % tidak lolos menggunakan kode di atas, bukan kode saya. Saya baru mengenal forum dan saya mungkin tidak mengerti bagaimana proses komentar, posting dan reputasi bekerja di sini, saya akan mengingatnya untuk saya selanjutnya, karena berdasarkan komentar sebelumnya Anda membutuhkan reputasi untuk membantu orang lain atau memberi komentar. Terima kasih.
Ozkar R