php 获取天气接口(免费)

58 阅读2分钟

介绍:

这是一个实时获取天气的免费接口。数据缓存3个小时

准备

  1. 获取当前城市:ip-api.com
  2. 获取当前城市id:城市搜索 for API | 和风天气开发服务 (qweather.com)
  3. 根据城市id获取3天天气:实时天气 for API | 和风天气开发服务 (qweather.com)
  4. 注册一下和风天气。建立一个项目即可获取到key。免费的是一天1000次调用。存一个缓存也够用了。

image.png

代码

class Weather extends Api
{
    protected $noNeedLogin = '*';
    protected $noNeedRight = '';
    protected $key = '使用你自己的KEY';
    public function _initialize()
    {
        parent::_initialize();
    }

    /**
     * 获取天气
     *
     * @ApiMethod (GET)
     */
    public function getWeather(){
        $weather_res = Cache::get('weather');
        if($weather_res){
            $this->success('天气获取成功',$weather_res);
        }
        //获取当前ip
        $ip = \think\Request::instance()->header('x-real-ip');
        if (!$ip) {
            $ip = \think\Request::instance()->ip();
        }
        //*****这里写了固定的ip记得更改********
        $ip = '58.32.20.0';
        //根据ip获取天气信息
        $location = $this->getLocationByIp($ip);
        if ($location && $location['status'] == 'success') {
            $regionName = $location['regionName'];
            $res_id = $this->getLocationById($regionName);
            if($res_id['code'] != 200){
                $this->error('天气获取失败');
            }
            $weather = $this->getWeatherByLocation($res_id['location'][0]['id']);
            if($weather['code'] != 200){
                $this->error('天气获取失败');
            }
            //加入文件缓存
            Cache::set('weather',$weather['daily'],10800);
            $this->success('天气获取成功',$weather['daily']);
        } else {
            $this->error('天气获取失败');
        }
    }
    //获取 IP 地址的地理位置信息
    public function getLocationByIp($ip)
    {
        $url = "http://ip-api.com/json/{$ip}";
        $location = file_get_contents($url);
        return json_decode($location, true);
    }
    public function getLocationById($city)
    {
        // 设置目标URL
        $url = "https://geoapi.qweather.com/v2/city/lookup?location={$city}&key={$this->key}";
        $compressedData = file_get_contents($url);
        // 检查是否成功获取数据
        if ($compressedData === false) {
            return ['code'=>400,'location'=>[],'msg'=>'Failed to fetch data'];
        }
        return $this->jsonGzipData($compressedData);
    }
    //根据地理位置信息获取天气信息
    public function getWeatherByLocation($regionName)
    {
        $apiKey = $this->key;
        $url = "https://devapi.qweather.com/v7/weather/3d?location={$regionName}&key={$apiKey}";
        $compressedData = file_get_contents($url);
        if ($compressedData === false) {
            return ['code'=>400,'location'=>[],'msg'=>'Failed to fetch data'];
        }
        return $this->jsonGzipData($compressedData);
    }
    /**
     * 处理JSON格式并Gzip压缩的数据
     */
    public function jsonGzipData($data)
    {
        // 解压Gzip数据
        $uncompressedData = gzdecode($data);
        if ($uncompressedData === false) {
            return ['code'=>400,'location'=>[],'msg'=>'Failed to decompress the Gzip data'];
        }
        // 解析JSON数据
        $jsonData = json_decode($uncompressedData, true);
        if (json_last_error() !== JSON_ERROR_NONE) {
            return ['code'=>400,'location'=>[],'msg'=>'Failed to decode JSON: '.json_last_error_msg()];
        }
        return $jsonData;
    }
}

总结

和风天气的文档参数解释并不齐全。请参考下方的表格

参数含义
fxDate预报日期
sunrise日出时间
sunset日落时间
moonrise月亮升起时间
moonset月亮落下时间
moonPhase月相,如“峨眉月”
moonPhaseIcon月相图标代码
tempMax最高气温
tempMin最低气温
iconDay白天天气图标代码
textDay白天天气状况,如“多云”
iconNight夜间天气图标代码
textNight夜间天气状况,如“阴”
wind360Day白天风向360度表示
windDirDay白天风向文字描述,如“北风”
windScaleDay白天风力等级,如“1-3”
windSpeedDay白天平均风速
wind360Night夜间风向360度表示
windDirNight夜间风向文字描述
windScaleNight夜间风力等级
windSpeedNight夜间平均风速
humidity相对湿度,百分比表示
precip降水量,单位通常为毫米(mm)
pressure气压,单位通常为百帕(hPa)
vis能见度,单位通常为千米(km)
cloud云量,百分比表示云遮蔽的程度
uvIndex紫外线指数,反映紫外线强度,数值越大表示紫外线越强,需要加强防护