原生PHP与Ajax实现三级联动下拉菜单

Ivy
Ivy
发布时间:2026-10-13 | 5人浏览过
原创

本文提供了一套基于原生技术栈(PHP + MySQL + JavaScript)的三级联动下拉菜单解决方案。通过解析HTML表单结构、后端数据查询接口以及前端的Ajax异步通信逻辑,帮助开发者理解并复现经典的无刷新数据联动效果。

实现目标

构建一个包含“一级分类”、“二级分类”和“三级分类”的下拉选择器组。当用户选择上一级菜单时,下一级菜单会自动通过Ajax获取对应的选项数据并更新显示,整个过程不刷新页面。

数据库准备

本示例使用 fitment 数据库中的 fitment_sort 表。该表至少应包含以下字段:
- id: 分类唯一标识
- name: 分类名称
- supid: 父级分类ID(顶级分类通常为0)

后端数据处理 (get2.php)

后端文件负责根据传入的父级ID,从数据库中查询对应的子级分类数据,并以特定格式返回字符串。原始代码采用较旧的 mysql_ 系列函数,此处保留其逻辑以供参考学习。

<?php
header('Content-Type:text/html;charset=GB2312');
$conn = mysql_connect('localhost', 'root', '') or die('Could not connect: ' . mysql_error());
mysql_select_db('fitment', $conn) or die ('Can\'t use database : ' . mysql_error());
mysql_query("set names 'gb2312'");

// 处理一级 -> 二级 的请求
if(isset($_GET["q"])){
    $strs = "SELECT * FROM fitment_sort WHERE supid='".$_GET["q"]."' ";
    $results = mysql_query($strs) or die("Invalid query: " . mysql_error());
    $strings = "";
    if($results){
        while ($arrs = mysql_fetch_array($results)){
            $strings .= $arrs["id"]."|".$arrs["name"].",";
        }
        // 去掉末尾逗号后输出
        echo substr($strings,0,strlen($strings)-1);
    }
}

// 处理二级 -> 三级的请求
if(isset($_GET["q2"])){
    $str = "SELECT * FROM fitment_sort WHERE supid= '".$_GET["q2"]."'";
    $result = mysql_query($str) or die("Invalid query: " . mysql_error());
    $string = "";
    if($result){
        while ($arr = mysql_fetch_array($result)){
            $string .= $arr["id"]."|".$arr["name"].",";
        }
        echo substr($string,0,strlen($string)-1);
    }
}
mysql_close($conn);
?>

前端逻辑与交互 (index.php & aa.js)

前端部分由主页面和外部JS文件组成。主页面负责展示表单控件,JS文件负责发起异步请求和处理响应。

第1步:初始化页面表单元素

在HTML中定义三个

<form>
<select name="sel" id="sel" onChange="showMenu(this.value);">
 <option>一级分类</option>
 <?php
 // 此处在原文中混入了直接填充一级选项的逻辑,实际应用中通常建议纯HTML初始或仅留默认项
 $conn = mysql_connect('localhost', 'root', '') or die('Could not connect: ' . mysql_error());
 mysql_select_db('fitment', $conn) or die ('Can\'t use database : ' . mysql_error());
 mysql_query("set names 'gb2312'");
 $str = "SELECT * FROM `fitment_sort` where supid = '0' ORDER BY `id` ASC";
 $result = mysql_query($str) or die("Invalid query: " . mysql_error());
 if($result)   while ($arr = mysql_fetch_array($result)){
     echo <<<EOD
 <option value={$arr["id"]}>{$arr["name"]}</option>
 EOD; }
 mysql_close($conn);
 ?>
</select>
<label>
<select name="sel2" id="sel2" onChange="showMenu2(this.value)">
 <option>二级分类</option>
 </select>
</label>
<label>
<select name="sel3" id="sel3">
 <option>三级分类</option>
</select>
</label>
</form>

第2步:构建Ajax对象

由于不同浏览器对异步请求对象的支持存在差异,需要封装一个兼容函数。虽然现代开发多用fetch或axios,但此原生写法有助于理解底层原理。

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

第3步:发送异步请求 (一级变二级)

当用户改变一级菜单选择时,触发 showMenu 函数。该函数将选中值传递给 get2.php?q=值,并将响应结果交给 BuildSel 处理。

function showMenu(str){
 var xmlHttp=GetXmlHttpObject();
 if (xmlHttp==null){
 return;
 }
 var url="get2.php?q="+str+"&sid="+Math.random();
 xmlHttp.onreadystatechange=stateChanged;
 xmlHttp.open("GET",url,true);
 xmlHttp.send(null);
}

第4步:处理响应并更新DOM

stateChanged 函数监测请求状态。当请求成功完成后,调用 BuildSel 清空并重新填充第二个下拉框,同时自动触发二级变化事件以加载三级数据。

function BuildSel(str,sel){
 sel.options.length=0;
 var arrstr = new Array();
 arrstr = str.split(",");
 if(str.length>0){
 for(var i=0;i<arrstr.length;i++) {
  var subarrstr=new Array();
  subarrstr=arrstr[i].split("|");
  sel.options.add(new Option(subarrstr[1],subarrstr[0]));
 }
 sel.options[0].selected=true;
 }
}

function stateChanged(){
 if (xmlHttp.readyState==4 || xmlHttp.readyState=="complete"){
 if(xmlHttp.status==200 || xmlHttp.status==0){
 BuildSel(xmlHttp.responseText,document.getElementById("sel2"));
 showMenu2(document.getElementById("sel2").value);
 }
 }
}

注意事项与排错

  • 废弃API警告:原文使用的 mysql_connect 等函数已在 PHP 7.0+ 中移除。若在实际生产环境运行,必须替换为 mysqli 或 PDO 扩展。
  • 跨域问题:确保 aa.js 请求的 get2.php 与当前网页位于同一域名下,否则将被浏览器安全策略拦截。
  • 字符集一致:数据库连接、查询及页面输出均需保持编码一致(如 GB2312 或 UTF8),防止中文乱码。

以上就是使用原生PHP和JavaScript实现三级级联下拉菜单的详细内容,更多关于PHP Ajax数据交互的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表