I have three values in a string like this:
$villes = '"paris","fes","rabat"';
When I feed it into a prepared statement like this:
$sql = 'SELECT distinct telecopie FROM `comptage_fax` WHERE `ville` IN(%s)';
$query = $wpdb->prepare($sql, $villes);
echo $query;
shows:
SELECT distinct telecopie FROM `comptage_fax` WHERE `ville` IN('"CHAPELLE VIVIERS ","LE MANS ","QUEND"')
It is not writing the string as three separate values — it is just one string with the double quotes escaped.
How can I properly implement a prepared statement in WordPress with multiple values?
Try this code:
implode()
array_fill()
call_user_func_array()
array_merge()
WordPress already has a function for this purpose, see esc_sql(). Here is the definition of this function:
You can use it like this:
FUNCTION:
USAGE:
RESULT:
May or may not be more efficient, however it is reusable.
Here is my approach for sanitizing
IN (...)
values for$wpdb
.$wpdb->prepare()
to ensure that it’s properly escaped.sprintf()
.The helper function:
Sample usage:
I created a tiny function that will generate the placeholders for a prepared statement from an array, i.e., something like
(%s,%d,%f)
, and conveniently, it will know exactly which placeholder to use depending on each item of the array.Considering the example from the question, first you’d need to convert the values to an array:
First is a modern set of a non-WordPress techniques using a mysqli prepared statement with an unknown number of values in an array. The second snippet will be the WordPress equivalent.
Let’s assume that the indexed array of input data is untrusted and accessible from
$_GET['villes']
. A prepared statement is the modern standard and preferred by professional developers over old/untrusted escaping techniques. The snippet to follow will return rows that have one of theville
values specified in the array. If the array is not declared or is empty, it will return ALL rows in the database table.Native PHP techniques:
From this point, you can access the rows of distinct
telecopie
values (which is technically an iterable result set object) as if iterating an indexed array of associative arrays with a simpleforeach()
.With WordPress’s helper methods the syntax is simpler because the variable binding and query execution is handled by
get_results()
:From this point,
$result
is an indexed array of associative arrays — specifically because ofARRAY_A
.$result
is not a result set object like in the first native php snippet. This means that you can use both classic looping language constructor or the full suite ofarray_
functions on the data.Useful References:
The
prepare
function also takes anarray
as the second parameter.You can try converting
$villes
like this:Current
Change it to
Now, try passing
$villes
to the prepare func and see if it works. Hope it helps.