PHP - Using PDO with IN clause array

前端 未结 8 1895
失恋的感觉
失恋的感觉 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 07:03

    I've just come up against this problem and coded a small wrapper. It's not the prettiest or best code I'm sure, but it might help somebody so here it is:

    function runQuery(PDO $PDO, string $sql, array $params = [])
    {
        if (!count($params)) {
            return $PDO->query($sql);
        }
    
        foreach ($params as $key => $values) {
            if (is_array($values)) {
                // get placeholder from array, e.g. ids => [7,12,3] would be ':ids'
                $oldPlaceholder  = ':'.$key;
                $newPlaceholders = '';
                $newParams = [];
                // loop through array to create new placeholders & new named parameters
                for($i = 1; $i <= count($values); $i++) {
                    // this gives us :ids1, :ids2, :ids3 etc
                    $newKey = $oldPlaceholder.$i;
                    $newPlaceholders .= $newKey.', ';
                    // this builds an associative array of the new named parameters
                    $newParams[$newKey] = $values[$i - 1];
                }
                //trim off the trailing comma and space
                $newPlaceholders = rtrim($newPlaceholders, ', ');
    
                // remove the old parameter
                unset($params[$key]);
    
                // and replace with the new ones
                $params = array_merge($params, $newParams);
    
                // amend the query
                $sql = str_replace($oldPlaceholder, $newPlaceholders, $sql);
            }
        }
    
        $statement = $PDO->prepare($sql);
        $statement->execute($params);
        return $statement;
    }
    

    E.g, passing these in:

    SELECT * FROM users WHERE userId IN (:ids)
    
    array(1) {
      ["ids"]=>
      array(3) {
        [0]=>
        int(1)
        [1]=>
        int(2)
        [2]=>
        int(3)
      }
    }
    

    Becomes:

    SELECT * FROM users WHERE userId IN (:ids1, :ids2, :ids3)
    
    array(3) {
      [":ids1"]=>
      int(1)
      [":ids2"]=>
      int(2)
      [":ids3"]=>
      int(3)
    }
    

    It's not bulletproof, but as a sole dev for my needs it does the job fine, so far anyway.

提交回复
热议问题