Yes, PDO does not have a builtin function for delimiting identifiers like table names and column names. The PDO::quote()
function is only for string literals and date literals.
For what it's worth, when I worked on Zend Framework, I implemented a quoteIdentifier()
function.
You're right that SELECT *
fetches all columns, likely using more memory and spoiling the benefit of covering indexes.
My recommendation is to whitelist column names. That is, make sure $info actually names a column of table
. Then you don't need to worry about the column name not existing, or containing a strange character, or anything. You get to control the set of columns that are legitimate to put in the query.
You should also delimit the column name anyway. Delimited identifiers are necessary if the column name contains punctuation, whitespace, international characters, or matches an SQL reserved word. See Do different databases use different name quote?
function getInfoById($id, $info) {
// you can make this a literal list, or query it from DESC or INFORMATION_SCHEMA
$cols = array('col1', 'col2', 'col3');
if (array_search($info, $cols) === false) {
return false;
}
$sql = "SELECT `$info` FROM table WHERE id = :id";
$stmt = $pdo->prepare($sql);
if ($stmt === false) {
return false;
}
. . .
}
I show more examples of whitelisting in my presentation SQL Injection Myths and Fallacies.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…