我們都知道,在很多的網站都提供了給用戶提供天氣預報的功能,有時會發現,用戶即使不輸入任何和自己有關的地理位置信息,同樣的網站也可以去判斷地理位置並且顯示天氣信息,我們可能會想到用ip去判斷地理位置,的確是這樣,但是,如果想自己一樣完全的開發,確實有一點麻煩,所以這裡簡單的說一下這個應用的業務邏輯(以用戶第一次打開頁面為起點):
1:獲取ip:ip按照我自己的說法有兩種,一種是獨立ip,真實存在,另一種是路由器分配的ip,這個當然不具有某種意義上的唯一性,這兩種ip當然都要考慮,第一種非常容易或得,取$_SERVER內的元素值就可以,但問題是第二種,像192.168.1.1這樣的是無法判斷的,那麼就沒法處理或得用戶的位置信息,這裡本來采用curl的擴展來抓取的,但是這個擴展說什麼就是無法使用,所以這種情況先放在一邊,僅考慮用戶使用獨立ip訪問的情況。
這裡補充一下,server的參數不是server_addr而是REMOTE_ADDR,只有這樣才能取到用戶的真是地址,這樣的話就不用麻煩的取另外處理
2:當我們獲取ip之後就應該根據ip地址庫去查找用戶的ip所在地,這裡有兩個地方需要注意,1:ip地址庫必須為utf-8編碼,2:或得的信息是一個完整的地址信息,而後面需要城市名稱局可以,所以,要做一下字符串的截取,或得簡化城市地址。
3:當或得了用戶的地址顯然還是不行,想想,最終於天氣接口對接獲取數據的是城市代碼,這兩個還是要轉化一下,這裡我采用了暴力的辦法遍歷城市代碼庫或得該城市的代碼。
4:獲取到城市的代碼之後,就要去連接數據接口獲取數據,這個數據時json數據,需要json_encode()轉碼,我這裡或得的是一個對象,有的接口不一樣,具體情況具體分析,然後,最重要的就是分配這些數據,說是這些,其實就是這個對象,後來發現沒有逐個分配是正確的,這樣有利於代碼的移植。
5:在視圖去調用模板分配的數據,相信這個都會。
6:其實上面的步驟已經把第一次打開頁面的整個業務邏輯給處理完了,還有一個就是我在視圖給用戶提供了輸入城市名查詢城市天氣的功能,這樣按順序的分析一下,正常的獲取用戶的輸入信息就是城市名
7:這裡就已經或得了城市名,直接參與獲取城市代碼的遍歷就可以了,這裡有個非常重要的邏輯問題就是先後順序和如何判斷才能夠把這兩個功能很好的結合在一塊,一定是:
先判斷是否系統自動獲取城市名稱是否為空,如果不為空只城市名就是或得的名字,反之,就提示ip地址沒有查詢到對應地址信息,緊接著,注意一定是緊接著下面,是順序結構,判斷用戶的輸入是否為空,如果不為空,那麼就讓城市名為用戶輸入,總而言之就是用戶的輸入權限一定要大於系統自動獲取的權限,這樣就可以完整的把兩個代碼結合在一起,另外,我是把獲取ip和取出城市名分別做成了兩個方法。
上面寫的比較亂,這樣的話,下面是我的部分實例代碼,因安全版權各方面原因,數據接口我做了處理不可以使用,僅提供方法參考,粘貼無用,自主研究。
視圖weather_test.html:
public function weather_test(){ require_once './Component/Citycode.php'; //////這裡是根據客戶端的ip判斷地理位置 //定義兩個標志變量 $count=0; $city_id='101120301';//默認大淄博 $city_name_cin=$_POST['cityname']; $city_sim_name=R('Test/get_user_cityname'); //這是系統根據ip自動判斷的位置 echo $city_sim_name; if($city_sim_name!=null){ $city_name_cin=$city_sim_name; } //這是用戶輸入的位置 if(!empty($_POST['cityname'])){ //放置信息覆蓋 $city_name_cin=$_POST['cityname']; } ////////不管是ip定位還是用戶輸入最終需要遍歷獲取城市代碼的變量只要$city_name_cin foreach ($citycode as $key => $value){ if($key==$city_name_cin){ $city_id=$citycode[$city_name_cin]; $count++; } } if($count==0){ echo 對不起,您輸入的地址沒有找到!默認淄博哦; }else{ echo $city_name_cin.的天氣信息如下; } //接口已經處理,請勿使用,僅供學習 $weather_interface_url=http://weatherai.markt.xiaomi.com/wtr-v2/weather?cityId=.$city_id.&mei=e32c88633283737f5d9f381d47&device=HM2013023&miuiVersion=JHBCNBD16.0&modDevice=ce=miuiWeatherAp; $all_weather_info = json_decode(file_get_contents($weather_interface_url)); //分配數據 $this->assign(all_info,$all_weather_info); $this->display(); } /////////////////////////////////////////////////// /* * 下面兩個分別是獲取主機ip和ip所在地的兩個 * 方法,最後的結果數值通過R方法,返回獲取 */ //方法1:獲取用戶ip public function get_user_ip(){ //先通過這種簡單的方法獲取主機的ip,通過R方法獲取 $host_ip=$_SERVER['SERVER_ADDR'];
return $host_ip; } //方法2:獲取地名 public function get_user_cityname(){ //得到用戶的ip $host_ip=R('Test/get_user_ip'); //這裡ip地址庫必須這樣實例化 $Ip = new OrgNetIpLocation('UTFWry.dat'); // 實例化類 參數表示IP地址庫文件 //可以同時放ip和域名 $area = $Ip->getlocation($host_ip); // 獲取域名服務器所在的位置 $city_allname=$area['country']; $sim_cityname=explode(市,explode(省, $city_allname)[1])[0]; return $sim_cityname; }