[英]Comma-separated values doesn't work in PHP MYSQL
I'm currently facing a difficulty where putting a comma-separated values to a MySQL NOT IN
doesn't give me the result I was hoping for. 我目前面临的一个困难是,将逗号分隔的值放到MySQL NOT IN
并不能给我我想要的结果。 There must be something I'm missing as I'm unsure what to search for this particular problem. 我不确定要搜索什么来寻找特定的问题,所以肯定有一些我想念的东西。 Running only the MySQL code works, but passing the parameter from another PHP function didn't. 仅运行MySQL代码即可,但是无法从另一个PHP函数传递参数。
Here's the code that's giving me a problem: 这是给我一个问题的代码:
$uid = 1;
$selected_uids = '1,2';
$result = $db->retrieveFollowingWithCondition($uid, $selected_uids);
...then somewhere along the code... ...然后在代码中的某处...
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);
...}
I've tested just putting '2' in $selected_uids
and it actually works. 我已经测试过,只是在$selected_uids
放入“ 2”,它实际上可以工作。 But once there's comma involved, the code runs but the $selected_uids
are still in the result. 但是一旦涉及到逗号,代码就会运行,但是$selected_uids
仍然在结果中。 Not sure this is a bad practice or just needing a minor adjustment to the code. 不确定这是一种不好的做法,还是只需要对代码进行少量调整即可。 Anyway, I'm really looking forward to understand why it's not working for me. 无论如何,我真的很期待了解为什么它对我不起作用。
By using s
in bind_param
you are telling PHP to treat the entire contents of $selected_uids
as a string. 通过在bind_param
使用s
,您将告诉PHP将$selected_uids
的全部内容视为字符串。 Therefore, " 1,2
" is treated as ('1,2')
instead of (1,2)
. 因此,“ 1,2
”被视为('1,2')
而不是(1,2)
。 Your problem is that bind_param
doesn't support arrays, so support of IN
queries is limited . 您的问题是bind_param
不支持数组,因此对IN
查询的支持是受限制的 。 There are a number of alternatives to get around this limitation, but since you are dealing with a list of ints, I would probably do a raw string concat. 有许多替代方法可以解决此限制,但是由于您要处理的是整数列表,因此我可能会使用原始字符串concat。
// 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`;");
Should also be noted: if I were trying to use strings for an IN
query, I would likely do the following: 还应注意:如果我尝试对IN
查询使用字符串,则可能会执行以下操作:
$filtered = array_map([$this->conn, 'escape_string'], $queried);
$inQuery = '\'' . implode('\',\'', $filtered) . '\'';
I find that notation cleaner and easier than a dynamically generated bind_param
format string. 我发现这种表示法比动态生成的bind_param
格式字符串更干净,更容易。
You should bind every parameter in IN(...) separately, but method bind_param doesn't support multiple calls. 您应该分别绑定IN(...)中的每个参数,但是方法bind_param不支持多个调用。 There is a nice class that can do this and you can find it on PHP documentation pages: Custom class for multiple bind_param 有一个不错的类可以做到这一点,您可以在PHP文档页面上找到它: 多个bind_param的自定义类
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.