php - 如何在 PHP PDO for MySQL 中使用 VARBINARY 准备语句?

标签 php mysql pdo prepared-statement varbinary

这是我用来尝试与使用 PHP PDO 的 VARBINARY 进行比较的代码:

$st = $pdo->prepare('SELECT * FROM `xf_ip` WHERE user_id = ? AND ip = ?;');
$st ->execute(array($new_row[':forums_id'], $hexip));

我尝试使用 0x ('0x' . $hexip) 作为前缀,并使用 bindParam:

$st = $pdo->prepare('SELECT * FROM `xf_ip` WHERE user_id = :user_id AND ip = :ip;');
$st->bindParam(':user_id', $new_row[':forums_id'], \PDO::PARAM_INT);
$st->bindParam(':ip', $hexip, \PDO::PARAM_LOB);
$st->execute();

这是唯一有效的查询,但它是一个不安全的查询,因为它没有准备好并且可能容易受到 SQL 注入(inject)攻击:

$st = $pdo->query('SELECT * FROM `xf_ip` WHERE user_id = ' . (int) $new_row[':forums_id'] . ' AND ip = 0x' . $hexip);

hexip 的格式必须是0xFFFFFFFF,不带引号,并且不能是整数格式,否则 MySQL 将不接受。

这对 PDO 来说是不可能的吗?

最佳答案

参数总是像您将它们作为字符串传递一样,至少在 MySQL PDO 驱动程序中是这样。八字符字符串“FFFFFFFF”不等于 0xFFFFFFFF 表示的 4 字节二进制字符串。以下两个 SQL 语句不相同:

SELECT * FROM `xf_ip` WHERE user_id = :user_id AND ip = 0xFFFFFFFF
SELECT * FROM `xf_ip` WHERE user_id = :user_id AND ip = 'FFFFFFFF'

但是将 'FFFFFFFF' 作为参数传递会执行与后一个语句类似的语句。

有两种解决方法:

一种是传递一串十六进制数字,但在将其与列进行比较之前,在 SQL 中使用 UNHEX() 将这些十六进制数字转换为等效的二进制字符串:

SELECT * FROM `xf_ip` WHERE user_id = :user_id AND ip = UNHEX(:ip)

另一个解决方案是传递一个二进制字符串,先在 PHP 中对其进行非十六进制处理:

$binip = hex2bin($hexip);
$st->bindParam(':ip', $binip, \PDO::PARAM_LOB);

关于php - 如何在 PHP PDO for MySQL 中使用 VARBINARY 准备语句?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59358851/

相关文章:

php curl 错误 : Failure when receiving data from the peer

php - 处理后数组值并转储到数据库

php - PDO 与 bindValue 绑定(bind)不起作用

PHP - 将准备好的 stmt 提取到类 : Fatal Error "class not found"

php - 从命令行调用 PHP 函数

php - 如何使用间隔将mysql日期字段与今天+30天进行比较

MySQL 时间戳错误

ios - 防止用户看到旧数据 MySQL/iOS

mysql - Ormlite for MySql 寻找错误的版本

php - 如何防止事务中的 MySQL 竞争条件重复条目