I have a similiar class with a lot of methods, but getData()
only returns the value of the $column
parameter.
private $db;
function __construct()
{
$this->db = new PDO('sqlite:\db');
}
public function getData($rowid, $column)
{
$st = $this->db->prepare('SELECT ? FROM tbl WHERE rowid=?');
$st->bindParam(1, $column, PDO::PARAM_STR);
$st->bindParam(2, $rowid, PDO::PARAM_INT);
if ($st->execute())
return $st->fetchColumn();
else
return false;
}
Every other parts of the class and the left out half of getData()
works. What's the problem here?
bindParam
is used to bind parameters, not identifiers. The value you bind there will be expanded as:
SELECT 'some_value' FROM tbl WHERE rowid='some_other_value';
...therefore equivalent to:
SELECT 'some_value';
You should only use parameters for actual parameters:
$this->db->prepare('SELECT '.$column.' FROM tbl WHERE rowid=?');
If your column is user-supplied and you want to escape it, use the proper escaping function. In this case, it's SQLite3::escapeString()
:
$column = SQLite3::escapeString($column);
$this->db->prepare('SELECT '.$column.' FROM tbl WHERE rowid=?');
If the column is not user-supplied, you don't really have to escape it.
identifier is not a string.
you can't bind identifiers.
you have to whitelist them instead.
or - better - design your application proper way that will require no dynamical fieldname at all.
$column
is user-supplied, which may not even be the case. There is no way to tell with the actual code - netcoder 2012-04-04 17:44
$rowid
is user-supplied, and I properly escape it - Gergő 2012-04-04 17:51
$rowid
is supplied by the query string, and its validiated as an integer. In such cases should I just pass the parameters to execute()
? And for single calls is it more reasonable to use query()
and exec()
? And finally is it a bad pratice in itself to have a method with column as a parameter, or briefly what should I pay attention to? Thank you in advance - Gergő 2012-04-04 19:54