PHP - Using PDO with IN clause array

前端 未结 8 1699
失恋的感觉
失恋的感觉 2020-11-21 06:03

I\'m using PDO to execute a statement with an IN clause that uses an array for its values:

$in_array = array(1, 2, 3);
$in_values = implode(\',\'         


        
8条回答
  •  面向向阳花
    2020-11-21 06:44

    PDO is not good with such things. You need to create a string with placeholders dynamically and insert it into the query, while binding array values the usual way. With positional placeholders it would be like this:

    $in  = str_repeat('?,', count($in_array) - 1) . '?';
    $sql = "SELECT * FROM my_table WHERE my_value IN ($in)";
    $stm = $db->prepare($sql);
    $stm->execute($in_array);
    $data = $stm->fetchAll();
    

    In case there are other placeholders in the query, you could use the following approach (the code is taken from my PDO tutorial):

    You could use array_merge() function to join all the variables into a single array, adding your other variables in the form of arrays, in the order they appear in your query:

    $arr = [1,2,3];
    $in  = str_repeat('?,', count($arr) - 1) . '?';
    $sql = "SELECT * FROM table WHERE foo=? AND column IN ($in) AND bar=? AND baz=?";
    $stm = $db->prepare($sql);
    $params = array_merge([$foo], $arr, [$bar, $baz]);
    $stm->execute($params);
    $data = $stm->fetchAll();
    

    In case you are using named placeholders, the code would be a little more complex, as you have to create a sequence of the named placeholders, e.g. :id0,:id1,:id2. So the code would be:

    // other parameters that are going into query
    $params = ["foo" => "foo", "bar" => "bar"];
    
    $ids = [1,2,3];
    $in = "";
    $i = 0;// we are using an external counter 
    // because the actual array keys could be dangerous
    foreach ($ids as $item)
    {
        $key = ":id".$i++;
        $in .= "$key,";
        $in_params[$key] = $item; // collecting values into a key-value array
    }
    $in = rtrim($in,","); // :id0,:id1,:id2
    
    $sql = "SELECT * FROM table WHERE foo=:foo AND id IN ($in) AND bar=:bar";
    $stm = $db->prepare($sql);
    $stm->execute(array_merge($params,$in_params)); // just merge two arrays
    $data = $stm->fetchAll();
    

    Luckily, for the named placeholders we don't have to follow the strict order, so we can merge our arrays in any order.

提交回复
热议问题