kol*_*pto 21 php mysql mergesort mysqli prepared-statement
想象一下,我们有一个查询:
SELECT * FROM somewhere WHERE `id` IN(1,5,18,25) ORDER BY `name`;
Run Code Online (Sandbox Code Playgroud)
以及要获取的ID数组: $ids = array(1,5,18,25)
准备好的陈述,建议准备一个陈述并多次调用:
$stmt = $mysqli->prepare('SELECT * FROM somewhere WHERE `id`=?;');
foreach ($ids as $id){
$stmt->bind_params('i', $id);
$stmt->exec();
}
Run Code Online (Sandbox Code Playgroud)
但现在我必须手动对结果进行排序.我有什么好的选择吗?
sle*_*led 23
你可以这样做:
$ids = array(1,5,18,25);
// creates a string containing ?,?,?
$clause = implode(',', array_fill(0, count($ids), '?'));
$stmt = $mysqli->prepare('SELECT * FROM somewhere WHERE `id` IN (' . $clause . ') ORDER BY `name`;');
call_user_func_array(array($stmt, 'bind_param'), $ids);
$stmt->execute();
// loop through results
Run Code Online (Sandbox Code Playgroud)
使用这个你为每个id调用bind_param,你有mysql完成的排序.
小智 6
我相信这是最简单的答案:
$ids = [1,2,3,4,5];
$pdos = $pdo->prepare("SELECT * FROM somwhere WHERE id IN (:"
. implode(',:', array_keys($ids)) . ") ORDER BY id");
foreach ($ids as $k => $id) {
$pdos->bindValue(":". $k, $id);
}
$pdos->execute();
$results = $pdos->fetchAll();
Run Code Online (Sandbox Code Playgroud)
这么久你的Ids数组不包含带有非法字符的键或键,它会起作用.
遇到相同的问题,并且除了7年前@sled的答案以外,这里还可能不执行此call_user_func_array(array($stmt, 'bind_param'), $ids);步骤,而只调用一次bind_params:
$ids = array(1,5,18,25);
// creates a string containing ?,?,?
$bindClause = implode(',', array_fill(0, count($ids), '?'));
//create a string for the bind param just containing the right amount of iii
$bindString = str_repeat('i', count($ids));
$stmt = $mysqli->prepare('SELECT * FROM somewhere WHERE `id` IN (' . $bindClause . ') ORDER BY `name`;');
$stmt->bind_params($bindString, ...$ids);
$stmt->execute();
Run Code Online (Sandbox Code Playgroud)
对于执行安全 mysqli 查询并将动态数量的传入值输入到 sql 字符串中的任务,准备好的语句是需要实现的专业技术。
\n假设传入的数据有效负载是用户提供的数据——这意味着我们无法保证数据的完整性,也无法保证数据量。事实上,预期的数据数组可能为空。下面的代码片段将演示如何将 id 数组传递给准备好的语句的子句IN ()中的条件。WHERE如果数组中没有值,则准备好的语句没有任何好处,不应使用。
MySQLi 结果集对象可以通过循环立即迭代foreach()。因此,没有必要进行迭代fetch调用;只需使用数组语法访问行数据。
ids 数组意味着 sql 将需要整数值。调用时bind_param(),第一个参数将是重复字符的单个字符串i。对于一般用途,如果数据是字符串或者您可能有多种数据类型(例如整数、浮点数/双精度数或字符串),那么使用重复s字符而不是i字符会更简单。
代码:(带有 SQL 的 PHPize.online 演示)
\n$ids = [1, 5, 18, 25]; // this could be, for example: $_GET[\'ids\']\n$count = count($ids);\n\n$sql = \'SELECT name FROM somewhere\';\n$orderBy = \'ORDER BY name\';\nif ($count) {\n $placeholders = implode(\',\', array_fill(0, $count, \'?\'));\n $stmt = $mysqli->prepare("$sql WHERE id IN ($placeholders) $orderBy");\n $stmt->bind_param(str_repeat(\'i\', $count), ...$ids);\n $stmt->execute();\n $result = $stmt->get_result();\n} else {\n $result = $mysqli->query("$sql $orderBy"); // a prepared statement is unnecessary\n}\nforeach ($result as $row) {\n echo "<div>{$row[\'name\']}</div>\\n";\n}\nRun Code Online (Sandbox Code Playgroud)\n我的 PHPize 演示的输出:
\n<div>Alan</div>\n<div>Bill</div>\n<div>Chad</div>\n<div>Dave</div>\nRun Code Online (Sandbox Code Playgroud)\n如果您出于任何原因不需要迭代结果集,那么您可以fetch_all()。这通常在立即回显或返回 json 编码的字符串(例如,作为对 ajax 调用的响应)时使用。在这种情况下,您将该foreach()块替换为:(PHPize.online Demo with SQL)
echo json_encode($result->fetch_all(MYSQLI_ASSOC));\nRun Code Online (Sandbox Code Playgroud)\n或者简单地转储多维数组:
\nvar_export($result->fetch_all(MYSQLI_ASSOC));\nRun Code Online (Sandbox Code Playgroud)\n我的 PHPize 演示的输出:
\n[{"name":"Alan"},{"name":"Bill"},{"name":"Chad"},{"name":"Dave"}]\nRun Code Online (Sandbox Code Playgroud)\n从 PHP8.1 及更高版本开始,不再需要调用,bind_param()因为该execute()方法可以以数组形式接收参数的有效负载(如 PDO)。
这意味着...
\n$stmt->bind_param(str_repeat(\'i\', $count), ...$ids);\n$stmt->execute();\nRun Code Online (Sandbox Code Playgroud)\n可以替换为...
\n$stmt->execute($ids);\nRun Code Online (Sandbox Code Playgroud)\n这是一个完整的基本示例:(PHPize.online Demo)
\n$ids = [1, 2, 3, 4, 5];\n$stmt = $mysqli->prepare("SELECT * FROM somewhere WHERE id IN (" . rtrim(str_repeat(\'?,\', count($ids)), \',\') . ") ORDER BY id");\n$stmt->execute($ids);\nvar_export($stmt->get_result()->fetch_all(MYSQLI_ASSOC));\nRun Code Online (Sandbox Code Playgroud)\n专题资源:
\nRFC由我们自己的Dharman \xe2\x99\xa6编写,并于 2021 年 3 月 27 日一致投票后作为 PHP8.1 的一部分实现。
\n| 归档时间: |
|
| 查看次数: |
19934 次 |
| 最近记录: |