如何在MySQL的PHP PDO中使用VARBINARY编写语句?

问题描述 投票:1回答:1

这是我用来尝试与使用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无法做到吗?

php mysql pdo prepared-statement varbinary
1个回答
0
投票

至少在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);

-1
投票

尝试不使用bindParam。这段代码对我使用PHP 7.2是成功的:

<?php
// CREATE TABLE xf_ip (user_id SERIAL, ip VARBINARY(255) NOT NULL)
// INSERT INTO test (ip) VALUES ("172.16.23.67"), ("10.12.34.66"), ("192.168.242.58");

$db = new PDO("mysql:host=localhost;dbname=test", "root", "");
$stmt = $db->prepare("SELECT * FROM xf_ip WHERE user_id = ? AND ip = ?");
$stmt->execute([1, "172.16.23.67"]);
print_r($stmt->fetchAll());

输出:

Array
(
    [0] => Array
        (
            [user_id] => 1
            [0] => 1
            [ip] => 172.16.23.67
            [1] => 172.16.23.67
        )

)
© www.soinside.com 2019 - 2024. All rights reserved.