gpt4 book ai didi

php - 无法选择 ip=inet_pton($ip)

转载 作者:IT老高 更新时间:2023-10-29 00:07:13 26 4
gpt4 key购买 nike

我在数据库中有一个名为 ip

的唯一列

IP 地址在使用 PHP 函数转换后以 BINARY(16)(无排序规则)形式存储在此列中

$store_ip = inet_pton($ip);

当我尝试插入相同的 IP 两次时,它工作正常,但由于它是唯一的而失败,

但是当我尝试选择 IP 时它不起作用并且总是返回 FALSE(未找到)

<?php

try {
$ip = inet_pton($_SERVER['REMOTE_ADDR']);
$stmt = $db->prepare("SELECT * FROM `votes` WHERE ip=?");
$stmt->execute([$ip]);
$get = $stmt->fetch();

if( ! $get){
echo 'Not found';
}else{
echo 'Found';
}

// close connection
$get = null;
$stmt = null;

} catch (PDOException $e) {
error_log($e->getMessage());
}

我插入IP的部分:

<?php

if( ! filter_var($ip, FILTER_VALIDATE_IP)){
return FALSE;
}

$ip = inet_pton($_SERVER['REMOTE_ADDR']);

try {
$stmt = $db->prepare("INSERT INTO votes(ip, answer) VALUES(?,?)");
$stmt->execute([$ip, $answer]);
$stmt = null;
} catch (PDOException $e) {
return FALSE;
}

最佳答案

首先修复,这很简单:如果要同时存储 IPv4 和 IPv6 地址,您应该使用 VARBINARY(16) 而不是 BINARY(16)

现在问题来了:为什么 BINARY(16) 不能按预期工作?

假设我们有一个表 ips,其中只有一列 ip BINARY(16) PRIMARY KEY。我们将默认的本地 IPv4 地址存储为

$stmt = $db->prepare("INSERT INTO ips(ip) VALUES(?)");
$stmt->execute([inet_pton('127.0.0.1')]);

并在数据库中找到以下值:

0x7F000001000000000000000000000000

如您所见 - 这是一个 4 字节二进制值 (0x7F000001)右填充零以适应 16 字节的固定长度列。

当你现在尝试用

找到它时
$stmt = $db->prepare("SELECT * FROM ips WHERE ip = ?");
$stmt->execute([inet_pton('127.0.0.1')]);

会发生以下情况:PHP 发送值 0x7F000001 作为参数,然后进行比较存储值 0x7F000001000000000000000000000000。但是由于两个不同长度的二进制值永远不相等,WHERE 条件将始终返回 FALSE。你可以试试

SELECT 0x00 = 0x0000

这将返回 0 (FALSE)。

注意:固定长度的非二进制字符串 (CHAR(N)) 的行为是不同的。

我们可以使用显式转换作为解决方法:

$stmt = $db->prepare("SELECT * FROM ips WHERE ip = CAST(? as BINARY(16))");
$stmt->execute([inet_pton('127.0.0.1')]);

它会找到该行。但是如果我们看看我们得到了什么

var_dump(inet_ntop($stmt->fetch(PDO::FETCH_OBJ)->ip));

我们会看到

string(8) "7f00:1::"

但这不是(真的)我们试图存储的内容。当我们现在尝试存储 7f00:1:: 时,我们会得到一个重复键错误,虽然我们还没有存储任何 IPv6 地址。

再一次:使用 VARBINARY(16),您可以保持您的代码不受影响。如果您存储许多 IPv4 地址,您甚至可以节省一些存储空间。

关于php - 无法选择 ip=inet_pton($ip),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55347251/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com