如何着手实施带有参数的准备好的语句,这个查询甚至可能吗?

How to go about implementing prepared statements with parameters, is it even possible with this query?

所以我是 MySQL 和 PHP 的新手,并且我建立了一个基于条件的查询,因为我们的数据库结构有点奇怪。在进一步开发之前,我想通过使用参数的准备好的语句来实现查询以防止注入。我看了一个视频说使用 real_escape_string 可以防止 sql 注入,所以我的第一个问题是,这就足够了吗?或者参数是绝对必要的。我感觉他们是。接下来的问题是,除了它很长之外,我实现它的方式有什么问题吗?一个表单基本上有4个下拉,每个下拉包含5个选项,用户可以从每个下拉select 1个选项,然后提交。使用 $_POST 变量,我 select 以我能想到的最好的方式从数据库中得到我需要的东西。所以,如果我这样做没有任何问题,那么我的问题是,我将在哪里以及如何开始用它来实现准备好的语句?我已经研究过了,但是很难理解我正在发生的事情。我在想我需要相同的 if-else 条件来设置参数,但我仍然对放置 ? 的位置感到困惑。如果有人能帮助我,我将不胜感激。谢谢....大查询如下:

此外,getHourValue() returns 一个附加字符串,其中包含一个查询序列,具体取决于 $_POST['hours'] 中的值,因为它是一个被反复使用的非常长的片段,我把它放在一个函数中。

            if($_POST['category'] == "anywhere") {
                if($_POST['food'] == "No") {
                    if($_POST['extra'] == "anything") {
                        $sql = "SELECT name, description FROM pubs WHERE (food LIKE '%Yes%' " . getHourValue($_POST['hours']) . ") 
                        OR (food LIKE '%No%' " . getHourValue($_POST['hours']) . ")";
                    }
                    else if($_POST['extra'] == "everything") {
                        $sql = "SELECT name, description FROM pubs WHERE (food LIKE '%Yes%' AND pool LIKE '%Yes%' AND dancing LIKE '%Yes%' AND tv LIKE '%Yes%' "
                                . getHourValue($_POST['hours']) . ") OR (food LIKE '%No%'
                                AND pool LIKE '%Yes%' AND dancing LIKE '%Yes%' AND tv LIKE '%Yes%' "
                                . getHourValue($_POST['hours']) . ")";
                    }
                    else {
                        $sql = "SELECT name, description FROM pubs WHERE (food LIKE '%Yes%' AND " . $_POST['extra'] . " LIKE '%Yes%' " . getHourValue($_POST['hours']) .") 
                        OR (food LIKE '%No%' AND " . $_POST['extra'] . " LIKE '%Yes%' " . getHourValue($_POST['hours']) . ")";
                    }
                }
                else if($_POST['extra'] == "anything") {
                    $sql = "SELECT name, description FROM pubs WHERE food LIKE '%Yes%' "
                            . getHourValue($_POST['hours']);
                }
                else if($_POST['extra'] == "everything") {
                    $sql = "SELECT name, description FROM pubs WHERE food LIKE '%Yes%'
                            AND pool LIKE '%Yes%' AND dancing LIKE '%Yes%' AND tv LIKE '%Yes%' " 
                            . getHourValue($_POST['hours']);
                }
                else { 
                    $sql = "SELECT name, description FROM pubs WHERE food LIKE '%Yes%' 
                            AND " . $_POST['extra'] . " LIKE '%Yes%' "
                            . getHourValue($_POST['hours']);
                }
            }
            else {
                if($_POST['food'] == "No") {
                    if($_POST['extra'] == "anything") {
                        $sql = "SELECT name, description FROM pubs WHERE (category LIKE '%" . $_POST['category'] . "%' " . getHourValue($_POST['hours']) . "
                                AND food LIKE '%Yes%') OR (category LIKE '%" . $_POST['category'] . "%' " . getHourValue($_POST['hours']) . " AND food LIKE '%No%')";

                    }
                    else if($_POST['extra'] == "everything") {
                        $sql = "SELECT name, description FROM pubs WHERE (category LIKE '%" . $_POST['category'] . "%'"
                                . getHourValue($_POST['hours']) . " AND food LIKE '%Yes%' AND pool LIKE '%Yes%' AND dancing LIKE '%Yes%' AND tv LIKE '%Yes%') 
                                OR (category LIKE '%" . $_POST['category'] . "%'"  
                                . getHourValue($_POST['hours']) . " AND food LIKE '%No%' AND pool LIKE '%Yes%' AND dancing LIKE '%Yes%' AND tv LIKE '%Yes%')";
                    }
                    else {
                        $sql = "SELECT name, description FROM pubs WHERE (category LIKE '%" . $_POST['category'] . "%' "
                            . getHourValue($_POST['hours']) . " AND food LIKE '%Yes%' AND " . $_POST['extra'] . " LIKE '%Yes%') OR (category LIKE '%" . $_POST['category'] . "%' " . getHourValue($_POST['hours']) . " 
                            AND food LIKE '%No%' AND " . $_POST['extra'] . " LIKE '%Yes%')";
                    }
                }
                else if($_POST['extra'] == "anything") {
                    $sql = "SELECT name, description FROM pubs WHERE category LIKE '%" . $_POST['category'] . "%'
                            AND food LIKE '%Yes%' "
                            . getHourValue($_POST['hours']);
                }
                else if($_POST['extra'] == "everything") {
                    $sql = "SELECT name, description FROM pubs WHERE category LIKE '%" . $_POST['category'] . "%'
                            AND food LIKE '%Yes%' AND pool LIKE '%Yes%' AND dancing LIKE '%Yes%' AND tv LIKE '%Yes%' "
                            . getHourValue($_POST['hours']);
                }
                else {
                    $sql = "SELECT name, description FROM pubs WHERE category LIKE '%" . $_POST['category'] . "%'
                            AND food LIKE '%Yes%' AND " . $_POST['extra'] . " LIKE '%Yes%' "
                            . getHourValue($_POST['hours']);
                }
            }

您可能应该创建某种查询生成器(或使用框架中的现有查询生成器)。在上面的代码中添加准备好的语句会使它变得更加复杂(尽管这不是借口)。

示例:您将所有条件收集到一个数组中,为每个条件注入占位符,然后在 PDO 语句上绑定值。

注意:以下未测试。

<?php

$sql = 'SELECT name, description FROM pubs';
$where = [];
$params = [];

// If condition
// then add it to where
// $where[] = '(field1 = :field1)';
// $params[':field1'] = $_POST['field1'];

// If another condition
// then add to where
// $where[] = 'field2 = :field2';
// $params[':field2'] = $_POST['field2'];

// Combine where conditions (you may need to implement both AND and OR)
if (!empty($where)) {
    $sql .= ' WHERE '.implode(' AND ', $where);
}

// Assuming this is your pdo object
$statement = $pdo->prepare($sql);

// Bind your parameter values
if (!empty($params)) {
    foreach ($params as $key => $value) {
        $statement->bindValue($key, $value, \PDO::_PARAM_STR);
    }
}

// Then fetch the records
$statement->execute();

$result = $statement->fetchAll(PDO::FETCH_ASSOC);

var_dump($result);