根據 ip
獲取地理定位,曾嘗試了 laravel
的torann/geoip
包,不是很準確。還有 百度 API
呼叫獲取地理資訊的方法,為了減少維護成本,最終用了thinkphp3.2
中的一個包,是否是內建的不太清楚,原理是包中內建了省市資料庫 UTFWry.dat
。
laravel 專案如何使用
我放在了專案 app
同級目錄 sdk
下。為了能夠使用,composer.json
中需將 IpLocation.class.php
新增到 classmap
自動載入中,以便該檔案能夠被自動載入(如果不太明白為何能自動載入,參考 Laravel Composer 自動載入原理)。
"autoload": {
"classmap": [
"database/seeds",
"database/factories",
"sdk/Org/Net/IpLocation.class.php"
]
},
新增後執行 composer dump-autoload
基本使用
$ip = new \Org\Net\IpLocation('UTFWry.dat');
$location = $ip->getlocation('223.104.1.100');
dd($location);
1. 標準返回值
我們拿 廣東深圳 的 ip 做示例
# 列印結果
array:5 [
"ip" => "223.104.1.100"
"beginip" => "223.104.1.0"
"endip" => "223.104.1.255"
"country" => "廣東省深圳市"
"area" => "移動"]
2. 個別地區返回值有所不同,左側為示範ip,右側為返回地區名稱
# 直轄市
'223.104.3.155',//北京市
'223.104.7.155',//天津市
'223.104.25.155',//重慶市
'223.104.5.200',//上海市徐彙區
# 自治區
'223.104.15.100',//內蒙古呼和浩特市
'223.104.29.100',//寧夏銀川市
'223.104.30.100',//新疆烏魯木齊市
'211.139.74.100',//西藏拉薩市
'218.204.63.100',//廣西百色市
'1.32.192.100',//香港
'60.246.49.100',//澳門
封裝一個返回地區id的方法函式
經常使用的話,一般喜歡放在 app\Helpers.php
中,
<?php
function get_ip_location($ip){
$ip_driver = new \Org\Net\IpLocation('UTFWry.dat');
$location = $ip_driver->getlocation($ip);
$location = $location['country']; //廣東省深圳市
// 如果沒有查詢到的預設返回值
$default = ['p_id'=>1,'c_id'=>0,'locname'=>'北京'];
// 如果有市 那麼市後邊的字元刪除 只保留到市
$city_strpos = mb_strpos($location, '市');
if($city_strpos){
$location = mb_substr($location, 0, $city_strpos + 1);
}
// 如果是直轄市,若匹配到直接返回,不繼續匹配 “區”
$spacial = ['北京','上海','天津','重慶'];//北京市/天津市/重慶市/上海市徐彙區
foreach ($spacial as $bj) {
if( strpos($location, $bj) !== false ){
$province_name = $bj;
$province_id = DB::table('loc_province')->where('name',$province_name)->value('province_id');
$city_id = 0;
return ['p_id'=>$province_id,'c_id'=>0,'locname'=>$bj.'市'];
}
}
// 其他標準查詢
$expect_ids = [36,37,38,39,69]; //排除北京、、以及想要排除的地區
$province_name = $city_name = ''; //初始化
$province_id = $city_id = 0;
// 所有省資料
$all_province = DB::table('loc_province')->whereNotIn('id', $expect_ids)->get();
foreach ($all_province as $prov) {
$name = $prov->name;
$prov_pos = mb_strpos($location, $name);
// 如果匹配到目標
if( $prov_pos !== false ){
$province_id = $prov->province_id;
$province_name = $name;
// 從字串中去除省名稱,並把省字去掉
$location = mb_substr($location, $prov_pos + mb_strlen($name));
$location = str_replace('省','',$location);
// 如果有“市”,那麼就提取出市的名稱
if($location && mb_strpos($location, '市')){
$city_name = rtrim($location, '市');
}
if($city_name){
$city_id = DB::table('loc_city')->where('name',$city_name)->value('cid');
}else{
$city_id = 1; // 預設省會
}
break;
}
}
if($province_name){
return ['p_id'=>$province_id,'c_id'=>$city_id,'locname'=>$province_name.$city_name];
}else{
return $default;
}
}
測試
$testips = [
'223.104.3.155',//北京市
'223.104.7.155',//天津市
'223.104.25.155',//重慶市
'223.104.5.200',//上海市徐彙區
'223.104.15.100',//內蒙古呼和浩特市
'223.104.29.100',//寧夏銀川市
'223.104.30.100',//新疆烏魯木齊市
'211.139.74.100',//西藏拉薩市
'218.204.63.100',//廣西百色市
'1.32.192.100',//香港
'60.246.49.100',//澳門
'223.104.1.100', //廣東省深圳市
];
echo "<pre>";
foreach ($testips as $ip) {
print_r(get_ip_location($ip));
}
檢查結果
Array
(
[p_id] => 1
[c_id] => 0
[locname] => 北京市
)
Array
(
[p_id] => 3
[c_id] => 0
[locname] => 天津市
)
Array
(
[p_id] => 4
[c_id] => 0
[locname] => 重慶市
)
Array
(
[p_id] => 2
[c_id] => 0
[locname] => 上海市
)
Array
(
[p_id] => 7
[c_id] => 1
[locname] => 內蒙古呼和浩特
)
Array
(
[p_id] => 29
[c_id] => 1
[locname] => 寧夏銀川
)
Array
(
[p_id] => 31
[c_id] => 1
[locname] => 新疆烏魯木齊
)
Array
(
[p_id] => 26
[c_id] => 1
[locname] => 西藏拉薩
)
Array
(
[p_id] => 21
[c_id] => 13
[locname] => 廣西百色
)
Array
(
[p_id] => 32
[c_id] => 1
[locname] => 香港
)
Array
(
[p_id] => 33
[c_id] => 1
[locname] => 澳門
)
Array
(
[p_id] => 20
[c_id] => 2
[locname] => 廣東深圳
)
END
本作品採用《CC 協議》,轉載必須註明作者和本文連結