OpenWeatherMap API报错时无法返回关联数组的问题如何解决?
问题原因
你遇到的报错核心是file_get_contents()的默认运行机制导致的:该函数在请求的接口返回4xx、5xx类错误状态码时,会直接抛出E_WARNING级别的错误(就是你看到的failed to open stream提示),并且不会读取接口返回的响应体内容,因此你拿到的$weather_api为空,自然无法通过json_decode得到接口返回的错误信息关联数组。
修复方案
方案1:修改流上下文配置,适配file_get_contents请求
新增流上下文配置,开启ignore_errors参数,让函数就算遇到HTTP错误也会读取响应体内容:
// 配置流上下文,忽略HTTP错误 $context = stream_context_create([ 'http' => [ 'ignore_errors' => true ] ]); // 对城市名做URL编码,避免特殊字符导致请求异常 $city = urlencode($city); // 请求时传入上下文配置 $weather_api = file_get_contents("https://api.openweathermap.org/data/2.5/weather?q={$city}&appid={$api_key}", false, $context); $weather_data = json_decode($weather_api, true); // 按返回的状态码判断请求结果 if (isset($weather_data['cod']) && $weather_data['cod'] >= 400) { // 此处可拿到接口返回的错误信息,自行做校验逻辑 echo "请求错误:" . $weather_data['message']; } else { // 正常业务逻辑 echo "<pre>"; print_r($weather_data); echo "</pre>"; }
方案2:使用cURL扩展发起请求(更推荐)
cURL的可控性更高,不会默认抛出警告,还能直接获取HTTP响应码做判断:
$city = urlencode($city); $ch = curl_init("https://api.openweathermap.org/data/2.5/weather?q={$city}&appid={$api_key}"); // 设置将响应结果作为字符串返回,而不是直接输出 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 执行请求 $weather_api = curl_exec($ch); // 获取HTTP响应状态码 $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); $weather_data = json_decode($weather_api, true); if ($httpCode >= 400) { echo "请求错误,状态码:" . $httpCode . ",错误信息:" . $weather_data['message']; } else { echo "<pre>"; print_r($weather_data); echo "</pre>"; }
额外注意
如果不希望页面显示file_get_contents的警告信息,除了上述修改方式外,也可以在生产环境调整php.ini的error_reporting配置关闭警告输出,不要长期用@错误抑制符处理,会掩盖其他潜在问题。
内容的提问来源于stack exchange,提问作者Shakti Goyal
相关产品推荐
相关产品推荐

