You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MVC架构下PDO绑定SQL函数致查询返回空数组问题求助

问题根源

你遇到的核心问题是PDO参数绑定会将传入的SQL函数(如WEEK(NOW()))当作普通字符串字面量处理,而非让MySQL执行该函数。例如你绑定'WEEK(NOW())'后,实际执行的SQL是semaine = 'WEEK(NOW())',这和数据库中存储的数字型周数完全不匹配,因此返回空数组。

解决方案

下面提供两种可靠的修正方案,你可以根据需求选择:

方案1:PHP端计算周数/年份,绑定数值(推荐)

在控制器中提前计算出具体的周数和年份数值,再传递给模型绑定,确保SQL匹配数据库中的数字字段。

修正后的控制器代码

if ($_SERVER['REQUEST_METHOD'] == 'POST'){
    // 计算目标周的年份和周数
    $targetTimestamp = $_POST['week'] == 'currentWeek' ? time() : strtotime('+1 week');
    $year = date('Y', $targetTimestamp);
    $week = date('W', $targetTimestamp); // ISO标准周数(1-53)

    // 统一调用模型方法,避免重复代码
    $entree = $menumodel->displayTypeOfProduitsPerWeek('entree', $week, $year);
    $plat = $menumodel->displayTypeOfProduitsPerWeek('plat', $week, $year);
    $dessert = $menumodel->displayTypeOfProduitsPerWeek('dessert', $week, $year);
}

修正后的模型代码

public function displayTypeOfProduitsPerWeek($type, $semaine, $annee)
{
    $query = "SELECT annee, semaine, titre, description, type, prix 
                FROM produit 
                WHERE semaine = :semaine 
                  AND type = :type 
                  AND annee = :annee";
    $statement = $this->pdo->prepare($query);
    
    // 周数和年份为整数,使用PARAM_INT更精准
    $statement->bindValue(':semaine', $semaine, PDO::PARAM_INT);
    $statement->bindValue(':annee', $annee, PDO::PARAM_INT);
    $statement->bindValue(':type', $type, PDO::PARAM_STR);
    
    $statement->execute();
    return $statement->fetchAll(PDO::FETCH_ASSOC);
}

方案2:模型中动态拼接安全的SQL函数

如果需要让MySQL端处理时间逻辑,可以在模型中根据传入的标识动态拼接SQL函数,但必须严格校验参数防止注入。

修正后的控制器代码

if ($_SERVER['REQUEST_METHOD'] == 'POST'){
    $weekType = $_POST['week'];
    $entree = $menumodel->displayTypeOfProduitsPerWeek('entree', $weekType);
    $plat = $menumodel->displayTypeOfProduitsPerWeek('plat', $weekType);
    $dessert = $menumodel->displayTypeOfProduitsPerWeek('dessert', $weekType);
}

修正后的模型代码

public function displayTypeOfProduitsPerWeek($type, $weekType = 'currentWeek')
{
    // 严格校验参数,仅允许合法值,防止SQL注入
    if (!in_array($weekType, ['currentWeek', 'nextWeek'])) {
        throw new InvalidArgumentException('无效的周类型参数');
    }

    // 根据参数选择对应的SQL时间函数
    $weekExpr = $weekType === 'currentWeek' ? 'WEEK(NOW())' : 'WEEK(DATE_ADD(NOW(), INTERVAL 7 DAY))';
    $yearExpr = $weekType === 'currentWeek' ? 'YEAR(NOW())' : 'YEAR(DATE_ADD(NOW(), INTERVAL 7 DAY))';

    $query = "SELECT annee, semaine, titre, description, type, prix 
                FROM produit 
                WHERE semaine = $weekExpr 
                  AND type = :type 
                  AND annee = $yearExpr";
    $statement = $this->pdo->prepare($query);
    $statement->bindValue(':type', $type, PDO::PARAM_STR);
    $statement->execute();
    return $statement->fetchAll(PDO::FETCH_ASSOC);
}
注意事项
  • 确保数据库中semaine字段存储的是数字类型(如INT),annee字段也是数字年份(如2024),否则即使修正代码也无法匹配。
  • 方案1更符合参数绑定的安全原则,推荐优先使用;方案2需严格控制参数范围,避免注入风险。

内容的提问来源于stack exchange,提问作者Maël Etienne

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 15:45:33