这是我的PHP代码的相关部分:
$dbh = new PDO("mysql:host=$hostname;dbname=$database", $username, $password);
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
//get values from AJAX
$whereCategory = isset($_GET['cat_code'])? "{$_GET['cat_code']}" : '';
$sortvalue = isset($_GET['sortvalue'])? "{$_GET['sortvalue']}" : '';
$sortorder = isset($_GET['sortorder'])? "{$_GET['sortorder']}" : '';
$sql = "select * from {$table} where cat_code = ':cat_code' order by ':sortvalue' ':sortorder';";
$stmt2 = $dbh->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY) );
$stmt2->execute(array(':cat_code' => $whereCategory,':sortvalue' => $sortvalue, ':sortorder' => $sortorder));
$result = $dbh->query($sql)->fetchAll(PDO::FETCH_ASSOC);
header('Content-type: application/json');
echo json_encode($result);
如果我var_dump
变量$where_category
,$sortorder
和$sortvalue
,它们就是我所期望的以及需要在查询中传递的正确数据。我在没有PDO的情况下直接尝试了查询,只是替换了正确的变量,我得到了我想要的东西,但显然我没有使用我的PDO方法正确地发送变量(例如它们)。
我没有收到任何错误,但也没有返回任何数据。
有什么建议吗?
答案 0 :(得分:3)
首先,不需要引用命名占位符,所以放弃它们。
其次,您无法绑定标识符(table / columns / DESC / ASC)您只能将这些标识符列入白名单。
第三,不要混用->query()
和->execute()
。仅使用->execute()
:
header('Content-type: application/json');
$dbh = new PDO("mysql:host=$hostname;dbname=$database", $username, $password);
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
//get values from AJAX
if(isset($_GET['cat_code'], $_GET['sortvalue'], $_GET['sortorder'])) {
$whereCategory = $_GET['cat_code'];
$sortvalue = $_GET['sortvalue'];
$sortorder = $_GET['sortorder'];
// super simple filtering
$default_tables = array('table1', 'table2', 'table3');
$default_columns = array('column1', 'column2', 'column3');
in_array(needle, haystack)
if(
in_array($table, $default_tables) &&
in_array($sortvalue, $default_columns) &&
in_array($sortorder, array('ASC', 'DESC'))
) {
// good to go
$sql = "SELECT * FROM $table where cat_code = :cat_code ORDER BY $sortvalue $sortorder";
$stmt2 = $dbh->prepare($sql);
$stmt2->execute(array(':cat_code' => $whereCategory));
echo json_encode($stmt2->fetchAll(PDO::FETCH_ASSOC));
} else {
// did not satisfy condition
}
}
旁注:这些默认表和列只是示例,您需要填充并将其与您的对应。您可以创建自己的方法/函数,如果您真的想要确定它,可以创建一个带有相应列的表的地图。
答案 1 :(得分:2)
改变这个 -
$result = $dbh->query($sql)->fetchAll(PDO::FETCH_ASSOC);
到此 -
$result = $stmt2->fetchAll(PDO::FETCH_ASSOC);
当你需要做的只是获取结果时,你试图再次运行查询。
答案 2 :(得分:1)
您正在运行的查询是针对准备好的语句,该语句不正确,删除查询并从execute语句中分配结果将起作用。你的php还有很多其他问题。同样使用直接来自用户的输入(例如表格(在此代码片段中似乎未定义),排序顺序和排序值使您可以打开sql注入。
$dbh = new PDO("mysql:host=$hostname;dbname=$database", $username, $password);
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
//get values from AJAX
$whereCategory = isset($_GET['cat_code'])? $_GET['cat_code'] : '';
$sortvalue = isset($_GET['sortvalue'])? $_GET['sortvalue'] : '';
$sortorder = isset($_GET['sortorder'])? $_GET['sortorder'] : '';
/** you cannot use prepared statements for doing the order by */
$sql = "select * from $table where cat_code = :cat_code order by $sortvalue $sortorder;";
$stmt2 = $dbh->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY) );
$query = $stmt2->execute(['cat_code' => $whereCategory]);
/** below line isn't needed because above on deals with it */
//$dbh->query($sql)->fetchAll(PDO::FETCH_ASSOC);
$result = $query->fetchAll();
header('Content-type: application/json');
echo json_encode($result);
答案 3 :(得分:0)
尝试不加引号:
$sql = "select * from {$table} where cat_code = :cat_code order by :sortvalue :sortorder;";
答案 4 :(得分:-1)
像这样使用
$result = $stmt2->fetchAll(PDO::FETCH_ASSOC);