主页>技术社区>IT 技术>编程开发>PHP

TP 判断IP是否在国内

eIT.com.cn 2023/3/17 23:49:51 阅读 4 次

打印


环境ThinkPHP+Redis

1.IP保存文件,文件名自定义,与后文对应

 

 

 2.获取IP信息脚本.sh文件

#!/bin/bash
#variables

ip_txt_path=/www/wwwroot/checkip/china_ip.txt;
ip_url='http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest';
php_path=/www/server/php/72/bin/php
script_path=/www/wwwroot/checkip/putip2redis.php

#mv old txt

cur_time=$(date +"%Y%m%d%H%M%S");
if [ -f ${ip_txt_path} ];then      mv ${ip_txt_path} ${ip_txt_path}_${cur_time};
fi

#download

/usr/bin/curl ${ip_url} | grep ipv4 | grep CN | awk -F\| '{ printf("%s/%d\n", $4, 32-log($5)/log(2)) }' >${ip_txt_path}

#parse 2 redis

echo "begin parse ip\n";
${php_path} ${script_path}

3.将IP信息保存到Redis中,上图中putip2redis.php文件

<?php
/*

解析国内ip地址列表,以ip地址的第一段为索引,
保存到redis中的一个hash中

by 刘宏缔
2020.04.02

*/
//------------------------------------------------settings
ini_set("display_errors","On");
error_reporting(E_ALL);
//------------------------------------------------constant
define("REDIS_SERVER", "127.0.0.1");
define("REDIS_PORT", "6379");
define("IP_FILE", "/www/wwwroot/isipchina/china_ip.txt");
define("IP_HASH_NAME", "china_ip_hash");
//------------------------------------------------link 4 redis
$redis_link = new \Redis();
$redis_link->connect(REDIS_SERVER,REDIS_PORT);

//------------------------------------------------main
set_ip_list(IP_FILE);

//------------------------------------------------function
//处理所有的ip范围到redis
function set_ip_list($ip_file) {   //从文件中得到所有的国内ip   $arr_all = file($ip_file);
   //遍历,得到所有的第一段   $arr_first = array();   foreach ($arr_all as $k => $rangeone) {       $rangeone = trim($rangeone);       if ($rangeone == "") {           continue;       }              $first = explode(".", $rangeone);       if (isset($first[0]) && $first[0]!='') {          $arr_first[] = $first[0];       }   }
   //对所有的第一段去除重复   $arr_first = array_unique($arr_first);
   //得到线上hash的所有key   $arr_hkeys = hash_keys(IP_HASH_NAME);
   //如果一个线上已存在的key不再存在于新ip的第一段的数组中   //需要从线上hash中删除   if (is_array($arr_hkeys) && sizeof($arr_hkeys)>0) {       foreach($arr_hkeys as $k => $hkey_one) {          if (!in_array($hkey_one, $arr_first)) {
echo "will delete :".$hkey_one."\n";
hash_delete_hkey(IP_HASH_NAME,$hkey_one);           }       }   }
   //得到每个第一段下面对应的所有ip地址段,保存到redis   foreach ($arr_first as $k => $first) {      add_a_list_by_first($first,$arr_all);     }

}


//把所有的第一段为指定数字的ip,添加到redis
function add_a_list_by_first($first,$arr) {
    $arr_line = array();    foreach ($arr as $k => $rangeone) {         $rangeone = trim($rangeone);         $first_a = explode(".", $rangeone);         if (!isset($first_a[0]) || $first_a[0] == "") {            continue;         }         $cur_first = $first_a[0];         if ($cur_first == $first) {
             $line = get_line_by_rangeone($rangeone);             //echo "line:".$line."\n";             $arr_line[] = $line;         } else {            continue;         }     }

     if (sizeof($arr_line) >0) {         $key_name = $first;         hash_set(IP_HASH_NAME,$key_name,$arr_line);     }
}


//得到一个ip地址段的起始范围
function get_line_by_rangeone($networkRange) {
       $s = explode('/', $networkRange);       $network_start = (double) (sprintf("%u", ip2long($s[0])));       $network_len = pow(2, 32 - $s[1]);       $network_end = $network_start + $network_len - 1;
       $line = $network_start."--".$network_end;       return $line;
}


//redis set 一个数组到hash
function hash_set($hash_name,$key_name,$arr_value){     global $redis_link;     $str_value = json_encode($arr_value);     $b = $redis_link->hset($hash_name, $key_name, $str_value);
}

//返回redis hash中
function hash_keys($hash_name) {     global $redis_link;     $arr = $redis_link->hKeys($hash_name);     return $arr;
}

//删除一个hash的hkey
function hash_delete_hkey($hash_name,$key_name) {     global $redis_link;     $redis_link->hdel($hash_name, $key_name);
}

?>

4.运行.sh文件初始化redis数据

5.添加类文件到TP的extend

<?php
namespace ipxx;
class Ipcheck
{
//------------------------------------------------function   function getRealIp()//判断来源IP   {
       return $_SERVER['REMOTE_ADDR'];   }


//判断一个ip是否属于china   function is_ip_in_china($ip)   {
//------------------------------------------------link 2 redis             $ip = trim($ip);       $first_a = explode(".", $ip);       if (!isset($first_a[0]) || $first_a[0] == "") {           //ip有误,按国外算           return false;       }       $first = $first_a[0];
       $arr_range = $this->hash_get(IP_HASH_NAME, $first);       if (!is_array($arr_range) || sizeof($arr_range) == 0) {           return false;       }
       if ($this->is_ip_in_arr_range($ip, $arr_range) == true) {           return true;       } else {           return false;       }   }

//判断一个ip是否属于ip的range数组   function is_ip_in_arr_range($ip, $arr_range)   {       $ip_long = (double)(sprintf("%u", ip2long($ip)));

       foreach ($arr_range as $k => $one) {           $one = trim($one);           //echo $one.":\n";           $arr_one = explode("--", $one);
           if (!isset($arr_one[0]) || !isset($arr_one[1])) {
continue;           }
           $begin = $arr_one[0];           $end = $arr_one[1];
           if ($ip_long >= $begin && $ip_long <= $end) {
return true;           }       }       return false;   }


//得到一个hash中对应key的value   function hash_get($hash_name, $key_name)   {      
//------------------------------------------------link 2 redis       $redis_link = new \Redis();       $redis_link->connect(REDIS_SERVER,REDIS_PORT);       $str = $redis_link->hget($hash_name, $key_name);       $arr = json_decode($str, true);       return $arr;   }
}

?>

6.引用类调用函数判断IP

use ipxx\Ipcheck;





public function test()   {       define("REDIS_SERVER", "127.0.0.1");       define("REDIS_PORT", "6379");       define("IP_HASH_NAME", "china_ip_hash");
       $ipcheck = new Ipcheck();       $redis_link = new \Redis();       $redis_link->connect(REDIS_SERVER,REDIS_PORT);       $userip=$_SERVER['REMOTE_ADDR'];        $is_in = $ipcheck->is_ip_in_china($userip);//判断一个ip是否国内的ip          if ($is_in == true) {         echo "china";       } else {         echo "foreign";       }   }

 

  







相关内容


热门栏目


特别声明


最新资讯
热讯排行



合作媒体友情链接
生活常识小贴士 软件开发教程 智慧城市生活网 息县通生活服务[移动版] 息县商圈[移动版] 美食菜谱
健康养生 法律知识 科技频道 电影影讯 留学考研学习 星座生肖|解梦说梦




关于我们 | 联系我们 | 合作媒体 | 使用条款 | 隐私权声明 | 版权声明

      Copyright © 2023 eIT.com.cn. All Rights Reserved. 豫ICP备2022012332号