如何着手实施带有参数的准备好的语句,这个查询甚至可能吗?
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);
所以我是 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);