options->sidebarBlock) && in_array('ShowSidebarWeather', $this->options->sidebarBlock) && ! $this->is('post')): ?> ['timeout' => 6, 'method' => 'GET']]); $geoJson = @file_get_contents($geoUrl, false, $ctx); } if ($geoJson) { $geoData = json_decode($geoJson, true); if (isset($geoData['location'][0]['id'])) { $location = $geoData['location'][0]['id']; } } } $url = 'https://' . $host . '/v7/weather/now?location=' . urlencode($location) . '&key=' . $apiKey . '&lang=zh'; // 优先使用 cURL,以支持连接/读取超时 $json = false; if (function_exists('curl_init')) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_ENCODING, ''); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3); // 连接超时 3s curl_setopt($ch, CURLOPT_TIMEOUT, 6); // 总超时 6s curl_setopt($ch, CURLOPT_USERAGENT, 'HarmonyHues-Weather/1.0'); $json = curl_exec($ch); $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($json === false || intval($http_code) !== 200) { $json = false; } } else { // 回退到 file_get_contents,但设置默认的 socket 超时 $ctx = stream_context_create([ 'http' => [ 'timeout' => 6, 'method' => 'GET', 'header' => "User-Agent: HarmonyHues-Weather/1.0\r\n" ] ]); $json = @file_get_contents($url, false, $ctx); } if ($json) { $data = json_decode($json, true); // 和风返回示例:{"code":"200","updateTime":"...","now":{...}} if (isset($data['code']) && ($data['code'] === '200' || $data['code'] === 200)) { $payload = json_encode([ 'city' => $city, 'timestamp' => time(), 'data' => $data, ]); @file_put_contents($cacheFile, $payload); return $data; } } return null; } $weather = hh_fetch_weather($city, $apiKey, $cacheFile, $apiHost); // 用于调试:记录请求 URL(和风天气) $reqUrl = 'https://' . $apiHost . '/v7/weather/now?location=' . urlencode($city) . '&key=' . $apiKey . '&lang=zh'; ?> false, 'city' => null, 'description' => null, 'temp' => null, 'feels_like' => null, 'humidity' => null, 'pressure' => null, 'wind_speed' => null, 'wind_deg' => null, 'wind_dir' => null, 'wind_scale' => null, 'icon_code' => null, 'precip' => null, 'vis' => null, 'cloud' => null, 'dew' => null, 'obsTime' => null, 'refer' => null, 'raw' => $raw, ]; if (!is_array($raw)) return $out; // QWeather 格式 if (isset($raw['now'])) { $now = $raw['now']; $out['ok'] = (isset($raw['code']) && ($raw['code'] === '200' || $raw['code'] === 200)); // 某些 Host 返回 location 字段,某些返回 location 数组 if (isset($raw['location']) && is_array($raw['location'])) { $out['city'] = $raw['location'][0]['name'] ?? $raw['location'][0]['adm2'] ?? null; } else { $out['city'] = $raw['location'] ?? null; } $out['description'] = $now['text'] ?? null; $out['temp'] = $now['temp'] ?? null; $out['feels_like'] = $now['feelsLike'] ?? null; $out['humidity'] = $now['humidity'] ?? null; $out['pressure'] = $now['pressure'] ?? null; $out['wind_speed'] = $now['windSpeed'] ?? null; $out['wind_dir'] = $now['windDir'] ?? ($now['wind360'] ?? null); $out['wind_scale'] = $now['windScale'] ?? null; $out['wind_deg'] = $now['wind360'] ?? null; $out['icon_code'] = $now['icon'] ?? null; $out['precip'] = $now['precip'] ?? null; $out['vis'] = $now['vis'] ?? null; $out['cloud'] = $now['cloud'] ?? null; $out['dew'] = $now['dew'] ?? null; $out['obsTime'] = $now['obsTime'] ?? null; $out['refer'] = $raw['refer'] ?? null; return $out; } // OpenWeatherMap 格式 if (isset($raw['weather'][0]) && isset($raw['main'])) { $w = $raw['weather'][0]; $m = $raw['main']; $out['ok'] = true; $out['city'] = $raw['name'] ?? null; $out['description'] = $w['description'] ?? null; $out['temp'] = $m['temp'] ?? null; $out['feels_like'] = $m['feels_like'] ?? ($m['feels_like'] ?? null); $out['humidity'] = $m['humidity'] ?? null; $out['pressure'] = $m['pressure'] ?? null; $out['wind_speed'] = $raw['wind']['speed'] ?? null; $out['wind_deg'] = $raw['wind']['deg'] ?? null; $out['icon'] = $w['icon'] ?? null; return $out; } return $out; } $norm = hh_normalize_weather($weather); // 格式化更新时间为“YYYY-MM-DD HH:MM”便于阅读 $displayObsTime = '-'; if (!empty($norm['obsTime'])) { try { $dt = new DateTime($norm['obsTime']); $displayObsTime = $dt->format('Y-m-d H:i'); } catch (Exception $e) { $displayObsTime = $norm['obsTime']; } } ?>