首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PHP/mysqli:用mysqli_stmt_bind_param()插入IP地址

PHP/mysqli:用mysqli_stmt_bind_param()插入IP地址
EN

Stack Overflow用户
提问于 2010-05-26 21:30:01
回答 2查看 4.6K关注 0票数 2

我有一个数据库表,其中包含一个无符号整数字段来存储访问者的IP地址:

代码语言:javascript
复制
`user_ip` INT(10) UNSIGNED DEFAULT NULL,

下面是试图存储IP地址的PHP代码片段:

代码语言:javascript
复制
$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);
}

插入操作成功,但是user_ip字段包含一个空值。我还尝试将mysqli_stmt_bind_param()中的参数类型(在上面的示例中设置为string )更改为整数,即mysqli_bind_param(.‘'si',.)-但没有用。

我还尝试使用以下代码来代替mysql的INET_ATON() SQL函数:

代码语言:javascript
复制
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()中的整数&字符串传递,但没有结果。

问题似乎在于参数化插入。

以下“旧式”代码工作正常,没有任何问题:

代码语言:javascript
复制
mysqli_query(..., "INSERT INTO visitors(user_email, user_ip) VALUES ('$email',INET_ATON('$ipaddr'))");

我在这里做错什么了?

提前感谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-05-26 21:33:48

我觉得应该是这样的:

代码语言:javascript
复制
$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的参数应该是要插入的实际值,而不是任何函数。

票数 2
EN

Stack Overflow用户

发布于 2010-05-26 21:37:29

绑定SQL查询参数只能用于值,而不能用于表达式或函数调用。所以当你这么做的时候

代码语言:javascript
复制
$remote_ip = "INET_ATON('$ipaddr')";

它绑定字符串"INET_ATON('value of $ipaddr')",而不是根据该名称绑定一个SQL函数的结果。当向整数列插入字符串值时,MySQL接受任何前导数字的数字值,在本例中没有前导数字。因此,值0被插入。

我建议您使用PHP的内置函数ip2long()

代码语言:javascript
复制
$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()转换为无符号整数的字符串表示形式。

代码语言:javascript
复制
<?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"
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2916962

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档