我有一个数据库表,其中包含一个无符号整数字段,用于存储访问者的IP地址:
`user_ip` INT(10) UNSIGNED DEFAULT NULL,
以下是试图存储IP地址的PHP代码片段:
$ipaddr = $_SERVER['REMOTE_ADDR'];
if ($stmt = mysqli_prepare($dbconn, 'INSERT INTO visitors(user_email, user_ip) VALUES (?,?)'))
{
$remote_ip = "INET_ATON('$ipaddr')";
mysqli_stmt_bind_param($stmt, 'ss', $email, $remote_ip);
if (mysqli_stmt_execute($stmt) === FALSE) return FALSE;
$rows_affected = mysqli_stmt_affected_rows($stmt);
mysqli_stmt_close($stmt);
}
INSERT操作成功,但user_ip字段包含空值。 我也尝试将mysqli_stmt_bind_param()中的参数类型(在上例中设置为字符串)更改为整数,即mysqli_bind_param(...'si',...) - 但是要没有用。
我也尝试使用以下代码而不是mysql的INET_ATON()SQL函数:
function IP_ATON($ipaddr)
{
$trio = intval(substr($ipaddr,0,3));
return ($trio>127) ? ((ip2long($ipaddr) & 0x7FFFFFFF) + 0x80000000) : ip2long($ipaddr);
}
它仍然不起作用 - 'user_ip'字段仍设置为null。我已经尝试将$ ip_addr变量作为整数和& mysqli_bind_param()中的字符串 - 无济于事。
似乎问题在于参数化插入。
以下“旧式”代码没有任何问题:
mysqli_query(..., "INSERT INTO visitors(user_email, user_ip) VALUES ('$email',INET_ATON('$ipaddr'))");
我在这里做错了什么?
提前致谢!
答案 0 :(得分:3)
我认为它应该是这样的:
$ipaddr = $_SERVER['REMOTE_ADDR'];
if ($stmt = mysqli_prepare($dbconn, 'INSERT INTO visitors(user_email, user_ip) VALUES (?, INET_ATON(?))'))
{
mysqli_stmt_bind_param($stmt, 'ss', $email, $ipaddr);
if (mysqli_stmt_execute($stmt) === FALSE) return FALSE;
$rows_affected = mysqli_stmt_affected_rows($stmt);
mysqli_stmt_close($stmt);
}
请注意第二次更改?以及将哪些参数发送到mysqli_stmt_bind_param。
因为传递给mysqli_stmt_bind_param的参数应该是要插入的实际值,而不是任何函数。
答案 1 :(得分:1)
绑定SQL查询参数只能用于值,而不能用于表达式或函数调用。所以当你这样做时:
$remote_ip = "INET_ATON('$ipaddr')";
它绑定字符串“INET_ATON($ $ ipaddr '的值)”,而不是该函数的SQL函数的结果。当字符串值插入整数列时,MySQL将获取任何前导数字的数值,在这种情况下,没有前导数字。所以插入了值0。
我建议您使用PHP的内置函数ip2long()
。
$remote_ip = ip2long($ipaddr);
mysqli_stmt_bind_param($stmt, 'ss', $email, $remote_ip);
虽然$remote_ip
现在是一个整数,但我已经读过mysqli无法绑定无符号整数,所以你应该在绑定时使用's'作为类型。
重新评论:你是对的,因为PHP不支持无符号整数,如果你的IP地址是128.0.0.0或更高,ip2long()
将返回一个负数。您可以使用sprintf()
转换为无符号整数的字符串表示形式:
<?php
$addr = '192.168.1.1';
$ip = ip2long($addr);
var_dump($ip);
// int(-1062731519)
$ip = sprintf("%u", ip2long($addr));
var_dump($ip);
// string(10) "3232235777"
var_dump(long2ip($ip));
// string(11) "192.168.1.1"