Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Formatting a PHP array for an SQL "IN" clause

I'm attempting to query a database for records where the "product_id" is included in an array of products IDs.

The array is the post result of a multiple select input (<select>) and looks like:

$clients = 
  Array ( 
    [0] => 80000016-1302638679
    [1] => 8000003B-1329924004
  )

I would like to pass that array to the "IN" clause of an SQL statement such as:

$sql = "SELECT * FROM sales WHERE product_id IN (".$clients.")";

...but this doesn't work (Error: Message: Array to string conversion).

Several posts suggest using this function to format the array in a way suitable for SQL:

function format_array($array){
    return implode(', ', $array);
  }
}

Such as ...

$sql = "SELECT * FROM sales WHERE product_id IN (".format_array($clients).")";

That results in this query:

SELECT * FROM sales WHERE product_id IN (80000016-1302638679, 8000003B-132992400)

...and this error:

Unknown column '8000003B' in 'where clause'

What am I doing wrong? Any help is greatly appreciated! I can clarify the question if needed :)

like image 396
Andrew Avatar asked Aug 06 '13 05:08

Andrew


People also ask

Can we use array in where clause?

We can pass an array with the help of where IN clause. Let us first create a new table for our example.

Can we use array in SQL query?

Conclusion. As you can see, SQL Server does not include arrays. But we can use table variables, temporary tables or the STRING_SPLIT function. However, the STRING_SPLIT function is new and can be used only on SQL Server 2016 or later versions.

How set PHP variable in SQL query?

The rules of adding a PHP variable inside of any MySQL statement are plain and simple: Any variable that represents an SQL data literal, (or, to put it simply - an SQL string, or a number) MUST be added through a prepared statement. No exceptions.

What is $SQL in PHP?

PHP is the most popular scripting language for web development. It is free, open source and server-side (the code is executed on the server). MySQL is a Relational Database Management System (RDBMS) that uses Structured Query Language (SQL).


4 Answers

There is a better way

You mention in the comments that you are using CodeIgniter. Unless you are making something extraordinarily complicated, there is no practical reason you should be building your own home-baked queries when you have where_in built in.

And if that doesn't work, then there is good ol' fashioned escape.


OK, so, you have most people saying that you need to quote the items and are giving you this:

function createInClause($arr)
{
    return '\'' . implode( '\', \'', $arr ) . '\'';
}

but that really isn't sufficient if you have the possibility for questionable input (such as '); DROP TABLE STUDENTS; --. To protect against that, you need to make sure you check for SQL injection:

function createInClause($arr)
{
    $tmp = array();
    foreach($arr as $item)
    {
        // this line makes sure you don't risk a sql injection attack
        // $connection is your current connection
        $tmp[] = mysqli_escape_string($connection, $item);
    }
    return '\'' . implode( '\', \'', $tmp ) . '\'';
}
like image 175
cwallenpoole Avatar answered Oct 04 '22 07:10

cwallenpoole


Try this to put your ids in quotes:

function format_array($array){
    return "'" . implode("', '", $array) . "'";
  }
}

As cwallenpoole pointed out, you should escape the string if you haven't already. Not escaping a string is extremely dangerous, especially if you have a public application.

like image 31
Daniel Williams Avatar answered Oct 04 '22 05:10

Daniel Williams


You need to put 80000016-1302638679 in quotation marks. Otherwise it assumes you are doing subtraction.

return "'".implode("', '", $array)."'";
like image 43
sashkello Avatar answered Oct 04 '22 05:10

sashkello


Use this function

function format_array($array){
    return implode("','", $array);
  }
}

And this query

$sql = "SELECT * FROM sales WHERE product_id IN ('".$clients."')";
like image 37
Garry Avatar answered Oct 04 '22 07:10

Garry