准备语句PHP中的多变量
我在准备SQL语句时遇到问题:准备语句PHP中的多变量,php,mysql,prepared-statement,Php,Mysql,Prepared Statement,我在准备SQL语句时遇到问题: $statement = $conexion->prepare( 'SELECT * FROM celulares WHERE (MARCA = :marca ) AND (CATEGORIA = :categoria1 OR CATEGORIA = :categoria2 OR CATEGORIA = :categoria3) AND (CATEGORIA2 = :categoria1 OR
$statement = $conexion->prepare(
'SELECT * FROM celulares
WHERE (MARCA = :marca )
AND
(CATEGORIA = :categoria1 OR CATEGORIA = :categoria2 OR CATEGORIA = :categoria3)
AND
(CATEGORIA2 = :categoria1 OR CATEGORIA2 = :categoria2 OR CATEGORIA2= :categoria3)
AND
(CATEGORIA3 = :categoria1 OR CATEGORIA3 = :categoria2 OR CATEGORIA3 = :categoria3)');
WHERE (MARCA = :marca OR MARCA = :marca2 OR MARCA = :marca3 )
为占位符提供以下值:
$statement->execute(array(':categoria1' => $categoria1,
':categoria2' => $categoria2,
':categoria3' => $categoria3,
':marca' => $query
));
根据某些结果,$query值在应用程序开始时可能会发生变化:
if ($entrada == "LG") {
if ($query == "") {
$query = "LG";
} else {
$query = $query . ' OR MARCA = "LG" ';
}
}
if ($entrada == "APPLE") {
if ($query == "") {
$query = "APPLE";
} else {
$query = $query . ' OR MARCA = "APPLE" ';
}
}
if ($entrada == "HUAWEI") {
if ($query == "") {
$query = "HUAWEI";
} else {
$query = $query . ' OR MARCA = "HUAWEI" ';
}
}
我尝试了很多方法,但没有一种方法能够解决它返回空数组的问题,唯一有效的方法是更改我准备好的语句的这一行:
$statement = $conexion->prepare(
'SELECT * FROM celulares
WHERE (MARCA = :marca )
AND
(CATEGORIA = :categoria1 OR CATEGORIA = :categoria2 OR CATEGORIA = :categoria3)
AND
(CATEGORIA2 = :categoria1 OR CATEGORIA2 = :categoria2 OR CATEGORIA2= :categoria3)
AND
(CATEGORIA3 = :categoria1 OR CATEGORIA3 = :categoria2 OR CATEGORIA3 = :categoria3)');
WHERE (MARCA = :marca OR MARCA = :marca2 OR MARCA = :marca3 )
和结果一样,我认为这不是最好的方法
更新:
现在在我的查询中尝试使用IN语句(感谢大家的帮助)
现在看来:
$marcas = array("LG", "HUAWEI"); (Static values for test)
$inQuery = implode(',', array_fill(0, count($marcas), '?'));
$statement = $conexion->prepare(
'SELECT * FROM celulares
WHERE (MARCA = IN (' . $inQuery . '))
AND
(CATEGORIA = :categoria1 OR CATEGORIA = :categoria2 OR CATEGORIA = :categoria3)
AND
(CATEGORIA2 = :categoria1 OR CATEGORIA2 = :categoria2 OR CATEGORIA2= :categoria3)
AND
(CATEGORIA3 = :categoria1 OR CATEGORIA3 = :categoria2 OR CATEGORIA3 = :categoria3)');
foreach ($marcas as $k => $marca) {
$statement->bindValue(($k+1), $marca);
}
$statement->bindValue(':categoria1', $categoria1);
$statement->bindValue(':categoria2', $categoria2);
$statement->bindValue(':categoria3', $categoria3);
$statement->execute();
获取:警告:PDOStatement::execute():SQLSTATE[HY093]:无效参数编号:混合命名参数和位置参数
尝试修复它您可以简化查询:
SELECT * FROM celulares
WHERE (MARCA = :marca )
AND (:categoria1,:categoria2,:categoria3)
IN (
(CATEGORIA,CATEGORIA2,CATEGORIA3),
(CATEGORIA,CATEGORIA3,CATEGORIA2),
(CATEGORIA2,CATEGORIA,CATEGORIA3),
(CATEGORIA2,CATEGORIA3,CATEGORIA),
(CATEGORIA3,CATEGORIA,CATEGORIA2),
(CATEGORIA3,CATEGORIA2,CATEGORIA)
)
这样,您只需传入一次类别,并将其与三个类别的六种可能排列进行比较
也就是说,这表明您的数据库状态非常差。一般来说,拥有任何类型的“column2”、“column3”系统都是需要重新构建数据库的一个标志——像上面那样,最终得到的查询只会变得更糟
具体来说,在这种情况下,只需添加CATEGORIEA4
即可将需要定义的排列数量从6增加到24
编辑:我完全错过了中关于
:marca
和的部分-我太专注于数据库在类别方面的糟糕状态,对不起 您可以简化查询:
SELECT * FROM celulares
WHERE (MARCA = :marca )
AND (:categoria1,:categoria2,:categoria3)
IN (
(CATEGORIA,CATEGORIA2,CATEGORIA3),
(CATEGORIA,CATEGORIA3,CATEGORIA2),
(CATEGORIA2,CATEGORIA,CATEGORIA3),
(CATEGORIA2,CATEGORIA3,CATEGORIA),
(CATEGORIA3,CATEGORIA,CATEGORIA2),
(CATEGORIA3,CATEGORIA2,CATEGORIA)
)
这样,您只需传入一次类别,并将其与三个类别的六种可能排列进行比较
也就是说,这表明您的数据库状态非常差。一般来说,拥有任何类型的“column2”、“column3”系统都是需要重新构建数据库的一个标志——像上面那样,最终得到的查询只会变得更糟
具体来说,在这种情况下,只需添加CATEGORIEA4
即可将需要定义的排列数量从6增加到24
编辑:我完全错过了
中关于:marca
和的部分-我太专注于数据库在类别方面的糟糕状态,对不起 好吧,我修复了它,可能这不是解决它的最佳方法,但我现在有了这个:
我用POST中的条目填充数组
$query = array();
$index = 0;
foreach ($_POST as $entrada) {
switch($entrada) {
case "SAMSUNG":
$query[] = "SAMSUNG";
break;
case "LG":
$query[] = "LG";
break;
case "APPLE":
$query[] = "APPLE";
break;
case "HUAWEI":
$query[] = "HUAWEI";
break;
}
}
$inQuery = str_repeat('?,', count($query) - 1) . '?';
这是我的新查询:问题是我将“?”与占位符(:)混合在一起,这是不推荐的
$statement = $conexion->prepare(
"SELECT * FROM celulares
WHERE ( MARCA IN($inQuery))
AND
(CATEGORIA = ? OR CATEGORIA = ? OR CATEGORIA = ?)
AND
(CATEGORIA2 = ? OR CATEGORIA2 = ? OR CATEGORIA2= ?)
AND
(CATEGORIA3 = ? OR CATEGORIA3 = ? OR CATEGORIA3 = ?)");
然后我会选择这样的值
$c = 0;
foreach ($query as $q => $queries) {
$c++;
$statement->bindValue(($q+1), $queries);
}
$statement->bindValue($c+1, $categoria1);
$statement->bindValue($c+2, $categoria2);
$statement->bindValue($c+3, $categoria3);
$statement->bindValue($c+4, $categoria1);
$statement->bindValue($c+5, $categoria2);
$statement->bindValue($c+6, $categoria3);
$statement->bindValue($c+7, $categoria1);
$statement->bindValue($c+8, $categoria2);
$statement->bindValue($c+9, $categoria3);
$statement->execute();
$resultados = $statement->fetchAll();
我用很多查询做了很多测试,效果很好,可能是一个“肮脏”的解决方案,但我会继续学习
谢谢大家对我的帮助 好吧,我修复了它,可能这不是解决它的最佳方法,但我现在有了这个:
我用POST中的条目填充数组
$query = array();
$index = 0;
foreach ($_POST as $entrada) {
switch($entrada) {
case "SAMSUNG":
$query[] = "SAMSUNG";
break;
case "LG":
$query[] = "LG";
break;
case "APPLE":
$query[] = "APPLE";
break;
case "HUAWEI":
$query[] = "HUAWEI";
break;
}
}
$inQuery = str_repeat('?,', count($query) - 1) . '?';
这是我的新查询:问题是我将“?”与占位符(:)混合在一起,这是不推荐的
$statement = $conexion->prepare(
"SELECT * FROM celulares
WHERE ( MARCA IN($inQuery))
AND
(CATEGORIA = ? OR CATEGORIA = ? OR CATEGORIA = ?)
AND
(CATEGORIA2 = ? OR CATEGORIA2 = ? OR CATEGORIA2= ?)
AND
(CATEGORIA3 = ? OR CATEGORIA3 = ? OR CATEGORIA3 = ?)");
然后我会选择这样的值
$c = 0;
foreach ($query as $q => $queries) {
$c++;
$statement->bindValue(($q+1), $queries);
}
$statement->bindValue($c+1, $categoria1);
$statement->bindValue($c+2, $categoria2);
$statement->bindValue($c+3, $categoria3);
$statement->bindValue($c+4, $categoria1);
$statement->bindValue($c+5, $categoria2);
$statement->bindValue($c+6, $categoria3);
$statement->bindValue($c+7, $categoria1);
$statement->bindValue($c+8, $categoria2);
$statement->bindValue($c+9, $categoria3);
$statement->execute();
$resultados = $statement->fetchAll();
我用很多查询做了很多测试,效果很好,可能是一个“肮脏”的解决方案,但我会继续学习
谢谢大家对我的帮助 看一下,我认为您需要在查询中使用IN语句,并在php代码中使用switch case。我不认为您可以在preparedStatement中设置一个参数值,因为该值实际上是一个SQL语句,比如下面的$query=$query'或者MARCA=“APPLE”
,这看起来像sql注入,这也是创建PS的原因之一。要保护/逃脱。。。因此,您的查询值可能会作为文本(转义)插入,我建议您将数组作为$query
列表MARCAs
传递,然后使用它来构建SQL:“MARCA=:val1或MARCA=:val2”
。etc基于marcas数组长度,然后设置参数:val1,:val2…
并执行。看一看,我认为您需要在php代码的查询和切换案例中使用IN语句。我认为您不能在preparedStatement中设置参数值,因为该值实际上是SQL语句,像这个$query=$query'或者MARCA=“APPLE”
,这看起来像sql注入,这也是创建PS的原因之一。要保护/逃脱。。。因此,您的查询值可能会作为文本(转义)插入,我建议您将数组作为$query
列表MARCAs
传递,然后使用它来构建SQL:“MARCA=:val1或MARCA=:val2”
。基于marcas数组长度等,然后设置参数:val1,:val2…
,然后执行。谢谢你,Niet,我是这个世界上的新手,正如你所看到的,类别由用户选择,他可以选择三个,因此不会有其他可能性,我相信还有其他更好的方法可以做到这一点,我会找出我能做些什么谢谢你Niet,我是这个世界上的新手,正如你所看到的,分类是由用户选择的,他可以选择三个,这样就不会有其他的可能性了,我相信还有其他更好的方法,我会找出我能做些什么