我的 Ajax PHP 过滤器如何不使用 PDO 过滤记录?
How is my Ajax PHP filter not filtering records with PDO?
所以我尝试使用带有 Ajax 和 PHP 的复选框来过滤记录。我正在尝试使用 PDO 过滤记录,因为它是最安全的选择。我想知道为什么过滤系统只在选中一个复选框时过滤,而不是更多。
这是我的代码:
if(isset($_POST['merk']))
{
// Pretty sure you have the following format 1,2,3,4 and not '1','2','3','4'
$merk = implode(',', $_POST['merk']);
if (preg_replace('/[^A-Za-z0-9\-]/', '', $merk)) {
// Notice that placeholders should not be quoted
$sql .= ' AND merk IN(:merk)';
}
}
if(isset($_POST['brandstof']))
{
$brandstof = implode(',', $_POST['brandstof']);
if (preg_replace('/[^A-Za-z0-9\-]/', '', $brandstof)) {
$sql .= ' AND brandstof IN(:brandstof)';
}
}
if(isset($_POST['carrosserie']))
{
$carrosserie = implode(',', $_POST['carrosserie']);
if (preg_replace('/[^A-Za-z0-9\-]/', '', $carrosserie)) {
$sql .= ' AND carrosserie IN(:carrosserie)';
}
}
如果复选框 merk
被选中,代码将被执行。查询可能有问题吗?
//We prepare our SELECT statement.
$statement = $pdo->prepare($sql);
if(isset($_POST['merk']))
{
$statement->bindParam(":merk", $merk);
// $params[] .= $merk;
}
if(isset($_POST['brandstof']))
{
$statement->bindParam(":brandstof", $brandstof);
// $params[] .= $brandstof;
}
if(isset($_POST['carrosserie']))
{
$statement->bindParam(":carrosserie", $carrosserie);
// $params[] .= $carrosserie;
}
$statement->execute();
此代码过滤一个复选框输入,但在选中两个复选框时停止过滤。请参阅下面的示例。
所以我的 POST 数据如下所示:Array ( [0] => BMW [1] => Skoda )
您在解析输入时使用了奇怪的引号,例如 "','"
。此外,您不应在语句中引用实际的占位符。
在聊天后我意识到问题是 IN 子句和 bindParams()
不支持数组。
来自 documentation for PDOStatement::execute:
input_parameters An array of values with as many elements as there are
bound parameters in the SQL statement being executed. All values are
treated as PDO::PARAM_STR.
Multiple values cannot be bound to a single parameter; for example, it
is not allowed to bind two values to a single named parameter in an
IN() clause.
为了解决这个问题,您需要将代码更改为如下内容:
// Enable error reporting to spot any warnings and errors.
ini_set('display_errors', true);
error_reporting(E_ALL);
$params = array();
// Creates an IN clause with placeholders and stores parameters
function createInParam(array $data, $name, $query, array &$params) {
$query .= " AND $name IN (";
foreach ($data as $key => $value) {
$params[$name . '_' . $key] = $value;
$query .= ":${name}_${key},";
}
return rtrim($query, ',') . ')';
}
// Bind all parameters to statement
function bindParams($statement, array $params) {
foreach ($params as $key => $value) {
$statement->bindParam(":$key", $params[$key]);
}
}
if (isset($_POST['merk'])) {
$merk = implode(',', $_POST['merk']);
if (preg_replace('/[^A-Za-z0-9\-]/', '', $merk)) {
$data = explode(',', $merk);
$sql = createInParam($data, 'merk', $sql, $params);
}
}
if (isset($_POST['brandstof'])) {
$brandstof = implode(',', $_POST['brandstof']);
if (preg_replace('/[^A-Za-z0-9\-]/', '', $brandstof)) {
$data = explode(',', $brandstof);
$sql = createInParam($data, 'brandstof', $sql, $params);
}
}
if (isset($_POST['carrosserie'])) {
$carrosserie = implode(',', $_POST['carrosserie']);
if (preg_replace('/[^A-Za-z0-9\-]/', '', $carrosserie)) {
$data = explode(',', $carrosserie);
$sql = createInParam($data, 'carrosserie', $sql, $params);
}
}
// Then bind all parameters and execute
bindParams($statement, $params);
if ($statement->execute()) {
// Success
}
做同样事情的另一种方法是:
$params = array();
if (isset($_POST['merk'])) {
$merk = implode(',', $_POST['merk']);
if (preg_replace('/[^A-Za-z0-9\-]/', '', $merk)) {
$inClause = implode(',', array_fill(0, count($_POST['merk']), '?'));
$sql .= " AND merk IN ($inClause)";
$params = array_merge($params, explode(',', $merk));
}
}
if (isset($_POST['brandstof'])) {
$brandstof = implode(',', $_POST['brandstof']);
if (preg_replace('/[^A-Za-z0-9\-]/', '', $brandstof)) {
$inClause = implode(',', array_fill(0, count($_POST['brandstof']), '?'));
$sql .= " AND brandstof IN ($inClause)";
$params = array_merge($params, explode(',', $brandstof));
}
}
if (isset($_POST['carrosserie'])) {
$carrosserie = implode(',', $_POST['carrosserie']);
if (preg_replace('/[^A-Za-z0-9\-]/', '', $carrosserie)) {
$inClause = implode(',', array_fill(0, count($_POST['carrosserie']), '?'));
$sql .= " AND carrosserie IN ($inClause)";
$params = array_merge($params, explode(',', $carrosserie));
}
}
if ($statement->execute($params)) {
// Success
}
所以我尝试使用带有 Ajax 和 PHP 的复选框来过滤记录。我正在尝试使用 PDO 过滤记录,因为它是最安全的选择。我想知道为什么过滤系统只在选中一个复选框时过滤,而不是更多。
这是我的代码:
if(isset($_POST['merk']))
{
// Pretty sure you have the following format 1,2,3,4 and not '1','2','3','4'
$merk = implode(',', $_POST['merk']);
if (preg_replace('/[^A-Za-z0-9\-]/', '', $merk)) {
// Notice that placeholders should not be quoted
$sql .= ' AND merk IN(:merk)';
}
}
if(isset($_POST['brandstof']))
{
$brandstof = implode(',', $_POST['brandstof']);
if (preg_replace('/[^A-Za-z0-9\-]/', '', $brandstof)) {
$sql .= ' AND brandstof IN(:brandstof)';
}
}
if(isset($_POST['carrosserie']))
{
$carrosserie = implode(',', $_POST['carrosserie']);
if (preg_replace('/[^A-Za-z0-9\-]/', '', $carrosserie)) {
$sql .= ' AND carrosserie IN(:carrosserie)';
}
}
如果复选框 merk
被选中,代码将被执行。查询可能有问题吗?
//We prepare our SELECT statement.
$statement = $pdo->prepare($sql);
if(isset($_POST['merk']))
{
$statement->bindParam(":merk", $merk);
// $params[] .= $merk;
}
if(isset($_POST['brandstof']))
{
$statement->bindParam(":brandstof", $brandstof);
// $params[] .= $brandstof;
}
if(isset($_POST['carrosserie']))
{
$statement->bindParam(":carrosserie", $carrosserie);
// $params[] .= $carrosserie;
}
$statement->execute();
此代码过滤一个复选框输入,但在选中两个复选框时停止过滤。请参阅下面的示例。
所以我的 POST 数据如下所示:Array ( [0] => BMW [1] => Skoda )
您在解析输入时使用了奇怪的引号,例如 "','"
。此外,您不应在语句中引用实际的占位符。
在聊天后我意识到问题是 IN 子句和 bindParams()
不支持数组。
来自 documentation for PDOStatement::execute:
input_parameters An array of values with as many elements as there are bound parameters in the SQL statement being executed. All values are treated as PDO::PARAM_STR.
Multiple values cannot be bound to a single parameter; for example, it is not allowed to bind two values to a single named parameter in an IN() clause.
为了解决这个问题,您需要将代码更改为如下内容:
// Enable error reporting to spot any warnings and errors.
ini_set('display_errors', true);
error_reporting(E_ALL);
$params = array();
// Creates an IN clause with placeholders and stores parameters
function createInParam(array $data, $name, $query, array &$params) {
$query .= " AND $name IN (";
foreach ($data as $key => $value) {
$params[$name . '_' . $key] = $value;
$query .= ":${name}_${key},";
}
return rtrim($query, ',') . ')';
}
// Bind all parameters to statement
function bindParams($statement, array $params) {
foreach ($params as $key => $value) {
$statement->bindParam(":$key", $params[$key]);
}
}
if (isset($_POST['merk'])) {
$merk = implode(',', $_POST['merk']);
if (preg_replace('/[^A-Za-z0-9\-]/', '', $merk)) {
$data = explode(',', $merk);
$sql = createInParam($data, 'merk', $sql, $params);
}
}
if (isset($_POST['brandstof'])) {
$brandstof = implode(',', $_POST['brandstof']);
if (preg_replace('/[^A-Za-z0-9\-]/', '', $brandstof)) {
$data = explode(',', $brandstof);
$sql = createInParam($data, 'brandstof', $sql, $params);
}
}
if (isset($_POST['carrosserie'])) {
$carrosserie = implode(',', $_POST['carrosserie']);
if (preg_replace('/[^A-Za-z0-9\-]/', '', $carrosserie)) {
$data = explode(',', $carrosserie);
$sql = createInParam($data, 'carrosserie', $sql, $params);
}
}
// Then bind all parameters and execute
bindParams($statement, $params);
if ($statement->execute()) {
// Success
}
做同样事情的另一种方法是:
$params = array();
if (isset($_POST['merk'])) {
$merk = implode(',', $_POST['merk']);
if (preg_replace('/[^A-Za-z0-9\-]/', '', $merk)) {
$inClause = implode(',', array_fill(0, count($_POST['merk']), '?'));
$sql .= " AND merk IN ($inClause)";
$params = array_merge($params, explode(',', $merk));
}
}
if (isset($_POST['brandstof'])) {
$brandstof = implode(',', $_POST['brandstof']);
if (preg_replace('/[^A-Za-z0-9\-]/', '', $brandstof)) {
$inClause = implode(',', array_fill(0, count($_POST['brandstof']), '?'));
$sql .= " AND brandstof IN ($inClause)";
$params = array_merge($params, explode(',', $brandstof));
}
}
if (isset($_POST['carrosserie'])) {
$carrosserie = implode(',', $_POST['carrosserie']);
if (preg_replace('/[^A-Za-z0-9\-]/', '', $carrosserie)) {
$inClause = implode(',', array_fill(0, count($_POST['carrosserie']), '?'));
$sql .= " AND carrosserie IN ($inClause)";
$params = array_merge($params, explode(',', $carrosserie));
}
}
if ($statement->execute($params)) {
// Success
}