求助:通过PHP获取JSON数据实现三级联动下拉选择框
我来帮你实现这个三级联动选择框需求,分PHP中间层和前端JS两部分来写,完全符合你的要求:
三级联动选择框(State → City → Company)实现方案
1. PHP中间层脚本(get-companies-data.php)
这个脚本作为中间代理,负责从API获取原始JSON数据并根据前端请求返回对应内容,以此隐藏真实的API URL。代码如下:
<?php // 替换为真实的API地址(仅服务器可见,前端无法获取) $api_url = 'https://your-real-api-url-here.com/data'; // 获取前端传递的动作参数 $action = $_GET['action'] ?? ''; // CURL请求API获取原始数据 $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $api_url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); curl_close($ch); // 处理API请求失败的情况 if (!$response) { echo json_encode(['error' => 'Failed to fetch data from API']); exit; } $data = json_decode($response, true); $companies = $data['companies'] ?? []; switch ($action) { case 'get-states': // 提取并去重所有州 $states = array_unique(array_column($companies, 'state')); sort($states); // 可选:对州名排序 echo json_encode($states); break; case 'get-cities': $selected_state = $_GET['state'] ?? ''; if (!$selected_state) { echo json_encode([]); exit; } // 提取对应州的不重复城市 $cities = []; foreach ($companies as $comp) { if ($comp['state'] === $selected_state && !in_array($comp['city'], $cities)) { $cities[] = $comp['city']; } } sort($cities); echo json_encode($cities); break; case 'get-companies': $selected_city = $_GET['city'] ?? ''; if (!$selected_city) { echo json_encode([]); exit; } // 提取对应城市的公司列表 $company_list = []; foreach ($companies as $comp) { if ($comp['city'] === $selected_city) { $company_list[] = $comp['company']; } } sort($company_list); echo json_encode($company_list); break; default: // 默认返回全部原始数据(用于调试) echo json_encode($companies); break; } ?>
2. 前端HTML与JS实现
保留你提供的三个选择框,添加联动逻辑。这里提供两种版本:jQuery简化版和原生JS无依赖版。
HTML部分(修正了原代码的select属性错误,改为selected)
<select name="state" id="state"> <option value="" selected>STATE</option> </select> <select name="city" id="city"> <option value="" selected>CITY</option> </select> <select name="company" id="company"> <option value="" selected>COMPANY</option> </select>
jQuery版本JS
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <script> $(document).ready(function() { // 页面加载时填充州选择框 $.ajax({ url: 'get-companies-data.php?action=get-states', type: 'GET', dataType: 'json', success: function(states) { states.forEach(state => { $('#state').append(`<option value="${state}">${state}</option>`); }); }, error: () => alert('Failed to load states') }); // 州选择变化时,更新城市选择框 $('#state').change(function() { const selectedState = $(this).val(); // 清空下级选择框的内容 $('#city').html('<option value="" selected>CITY</option>'); $('#company').html('<option value="" selected>COMPANY</option>'); if (!selectedState) return; $.ajax({ url: `get-companies-data.php?action=get-cities&state=${selectedState}`, type: 'GET', dataType: 'json', success: function(cities) { cities.forEach(city => { $('#city').append(`<option value="${city}">${city}</option>`); }); }, error: () => alert('Failed to load cities') }); }); // 城市选择变化时,更新公司选择框 $('#city').change(function() { const selectedCity = $(this).val(); $('#company').html('<option value="" selected>COMPANY</option>'); if (!selectedCity) return; $.ajax({ url: `get-companies-data.php?action=get-companies&city=${selectedCity}`, type: 'GET', dataType: 'json', success: function(companies) { companies.forEach(company => { $('#company').append(`<option value="${company}">${company}</option>`); }); }, error: () => alert('Failed to load companies') }); }); }); </script>
原生JS版本(无依赖)
document.addEventListener('DOMContentLoaded', function() { const stateSelect = document.getElementById('state'); const citySelect = document.getElementById('city'); const companySelect = document.getElementById('company'); // 封装AJAX请求工具函数 function fetchData(url, callback) { const xhr = new XMLHttpRequest(); xhr.open('GET', url, true); xhr.onload = function() { if (xhr.status >= 200 && xhr.status < 300) { callback(JSON.parse(xhr.responseText)); } else { alert('Failed to fetch data'); } }; xhr.onerror = () => alert('Request error'); xhr.send(); } // 加载州列表 fetchData('get-companies-data.php?action=get-states', function(states) { states.forEach(state => { const option = document.createElement('option'); option.value = state; option.textContent = state; stateSelect.appendChild(option); }); }); // 州选择变化事件 stateSelect.addEventListener('change', function() { const selectedState = this.value; citySelect.innerHTML = '<option value="" selected>CITY</option>'; companySelect.innerHTML = '<option value="" selected>COMPANY</option>'; if (!selectedState) return; fetchData(`get-companies-data.php?action=get-cities&state=${selectedState}`, function(cities) { cities.forEach(city => { const option = document.createElement('option'); option.value = city; option.textContent = city; citySelect.appendChild(option); }); }); }); // 城市选择变化事件 citySelect.addEventListener('change', function() { const selectedCity = this.value; companySelect.innerHTML = '<option value="" selected>COMPANY</option>'; if (!selectedCity) return; fetchData(`get-companies-data.php?action=get-companies&city=${selectedCity}`, function(companies) { companies.forEach(company => { const option = document.createElement('option'); option.value = company; option.textContent = company; companySelect.appendChild(option); }); }); }); }); </script>
关键说明
- 隐藏API URL:所有API请求通过PHP脚本转发,前端无法获取真实API地址,完全满足你的需求。
- 数据去重:通过PHP的
array_unique和循环判断,确保州、城市选项无重复。 - 联动逻辑:每次上级选择变化时,自动清空下级选项并重新请求对应数据,保证数据关联性正确。
- 兼容性:原生JS版本不依赖任何第三方库,适合无法引入jQuery的场景。
你只需要将PHP脚本中的$api_url替换为真实的API地址,将所有文件放在同一服务器目录下即可运行。
内容的提问来源于stack exchange,提问作者Patrick
相关产品推荐
相关产品推荐

