
本文介绍如何构建一个轻量级 php 搜索页面,支持用户输入字符(如“a”)和选择出生年份,精准筛选出姓名包含该字符且出生年份匹配的人员信息,并提供可运行、结构清晰、易于维护的代码实现。
要实现一个简洁可靠的姓名+年份联合搜索功能,关键在于解耦数据、逻辑与展示,避免 include 带来的变量作用域混乱和重复加载问题——这正是原代码中 function.php 的核心缺陷:include("data.php") 在函数内部执行时,$person 数组无法正确作用于函数作用域(尤其在严格模式或现代 PHP 版本下易失效),且 strpos(strtolower(...), $word) 未对搜索词做小写处理,导致大小写敏感不一致。
以下是推荐的重构方案,采用函数式设计 + 显式参数传递,确保可测试性与可维护性:
✅ 正确实现:分离数据、搜索逻辑与页面渲染
1. data.php(纯数据定义,不执行逻辑)
<?php
return [
['name' => 'Daniel', 'dateofbirth' => 2000],
['name' => 'Gaetan', 'dateofbirth' => 1980],
['name' => 'Anna', 'dateofbirth' => 2000],
['name' => 'Ben', 'dateofbirth' => 1995],
];2. functions.php(专注业务逻辑)
立即学习“PHP免费学习笔记(深入)”;
<?php
function findPeopleByKeywordAndYear(string $keyword, int $year, array $people): array {
$results = [];
$keywordLower = strtolower($keyword);
foreach ($people as $person) {
// 同时满足:姓名含关键词(忽略大小写)且出生年份匹配
if (stripos($person['name'], $keywordLower) !== false && $person['dateofbirth'] === $year) {
$results[] = $person;
}
}
return $results;
}✅ 使用 stripos() 替代 strpos(strtolower()),更简洁安全;=== 严格比较避免类型隐式转换错误。
3. index.php(前端表单 + 结果展示)
<?php
require_once 'data.php';
require_once 'functions.php';
$people = require 'data.php'; // 加载数据
$results = [];
if ($_SERVER['REQUEST_METHOD'] === 'GET' && !empty($_GET['q']) && isset($_GET['year'])) {
$searchTerm = trim($_GET['q']);
$birthYear = (int)$_GET['year'];
if (!empty($searchTerm)) {
$results = findPeopleByKeywordAndYear($searchTerm, $birthYear, $people);
}
}
?>
<!DOCTYPE html>
<html>
<head><title>Name Search</title></head>
<body>
<h2>Search by Name & Birth Year</h2>
<form method="GET">
<label>Keyword: <input type="text" name="q" value="<?= htmlspecialchars($_GET['q'] ?? '') ?>" required></label><br><br>
<label>Birth Year:
<select name="year" required>
<option value="">-- Select Year --</option>
<option value="2000" <?= ($_GET['year'] ?? '') == '2000' ? 'selected' : '' ?>>2000</option>
<option value="1980" <?= ($_GET['year'] ?? '') == '1980' ? 'selected' : '' ?>>1980</option>
<option value="1995" <?= ($_GET['year'] ?? '') == '1995' ? 'selected' : '' ?>>1995</option>
</select>
</label><br><br>
<button type="submit">Search</button>
</form>
<?php if (!empty($results)): ?>
<h3>Results (<?= count($results) ?>)</h3>
<ul>
<?php foreach ($results as $person): ?>
<li><?= htmlspecialchars($person['name']) ?> (born <?= $person['dateofbirth'] ?>)</li>
<?php endforeach; ?>
</ul>
<?php elseif ($_SERVER['REQUEST_METHOD'] === 'GET' && !empty($_GET['q'])): ?>
<p><em>No matches found for "<strong><?= htmlspecialchars($_GET['q']) ?></strong>" in year <?= htmlspecialchars($_GET['year'] ?? 'N/A') ?>.</em></p>
<?php endif; ?>
</body>
</html>⚠️ 重要注意事项
- 安全性:所有用户输入($_GET['q'], $_GET['year'])均经 htmlspecialchars() 转义,防止 XSS;年份强制 (int) 类型转换,杜绝注入风险。
- 健壮性:空值校验、trim() 清理空白、!empty() 防止空搜索。
- 可扩展性:若未来迁移到数据库,只需重写 findPeopleByKeywordAndYear() 内部为 PDO 查询,上层调用完全不变。
- 生产建议:如答案中强调,真实项目务必使用 MySQL/PostgreSQL 存储数据,并通过 WHERE name LIKE '%a%' AND dateofbirth = 2000 实现高效索引查询——PHP 数组搜索仅适用于极小规模演示。
此方案结构清晰、无副作用、符合 PSR-12 编码规范,是学习 PHP 表单处理与基础搜索逻辑的理想实践模板。











