Jak utworzyć sparametryzowane zapytanie PDO z instrukcją LIKE?


108

Oto moja próba:

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

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

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

Odpowiedzi:


124

Zrozumiałem to zaraz po tym, jak opublikowałem:

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

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

1
@Andrew: a co, jeśli likeużyto wielu ? w jaki sposób tablica execute powinna być wykonywana w kolejności?
— logan

dzięki. miał podobny problem z csharp + Mysql + ODBC, używając w ten sposób żadnych wierszy przy użyciu polecenia „select * from table, gdzie kolumna taka jak '%?%';” ale czy jeśli tak jak ty zrobiłeś "wybierz * z tabeli, gdzie kolumna taka jak?;" i ustaw ciąg parametrów tak: string frag = $ "% {searchFragment}%"; następnie użyj frag jako wartości parametru. Dziwne
— sdjuan

2
PDO powinno uciekać przed tym% w wywołaniu execute. Odpowiedź Kaqai jest lepsza
— Peter Bagnall

Wydaje się, że warto zauważyć, że najwyższa notatka wniesiona przez użytkowników na stronie dokumentacji PDOStatement :: bindParam oferuje inne podejście: dodaj znak (i) procentu do zmiennej przed jej związaniem.
— Dan Robinson,

Spójrz na rozwiązanie Gavina, zaczerpnięte ze strony Your Common Sense, u dołu tego wątku. Prosty. Logiczny.
— RationalRabbit

85

Dla tych, którzy używają nazwanych parametrów, oto jak używać LIKEz %częściowym dopasowaniem dla baz danych MySQL :

WHERE nazwa_kolumny LIKE CONCAT („%”,: niebezpieczny ciąg, „%”)

gdzie nazwany parametr jest :dangerousstring.

Innymi słowy, %we własnym zapytaniu używaj jawnie znaków bez zmiany znaczenia, które są oddzielone i na pewno nie są danymi wejściowymi użytkownika.

Edycja: składnia konkatenacji dla baz danych Oracle używa operatora konkatenacji:, ||więc po prostu stanie się:

GDZIE nazwa_kolumny LIKE '%' || : niebezpieczny ciąg || „%”

Istnieją jednak zastrzeżenia, ponieważ @bobince wspomina tutaj, że:

Trudność pojawia się, gdy chcesz zezwolić dosłownym %lub _znak w ciągu wyszukiwania, bez konieczności działać jako zamiennika.

Jest to więc coś, na co należy uważać podczas łączenia polubień i parametryzacji.


6
+1 - wydaje mi się, że to dobre podejście, ponieważ cała konkatenacja odbywa się w bazie danych po zastąpieniu symbolu zastępczego, a to oznacza, że ​​można użyć nazwanych symboli zastępczych. Warto wspomnieć, że powyższa składnia dotyczy Oracle - w MySQL jest to składnia LIKE CONCAT('%', :something, '%'). Źródła: stackoverflow.com/a/661207/201648
— Aaron Newton,

1
To nie zadziałało w moim przypadku, ale skierowało mnie na właściwą drogę. Musiałem zrobić LIKE '%': coś '%', żeby to zadziałało.
— Christopher Smit,

Wiem, że to nie na temat, ale udało mi się wykonać wstrzyknięcie sql nawet przy użyciu tego stwierdzenia, dlaczego?
— Thiago Dias

To nie zadziałało dla mnie, przetestowałem to również za pomocą polecenia SQL, SELECT * FROM calculation WHERE ( email LIKE '%' || luza || '%' OR siteLocation LIKE '%'|| luza ||'%' OR company LIKE '%' ||luza ||'%' )co dałoby mi błąd.
— Luzan Baral

@AaronNewton and it means named placeholders can be used. Jak to jest w ogóle problem z nazwanymi symbolami zastępczymi podczas konkatenacji w PHP? Oczywiście konkatenacja w PHP obsługuje zarówno nazwane, jak i pozycyjne i jest bardziej przenośna, ponieważ możesz użyć tego samego zapytania dla dowolnej bazy danych. I naprawdę nie rozumiem, dlaczego tak wielu ludzi, że istnieje jakikolwiek różnica między nazwanych i pozycyjnych zastępcze.
— Twój zdrowy rozsądek

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
Czy jest jakaś przewaga używania tego nad zaakceptowaną odpowiedzią? Czy używanie bindValuechroni przed atakami iniekcyjnymi? Zaakceptowana odpowiedź w zasadzie neguje wartość używania ?symboli zastępczych, łącząc ciąg wyszukiwania %z polubieniem w dawnych dniach.
— felwithe

Jaki jest sens używania negacji przed $ query-> rowCount () == 0? Czy to rzeczywiście ma sens?
— ssi-anik

15

Możesz także spróbować tego. Mam podobny problem, ale po badaniach uzyskałem wynik.

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

Edytowałem Twój post, aby umieścić kod w bloku kodu - możesz przeczytać więcej o formatowaniu postów na stackoverflow.com/help/formatting . Jakiś inny użytkownik zdecydował się zagłosować przeciw Twojej odpowiedzi bez pozostawiania komentarza, więc nie jestem pewien, co jest przyczyną takiego głosu.
— josliber

2
Powtarzam, nie głosowałem nad twoim pytaniem; ktoś inny przegłosował.
— josliber

3

To działa:

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

2

Mam to z urojeń php

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

U mnie to działa, bardzo proste. Jak mówi, przed wysłaniem go do zapytania należy najpierw „przygotować nasz kompletny dosłowny”


0

PDO ucieka „%” (może prowadzić do wstrzyknięcia sql) : Użycie poprzedniego kodu da pożądane rezultaty, gdy szuka się dopasowania częściowych ciągów, ALE jeśli odwiedzający wpisze znak „%”, nadal otrzymasz wyniki, nawet jeśli tego nie zrobisz nie mam nic zapisanego w bazie danych (może to prowadzić do wstrzyknięć sql)

Wypróbowałem wiele wariacji, wszystkie z tym samym rezultatem PDO ucieka przed „%” wiodącymi niechcianymi / niespodziewanymi wynikami wyszukiwania.

Pomyślałam, że warto się tym podzielić, jeśli ktoś znalazł przy nim jakieś słowo, proszę o podzielenie się nim


1
To pochodzi z podręcznika: us3.php.net/manual/en/pdo.prepared-statements.php To kolejny post na ten temat: stackoverflow.com/questions/22030451/ ... Naprawdę chciałbym poznać Twoją opinię na temat ten problem.
— Ozkar R

1
Możliwe rozwiązanie (Nie testowano) Użyj CONCAT , na przykład: $ sql = „SELECT item_title FROM item WHERE item_title LIKE CONCAT ('%',?, '%')”; Źródła
— Ozkar R

3
PDO nie wymyka się%. To twój kod robi to źle. Aby uzyskać rozwiązanie, powinieneś przeczytać odpowiedzi już podane tutaj
— Your Common Sense

Dziękuję za sugestie. W każdym razie testowany kod był kodem z podręcznika, używając symbolu zastępczego, aby uniknąć iniekcji SQL, nadal otrzymuję ten sam wynik. Przykład # 6 Nieprawidłowe użycie zastępczego PDO powoduje zmianę% przy użyciu powyższego kodu, a nie mojego kodu. Jestem nowy na forum i być może nie rozumiem, jak działa tutaj proces komentowania, publikowania postów i reputacji. Będę o tym pamiętać przy następnym, ponieważ na podstawie poprzedniego komentarza potrzebujesz reputacji, aby pomagać innym lub komentować. dzięki.
— Ozkar R
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.