
本文介绍如何通过 php 和 mysql 实现下拉选择框(`
在实际业务系统中(如合同管理系统),用户常需从大量选项中快速定位目标条目。例如,从如下合同名称中筛选出“2023 年的框架协议”:
- FRAMEWORK CONTRACT TO CONTRACT 19/ 2023
- SUPPLEMENT TO THE FRAMEWORK CONTRACT 1 / 2022
- SUPPLEMENT TO THE SPECIFIC CONTRACT 1/2023
仅靠前端 JavaScript 过滤在数据量大时体验差且不安全;而直接在后端 SQL 中硬编码关键词(如 LIKE '%FRAMEWORK CONTRACT%' AND LIKE '%2023%')虽简单,但存在 SQL 注入风险,且难以复用。
✅ 推荐方案:服务端动态构建参数化查询
假设合同标题存储在数据库字段 id_contrato(或更合理的 titulo_contrato)中,我们应使用 mysqli 或 PDO 的预处理语句,将多个关键词安全地注入 WHERE ... LIKE 条件中。
立即学习“PHP免费学习笔记(深入)”;
以下为基于 mysqli 的完整、安全示例:
<?php
// 假设已建立 $conexion 连接
$keywords = ['FRAMEWORK CONTRACT', '2023']; // 可来自表单 GET/POST,需清洗
// 动态构建 WHERE 子句:每个关键词对应一个 LIKE 条件
$placeholders = [];
$params = [];
$types = '';
foreach ($keywords as $kw) {
$placeholders[] = "id_contrato LIKE ?";
$params[] = '%' . trim($kw) . '%';
$types .= 's';
}
$whereClause = !empty($placeholders) ? 'WHERE ' . implode(' AND ', $placeholders) : '';
$sql = "SELECT * FROM `contratos` $whereClause";
$stmt = mysqli_prepare($conexion, $sql);
if ($stmt) {
if (!empty($params)) {
mysqli_stmt_bind_param($stmt, $types, ...$params);
}
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
echo '<select name="contrato_id">';
echo '<option value="">Seleccione...</option>';
while ($row = mysqli_fetch_assoc($result)) {
// 注意:务必对输出内容做 HTML 转义,防止 XSS
$displayText = htmlspecialchars(
$row['id_contrato'] . '-' . ($tipo_nombre ?? '') . ' ' .
($row['no_ctto'] ?? '') . ' /' . ($row['anno'] ?? ''),
ENT_QUOTES, 'UTF-8'
);
echo '<option value="' . (int)$row['id'] . '">' . $displayText . '</option>';
}
echo '</select>';
mysqli_stmt_close($stmt);
} else {
error_log("SQL 准备失败: " . mysqli_error($conexion));
echo '<select disabled><option>Error loading options</option></select>';
}
?>? 关键说明与最佳实践:
- 字段命名建议:原始代码中拼接逻辑混乱(如 $tipo_nombre 未定义),应确保所有变量已声明或从数据库中获取;理想结构是 titulo_contrato 字段直接存储完整标题,避免运行时拼接。
- 关键词来源:$keywords 应来自用户输入(如搜索框),务必先 trim()、htmlspecialchars()(输出前)、并校验长度/字符集,拒绝非法模式(如 %, _, ' 等通配符滥用)。
-
性能提示:LIKE '%keyword%' 无法使用常规索引,若数据量超万级,建议:
- 添加全文索引(FULLTEXT)并改用 MATCH ... AGAINST;
- 或引入 Elasticsearch / Meilisearch 等专用搜索服务。
- 可扩展性设计:将上述查询逻辑封装为函数(如 getFilteredContracts(array $keywords)),便于在列表页、API 接口等多处复用。
? 总结:多关键词过滤不是简单的字符串拼接,而是安全、可维护、可扩展的数据检索能力。坚持使用预处理语句 + 输入清洗 + 输出转义,是构建健壮 Web 表单的基础防线。











