Làm cách nào để tạo truy vấn tham số PDO với câu lệnh LIKE?


107

Đây là nỗ lực của tôi về nó:

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

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

while ($results = $query->fetch()) 
{
    echo $results['column'];
}

Câu trả lời:


124

Tìm ra nó ngay sau khi tôi đăng:

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

while ($results = $query->fetch())
{
    echo $results['column'];
}

1
@Andrew: nếu likesử dụng nhiều thì sao? mảng thực thi nên thực thi theo thứ tự như thế nào?
logan

cảm ơn. đã gặp sự cố tương tự với csharp + Mysql + ODBC bằng cách sử dụng như nó sẽ không trả về bất kỳ hàng nào bằng cách sử dụng "select * từ bảng trong đó cột như '%?%';" nhưng nếu tôi làm như bạn đã làm "chọn * từ bảng có cột như thế nào ?;" và đặt chuỗi tham số sao cho: string frag = $ "% {searchFragment}%"; sau đó sử dụng frag cho giá trị tham số. Kỳ lạ
sdjuan

2
PDO nên thoát% đó trong lệnh gọi thực thi. Câu trả lời Kaqai là tốt hơn
Peter Bagnall

Có vẻ như đáng chú ý là đầu sử dụng đã góp phần lưu ý trên trang tài liệu PDOStatement :: bindParam Mời một cách tiếp cận khác nhau: Thêm ký hiệu phần trăm (s) vào biến trước khi ràng buộc nó.
Dan Robinson,

Hãy xem giải pháp của gavin, được lấy từ trang Your Common Sense, gần cuối chủ đề này. Đơn giản. Hợp lý.
RationalRabbit

85

Đối với những người sử dụng các tham số được đặt tên, đây là cách sử dụng LIKEvới %đối sánh từng phần cho cơ sở dữ liệu MySQL :

WHERE column_name LIKE CONCAT ('%',: riskstring, '%')

tham số được đặt tên ở đâu :dangerousstring.

Nói cách khác, sử dụng %các dấu hiệu không thoát rõ ràng trong truy vấn của riêng bạn, được phân tách và chắc chắn không phải là đầu vào của người dùng.

Chỉnh sửa: Cú pháp nối cho cơ sở dữ liệu Oracle sử dụng toán tử nối:, ||vì vậy nó sẽ đơn giản trở thành:

WHERE column_name LIKE '%' || : chuỗi nguy hiểm || '%'

Tuy nhiên, có những lưu ý khi @bobince đề cập ở đây rằng:

Các khó khăn đến khi bạn muốn cho phép một chữ %hoặc _nhân vật trong chuỗi tìm kiếm, mà không cần phải nó hoạt động như một ký tự đại diện.

Vì vậy, đó là điều khác cần chú ý khi kết hợp like và tham số hóa.


6
+1 - đây có vẻ như là một cách tiếp cận tốt đối với tôi vì tất cả các phép nối xảy ra trong cơ sở dữ liệu sau khi trình giữ chỗ đã được thay thế và nó có nghĩa là có thể sử dụng trình giữ chỗ được đặt tên. Điều đáng nói là cú pháp trên là dành cho Oracle - trong MySQL thì cú pháp là như vậy LIKE CONCAT('%', :something, '%'). Tham khảo: stackoverflow.com/a/661207/201648
Aaron Newton

1
Điều này không hiệu quả với tôi chính xác, nhưng đã giúp tôi đi đúng hướng. Tôi đã phải làm LIKE '%': cái gì đó '%' để nó hoạt động.
Christopher Smit

Tôi biết điều này là lạc đề nhưng tôi đã có thể thực hiện tiêm sql ngay cả khi sử dụng trạng thái này, tại sao?
Thiago Dias

Điều này không hiệu quả với tôi, tôi cũng đã thử nghiệm nó bằng lệnh SQL, SELECT * FROM calculation WHERE ( email LIKE '%' || luza || '%' OR siteLocation LIKE '%'|| luza ||'%' OR company LIKE '%' ||luza ||'%' )điều này sẽ cho tôi lỗi.
Luzan Baral

@AaronNewton and it means named placeholders can be used. Làm thế nào nó thậm chí là một vấn đề với trình giữ chỗ có tên khi bạn nối trong PHP? Rõ ràng là nối trong PHP hỗ trợ cả được đặt tên và vị trí và dễ di động hơn vì bạn có thể sử dụng cùng một truy vấn cho bất kỳ cơ sở dữ liệu nào. Tôi thực sự không hiểu tại sao nhiều người nghĩ rằng có bất kỳ sự khác biệt nào giữa trình giữ chỗ có tên và vị trí.
Your Common Sense

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';
}

1
Có lợi thế nào khi sử dụng điều này so với câu trả lời được chấp nhận không? Sử dụng có bindValuebảo vệ chống lại các cuộc tấn công tiêm không? Câu trả lời được chấp nhận về cơ bản phủ định giá trị của việc sử dụng ?trình giữ chỗ bằng cách nối chuỗi tìm kiếm để %thích trong những ngày xưa.
felwithe

Lợi ích của việc sử dụng phủ định trước $ query-> rowCount () == 0 là gì? Điều này thực sự có ý nghĩa?
ssi-anik

14

Bạn cũng có thể thử cái này. Tôi phải đối mặt với vấn đề tương tự nhưng đã có kết quả sau khi nghiên cứu.

$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);

Tôi đã chỉnh sửa bài đăng của bạn để đưa mã vào một khối mã - bạn có thể đọc thêm về định dạng bài đăng tại stackoverflow.com/help/formatting . Một số người dùng khác đã chọn phản đối câu trả lời của bạn mà không để lại nhận xét, vì vậy tôi không chắc chắn về nguyên nhân của phản đối.
josliber

2
Nhắc lại, tôi đã không bỏ phiếu cho câu hỏi của bạn; ai đó khác phản đối.
josliber

3

Những công việc này:

search `table` where `column` like concat('%', :column, '%')

2

Tôi nhận được điều này từ ảo tưởng php

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

Và nó hoạt động đối với tôi, rất đơn giản. Giống như anh ấy nói, bạn phải "chuẩn bị nghĩa đen hoàn chỉnh của chúng tôi trước" trước khi gửi nó đến truy vấn


0

PDO thoát khỏi "%" (Có thể dẫn đến chèn sql) : Việc sử dụng mã trước đó sẽ cho kết quả mong muốn khi tìm cách khớp các chuỗi một phần NHƯNG nếu khách truy cập nhập ký tự "%", bạn vẫn sẽ nhận được kết quả ngay cả khi bạn không t có bất kỳ thứ gì được lưu trữ trong cơ sở dữ liệu (nó có thể dẫn đến việc tiêm sql)

Tôi đã thử rất nhiều biến thể đều có cùng kết quả PDO đang thoát "%" dẫn đến kết quả tìm kiếm không mong muốn / không được giải thích.

Tôi mặc dù nó rất đáng để chia sẻ nếu ai đó tìm thấy một từ xung quanh nó, hãy chia sẻ nó


1
Đây là từ Hướng dẫn sử dụng: us3.php.net/manual/en/pdo.prepared-statements.php Đây là một bài đăng khác về chủ đề: stackoverflow.com/questions/22030451/… Tôi thực sự muốn biết ý kiến ​​của bạn về phát hành này.
Ozkar R

1
Giải pháp khả thi (Không được kiểm tra) Sử dụng CONCAT , như: $ sql = “SELECT item_title FROM item WHERE item_title LIKE CONCAT ('%',?, '%')”; Tham khảo: blog.mclaughlinsoftware.com/2010/02/21/php-binding-a-wildcard
Ozkar R

3
PDO không thoát%. Đó là mã của bạn làm sai. Đối với giải pháp, bạn phải đọc các câu trả lời đã được cung cấp ở đây
Your Common Sense,

Cảm ơn bạn đã gợi ý cho bạn. Dù sao mã được kiểm tra là mã từ hướng dẫn sử dụng, sử dụng trình giữ chỗ để tránh chèn SQL, tôi vẫn nhận được kết quả tương tự Ví dụ # 6 Sử dụng không hợp lệ trình giữ chỗ PDO không thoát% bằng cách sử dụng mã trên, không phải mã của tôi. Tôi là người mới tham gia diễn đàn và tôi có thể không hiểu quá trình bình luận, đăng bài và danh tiếng hoạt động như thế nào ở đây, tôi sẽ ghi nhớ điều đó cho lần tiếp theo của tôi, bởi vì dựa trên nhận xét trước đó, bạn cần danh tiếng để giúp người khác hoặc đưa ra nhận xét. cảm ơn.
Ozkar R
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.