Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/239.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
准备语句PHP中的多变量_Php_Mysql_Prepared Statement - Fatal编程技术网

准备语句PHP中的多变量

准备语句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

我在准备SQL语句时遇到问题:

$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,我是这个世界上的新手,正如你所看到的,分类是由用户选择的,他可以选择三个,这样就不会有其他的可能性了,我相信还有其他更好的方法,我会找出我能做些什么