
本文详解 PHP 动态日期在 SQL BETWEEN 查询中失效的原因,并提供基于 mysqli 和 PDO 的安全、规范解决方案,重点强调参数化预处理语句防止 SQL 注入。
本文详解 php 动态日期在 sql `between` 查询中失效的原因,并提供基于 mysqli 和 pdo 的安全、规范解决方案,重点强调参数化预处理语句防止 sql 注入。
在 PHP 中直接拼接字符串构建 SQL 查询(如 $sql = "WHERE $pick_date BETWEEN ...")看似简洁,实则存在两大严重问题:语法风险与安全漏洞。
首先,语法层面:当 $pick_date = '2022-06-06' 时,未经引号包裹的变量拼接会导致生成非法 SQL:
SELECT id FROM tblseasons WHERE 2022-06-06 BETWEEN date(se_from) AND date(se_to)
MySQL 将 2022-06-06 解析为算术表达式 2022 - 6 - 6 = 2010,而非日期字面量,从而引发逻辑错误或类型不匹配异常。即使手动加单引号(如 '$pick_date'),仍无法规避 SQL 注入——攻击者可构造 '2022-06-06' OR '1'='1' -- 等恶意输入,彻底破坏查询逻辑与数据安全。
✅ 正确做法是完全剥离 SQL 结构与数据,使用参数化预处理语句(Prepared Statements)。数据库驱动会自动转义并安全绑定值,确保日期被严格作为字符串/日期类型处理。
立即学习“PHP免费学习笔记(深入)”;
✅ 推荐方案一:mysqli 预处理(面向对象风格)
$mysqli = new mysqli("localhost", "user", "dbpass", "dbname1");
if ($mysqli->connect_error) {
die("连接失败: " . $mysqli->connect_error);
}
$pick_date = '2022-06-06';
$sql = "SELECT id FROM tblseasons WHERE ? BETWEEN DATE(se_from) AND DATE(se_to)";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param("s", $pick_date); // "s" 表示字符串类型
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
echo htmlspecialchars($row['id']) . "<br>";
}
$stmt->close();
$mysqli->close();✅ 推荐方案二:PDO 预处理(命名占位符更清晰)
try {
$pdo = new PDO('mysql:host=localhost;dbname=dbname1;charset=utf8mb4', "user", "dbpass", [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
]);
$pick_date = '2022-06-06';
$sql = "SELECT id FROM tblseasons WHERE :pick_date BETWEEN DATE(se_from) AND DATE(se_to)";
$stmt = $pdo->prepare($sql);
$stmt->execute([':pick_date' => $pick_date]);
foreach ($stmt as $row) {
echo htmlspecialchars($row['id']) . "<br>";
}
} catch (PDOException $e) {
error_log("数据库错误: " . $e->getMessage());
echo "查询失败,请稍后重试。";
}⚠️ 关键注意事项
- 绝不拼接用户输入:包括表单提交、URL 参数、Cookie 等任何外部数据;
- 显式指定字符集(如 charset=utf8mb4)避免中文或特殊字符乱码;
- 启用错误报告机制(如 PDO 的 PDO::ERRMODE_EXCEPTION)便于调试;
- DATE() 函数用于剥离时间部分,确保仅比较日期;若字段本身为 DATE 类型,可省略;
- 输出前务必使用 htmlspecialchars() 防止 XSS 攻击。
通过参数化查询,你不仅解决了动态日期解析失败的问题,更从根本上筑牢了 Web 应用的安全防线。这是现代 PHP 数据库操作不可妥协的最佳实践。



















