#php #mysql #loops #pdo #parameterized
#php #mysql #циклы #pdo #параметризованный
Вопрос:
Я переключаю веб-приложение, над которым я работаю, на PDO (из ужасного и небезопасного mysql_query), и у меня возникают некоторые трудности с тем, как адаптировать существующий запрос к новому формату. Запрос находит мультимедийные элементы определенных типов файлов:
GET отформатирован как: jpg, png, gif
(Приведенный ниже код избегал чего-либо, но был упрощен для этого примера)
$query = "SELECT * FROM `media` WHERE `active` = '1' AND `thumb` IS NULL ";
if($_GET['extensions']){
$extensions = array_filter(explode(',',str_replace(' ','',strtolower($_GET['extensions']))));
foreach($extensions as $extension){
$extension_sql[] = "`type` = '$extension' ";
}
if(count($extension_sql) > 0){
$query .= 'AND (' . implode('OR ', $extension_sql) . ')';
}
}
$query .= "ORDER BY `created` DESC ";
$result = mysql_query($query);
while($media = mysql_fetch_array($result)){
// Do stuff
}
Возможно, я собирался сделать это совершенно обратным образом, и для этого следовало бы использовать функцию IN (), но, несмотря на это, мне нужно преобразовать это в параметризованный оператор PDO, такой как:
$sth = $dbh->prepare("SELECT * FROM `media` WHERE `active` = '1' AND `thumb` IS NULL AND `type` IN(:set) ORDER BY `created` DESC ");
$types = implode(',', array_filter(explode(',',str_replace(' ','',strtolower($_GET['extensions']))));
$sth->bindParam(':set', $types);
$sth->execute();
while($datatype_option_row = $sth->fetch()){
// Do stuff
}
Очевидно, что это не сработает … но я пытаюсь быть эффективным и безопасным с небольшим успехом. Я мог бы выполнить цикл по типам файлов для создания SQL, а затем снова выполнить цикл по привязкам… но хотел посмотреть, есть ли у кого-нибудь здесь мудрый совет по другому подходу.
TL; DR: Пытаюсь найти наилучший способ параметризации динамических списков условных выражений SQL.
Заранее спасибо!
Ответ №1:
Как я понял, ключом была FIND_IN_SET
функция, поскольку это короткий список типов:
$type_sql = ($_GET['extensions'])? "AND FIND_IN_SET(`type`, :type)" : "";
$sth = $dbh->prepare("SELECT * FROM `media` WHERE `active` = '1' AND `thumb` IS NULL $type_sql ORDER BY `created` DESC ");
$sth->bindParam(':type', $_GET['extensions']);
$sth->execute();
while($media = $sth->fetch()){
// Do stuff
}