匹配多列的位置... PHP PDO

时间:2015-05-29 16:01:47

标签: php mysql angularjs

我有一个有效的搜索查询,但不是我希望的方式。这里:

 try{
    /*

    Create Search Query. 

    */

    //Include database config file.
    include('config.php');
    //Get values from Angular.
    $valuesPost=$_POST;
    $values=array();
    foreach ($valuesPost as $rows) {
        $decodedValues=json_decode($rows, TRUE);
        $values[]=$decodedValues;
    }
    //Get table from post values.
    $table=$values[0]["table"];
    //Get limit from post values.
    $limit=$values[0]["limit"];
    //Get offset from post values.
    $offset=$values[0]["offset"];
    //Get orderBy from post values.
    $orderBy=$values[0]["orderBy"];
    //Unset Whole array
    unset($values[0]);

    //Create cats fields
        $cats=array_keys($values[1]);
        if(empty($cats)) {
            $cats = null;
        } else {
            foreach($cats as &$val){
                $val="cat_id = :".$val;
            }
            $cats=implode(" OR ", $cats);
        }
    //Create subCats fields
        $subCats=array_keys($values[2]);
        if(empty($values[2])) {
            $subCats[0] = null;
        } else {
            foreach($subCats as &$val){
                $val="sub_cat_id = :".$val;
            }
            $subCats=implode(" OR ", $subCats);
        }
    //Create colourCats fields
        $colourCats=array_keys($values[3]);
        if(empty($colourCats)) {
            $colourCats[0] = null;
        } else {
            foreach($colourCats as &$val){
                $val="colour_id = :".$val;
            }
            $colourCats=implode(" OR ", $colourCats);
        }
    $where = "";
    //Create Where Statement
        if(empty($cats[0]) && empty($subCats[0])){
            $where = $colourCats;
        }
        if(empty($cats[0]) && empty($colourCats[0])){
            $where = $subCats;
        }
        if(empty($subCats[0]) && empty($colourCats[0])){
            $where = $cats;
        }
        if(empty($colourCats[0]) && !empty($cats[0]) && !empty($subCats[0])){
            $where = $cats." AND ".$subCats;
        }
        if(empty($subCats[0]) && !empty($cats[0]) && !empty($colourCats[0])){
            $where = $cats." AND ".$colourCats;
        }
        if(empty($cats[0]) && !empty($subCats[0]) && !empty($colourCats[0])){
            $where = $subCats." AND ".$colourCats;
        }
        if(!empty($cats[0]) && !empty($subCats[0]) && !empty($colourCats[0])){
            $where = $cats." AND ".$subCats." AND ".$colourCats;
        }
    //Search query.
    $search="SELECT * FROM $table WHERE $where ORDER BY $orderBy LIMIT $limit OFFSET $offset";  
    /*  
    Database Connection.
    */

    //Crate a database connection variable: $conn and error checking attributes.    
    $conn = new PDO($DB_SETTINGS, $DB_USER, $DB_PASS);
    $conn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
    /*

    PDO WORK.

    */

    //SEARCH_LIKE_ALL QUERY!
    //Prepare query.
    $search_qry=$conn->prepare($search);
    //For each array index create array $rows.
    foreach ($values as $rows) {
        //Bind each value to $value_fields from $rows array.
        foreach ($rows as $key => &$value) {
            switch(gettype($value)) {
                case 'integer':
                case 'double':
                $search_qry->bindParam(':' . $key, $value, PDO::PARAM_INT);
                break;
                default:
                $search_qry->bindParam(':' . $key, $value, PDO::PARAM_STR);
            }
        }   
    }
    $search_qry->execute();
    $rows = $search_qry->fetchAll(PDO::FETCH_ASSOC);

    echo json_encode($rows);
} catch(PDOException $e) {
    echo 'ERROR: ' . $e->getMessage();
}

它构建查询很好。在我的angularjs脚本中,我构建了一个多维数组,其中index [0]包含诸如table,orderby和limits之类的数据。索引[1]包含一系列类别。索引[2]子类别数组和索引[3]颜色类别数组。我的问题是搜索查询带回了我不期望的数据。所以我要说我发送这种类型的数组:

values[0]={table: table, order_by: prod_code, limit: 10, offset 0}

values[1]={cat_id0: 1};

values[2]={sub_cat_id0: 1, sub_cat_id1: 3}

values[3]={colour_id0: 1, colour_id1: 2}

我只想要猫1中的产品与子猫2& 3和颜色id 1& 2.当我从数组中删除子cat id但仍处于搜索状态时,它正在改变顺序,我假设此产品稍后被颜色ID拾取。查询是错误的还是我搜索的方式。

从上面的数组:

$search="SELECT * FROM table WHERE cat_id=:cat_id0 AND sub_cat_id=:sub_cat_id0 OR sub_cat_id=:sub_cat_id1 AND colour_id=:colour_id0 OR colour_id=:colour_id1 ORDER BY prod_code LIMIT 10 OFFSET 0"

1 个答案:

答案 0 :(得分:1)

我认为您遇到的最大问题是ANDOR之间的优先顺序。

 SELECT a
      , b
      , c
      , a OR b AND c
      , (a OR b) AND c
   FROM ( SELECT 1 AS a UNION SELECT 0 ) a 
  CROSS
   JOIN ( SELECT 1 AS b UNION SELECT 0 ) b 
  CROSS
   JOIN ( SELECT 1 AS c UNION SELECT 0 ) c 
  WHERE NOT (a.a = b.b AND a.a = c.c)
  ORDER BY c, b, a 

     a       b       c  a OR b AND c  (a OR b) AND c  
------  ------  ------  ------------  --------------
     1       0       0             1               0
     0       1       0             0               0
     1       1       0             1               0
     0       0       1             0               0
     1       0       1             1               1
     0       1       1             1               1  

也就是说

 foo = a OR foo = b AND bar = c

评估为:

 ( foo = a ) OR ( foo = b AND bar = c )

当你可能想要的是:

 (foo = a OR foo = b ) AND ( bar = c )

我无法破译代码正在执行的操作。

例如,为什么在构建WHERE子句时需要所有这些条件的排列?为什么所有这些检查?为什么不简单,比如:

$where = " 1=1";
if (!empty($cats[0]) {
   $where .= " AND (" . $cats . ")";
} 
if (!empty($subCats[0]) {
   $where .= " AND (" . $subCats . ")";
} 
if (!empty($colourCats[0]) {
   $where .= " AND (" . $colourCats . ")";
} 

此外,测试平等的所有OR条件

   foo = a OR foo = b OR foo = c OR foo = d

使用IN

可以更优雅地表达
   foo IN (a,b,c,d)
//Create cats fields
    $cats=array_keys($values[1]);
    if(empty($cats)) {
        $cats = null;
    } else {

        $cats=" cat_id IN (". implode(",",$cats) . ");

    }