我很好奇是否有可能使用PDO将值数组绑定到占位符。这里的用例试图传递一个值数组,以便与IN()条件一起使用。
我希望能够这样做:
<?php
$ids=array(1,2,3,7,8,9);
$db = new PDO(...);
$stmt = $db->prepare(
'SELECT *
FROM table
WHERE id IN(:an_array)'
);
$stmt->bindParam('an_array',$ids);
$stmt->execute();
?>
并让PDO绑定并引用数组中的所有值。
目前我正在做:
<?php
$ids = array(1,2,3,7,8,9);
$db = new PDO(...);
foreach($ids as &$val)
$val=$db->quote($val); //iterate through array and quote
$in = implode(',',$ids); //create comma separated list
$stmt = $db->prepare(
'SELECT *
FROM table
WHERE id IN('.$in.')'
);
$stmt->execute();
?>
这当然是工作,但只是想知道是否有一个内置的解决方案,我错过了?
稍微编辑一下施纳勒的代码
<?php
$ids = array(1, 2, 3, 7, 8, 9);
$inQuery = implode(',', array_fill(0, count($ids)-1, '?'));
$db = new PDO(...);
$stmt = $db->prepare(
'SELECT *
FROM table
WHERE id IN(' . $inQuery . ')'
);
foreach ($ids as $k => $id)
$stmt->bindValue(($k+1), $id);
$stmt->execute();
?>
//implode(',', array_fill(0, count($ids)-1), '?'));
//'?' this should be inside the array_fill
//$stmt->bindValue(($k+1), $in);
// instead of $in, it should be $id
您首先在查询中设置“?”的个数,然后由一个“for”发送参数
像这样:
require 'dbConnect.php';
$db=new dbConnect();
$array=[];
array_push($array,'value1');
array_push($array,'value2');
$query="SELECT * FROM sites WHERE kind IN (";
foreach ($array as $field){
$query.="?,";
}
$query=substr($query,0,strlen($query)-1);
$query.=")";
$tbl=$db->connection->prepare($query);
for($i=1;$i<=count($array);$i++)
$tbl->bindParam($i,$array[$i-1],PDO::PARAM_STR);
$tbl->execute();
$row=$tbl->fetchAll(PDO::FETCH_OBJ);
var_dump($row);
在MySQL和PDO中,我们可以使用JSON数组和JSON_CONTAINS() (https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#function_json-contains)进行搜索。
$ids = [123, 234, 345, 456]; // Array of users I search
$ids = json_encode($ids); // JSON conversion
$sql = <<<SQL
SELECT ALL user_id, user_login
FROM users
-- Cast is mandatory beaucause JSON_CONTAINS() waits JSON doc candidate
WHERE JSON_CONTAINS(:ids, CAST(user_id AS JSON))
SQL;
$search = $pdo->prepare($sql);
$search->execute([':ids' => $ids]);
$users = $search->fetchAll();
我们也可以使用JSON_TABLE() (https://dev.mysql.com/doc/refman/8.0/en/json-table-functions.html#function_json-table)进行更复杂的情况和JSON数据探索:
$users = [
['id' => 123, 'bday' => ..., 'address' => ...],
['id' => 234, 'bday' => ..., 'address' => ...],
['id' => 345, 'bday' => ..., 'address' => ...],
]; // I'd like to know their login
$users = json_encode($users);
$sql = <<<SQL
SELECT ALL user_id, user_login
FROM users
WHERE user_id IN (
SELECT ALL user_id
FROM JSON_TABLE(:users, '$[*]' COLUMNS (
-- Data exploration...
-- (if needed I can explore really deeply with NESTED kword)
user_id INT PATH '$.id',
-- I could skip these :
user_bday DATE PATH '$.bday',
user_address TINYTEXT PATH '$.address'
)) AS _
)
SQL;
$search = $pdo->prepare($sql);
$search->execute([':users' => $users]);
...
对我来说,更性感的解决方案是构造一个动态关联数组并使用它
// A dirty array sent by user
$dirtyArray = ['Cecile', 'Gilles', 'Andre', 'Claude'];
// we construct an associative array like this
// [ ':name_0' => 'Cecile', ... , ':name_3' => 'Claude' ]
$params = array_combine(
array_map(
// construct param name according to array index
function ($v) {return ":name_{$v}";},
// get values of users
array_keys($dirtyArray)
),
$dirtyArray
);
// construct the query like `.. WHERE name IN ( :name_1, .. , :name_3 )`
$query = "SELECT * FROM user WHERE name IN( " . implode(",", array_keys($params)) . " )";
// here we go
$stmt = $db->prepare($query);
$stmt->execute($params);