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. 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. How would I do this?

This will be an UPDATE query, for each individual ID in the array.

Answers


As with nearly all "How do I do SQL from within PHP" questions - You really should use prepared statements. 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.

  • 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.

Why prepared statements?

  • Prepared statements are a lot safer because they make SQL injection attacks impossible. 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.
  • Only parameter values are sent to the database on execute(), so less data needs to go over the wire when used repeatedly.

In longer loops the execution time difference between using a prepared statement and sending plain SQL will become noticeable.


Using the "IN" Clause

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:

$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.

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);

Need Your Help

Variables are null even after assigning a value to them (Java)

java class variables methods null

I'm trying to write a method that will add song information (input by the user) to a database. Once the user adds the song details (name, artist, file size, duration), they should be saved in the f...

nil is not a legal NSManagedObjectContext Error

ios objective-c xcode

I am trying to retrieve value from an entity which I am using and then display the total to the user. The method i am using works perfectly in a masterviewcontroler class i have but i have added this