php_在线判断来源IP是否为国内IP(筛选国内国外ip办法)
一朋友需要这个功能。我在我所熟悉的编写语言中想到了个办法
1.java 搭建麻烦
2.python 环境不好搭配 不适合给小白新手朋友用
3.易语言 (速度太慢)
4.php (毫秒级别 就它了)
环境:
宝塔 Redis
1.在宝塔面板中安装Redis
2.配置Redis(不需要改)
3. 在安装的PHP中安装Redis扩展。
4.在面板的安全配置里,开放相应的Redis端口(Redis使用的是6379端口,就开放6379端口)。(如果你是腾讯云什么还要去 控制后台修改 百度下开放端口就知道了)
5.测试是否成功配置好环境源码(php)
<?php $redis = new \Redis(); $redis->connect('127.0.0.1', 6379);//serverip port $redis ->set( "test" , "Hello World "); echo $redis ->get( "test"); echo "Server is running: " .$redis->ping();
没问题的话。那么现在其他源码:
#!/bin/bash #variables ip_txt_path=/www/wwwroot/isipchina/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/isipchina/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}
ip_txt_path=/www/wwwroot/isipchina/china_ip.txt; //存放国内字段IP文本的地址记得看路径
ip_url=’http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest’;//不需要改
php_path=/www/server/php/72/bin/php //宝塔php72
script_path=/www/wwwroot/isipchina/putip2redis.php //把txt的内容 redis存进去数据库
${php_path} ${script_path}//运行php文件
putip2redis.php
修改地址:define(“IP_FILE”, “/www/wwwroot/isipchina/china_ip.txt”);
<?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); } ?>
ipchina.php 用来判断ip是否为国内ip( 无需修改)
<?php /* 判断一个ip是否国内的ip 需要连接到redis服务器进行判断 */ //------------------------------------------------settings ini_set("display_errors","On"); error_reporting(E_ALL); $t1 = microtime(true); //------------------------------------------------constant define("REDIS_SERVER", "127.0.0.1"); define("REDIS_PORT", "6379"); define("IP_HASH_NAME", "china_ip_hash"); //------------------------------------------------link 2 redis $redis_link = new \Redis(); $redis_link->connect(REDIS_SERVER,REDIS_PORT); //------------------------------------------------main //$ip = getRealIp(); $ip = getRealIp();//在线获取用户IP $is_in = is_ip_in_china($ip);//判断一个ip是否国内的ip echo "ip:".getRealIp().PHP_EOL; if ($is_in == true) { echo "china"; } else { echo "foreign"; } //------------------------------------------------function function getRealIp()//判断来源IP { $ip=false; if(!empty($_SERVER["HTTP_CLIENT_IP"])){ $ip = $_SERVER["HTTP_CLIENT_IP"]; } if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { $ips = explode (", ", $_SERVER['HTTP_X_FORWARDED_FOR']); if ($ip) { array_unshift($ips, $ip); $ip = FALSE; } for ($i = 0; $i < count($ips); $i++) { if (!eregi ("^(10│172.16│192.168).", $ips[$i])) { $ip = $ips[$i]; break; } } } return ($ip ? $ip : $_SERVER['REMOTE_ADDR']); } //判断一个ip是否属于china function is_ip_in_china($ip) { $ip = trim($ip); $first_a = explode(".", $ip); if (!isset($first_a[0]) || $first_a[0] == "") { //ip有误,按国外算 return false; } $first = $first_a[0]; $arr_range = hash_get(IP_HASH_NAME,$first); if (!is_array($arr_range) || sizeof($arr_range) == 0) { return false; } if (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){ global $redis_link; $str = $redis_link->hget($hash_name, $key_name); $arr = json_decode($str,true); return $arr; } $t2 = microtime(true);//计算时间 echo '耗时'.round($t2-$t1,6).'s /by:老马 '; ?>
脚本格式:
任务名字:更新中国IP库
任务代码:
sh /www/wwwroot/isipchina/downchinaip.sh >> /www/wwwroot/isipchina/downchinaiplogs.log 2>&1
如果你们路径有改记得 对应改下