PDO Параметризованный оператор SELECT с зацикленным условным обозначением

#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
}