This question already has an answer here:
In my mind I have a query that goes something like this:
$sort = isset($sort) ? sanitize($_sort) : 'id';
if ($result = $link->prepare("
SELECT id, price
FROM items
ORDER BY ?
"))
{
$result->bind_param("s", $sort);
$result->execute();
etc...
}
When I run this code block without setting the sort variable it runs without an error relating to the use of the ?
in the ORDER BY clause and a result set is displayed in what appears to be a result set with "ORDER BY id".
If I set the sort variable to something like "price ASC" I still get a result set that seems to be "ORDER BY id" instead of "ORDER BY price ASC".
Now, if I alter the code and run it like this:
$sort = isset($sort) ? sanitize($_sort) : 'id';
if ($result = $link->prepare("
SELECT id, price
FROM items
ORDER BY $sort
"))
{
$result->execute();
etc...
}
It runs correctly, with a result set that is the same as my query in phpMyAdmin.
What exactly is going on here and why the query does not run as I initially intended using bind_param.
In my mind, it should work because no error comes up relating to such use... But in practice it seems that it does not work for an ORDER BY clause. It's almost like it is not translating the sort variable while running bind_param.
EDIT:
For anyone interested -
if (isset($sort))
{
$acceptableSortValues = array('name', 'price ASC', 'price DESC');
$sort = sanitize($sort);
if (!in_array($sort, $acceptableSortValues))
{
$sort = 'name';
}
}
else
{
$sort = 'name';
}
if ($result = $link->prepare("
SELECT name, price
FROM items
ORDER BY $sort
"))
{
$result->execute();
etc...
}
Only data can be bound with placeholders.
Column/table names are part of the schema and cannot be bound. (The fact that it generates "odd results" instead of simply yielding an error is a peculiarity of the implementation.)
I would suggest using a white-list of column-names and controlled string interpolation.
来源:https://stackoverflow.com/questions/12021018/is-it-possible-to-use-bind-param-for-order-by