简体   繁体   English

我有一个整数数组,如何在mysql查询中使用每个整数(在php中)?

[英]I have an array of integers, how do I use each one in a mysql query (in php)?

I have an array full of random content item ids. 我有一个充满随机内容项ID的数组。 I need to run a mysql query (id in the array goes in the WHERE clause), using each ID that's in the array, in the order that they appear in the said array. 我需要运行mysql查询(数组中的ID在WHERE子句中),并使用数组中的每个ID并按照它们在所述数组中出现的顺序进行操作。 How would I do this? 我该怎么做?

This will be an UPDATE query, for each individual ID in the array. 对于数组中的每个ID,这将是一个UPDATE查询。

As with nearly all "How do I do SQL from within PHP" questions - You really should use prepared statements. 与几乎所有“如何在PHP中执行SQL”问题一样,您实际上应该使用准备好的语句。 It's not that hard: 这并不难:

$ids  = array(2, 4, 6, 8);

// prepare an SQL statement with a single parameter placeholder
$sql  = "UPDATE MyTable SET LastUpdated = GETDATE() WHERE id = ?";
$stmt = $mysqli->prepare($sql);

// bind a different value to the placeholder with each execution
for ($i = 0; $i < count($ids); $i++)
{
    $stmt->bind_param("i", $ids[$i]);
    $stmt->execute();
    echo "Updated record ID: $id\n";
}

// done
$stmt->close();

Alternatively, you can do it like this: 或者,您可以这样做:

$ids    = array(2, 4, 6, 8);

// prepare an SQL statement with multiple parameter placeholders
$params = implode(",", array_fill(0, count($ids), "?"));
$sql    = "UPDATE MyTable SET LastUpdated = GETDATE() WHERE id IN ($params)";
$stmt   = $mysqli->prepare($sql);

// dynamic call of mysqli_stmt::bind_param                    hard-coded eqivalent
$types = str_repeat("i", count($ids));                        // "iiii"
$args = array_merge(array($types), $ids);                     // ["iiii", 2, 4, 6, 8]
call_user_func_array(array($stmt, 'bind_param'), ref($args)); // $stmt->bind_param("iiii", 2, 4, 6, 8)

// execute the query for all input values in one step
$stmt->execute();

// done
$stmt->close();
echo "Updated record IDs: " . implode("," $ids) ."\n";

// ----------------------------------------------------------------------------------
// helper function to turn an array of values into an array of value references
// necessary because mysqli_stmt::bind_param needs value refereces for no good reason
function ref($arr) {
    $refs = array();
    foreach ($arr as $key => $val) $refs[$key] = &$arr[$key];
    return $refs;
}

Add more parameter placeholders for other fields as you need them. 根据需要为其他字段添加更多参数占位符。

Which one to pick? 选哪一个?

  • The first variant works with a variable number of records iteratively, hitting the database multiple times. 第一种变体可迭代处理可变数量的记录,从而多次访问数据库。 This is most useful for UPDATE and INSERT operations. 这对于UPDATE和INSERT操作最有用。

  • The second variant works with a variable number of records too, but it hits the database only once. 第二种变体也适用于可变数量的记录,但是它只命中一次数据库。 This is much more efficient than the iterative approach, obviously you can only do the same thing to all affected records. 这比迭代方法高效得多,显然,您只能对所有受影响的记录执行相同的操作。 This is most useful for SELECT and DELETE operations, or when you want to UPDATE multiple records with the same data. 这对于SELECT和DELETE操作,或者要更新具有相同数据的多条记录时最有用。

Why prepared statements? 为什么要准备陈述?

  • Prepared statements are a lot safer because they make SQL injection attacks impossible. 预备语句更安全,因为它们使SQL注入攻击变得不可能。 This is the primary reason to use prepared statements, even if it is more work to write them. 这是使用准备好的语句的主要原因,即使编写它们是更多的工作。 A sensible habit to get into is: Always use prepared statements, even if you think it's "not really necessary." 养成明智的习惯:即使您认为“不是真的”,也要始终使用准备好的语句。 Neglect will come and bite you (or your customers). 疏忽会来咬你(或你的顾客)。
  • Re-using the same prepared statement multiple times with different parameter values is more efficient than sending multiple full SQL strings to the database, because the database only needs to compile the statement once and can re-use it as well. 与将多个完整的SQL字符串发送到数据库相比,以不同的参数值多次重复使用同一条准备好的语句效率更高,因为数据库只需要编译一次该语句即可,并且也可以重新使用它。
  • Only parameter values are sent to the database on execute() , so less data needs to go over the wire when used repeatedly. 仅参数值通过execute()发送到数据库,因此重复使用时,需要较少的数据通过网络。

In longer loops the execution time difference between using a prepared statement and sending plain SQL will become noticeable. 在更长的循环中,使用准备好的语句和发送纯SQL之间的执行时间差异将变得明显。

Using the "IN" Clause 使用“ IN”子句

Might be what you're after 可能是你所追求的

$ids = array(2,4,6,8);
$ids = implode($ids);
$sql="SELECT * FROM my_table WHERE id IN($ids);";
mysql_query($sql);

otherwise, what's wrong with 不然怎么了

$ids = array(2,4,6,8);
foreach($ids as $id) {
    $sql="SELECT * FROM my_table WHERE ID = $id;";
    mysql_query($sql);
}

Amen to Tomalak's comment on statements. 阿曼·托玛拉克对声明的评论。

However, if you do not wish to use mysqli, you can always use intval() to prevent injection: 但是,如果您不想使用mysqli,则可以始终使用intval()防止注入:

$ids  = array(2, 4, 6, 8);
for ($i = 0; $i < count($ids); $i++)
{
    mysql_query("UPDATE MyTable SET LastUpdated = GETDATE() WHERE id = " . intval($ids[$i]));
}
$values_filtered = array_filter('is_int', $values);
if (count($values_filtered) == count($values)) {
    $sql = 'update table set attrib = 'something' where someid in (' . implode(',', $values_filtered) . ');';
    //execute
} else {
    //do something
}

You could do something like the following, however you need to be VERY careful that the array only contains integers otherwise you could end up with SQL injection. 您可以执行以下操作,但是要非常小心,数组仅包含整数,否则可能会导致SQL注入。

You really don't want to be doing multiple queries to get the content out if you can help it. 如果您愿意的话,您确实不想执行多个查询来获取内容。 Something like this might be what you are after. 这样的事情可能就是您所追求的。

foreach ($array as $key = $var) {
   if ((int) $var <= 0) {
       unset($array[$key]);
   }
}


$query = "SELECT * 
from content 
WHERE contentid IN ('".implode("','", $array)."')";

$result = mysql_query($query);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM