Як створити параметризований запит PDO з оператором LIKE?


107

Ось моя спроба на це:

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

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

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

Відповіді:


124

З'ясував це відразу після публікації:

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

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

1
@Andrew: що робити, якщо likeвикористовується декілька ? як повинен виконуватися масив файлів для виконання?
— логан

Дякую. була аналогічна проблема з csharp + Mysql + ODBC, використовуючи, якби він не повертав жодних рядків, використовуючи "select * з таблиці, де стовпець на зразок"%?% ";" але якщо я буду так, як ви зробили "select * з таблиці, де стовпчик, як ?;" і встановіть рядок параметра таким чином: string frag = $ "% {searchFragment}%"; потім використовуйте frag для значення параметра. Weird
— sdjuan

2
PDO повинен уникати цього% у виклику виконання. Відповідь Какая краща
— Пітер Баньялл

Здається , варто відзначити , що топ користувачів сприяли приміткою на PDOStatement :: bindParam документації сторінка пропонує інший підхід: Додати знак відсотка (и) зі змінним до його зв'язування.
— Ден Робінсон

Подивіться на рішення Гевіна, взяте зі сторінки Вашого здорового глузду, внизу цієї теми. Простий. Логічні.
— RationalRabbit

85

Для тих, хто використовує названі параметри, ось як використовувати LIKEз %частковою відповідністю для баз даних MySQL :

WHERE_ ім'я стовпця LIKE CONCAT ('%',: dangerousstring, '%')

де вказаний параметр :dangerousstring.

Іншими словами, використовуйте %у власному запиті явно нерозміщені знаки, які відокремлюються і, безумовно, не вводяться користувачами.

Редагувати: Синтаксис конкатенації для баз даних Oracle використовує оператор конкатенації:, ||тому він просто стане:

WHERE_ ім'я стовпця LIKE '%' || : небезпечний рядок || '%'

Однак є застереження, як @bobince згадує тут :

Труднощі виникає , коли ви хочете , щоб в буквальному сенсі %або _символ в рядку пошуку, без нього виступати в якості шаблону.

Тож це ще щось, на що слід звернути увагу, поєднуючи вподобання та параметризацію.


6
+1 - це здається мені хорошим підходом, оскільки все конкатенація відбувається в базі даних після того, як замість заповнювача заповниться, і це означає, що можна використовувати названі заповнювачі. Варто згадати, що вищевказаний синтаксис призначений для Oracle - у MySQL синтаксис є LIKE CONCAT('%', :something, '%'). Довідка: stackoverflow.com/a/661207/201648
— Аарон Ньютон

1
Це не спрацювало точно для мене, але привело мене в правильний шлях. Мені довелося зробити ПОДОБУВАННЯ "%": щось "%", щоб воно працювало.
— Крістофер Сміт

Я знаю, що це поза темою, але мені вдалося здійснити інжекцію sql, навіть використовуючи цю статтю, чому?
— Тіаго Діас

Це не спрацювало для мене, я також тестував його за допомогою команди SQL, SELECT * FROM calculation WHERE ( email LIKE '%' || luza || '%' OR siteLocation LIKE '%'|| luza ||'%' OR company LIKE '%' ||luza ||'%' )це дало б мені помилку.
— Лузан Барал

@AaronNewton and it means named placeholders can be used. Як навіть виникає проблема з названими заповнювачами, коли ви об'єдналися в PHP? Очевидно, що об'єднання в PHP підтримує і названі, і позиційні, і більш портативні, оскільки ви можете використовувати один і той же запит для будь-якої бази даних. Я не розумію , чому так багато людей , думає , що є якась - або різниця між іменованих і позиційними наповнювачами.
— Твій здоровий глузд

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
Чи є якась перевага використання цього над прийнятою відповіддю? Чи використовує bindValueзахист від ін'єкційних атак? Прийнята відповідь, в основному, заперечує значення використання ?заповнювачів шляхом об'єднання рядка пошуку, %як у дні ваших днів.
— felwithe

Який сенс використовувати заперечення перед $ query-> rowCount () == 0? Це насправді має сенс?
— ssi-anik

14

Ви також можете спробувати цей. Я стикаюся з подібною проблемою, але отримав результат після досліджень.

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

Я відредагував вашу публікацію, щоб ввести код у блок коду - докладніше про форматування публікацій ви можете прочитати на сайті stackoverflow.com/help/formatting . Інший користувач вирішив оскаржити вашу відповідь, не залишаючи коментарів, тож я не впевнений у причині протидії.
— josliber

2
Повторюсь, я не проголосував за ваше запитання; хтось інший зголосився.
— josliber


2

Я отримав це через марення PHP

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

І це працює для мене, дуже просто. Як він каже, ви повинні "підготувати наш повний буквальний текст", перш ніж надсилати його на запит


0

PDO уникає "%" (це може призвести до введення sql) : Використання попереднього коду дасть бажання отримати результати, якщо шукати відповідність часткових рядків, АЛЕ, якщо відвідувач набере символ "%", ви все одно отримаєте результати, навіть якщо не будете " не мати нічого, що зберігається в базі даних (це може призвести до введення sql)

Я спробував багато варіацій, все з тим самим результатом PDO уникає "%", ведучи небажані / невикористані результати пошуку.

Я хоч варто було поділитися, якщо хтось знайшов навколо нього слово, будь ласка, поділіться ним


1
Це з Керівництва: us3.php.net/manual/en/pdo.prepared-statements.php Це ще один пост , де про цю тему: stackoverflow.com/questions/22030451 / ... я owuld дійсно хотів би знати Вашу думку про це питання.
— Ozkar R

1
Можливе рішення (Не перевірено) Використовуйте CONCAT , як-от: $ sql = «ВИБІРТЕ item_title З елемента, ЩО item_title LIKE CONCAT ('%',?, '%')»; Довідка: blog.mclaughlinsoftware.com/2010/02/21/php-binding-a-wildcard
— Ozkar R

3
PDO не уникає%. Це ваш код, який робить це неправильно. На вирішення ви повинні прочитати відповіді, які вже надані тут
— Ваше здорове почуття,

Дякую за ваші пропозиції. У будь-якому випадку тестований код був кодом з посібника, використовуючи заповнювач, щоб уникнути ін'єкції SQL, я все одно отримую той самий результат Приклад №6 Неправильне використання PDO- заповнення місця заповнення % використовує вищевказаний код, а не мій код. Я новачок у форумі, і я, можливо, не розумію, як тут працює процес коментування, публікації та репутації, я пам’ятатиму про це для свого наступного, тому що виходячи з попереднього коментаря вам потрібна репутація, щоб допомогти іншим або зробити коментарі. Дякую.
— Ozkar R
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.