如何在 PHP PDO 中为 MySQL 准备一个带有 VARBINARY 的语句?
How do I prepare a statement with VARBINARY in PHP PDO for MySQL?
这是我用来尝试与使用 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 注入的攻击:
$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 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 注入的攻击:
$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);