PHP整合多个API数据并以Json返回 实例 By Lyndon

[proper usage syntax]

事情是这样的,信息课的作业是要用App Inventor2做一个天气查询软件,老师要求使用API获取Json数据来做,然而我一开始是懵逼的,毕竟之前从来没有研究过Json。。。

所以当我看到

{“errNum”:0,”errMsg”:”success”,”retData”:{“city”:”\u5317\u4eac”,”pinyin”:”beijing”,”citycode”:”101010100″,”date”:”16-02-21″,”time”:”18:00″,”postCode”:”100000″,”longitude”:116.391,”latitude”:39.904,”altitude”:”33″,”weather”:”\u591a\u4e91″,”temp”:”-3″,”l_tmp”:”-3″,”h_tmp”:”6″,”WD”:”\u65e0\u6301\u7eed\u98ce\u5411″,”WS”:”\u5fae\u98ce(<10km\/h)”,”sunrise”:”06:59″,”sunset”:”17:56″}}

这样子的东西的时候我是无语的

图片1

图片2

当我看到以上两张图片的时候我是崩溃的(手动再见

特别是当他给我看以下这个复杂版的API的时候

微信截图_20160518163632

你在搞笑吗(手动微笑


那么作为一个很懒的人,我自然是不会想用App Inventor一层一层解析json数据的,毕竟拼图式编程效率低到我不能忍受

然后我就开始在API想办法。我希望能自己写一个查询接口,只需要传入经纬度,就能自动利用谷歌地图API查询到城市(县),然后调用百度API市场提供天气查询API查询到天气,最后经过数据整合,只向客户端输出我需要用到的数据。

一个晚上之后,以下

<?php 
if($_POST['key']!="******************"){
exit ("Access Denied");
}

这里是使用一个POST参数”key”对客户端访问是否合法作一个验证。

function urlget($urld){
$ch = curl_init();
$url = "$urld";
$header = array(
'apikey: ******************',
);
// 添加apikey到header
curl_setopt($ch, CURLOPT_HTTPHEADER , $header);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// 执行HTTP请求
curl_setopt($ch , CURLOPT_URL , $url);
$res = curl_exec($ch);
$res=json_decode($res,true);
return $res;
}

这里定义了一个向API查询数据的过程,只需输入目标地址,即可获取内容。其中$header中的apikey是百度APIStore的APIKey,在谷歌地图中无需调用,为了偷懒,我就一并加上了。

if($_POST['key']=="******************"){
$lat=$_GET['lat'];
$lng=$_GET['lng'];
$urld="http://maps.google.cn/maps/api/geocode/json?latlng=$lat,$lng&amp;amp;language=CN";
$cityres=urlget($urld);
//var_dump($cityres);
$i=0;
$addtype=$cityres["results"][0]['address_components'][$i]['types'][0];
while($addtype!='locality'){
$i=$i+1;
$addtype=$cityres["results"][0]['address_components'][$i]['types'][0];
while($i==10){
$addtype="locality";
$fail='y';
}}

这里是利用谷歌地图API查询当前的区县级名称,由于谷歌地图API的特性,区县级所在的索引项并不一定,所以运用循环查询直到查询到”locality”即区县级所在项。

(后面多次验证发现有个别经纬度是查不到区县的,当然啦反正作业都交了我就没有修改了,有兴趣的同学可以自己研究研究~

if($i<10){
$city=$cityres["results"][0]['address_components'][$i]['long_name'];
$scity=substr($city,0,strlen($city)-3);
$i=$i-1;
$dis=$cityres["results"][0]['address_components'][$i]['long_name'];
$sdis=substr($dis,0,strlen($dis)-3);

由于查询出来的结果是包含“区”或“县”字的,用substr函数可以截掉最后一个字。

$urld= 'http://apis.baidu.com/heweather/weather/free?city='.$sdis;
$weares=urlget($urld);
$status=$weares['HeWeather data service 3.0'][0]['status'];//尝试区县级查询
//echo $sdis;
//echo $status;

利用刚才获取到的区县名称进行查询

if($status=='ok'){
$dis_check=true;//区县级可查,则用区县级查。需要核对县级经纬度是否正确。
$dis_lat=$weares['HeWeather data service 3.0'][0]['basic']['lat'];
$dis_lng=$weares['HeWeather data service 3.0'][0]['basic']['lon'];
/*echo $dis_lng;
echo $dis_lat;*/
$urld="http://maps.google.cn/maps/api/geocode/json?latlng=$dis_lat,$dis_lng&amp;language=CN";
$disres=urlget($urld);
if($disres["results"][0]['address_components'][$i]['long_name']!=$dis){
$ccity=$scity;
}else{$ccity=$sdis;}

假如区县名称查询成功,我们需要核对他所查询到的区县是不是我们当前所在位置,因为经过尝试发现,在广州市白云区查询时,利用“白云”可得到结果,然而这个“白云”是贵州省某地地名,所以我们要比对查询到的地区的市级名称是否与当前所在城市相符合。

}else{
$ccity=$scity;//区县级不可查,则用市级查。
}
 
$urld= 'http://apis.baidu.com/heweather/weather/free?city='.$ccity;
$weares=urlget($urld);

这里就是获取到天气信息啦!

date_default_timezone_set('Asia/Shanghai');
$ndate=date('n/j', time());
//$tdate=$weares['HeWeather data service 3.0'][0]['daily_forecast'][1]['date'];
//$ttdate=$weares['HeWeather data service 3.0'][0]['daily_forecast'][2]['date'];
$tttdate=date('n/j',strtotime($weares['HeWeather data service 3.0'][0]['daily_forecast'][3]['date']));
$ncond=$weares['HeWeather data service 3.0'][0]['now']['cond']['txt'];
$ntmp=$weares['HeWeather data service 3.0'][0]['now']['tmp'];
$tcond=$weares['HeWeather data service 3.0'][0]['daily_forecast'][1]['cond']['txt_d'].'转'.$weares['HeWeather data service 3.0'][0]['daily_forecast'][1]['cond']['txt_n'];
if($weares['HeWeather data service 3.0'][0]['daily_forecast'][1]['cond']['txt_d']==$weares['HeWeather data service 3.0'][0]['daily_forecast'][1]['cond']['txt_n']){
$tcond=$weares['HeWeather data service 3.0'][0]['daily_forecast'][1]['cond']['txt_d'];
}
$ttmp=$weares['HeWeather data service 3.0'][0]['daily_forecast'][1]['tmp']['min'].'℃~'.$weares['HeWeather data service 3.0'][0]['daily_forecast'][1]['tmp']['max']."℃";
$ttcond=$weares['HeWeather data service 3.0'][0]['daily_forecast'][2]['cond']['txt_d'].'转'.$weares['HeWeather data service 3.0'][0]['daily_forecast'][2]['cond']['txt_n'];
if($weares['HeWeather data service 3.0'][0]['daily_forecast'][2]['cond']['txt_d']==$weares['HeWeather data service 3.0'][0]['daily_forecast'][2]['cond']['txt_n']){
$ttcond=$weares['HeWeather data service 3.0'][0]['daily_forecast'][2]['cond']['txt_d'];
}
$tttmp=$weares['HeWeather data service 3.0'][0]['daily_forecast'][2]['tmp']['min'].'℃~'.$weares['HeWeather data service 3.0'][0]['daily_forecast'][2]['tmp']['max']."℃";
$tttcond=$weares['HeWeather data service 3.0'][0]['daily_forecast'][3]['cond']['txt_d'].'转'.$weares['HeWeather data service 3.0'][0]['daily_forecast'][3]['cond']['txt_n'];
if($weares['HeWeather data service 3.0'][0]['daily_forecast'][3]['cond']['txt_d']==$weares['HeWeather data service 3.0'][0]['daily_forecast'][3]['cond']['txt_n']){
$tttcond=$weares['HeWeather data service 3.0'][0]['daily_forecast'][3]['cond']['txt_d'];
}
$ttttmp=$weares['HeWeather data service 3.0'][0]['daily_forecast'][3]['tmp']['min'].'℃~'.$weares['HeWeather data service 3.0'][0]['daily_forecast'][3]['tmp']['max']."℃";

利用php我们可以很方便地获取各个索引项的内容而无须像app inventor那样一个一个去数第几个第几个。然后直接用json来输出即可。

$arr=Array(
'ndate' =&gt;$ndate,
'ncond' =&gt;$ncond." ".$ntmp."℃",
'tcond' =&gt;$tcond,
'ttmp' =&gt;$ttmp,
'ttcond' =&gt;$ttcond,
'tttmp' =&gt;$tttmp,
'tttdate' =&gt;$tttdate,
'tttcond' =&gt;$tttcond,
'ttttmp' =&gt;$ttttmp,
'city'=&gt;$city,
'dis' =&gt;$dis,
'status' =&gt;'ok');
echo json_encode($arr);
}elseif($fail=='y'){
$arr=Array(
'status' =&gt;'unknow city');
echo json_encode($arr);
}else{
$arr=Array(
'status' =&gt;'unknow erro');
echo json_encode($arr);
}
}
代码完

以上就是本实例的全部内容,将key和apikey替换成你自己的以后可以直接使用。

最后的错误输出由于时间仓促并没有完善,各位大大可以自行研究一下,也欢迎来跟我交流~

未经允许不得转载:Lyndon's Studio » PHP整合多个API数据并以Json返回 实例 By Lyndon