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

Ajax PHP 二級聯動選單:城市選擇即時載入實作教學

     編輯:PHP 相關知識

前言

二級聯動選單是表單設計常見需求:選擇「省份」後,自動載入對應的「城市」選項。本文示範使用原生 JavaScript (XMLHttpRequest) 搭配 PHP 後端,實現無刷新動態載入城市資料。

前端頁面結構與邏輯

包含兩個 <select> 元素:省份下拉選單綁定 onchange="sendrequest()",城市選單初始為空 <div id="city">,等待 AJAX 回填 <option> 選項。

<select id="province" onchange="sendrequest()">
    <option value="">請選擇省份</option>
    <option value="gd">廣東</option>
    <option value="bj">北京</option>
    <!-- 更多省份 -->
</select>

<div id="city"></div>  <!-- 這裡將被注入 <select> 城市選單 -->

JavaScript 核心流程

  1. getxmlhttprequest():跨瀏覽器建立 XMLHttpRequest 物件 (現代瀏覽器 / IE ActiveX)
  2. sendrequest():取得選中的省份值,構建 URL (city.php?prov=gd),發送 GET 請求
  3. updatepage():回調函式,檢查 readyState===4 && status===200,將 responseText 寫入 city 容器
<script>
var xmlhttp = null;

function getxmlhttprequest() {
    var xmlhttp = null;
    try { xmlhttp = new XMLHttpRequest(); }
    catch(e) {
        try { xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); }
        catch(e) { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); }
    }
    return xmlhttp;
}

function sendrequest() {
    var prov = document.getElementById("province").value;
    if (!prov) return;

    xmlhttp = getxmlhttprequest();
    if (!xmlhttp) { alert("瀏覽器不支援 XMLHttpRequest"); return; }

    var url = "city.php?prov=" + encodeURIComponent(prov);
    xmlhttp.open("GET", url, true);
    xmlhttp.onreadystatechange = updatepage;
    xmlhttp.send(null);
}

function updatepage() {
    if (xmlhttp.readyState === 4 && xmlhttp.status === 200) {
        document.getElementById("city").innerHTML = xmlhttp.responseText;
    }
}
</script>

後端 PHP 處理邏輯 (city.php)

定義省份-城市對應陣列,接收 $_GET['prov'],輸出城市 <select> 選項。注意編碼轉換:頁面為 GB2312,PHP 輸出需 iconv('gb2312','utf-8',...) 或統一改用 UTF-8。

<?php
$city_arr = array(
    "gd" => "廣州,深圳,珠海,佛山",
    "bj" => "北京",
    "sh" => "上海",
    // 更多省份...
);

if (empty($_GET['prov'])) {
    echo '<font color="red">請先選擇省份</font>';
} else {
    $prov = $_GET['prov'];
    $cities = explode(',', $city_arr[$prov] ?? '');
    
    echo '<select name="city">';
    echo '<option value="">請選擇城市</option>';
    foreach ($cities as $city) {
        echo "<option value=\"$city\">$city</option>";
    }
    echo '</select>';
}
?>

資料庫驅動版本擴展

實務專案中城市資料通常存於資料表:

CREATE TABLE `areas` (
    `id` INT AUTO_INCREMENT PRIMARY KEY,
    `name` VARCHAR(50) NOT NULL,
    `parent_id` INT DEFAULT 0,
    `level` TINYINT DEFAULT 1  -- 1=省, 2=市, 3=區
);

-- 查詢城市
$stmt = $pdo->prepare("SELECT name FROM areas WHERE parent_id = (SELECT id FROM areas WHERE name = ? AND level = 1) AND level = 2");
$stmt->execute([$_GET['prov']]);
$cities = $stmt->fetchAll(PDO::FETCH_COLUMN);

現代化重構建議

  • Fetch API:取代 XMLHttpRequest,支援 Promise 鏈式寫法
  • JSON 介面:後端回傳 json_encode($cities),前端動態建立 <option>,分離資料與表現
  • 防抖處理:若支援輸入框搜尋,加入 setTimeout 避免頻繁請求
  • 快取機制:前端 Map 快取已載入省份的城市資料,避免重複請求
  • 無障礙:<select> 保留原生鍵盤操作,ARIA 標籤完善
// 現代化 Fetch + JSON 版本
async function loadCities(provinceCode) {
    const res = await fetch(`api/cities.php?prov=${encodeURIComponent(provinceCode)}`);
    const cities = await res.json();
    
    const select = document.getElementById('city-select');
    select.innerHTML = '<option value="">請選擇城市</option>';
    cities.forEach(city => {
        const opt = document.createElement('option');
        opt.value = city;
        opt.textContent = city;
        select.appendChild(opt);
    });
}

總結

Ajax 二級聯動選單展示了前後端非同步協作的經典模式。從原生 XMLHttpRequest 進化到 fetch/async-await、從字串拼接 HTML 到 JSON 資料驅動、從硬編碼陣列到資料庫動態查詢,每一步都提升了可維護性與使用者體驗。

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