本文目录导读:

- 使用IPIP.net或纯真IP数据库(推荐)
- 使用IP地理位置API(在线查询)
- Nginx反向代理拦截(性能最优)
- 混合方案(缓存+数据库)
- 使用CDN/WAF服务(推荐企业使用)
- 注意事项
- 完整示例(推荐方案)
针对PHP项目拦截境外IP访问,有以下几种常用方案,按推荐程度排序:
使用IPIP.net或纯真IP数据库(推荐)
方案A:IPIP.net免费版
<?php
// 下载IPIP.net的datx文件(免费版)
// https://www.ipip.net/product/client.html
require_once 'IP.class.php';
function isChinaIP($ip) {
$ipdb = new IP('ipipfree.ipdb');
$result = $ipdb->find($ip, 'CN');
return $result[0] === '中国';
}
$userIP = $_SERVER['REMOTE_ADDR'];
if (!isChinaIP($userIP)) {
header('HTTP/1.1 403 Forbidden');
die('Access Denied');
}
?>
方案B:纯真IP数据库
<?php
// 使用纯真IP数据库(推荐QQWry.dat)
require_once 'ip_library.php';
function isChinaIP($ip) {
$location = ip2location($ip);
return strpos($location, '中国') !== false ||
strpos($location, 'China') !== false;
}
?>
使用IP地理位置API(在线查询)
<?php
function isForeignIP($ip) {
// 使用ip-api.com免费API
$url = "http://ip-api.com/json/{$ip}";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
return $data['countryCode'] !== 'CN';
}
$userIP = $_SERVER['REMOTE_ADDR'];
if (isForeignIP($userIP)) {
header('HTTP/1.1 403 Forbidden');
exit('Access Denied');
}
?>
Nginx反向代理拦截(性能最优)
# 在nginx配置中
geo $country {
default 1;
include /etc/nginx/geo/china_ip.txt; # 中国IP列表
}
server {
location / {
if ($country = 1) {
return 403;
}
# 正常处理...
}
}
混合方案(缓存+数据库)
<?php
class IPBlocker {
private $cacheFile = '/tmp/ip_cache.json';
private $cacheTime = 3600; // 1小时缓存
public function checkIP($ip) {
// 先检查缓存
$cached = $this->getCache($ip);
if ($cached !== null) {
return $cached;
}
// 查询IP归属地
$isChina = $this->isChinaIP($ip);
// 写入缓存
$this->setCache($ip, $isChina);
return $isChina;
}
private function isChinaIP($ip) {
// 使用IPIP.net或纯真数据库查询
// ...
}
}
?>
使用CDN/WAF服务(推荐企业使用)
- Cloudflare:规则拦截非中国IP
- 阿里云WAF:地域封禁
- 腾讯云CDN:IP黑白名单
注意事项
- 性能考虑:避免每次请求都查询API,建议使用本地数据库+缓存
- 误伤问题:海外华人、VPN用户可能被误伤
- 动态IP:部分境外IP可能走境内代理
- IPv6:需要同时处理IPv6地址
完整示例(推荐方案)
<?php
// 使用composer安装 ipip/ipip-php
// composer require ipip/ipip-php
require 'vendor/autoload.php';
use ipip\db\City;
function blockForeignIP() {
try {
$ip = $_SERVER['REMOTE_ADDR'];
$db = new City('/path/to/ipipfree.ipdb');
$result = $db->find($ip, 'CN');
// 如果返回的国家不是中国
if ($result[0] !== '中国') {
header('HTTP/1.1 403 Forbidden');
echo json_encode([
'code' => 403,
'message' => 'Access Denied: Foreign IP'
]);
exit;
}
} catch (Exception $e) {
// 数据库加载失败时的处理
error_log('IP Database error: ' . $e->getMessage());
}
}
// 在项目入口处调用
blockForeignIP();
?>
最佳实践建议:使用IPIP.net离线数据库 + 本地缓存机制,既能保证性能又能确保准确性,对于高流量站点,建议在Nginx/CDN层做拦截。