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".
HERE IS THE PROBLEM IN ONE SENTANCE :
Now 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".
When I run the query as a query in phpmyadmin, it returns the correct result set based on "price ASC" if I define the query that way.
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...
Could someone please enlighten me as to 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. Its almost like it is not translating the sort variable while running bind_param.
Thank you for reading my question and any input relating to it would be greatly appreciated!!
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.