逗号分隔值在 PHP MYSQL 中不起作用
Comma-separated values doesn't work in PHP MYSQL
我目前遇到了一个困难,将逗号分隔值放入 MySQL NOT IN
并没有给我希望的结果。一定有一些我遗漏的东西,因为我不确定要搜索什么这个特定问题。 运行 只有 MySQL 代码有效,但从另一个 PHP 函数传递参数没有。
这是给我带来问题的代码:
$uid = 1;
$selected_uids = '1,2';
$result = $db->retrieveFollowingWithCondition($uid, $selected_uids);
...然后在代码的某处...
public function retrieveFollowingWithCondition($uid, $selected_uids) {
$stmt = $this->conn->prepare("SELECT *
FROM `friendlist`
WHERE `uid` = ? AND `buddy_uid` NOT IN (?)
GROUP BY `buddy_uid`;");
$stmt->bind_param("is", $uid, $selected_uids);
...}
我测试过在 $selected_uids
中输入“2”,它确实有效。但是一旦涉及逗号,代码就会运行,但 $selected_uids
仍在结果中。不确定这是一种不好的做法还是只需要对代码进行微小的调整。无论如何,我真的很期待了解为什么它对我不起作用。
通过在 bind_param
中使用 s
,您告诉 PHP 将 $selected_uids
的全部内容视为一个字符串。因此,“1,2
”被视为 ('1,2')
而不是 (1,2)
。 Your problem is that bind_param
doesn't support arrays, so support of IN
queries is limited。有许多替代方法可以绕过此限制,但由于您正在处理一个整数列表,我可能会执行原始字符串连接。
// using is_numeric because is_int("1") === false
$filtered = array_filter('is_numeric', $selected_uids);
// You could also just call array_map('intval', $selected_uids);
// Depending on your needs.
if(!$filtered) {
return; // No valid values
}
$filteredStr = implode(',', $filtered);
$stmt = $this->conn->prepare("SELECT *
FROM `friendlist`
WHERE `uid` = ? AND `buddy_uid` NOT IN ($filteredStr)
GROUP BY `buddy_uid`;");
还应注意:如果我尝试将字符串用于 IN
查询,我可能会执行以下操作:
$filtered = array_map([$this->conn, 'escape_string'], $queried);
$inQuery = '\'' . implode('\',\'', $filtered) . '\'';
我发现该符号比动态生成的 bind_param
格式字符串更清晰、更容易。
您应该分别绑定 IN(...) 中的每个参数,但方法 bind_param 不支持多次调用。有一个很好的 class 可以做到这一点,您可以在 PHP 文档页面上找到它:
Custom class for multiple bind_param
我目前遇到了一个困难,将逗号分隔值放入 MySQL NOT IN
并没有给我希望的结果。一定有一些我遗漏的东西,因为我不确定要搜索什么这个特定问题。 运行 只有 MySQL 代码有效,但从另一个 PHP 函数传递参数没有。
这是给我带来问题的代码:
$uid = 1;
$selected_uids = '1,2';
$result = $db->retrieveFollowingWithCondition($uid, $selected_uids);
...然后在代码的某处...
public function retrieveFollowingWithCondition($uid, $selected_uids) {
$stmt = $this->conn->prepare("SELECT *
FROM `friendlist`
WHERE `uid` = ? AND `buddy_uid` NOT IN (?)
GROUP BY `buddy_uid`;");
$stmt->bind_param("is", $uid, $selected_uids);
...}
我测试过在 $selected_uids
中输入“2”,它确实有效。但是一旦涉及逗号,代码就会运行,但 $selected_uids
仍在结果中。不确定这是一种不好的做法还是只需要对代码进行微小的调整。无论如何,我真的很期待了解为什么它对我不起作用。
通过在 bind_param
中使用 s
,您告诉 PHP 将 $selected_uids
的全部内容视为一个字符串。因此,“1,2
”被视为 ('1,2')
而不是 (1,2)
。 Your problem is that bind_param
doesn't support arrays, so support of IN
queries is limited。有许多替代方法可以绕过此限制,但由于您正在处理一个整数列表,我可能会执行原始字符串连接。
// using is_numeric because is_int("1") === false
$filtered = array_filter('is_numeric', $selected_uids);
// You could also just call array_map('intval', $selected_uids);
// Depending on your needs.
if(!$filtered) {
return; // No valid values
}
$filteredStr = implode(',', $filtered);
$stmt = $this->conn->prepare("SELECT *
FROM `friendlist`
WHERE `uid` = ? AND `buddy_uid` NOT IN ($filteredStr)
GROUP BY `buddy_uid`;");
还应注意:如果我尝试将字符串用于 IN
查询,我可能会执行以下操作:
$filtered = array_map([$this->conn, 'escape_string'], $queried);
$inQuery = '\'' . implode('\',\'', $filtered) . '\'';
我发现该符号比动态生成的 bind_param
格式字符串更清晰、更容易。
您应该分别绑定 IN(...) 中的每个参数,但方法 bind_param 不支持多次调用。有一个很好的 class 可以做到这一点,您可以在 PHP 文档页面上找到它: Custom class for multiple bind_param