好吧,我已经在这里待了几个小时,而对于我的生活,我无法弄清楚出了什么问题。代码如下:
$str = "%" . $_POST['str'] . "%";
$offset = (int) $_POST['offset'];
try {
$stmt = $dbh->prepare("SELECT * FROM Spells WHERE :col LIKE :str ORDER BY :sort LIMIT 10 OFFSET :offset");
$stmt->bindParam(":col",$_POST['col']);
$stmt->bindParam(":str",$str);
$stmt->bindParam(":offset",$offset, PDO::PARAM_INT);
$stmt->bindParam(":sort",$_POST['sort']);
$stmt->execute();
}
catch (PDOException $e) {
echo "MySQL error: " . $e->getMessage() . "<br/>";
die();
}
与数据库的连接正常,没有错误发生。如果我在搜索字段中键入%
(在查询中将其输出为%%%
),结果将按预期返回。
我在phpMyAdmin中尝试了相同的查询,它运行正常。我一直在使用已弃用的mysql_*
函数来更新这个脚本,之前工作正常。
上一个已弃用的查询示例:
$sql = "SELECT * FROM Spells WHERE " . $col . " LIKE '%" . $str . "%' ORDER BY " . $sort . " LIMIT 10 OFFSET " . $offset;
正如我可能已经说过的那样,我也一直在这个网站上搜索,试图寻找解决方案;什么都没有用,甚至没有MySQL的CONCAT('%',:str,'%')
。
我正在测试的服务器正在运行php 5.3.17版。
我的问题,如果我没说清楚,我在这里做错了什么?对于那些想知道的人(我以为我把它放了但显然我没有),没有错误消息。
答案 0 :(得分:2)
问题在于您无法使用参数代替identifiers。这意味着您无法对列名或表名进行参数化。
执行时查询的基本外观是
SELECT * FROM Spells WHERE 'some_column_name' LIKE '%something%'...
我会建立一个搜索和排序列名称的白名单,并使用它们构建您的查询。这是一个非常简单的例子
$search = array('col1', 'col2', 'col3');
$defaultSearch = 'col1';
$sort = array('col1', 'col2');
$defaultSort = 'col1';
$col = in_array($_POST['col'], $search) ? $_POST['col'] : $defaultSearch;
$sort = in_array($_POST['sort'], $sort) ? $_POST['sort'] : $defaultSort;
$sql = sprintf('SELECT * FROM Spell WHERE %s LIKE :str ORDER BY %s LIMIT 10 OFFSET :offset',
$col, $sort);
$stmt = $dbh->prepare($sql);
// bind :str and :offset, and so on