PHP中根据IP地址判断城市实现城市切换或跳转代码


Posted in PHP onSeptember 04, 2012

获取IP地址

<?php
function GetIP() {
    if ($_SERVER["HTTP_X_FORWARDED_FOR"])
        $ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
    else if ($_SERVER["HTTP_CLIENT_IP"])
        $ip = $_SERVER["HTTP_CLIENT_IP"];
    else if ($_SERVER["REMOTE_ADDR"])
        $ip = $_SERVER["REMOTE_ADDR"];
    else if (getenv("HTTP_X_FORWARDED_FOR"))
        $ip = getenv("HTTP_X_FORWARDED_FOR");
    else if (getenv("HTTP_CLIENT_IP"))
        $ip = getenv("HTTP_CLIENT_IP");
    else if (getenv("REMOTE_ADDR"))
        $ip = getenv("REMOTE_ADDR");
    else
        $ip = "Unknown";
    return $ip;
}
echo GetIP();
?>

方法二
function getip ()
{
                if (getenv('http_client_ip')) {
                        $ip = getenv('http_client_ip');
                } else if (getenv('http_x_forwarded_for')) {
                        $ip = getenv('http_x_forwarded_for');
                } else if (getenv('remote_addr')) {
                        $ip = getenv('remote_addr');
                } else {
                        $ip = $_server['remote_addr'];
                }
                return $ip;

PHP通过IP地址判断用户所在城市
上文已经获得了用户IP地址,接下来,我们就是根据这个IP地址获得用户所在城市了。开始之前,我们需要下载一个现成的数据库QQ IP数据库。
最新IP地址数据库:https://3water.com/softs/10529.html
使用方法:解压后QQWry.Dat就是我们想要IP地址数据库,我们新建一个ipcity文件夹,将数据库放在下面。QQ IP数据库使用非常方便,数据也很齐全,你可以及时关注官方更新以保持数据最新,强力推荐一下:)
接下来,我们在上面的ipcity目录下新建一个ipaddress.php文件,直接复制以下代码进去即可,重要的地方也作了相应注释。B段:
<?
/*
函数名称:ipCity
参数说明:$userip——用户IP地址
函数功能:PHP通过IP地址判断用户所在城市
author:lee
contact:xpsem2010@gmail.com
*/
function ipCity($userip) {
    //IP数据库路径,这里用的是QQ IP数据库 20110405 纯真版
    $dat_path = 'QQWry.dat';
    //判断IP地址是否有效
    if(!ereg("^([0-9]{1,3}.){3}[0-9]{1,3}$", $userip)){
        return 'IP Address Invalid';
    }
    //打开IP数据库
    if(!$fd = @fopen($dat_path, 'rb')){
        return 'IP data file not exists or access denied';
    }
    //explode函数分解IP地址,运算得出整数形结果
    $userip = explode('.', $userip);
    $useripNum = $userip[0] * 16777216 + $userip[1] * 65536 + $userip[2] * 256 + $userip[3];
    //获取IP地址索引开始和结束位置
    $DataBegin = fread($fd, 4);
    $DataEnd = fread($fd, 4);
    $useripbegin = implode('', unpack('L', $DataBegin));
    if($useripbegin < 0) $useripbegin += pow(2, 32);
    $useripend = implode('', unpack('L', $DataEnd));
    if($useripend < 0) $useripend += pow(2, 32);
    $useripAllNum = ($useripend - $useripbegin) / 7 + 1;
    $BeginNum = 0;
    $EndNum = $useripAllNum;
    //使用二分查找法从索引记录中搜索匹配的IP地址记录
    while($userip1num>$useripNum || $userip2num<$useripNum) {
        $Middle= intval(($EndNum + $BeginNum) / 2);
        //偏移指针到索引位置读取4个字节
        fseek($fd, $useripbegin + 7 * $Middle);
        $useripData1 = fread($fd, 4);
        if(strlen($useripData1) < 4) {
            fclose($fd);
            return 'File Error';
        }
        //提取出来的数据转换成长整形,如果数据是负数则加上2的32次幂
        $userip1num = implode('', unpack('L', $useripData1));
        if($userip1num < 0) $userip1num += pow(2, 32);
        //提取的长整型数大于我们IP地址则修改结束位置进行下一次循环
        if($userip1num > $useripNum) {
            $EndNum = $Middle;
            continue;
        }
        //取完上一个索引后取下一个索引
        $DataSeek = fread($fd, 3);
        if(strlen($DataSeek) < 3) {
            fclose($fd);
            return 'File Error';
        }
        $DataSeek = implode('', unpack('L', $DataSeek.chr(0)));
        fseek($fd, $DataSeek);
        $useripData2 = fread($fd, 4);
        if(strlen($useripData2) < 4) {
            fclose($fd);
            return 'File Error';
        }
        $userip2num = implode('', unpack('L', $useripData2));
        if($userip2num < 0) $userip2num += pow(2, 32);
        //找不到IP地址对应城市
        if($userip2num < $useripNum) {
            if($Middle == $BeginNum) {
                fclose($fd);
                return 'No Data';
            }
            $BeginNum = $Middle;
        }
    }
    $useripFlag = fread($fd, 1);
    if($useripFlag == chr(1)) {
        $useripSeek = fread($fd, 3);
        if(strlen($useripSeek) < 3) {
            fclose($fd);
            return 'System Error';
        }
        $useripSeek = implode('', unpack('L', $useripSeek.chr(0)));
        fseek($fd, $useripSeek);
        $useripFlag = fread($fd, 1);
    }
    if($useripFlag == chr(2)) {
        $AddrSeek = fread($fd, 3);
        if(strlen($AddrSeek) < 3) {
            fclose($fd);
            return 'System Error';
        }
        $useripFlag = fread($fd, 1);
        if($useripFlag == chr(2)) {
            $AddrSeek2 = fread($fd, 3);
            if(strlen($AddrSeek2) < 3) {
                fclose($fd);
                return 'System Error';
            }
            $AddrSeek2 = implode('', unpack('L', $AddrSeek2.chr(0)));
            fseek($fd, $AddrSeek2);
        } else {
            fseek($fd, -1, SEEK_CUR);
        }
        while(($char = fread($fd, 1)) != chr(0))
            $useripAddr2 .= $char;
        $AddrSeek = implode('', unpack('L', $AddrSeek.chr(0)));
        fseek($fd, $AddrSeek);
        while(($char = fread($fd, 1)) != chr(0))
            $useripAddr1 .= $char;
    } else {
        fseek($fd, -1, SEEK_CUR);
        while(($char = fread($fd, 1)) != chr(0))
            $useripAddr1 .= $char;
        $useripFlag = fread($fd, 1);
        if($useripFlag == chr(2)) {
            $AddrSeek2 = fread($fd, 3);
            if(strlen($AddrSeek2) < 3) {
                fclose($fd);
                return 'System Error';
            }
            $AddrSeek2 = implode('', unpack('L', $AddrSeek2.chr(0)));
            fseek($fd, $AddrSeek2);
        } else {
            fseek($fd, -1, SEEK_CUR);
        }
        while(($char = fread($fd, 1)) != chr(0)){
            $useripAddr2 .= $char;
        }
    }
    fclose($fd);
    //返回IP地址对应的城市结果
    if(preg_match('/http/i', $useripAddr2)) {
        $useripAddr2 = '';
    }
    $useripaddr = "$useripAddr1 $useripAddr2";
    $useripaddr = preg_replace('/CZ88.Net/is', '', $useripaddr);
    $useripaddr = preg_replace('/^s*/is', '', $useripaddr);
    $useripaddr = preg_replace('/s*$/is', '', $useripaddr);
    if(preg_match('/http/i', $useripaddr) || $useripaddr == '') {
        $useripaddr = 'No Data';
    }
    return $useripaddr;
}
?>

PHP根据IP地址实现城市切换或跳转
到这里,其实问题已经很简单了,用简单的js就通通搞定。C段如下:
//根据IP地址跳转指定页面js取得城市
var city='<?echo ipCity($xp_UserIp);?>';

//根据IP地址所有城市跳转到指定页面
if(city.indexOf("上海市")>=0){
        window.location.href="http://shanghai.demo.com/";
}

将开头的A段代码和上面的C段代码分别放在B段代码的头和尾,然后我们在需要跳转的页面加入以下代码:
<script src="/ipcity/ipaddress.php" type="text/javascript" language="javascript"></script>
 

刷新页面,是不是达到预想的效果了呢?
上面的代码只是简单的判断了ip那里就跳到那,如果出现如,我想把湖南所有IP都跳到长沙去,那像衡阳,刘阳,耒阳 这些就要作多次父线处理了,要想知道请看下集。
PHP 相关文章推荐
php 面试碰到过的问题 在此做下记录
Jun 09 PHP
php学习之流程控制实现代码
Jun 09 PHP
PHP模板引擎Smarty的缓存使用总结
Apr 24 PHP
ThinkPHP CURD方法之order方法详解
Jun 18 PHP
ThinkPHP后台首页index使用frameset时的注意事项分析
Aug 22 PHP
php rsa加密解密使用详解
Jan 14 PHP
php设计模式之单例模式代码
Jun 11 PHP
浅谈PHP检查数组中是否存在某个值 in_array 函数
Jun 13 PHP
PHP magento后台无法登录问题解决方法
Nov 24 PHP
php注册系统和使用Xajax即时验证用户名是否被占用
Aug 31 PHP
php实现的AES加密类定义与用法示例
Jan 29 PHP
Laravel Eloquent ORM 多条件查询的例子
Oct 10 PHP
PHP中“简单工厂模式”实例代码讲解
Sep 04 #PHP
通过php快速统计某个数据库中每张表的数据量
Sep 04 #PHP
比较discuz和ecshop的截取字符串函数php版
Sep 03 #PHP
Windows下部署Apache+PHP+MySQL运行环境实战
Aug 31 #PHP
关于UEditor编辑器远程图片上传失败的解决办法
Aug 31 #PHP
php数组一对一替换实现代码
Aug 31 #PHP
PHP 利用AJAX获取网页并输出的实现代码(Zjmainstay)
Aug 31 #PHP
You might like
FCKeditor添加自定义按钮
2008/03/27 PHP
php简单提示框alert封装函数
2010/08/08 PHP
PHP重置数组为连续数字索引的几种方式总结
2018/03/12 PHP
javascript语句中的CDATA标签的意义
2007/05/09 Javascript
Mootools 1.2教程 滑动效果(Slide)
2009/09/15 Javascript
js多级树形弹出一个小窗口层(非常好用)实例代码
2013/03/19 Javascript
JavaScript获取flash对象与网上的有所不同
2014/04/21 Javascript
jQuery+css3动画属性制作猎豹浏览器宽屏banner焦点图
2015/03/16 Javascript
关于backbone url请求中参数带有中文存入数据库是乱码的快速解决办法
2016/06/13 Javascript
js实现多图左右切换功能
2016/08/04 Javascript
js制作简单的音乐播放器的示例代码
2017/08/28 Javascript
jfinal与bootstrap的登出实战详解
2017/11/27 Javascript
Vue中的v-for循环key属性注意事项小结
2018/08/12 Javascript
JavaScript代码调试方法实例小结
2019/01/05 Javascript
js实现简单掷骰子小游戏
2019/10/24 Javascript
使用Mock.js生成前端测试数据
2020/12/13 Javascript
vue实现按钮切换图片
2021/01/20 Vue.js
python中的yield使用方法
2014/02/11 Python
深入探究Python中变量的拷贝和作用域问题
2015/05/05 Python
浅谈python新手中常见的疑惑及解答
2016/06/14 Python
pandas DataFrame创建方法的方式
2019/08/02 Python
python通过文本在一个图中画多条线的实例
2020/02/21 Python
Python tkinter 下拉日历控件代码
2020/03/04 Python
Python高并发和多线程有什么关系
2020/11/14 Python
CSS3 @font-face属性使用指南
2014/12/12 HTML / CSS
美体小铺英国官网:The Body Shop英国
2017/01/24 全球购物
关键字throw与throws的用法差异
2016/11/22 面试题
新员工培训个人的自我评价
2013/10/09 职场文书
《去年的树》教学反思
2014/04/11 职场文书
公务员年度考核登记表个人总结
2015/02/12 职场文书
家属慰问信
2015/02/14 职场文书
迎新生晚会主持词
2015/06/30 职场文书
学习计划是什么
2019/04/30 职场文书
python编写五子棋游戏
2021/05/25 Python
react antd实现动态增减表单
2021/06/03 Javascript
GO语言字符串处理函数之处理Strings包
2022/04/14 Golang