PHP中IP地址与整型数字互相转换详解


Posted in PHP onAugust 20, 2014

IP转换成整型存储是数据库优化一大趋势,不少人目前存储IP时还在使用字符串类型存储,字符串索引比整型索引消耗资源很多,特别是表中数据量大的时候,以及求查询某一个ip段的数据,今天说的ip是指ip4,ip6不在本文范围内。

系统函数ip2long与long2ip
PHP中有内置函数ip2long可以将ip地址转换整型。

$ip = '210.110.11.49';

echo ip2long($ip);

输出:
-764540111

输出的整型有负号是因为我们得到的结果是有符号整型,有符号整型最大值2147483647,要把结果转换为无符号型可以这么写:
3530427185

使用long2ip把整型转换回ip地址

$ip = '210.110.11.49';

$ip_int = ip2long($ip);

echo $ip."<br />";

echo $ip_int."<br />";

echo long2ip($ip_int);

输出:
210.110.11.49

-764540111

210.110.11.49

从结果可以看到,ip与整型可以通过函数完成。

系统函数小bug

这中bug网上一搜都是,大意说的是ip某段加个前导0,先来看看这个bug实例

$ip = '210.110.011.49';

$ip_int = ip2long($ip);

echo $ip."<br />";

echo $ip_int."<br />";

echo long2ip($ip_int);

输出:
210.110.011.49

-764540623

210.110.9.49

转换结果不匹配,我们试着在ip第一段数字前加前导0,再看看

$ip = '021.110.11.49';

$ip_int = ip2long($ip);

echo $ip."<br />";

echo $ip_int."<br />";

echo long2ip($ip_int);

输出:
021.110.11.49

292424497

17.110.11.49

转换结果都出错。以上例子都是因为加了前导0后导致转换结果出错,连带逆转结果与原转换ip不匹配。

转换原理

目前有两个算法:
第一、第一段乘以256的三次方,第二段乘以256的平方,第三段乘以256、最后总和

$ip = '0210.110.11.49';

 

function ipToInt($ip){

    $iparr = explode('.',$ip);

    $num = 0;

    for($i=0;$i<count($iparr);$i++){

        $num += intval($iparr[$i]) * pow(256,count($iparr)-($i+1));

    }

    return $num;

}

 

echo  $ip.'<br />';

$ip_int = ipToInt($ip);

echo $ip_int.'<br />';

echo long2ip($ip_int);

输出:
0210.110.11.49

3530427185

210.110.11.49

第二、通过位运算符

$ip = '0210.110.11.49';

 

function ipToInt($ip){

    $iparr = explode('.',$ip);

    return (intval($iparr[0]<<24))|(intval($iparr[1])<<16)|(intval($iparr[2])<<8)| (intval($iparr[3]));

}

 

echo  $ip.'<br />';

$ip_int = ipToInt($ip);

echo $ip_int.'<br />';

echo long2ip($ip_int);

输出:
0210.110.11.49

-764540111

210.110.11.49

检测IP是否合法

第一、自己遍历检测

function check_ip($ip){

    $iparr = explode('.',$ip);

    foreach($iparr as $v){ if($v>255) return false; }

    return true;

}

 

echo '210.285.11.49,';

var_dump(check_ip('210.285.11.49'));

echo '<br />';

echo '210.205.11.49,';

var_dump(check_ip('210.205.11.49'));

[code]
输出:

[code]

210.285.11.49,bool(false)

210.205.11.49,bool(true)

第二、使用ip2long返回
function check_ip($ip){

    if(ip2long($ip)) return true;

    return false;

}

 

echo '210.285.11.49,';

var_dump(check_ip('210.285.11.49'));

echo '<br />';

echo '210.205.11.49,';

var_dump(check_ip('210.205.11.49'));

输出:
210.285.11.49,bool(false)

210.205.11.49,bool(true)

后记

不少人把ip写库用ip2long转换存放int类型的字段中,但是,在不同的系统平台上,ip2long函数得到的值是不同的,因此可能造成在从数据库中读出数据逆转ip时用long2ip得到的ip与原ip不符合
如果是mysql可以使用mysql系统函数INET_ATON与INET_NTOA解决,或者使用bigint类型处理,要么自己写函数。

PHP 相关文章推荐
PHP开发环境配置(MySQL数据库安装图文教程)
Apr 28 PHP
php中经典方法实现判断多维数组是否为空
Oct 23 PHP
php数据库备份还原类分享
Mar 20 PHP
PHP中nowdoc和heredoc使用需要注意的一点
Mar 21 PHP
php生成静态页面的简单示例
Apr 17 PHP
php+ajax实时刷新简单实例
Feb 25 PHP
php项目中百度 UEditor 简单安装调试和调用
Jul 15 PHP
thinkPHP框架可添加js事件的分页类customPage.class.php完整实例
Mar 16 PHP
php和nginx交互实例讲解
Sep 24 PHP
Laravel5.1 框架数据库操作DB运行原生SQL的方法分析
Jan 07 PHP
PHP扩展类型及安装方式解析
Apr 27 PHP
PhpSpreadsheet中文文档 | Spreadsheet操作教程实例
Apr 01 PHP
PHP函数http_build_query使用详解
Aug 20 #PHP
PHP函数in_array()使用详解
Aug 20 #PHP
PHP中使用json数据格式定义字面量对象的方法
Aug 20 #PHP
PHP采用自定义函数实现遍历目录下所有文件的方法
Aug 19 #PHP
浅谈php函数serialize()与unserialize()的使用方法
Aug 19 #PHP
PHP将回调函数作用到给定数组单元的方法
Aug 19 #PHP
php实现文件下载代码分享
Aug 19 #PHP
You might like
PHP连接SQLServer2005方法及代码
2013/12/26 PHP
ThinkPHP分页类使用详解
2014/03/05 PHP
zf框架的db类select查询器join链表使用示例(zend框架)
2014/03/14 PHP
PHP strtotime函数用法、实现原理和源码分析
2015/02/04 PHP
浅谈Laravel POST,PUT,PATCH 路由的区别
2019/10/15 PHP
php判断某个方法是否存在函数function_exists (),method_exists()与is_callable()区别与用法解析
2020/04/20 PHP
ajax更新数据后,jquery、jq失效问题
2011/03/16 Javascript
19个很有用的 JavaScript库推荐
2011/06/27 Javascript
如何让div span等元素能响应键盘事件操作指南
2012/11/13 Javascript
Google官方支持的NodeJS访问API,提供后台登录授权
2014/07/29 NodeJs
javascript+canvas制作九宫格小程序
2014/12/28 Javascript
C++中的string类的用法小结
2015/08/07 Javascript
JS实现黑色大气的二级导航菜单效果
2015/09/18 Javascript
JavaScript中对DOM节点的访问、创建、修改、删除
2015/11/16 Javascript
js实现的简单图片浮动效果完整实例
2016/05/10 Javascript
限制复选框最多选择项的实现代码
2016/05/30 Javascript
AngularJs验证重复密码的方法(两种)
2016/11/25 Javascript
jQuery插件Echarts实现的双轴图效果示例【附demo源码下载】
2017/03/04 Javascript
Vue 创建组件的两种方法小结(必看)
2018/02/23 Javascript
详解vuex结合localstorage动态监听storage的变化
2018/05/03 Javascript
nodejs npm错误Error:UNKNOWN:unknown error,mkdir 'D:\Develop\nodejs\node_global'at Error
2019/03/02 NodeJs
js实现全选和全不选
2020/07/28 Javascript
py2exe 编译ico图标的代码
2013/03/08 Python
Python写的PHPMyAdmin暴力破解工具代码
2014/08/06 Python
python排序方法实例分析
2015/04/30 Python
用Python中的字典来处理索引统计的方法
2015/05/05 Python
python merge、concat合并数据集的实例讲解
2018/04/12 Python
浅谈pyqt5中信号与槽的认识
2019/02/17 Python
PyQt5实现简单数据标注工具
2019/03/18 Python
keras输出预测值和真实值方式
2020/06/27 Python
就业意向书范文
2014/04/01 职场文书
单位授权委托书范本
2014/09/26 职场文书
2014村书记党建工作汇报材料
2014/11/02 职场文书
个人学习党的群众路线教育实践活动心得体会
2014/11/05 职场文书
昆虫记读书笔记
2015/06/26 职场文书
2019年销售人员的职业生涯规划书
2019/03/25 职场文书