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与java通过socket通信的实现代码
Oct 21 PHP
PHP实现获取域名的方法小结
Nov 05 PHP
php集成环境xampp中apache无法启动问题解决方案
Nov 18 PHP
php基于socket实现SMTP发送邮件的方法
Mar 05 PHP
递归实现php数组转xml的代码分享
May 14 PHP
实例讲解php数据访问
May 09 PHP
PHP单链表的实现代码
Jul 05 PHP
php中文乱码问题的终极解决方案汇总
Aug 01 PHP
简单实现php上传文件功能
Sep 21 PHP
golang实现php里的serialize()和unserialize()序列和反序列方法详解
Oct 30 PHP
PHP的PDO错误与错误处理
Jan 27 PHP
PHP终止脚本运行三种实现方法详解
Sep 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
Smarty的配置与高级缓存技术分享
2012/06/05 PHP
php内嵌函数用法实例
2015/03/20 PHP
PHP定时任务获取微信access_token的方法
2016/10/10 PHP
Zend Framework常用校验器详解
2016/12/09 PHP
php获取客户端IP及URL的方法示例
2017/02/03 PHP
Laravel下生成验证码的类
2017/11/15 PHP
php使用imagecopymerge()函数创建半透明水印
2018/01/25 PHP
PHP实现APP微信支付的实例讲解
2018/02/10 PHP
PHP语言对接抖音快手小红书视频/图片去水印API接口源码
2020/08/11 PHP
学习ExtJS TextField常用方法
2009/10/07 Javascript
javascript DOM编程实例(智播客学习)
2009/11/23 Javascript
firefox事件处理之自动查找event的函数(用于onclick=foo())
2010/08/05 Javascript
jQuery弹出层始终垂直居中相对于屏幕或当前窗口
2013/04/01 Javascript
node.js中的fs.open方法使用说明
2014/12/17 Javascript
jQuery实现冻结表头的方法
2015/03/09 Javascript
jQuery实现3D文字特效的方法
2015/03/10 Javascript
jQuery使用fadeout实现元素渐隐效果的方法
2015/03/27 Javascript
JavaScript使用DeviceOne开发实战(一) 配置和起步
2015/12/01 Javascript
jQuery实现的左右移动焦点图效果
2016/01/14 Javascript
js密码强度实时检测代码
2016/03/02 Javascript
用js读写cookie的简单方法(推荐)
2016/08/08 Javascript
微信公众号菜单配置微信小程序实例详解
2017/03/31 Javascript
Vue.js实现表格渲染的方法
2018/09/07 Javascript
vue服务端渲染页面缓存和组件缓存的实例详解
2018/09/18 Javascript
[35:26]DOTA2上海特级锦标赛B组小组赛#2 VG VS Fnatic第三局
2016/02/26 DOTA
python计算文本文件行数的方法
2015/07/06 Python
python3.4实现邮件发送功能
2018/05/28 Python
Python importlib动态导入模块实现代码
2020/04/16 Python
Python检测端口IP字符串是否合法
2020/06/05 Python
日本最大的旅游网站:Rakuten Travel(乐天旅游)
2018/08/02 全球购物
餐饮企业总经理岗位职责范文
2014/02/18 职场文书
《少年王冕》教学反思
2014/04/11 职场文书
工程售后服务方案
2014/06/08 职场文书
2015年度物流工作总结
2015/04/30 职场文书
导游词之云南丽江古城
2019/09/17 职场文书
MySQL中使用or、in与union all在查询命令下的效率对比
2021/05/26 MySQL