首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP + AJAX 即時天氣預報模組實作 (串接中國天氣網 API)

     編輯:PHP 相關知識

打造無刷新體驗的天氣查詢功能:前端下拉選單選城市 → AJAX POST 城市代碼 → PHP 串接中國天氣網 API → 回傳 JSON → 前端動態渲染。完整前後端代碼可直接部署。

API 來源說明

中國天氣網公開 API (無需 Key):

  • 即時天氣:https://www.weather.com.cn/data/sk/{city_id}.html
  • 城市列表:https://www.weather.com.cn/data/city3jdata/china.html (可抓取所有城市代碼)
  • 城市代碼範例:北京 101010100、上海 101020100、廣州 101280101

前端頁面 (index.php)

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>即時天氣查詢</title>
    <style>
        body { font-family: sans-serif; padding: 20px; }
        #weatherInfo { margin-top: 15px; padding: 10px; background: #f0f8ff; border-radius: 4px; min-height: 80px; }
        .loading { color: #666; font-style: italic; }
        .error { color: #c00; }
    </style>
</head>
<body>
    <h2>城市天氣即時查詢</h2>
    <select id="citySelect">
        <option value="">-- 請選擇城市 --</option>
        <option value="101010100">北京</option>
        <option value="101020100">上海</option>
        <option value="101030100">天津</option>
        <option value="101040100">重慶</option>
        <option value="101280101">廣州</option>
        <option value="101210101">杭州</option>
        <option value="101200101">武漢</option>
    </select>
    <div id="weatherInfo">選擇城市後將顯示即時天氣...</div>

    <script>
        const select = document.getElementById('citySelect');
        const infoDiv = document.getElementById('weatherInfo');

        select.addEventListener('change', function() {
            const cityId = this.value;
            if (!cityId) {
                infoDiv.innerHTML = '請選擇城市';
                return;
            }
            infoDiv.innerHTML = '<span class="loading">載入中...</span>';

            // 使用 Fetch API (現代瀏覽器原生支援)
            fetch('weather.php', {
                method: 'POST',
                headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                body: 'cityid=' + encodeURIComponent(cityId)
            })
            .then(response => response.text()) // PHP 直接輸出 HTML 片段
            .then(html => { infoDiv.innerHTML = html; })
            .catch(err => { infoDiv.innerHTML = '<span class="error">請求失敗: ' + err + '</span>'; });
        });
    </script>
</body>
</html>

後端處理 (weather.php)

<?php
header('Content-Type: text/html; charset=utf-8');
header('Cache-Control: no-cache, must-revalidate');

$cityId = isset($_POST['cityid']) ? trim($_POST['cityid']) : '101010100'; // 預設北京

// 驗證城市代碼格式 (9位數字)
if (!preg_match('/^\d{9}$/', $cityId)) {
    echo '<span class="error">無效城市代碼</span>';
    exit;
}

$apiUrl = "https://www.weather.com.cn/data/sk/{$cityId}.html";

// 使用 cURL 更穩健 (支援超時、錯誤處理)
$ch = curl_init($apiUrl);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 5, // 5秒超時
    CURLOPT_CONNECTTIMEOUT => 3,
    CURLOPT_USERAGENT => 'Mozilla/5.0 (WeatherBot)',
]);
$json = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($httpCode !== 200 || !$json) {
    echo '<span class="error">氣象服務暫時不可用</span>';
    exit;
}

$data = json_decode($json, true);
if (!isset($data['weatherinfo'])) {
    echo '<span class="error">資料格式異常</span>';
    exit;
}

$w = $data['weatherinfo'];
// 組裝顯示 HTML
echo '<strong>城市:</strong>' . htmlspecialchars($w['city']) . '<br>';
echo '<strong>溫度:</strong>' . htmlspecialchars($w['temp']) . '°C<br>';
echo '<strong>風向:</strong>' . htmlspecialchars($w['WD']) . '<br>';
echo '<strong>風力:</strong>' . htmlspecialchars($w['WS']) . '<br>';
echo '<strong>濕度:</strong>' . htmlspecialchars($w['SD']) . '<br>';
echo '<strong>更新時間:</strong>' . htmlspecialchars($w['time']) . '<br>';
?>

進階:動態載入城市列表 (避免硬編碼)

<?php
// get_cities.php
header('Content-Type: application/json; charset=utf-8');
$url = 'https://www.weather.com.cn/data/city3jdata/china.html';
$json = @file_get_contents($url);
if ($json) {
    // 原始資料結構較複雜,這裡簡化輸出前端所需格式
    // 實際專案建議抓取後快取到本地資料庫/Redis,避免頻繁請求外部 API
    echo $json; 
} else {
    echo '[]';
}
?>

前端用 fetch('get_cities.php') 取得城市陣列,動態填充 <select>。

錯誤處理與優化重點

問題解決方案
外部 API 回應慢/失敗PHP 端設定 cURL 超時;前端顯示載入狀態;快取 API 結果 (Redis/File cache 10-30 分鐘)
跨域請求被瀏覽器攔截前端請求自家 PHP (weather.php),由 PHP 代理外部 API,天然解決跨域
編碼亂碼API 回傳 UTF-8,PHP header('Content-Type: ... charset=utf-8'),前端頁面 <meta charset="utf-8">
城市代碼變更定期同步官方城市列表,或使用高德/百度地圖 API 獲取更準確的城市編碼

擴展:顯示 3-7 天預報

使用另一個 API:https://www.weather.com.cn/data/zs/{city_id}.html (生活指數) 或 https://m.weather.com.cn/data/{city_id}.html (多日預報),解析 JSON 並前端用圖表/卡片展示。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved