如何在 LIMIT 子句中应用 bindValue 方法?
- 2024-09-29 23:09:00
- admin 原创
- 92
问题描述:
这是我的代码的快照:
$fetchPictures = $PDO->prepare("SELECT *
FROM pictures
WHERE album = :albumId
ORDER BY id ASC
LIMIT :skip, :max");
$fetchPictures->bindValue(':albumId', $_GET['albumid'], PDO::PARAM_INT);
if(isset($_GET['skip'])) {
$fetchPictures->bindValue(':skip', trim($_GET['skip']), PDO::PARAM_INT);
} else {
$fetchPictures->bindValue(':skip', 0, PDO::PARAM_INT);
}
$fetchPictures->bindValue(':max', $max, PDO::PARAM_INT);
$fetchPictures->execute() or die(print_r($fetchPictures->errorInfo()));
$pictures = $fetchPictures->fetchAll(PDO::FETCH_ASSOC);
我明白了
您的 SQL 语法有错误;请查阅与您的 MySQL 服务器版本相对应的手册,以了解在第 1 行 ''15', 15' 附近使用的正确语法
似乎 PDO 在 SQL 代码的 LIMIT 部分为我的变量添加了单引号。我查找了一下,发现了这个我认为相关的错误:
http://bugs.php.net/bug.php ?id=44639
这就是我所看到的吗?这个错误自 2008 年 4 月以来就一直存在!我们在此期间应该做什么?
我需要建立一些分页,并且在发送 SQL 语句之前需要确保数据是干净的、SQL 注入安全的。
解决方案 1:
我记得以前遇到过这个问题。将值转换为整数,然后再将其传递给 bind 函数。我认为这可以解决问题。
$fetchPictures->bindValue(':skip', (int) trim($_GET['skip']), PDO::PARAM_INT);
解决方案 2:
最简单的解决方案是关闭模拟模式。只需添加以下行即可
$PDO->setAttribute( PDO::ATTR_EMULATE_PREPARES, false );
此外,创建 PDO 连接时可以将此模式设置为构造函数参数。这可能是一个更好的解决方案,因为有些人报告他们的驱动程序不支持该setAttribute()
功能。
它不仅可以解决绑定问题,还可以让你直接将值发送到execute()
,这将大大缩短你的代码。假设已经设置了模拟模式,整个过程将需要多达六行代码
$skip = isset($_GET['skip']) ? (int)trim($_GET['skip']) : 0;
$sql = "SELECT * FROM pictures WHERE album = ? ORDER BY id LIMIT ?, ?";
$stmt = $PDO->prepare($sql);
$stmt->execute([$_GET['albumid'], $skip, $max]);
$pictures = $stmt->fetchAll(PDO::FETCH_ASSOC);
解决方案 3:
查看错误报告,以下内容可能有效:
$fetchPictures->bindValue(':albumId', (int)$_GET['albumid'], PDO::PARAM_INT);
$fetchPictures->bindValue(':skip', (int)trim($_GET['skip']), PDO::PARAM_INT);
但您确定传入的数据正确吗?因为在错误消息中,数字后面似乎只有一个引号(而不是整个数字都括在引号中)。这也可能是传入数据有误。您可以执行操作print_r($_GET);
来找出原因吗?
解决方案 4:
这只是总结。
有四个选项可以参数化 LIMIT/OFFSET 值:
PDO::ATTR_EMULATE_PREPARES
按照上面所述禁用。
这会阻止传递的值->execute([...])
始终显示为字符串。
切换到手动
->bindValue(..., ..., PDO::PARAM_INT)
参数填充。
但是它不如 ->execute list[] 方便。
只需在这里做出例外,并在准备 SQL 查询时插入纯整数即可。
$limit = intval($limit);
$s = $pdo->prepare("SELECT * FROM tbl LIMIT {$limit}");
选角很重要。通常->prepare(sprintf("SELECT ... LIMIT %d", $num))
用于此类目的。
如果您不使用 MySQL,而是使用 SQLite 或 Postgres;您也可以直接在 SQL 中转换绑定参数。
SELECT * FROM tbl LIMIT (1 * :limit)
再次强调,MySQL/MariaDB 不支持 LIMIT 子句中的表达式。目前还不支持。
解决方案 5:
为了LIMIT :init, :end
您需要以那种方式进行绑定。如果您有类似的东西$req->execute(Array());
,它将无法工作,因为它将转换PDO::PARAM_STR
为数组中的所有变量,并且LIMIT
您绝对需要一个 Integer。bindValue 或 BindParam 随你便。
$fetchPictures->bindValue(':albumId', (int)$_GET['albumid'], PDO::PARAM_INT);
解决方案 6:
由于没有人解释为什么会发生这种情况,所以我要添加一个答案。它之所以出现这种情况,是因为您正在使用trim()
。如果您查看 PHP 手册trim
,返回类型是string
。然后您尝试将其作为传递PDO::PARAM_INT
。解决此问题的几种方法是:
用于
filter_var($integer, FILTER_VALIDATE_NUMBER_INT)
确保您传递的是一个整数。正如其他人所说,使用
intval()
铸造
(int)
检查它是否是一个整数
is_int()
还有很多方法,但这基本上是根本原因。
解决方案 7:
使用 PDO::PARAM_INT 绑定值偏移和限制,它将起作用
解决方案 8:
//之前(当前错误)$query = " .... LIMIT :p1, 30;"; ... $stmt->bindParam(':p1', $limiteInferior);
//AFTER(错误已更正)$query = " .... LIMIT :p1, 30;"; ... $limiteInferior = (int)$limiteInferior; $stmt->bindParam(':p1', $limiteInferior, PDO::PARAM_INT);
解决方案 9:
PDO::ATTR_EMULATE_PREPARES
给了我
驱动程序不支持该功能:该驱动程序不支持设置属性的错误。
我的解决方法是将变量设置$limit
为字符串,然后将其组合到准备语句中,如下例所示:
$limit = ' LIMIT ' . $from . ', ' . $max_results;
$stmt = $pdo->prepare( 'SELECT * FROM users WHERE company_id = :cid ORDER BY name ASC' . $limit . ';' );
try {
$stmt->execute( array( ':cid' => $company_id ) );
...
}
catch ( Exception $e ) {
...
}
解决方案 10:
不同版本的 PHP 和 PDO 之间存在很多问题。我尝试了 3 或 4 种方法,但无法使 LIMIT 正常工作。
我的建议是使用字符串格式化/连接和intval()过滤器:
$sql = 'SELECT * FROM `table` LIMIT ' . intval($limitstart) . ' , ' . intval($num).';';
使用 intval() 来防止 SQL 注入非常重要,特别是当您从 $_GET 或类似方法获取限制时。 如果您这样做,这是使 LIMIT 正常工作的最简单方法。
关于“PDO 中的 LIMIT 问题”有很多讨论,但我的想法是,PDO 参数从未用于 LIMIT,因为它们始终是整数,快速过滤器可以工作。不过,这有点误导,因为哲学一直是不要自己做任何 SQL 注入过滤,而是“让 PDO 处理它”。
解决方案 11:
请尝试以下操作:
$sql2 = "SELECT * FROM tab ORDER BY id DESC limit 2
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件