2

让我们在一个场景中说:$ids = 2,3. 但由于某种原因,记录被返回,好像:$ids = 2.

我相信完整代码的这一行存在一些问题,因为当我 echo 时$ids,它返回2,3,但实际查询返回时好像只有一个 id。即它只返回一门课程的事件(id 2)。

$statement->execute(array("ids" => $ids, 'timestart' => $timestart, 'timeend' => $timeend))) {

我的完整代码:

$ids = array_map(function($item) { return $item->id; }, $entitlementsVOs);
$ids = implode(', ', $ids); //echo shows 2,3

$timestart = isset($_GET['start']) && $_GET['start'] != "" ? $_GET['start'] : null;
$timeend = isset($_GET['end']) && $_GET['end'] != "" ? $_GET['end'] : null;

$statement = $this->connection->prepare("SELECT name AS title, timestart AS start, timestart + timeduration AS end FROM event WHERE courseid IN(:ids) AND timestart >= :timestart AND timestart + timeduration <= :timeend");
$statement->setFetchMode(\PDO::FETCH_CLASS, get_class(new EventVO()));


if($statement->execute(array("ids" => $ids, 'timestart' => $timestart, 'timeend' => $timeend))) {
    return $statement->fetchAll();
} else {
    return null;
}

ps 在 mysql 工作台中手动运行此查询会返回我的两条记录(1 条来自课程 id 2,另一条来自课程 3),其中我用 (2,3) 替换运算符,但在 php 执行中我只得到一条记录。

如果我硬编码 php 中的值courseid IN(2,3),例如:

$statement = $this->connection->prepare("SELECT name AS title, timestart AS start, timestart + timeduration AS end FROM event WHERE courseid IN(2,3) AND timestart >= :timestart AND timestart + timeduration <= :timeend");

我得到了我的期望,所以我相信implode, orIN运算符 or存在一些问题$statement->execute

编辑:

我已经阅读了欺骗,但我不知道从哪里开始使用命名占位符来完成相同的操作。我的问题是,当我同时命名参数和 IN 运算符时,受骗者仅将 IN 运算符与位置占位符一起使用。

编辑 2

我已经阅读了第二个骗局,它不相关,我的问题同时使用了 IN 和命名占位符,链接的问题没有解决这个问题,但是,我现在在答案中找到了解决方案。

4

1 回答 1

2

这应该适合你:

因此,正如评论中已经说过的,您需要为要绑定到 IN 子句中的每个值设置一个占位符。

在这里,我首先创建仅包含普通 ID 的数组$ids,例如

[2, 3]

然后我还创建了$preparedIds将占位符保存为数组的数组,稍后您将在准备好的语句中使用它。这个数组看起来像这样:

[":id2", ":id3"]

我还创建了一个名为的数组$preparedValues,其中包含$preparedIdsas 键和$ids值,然后您可以将其用于execute()调用。数组看起来像这样:

[":id2" => 2, ":id3" => 3]

之后你就可以走了。在准备好的语句中,我只是implode()数组$preparedIds,因此 SQL 语句看起来像这样:

... IN(:id2,:id3) ...

然后你可以简单地execute()查询。我只是array_merge()你的$preparedValues数组和其他占位符数组。

<?php

    $ids = array_map(function($item){
        return $item->id;
    }, $entitlementsVOs);

    $preparedIds = array_map(function($v){
        return ":id$v";
    }, $ids);

    $preparedValues = array_combine($preparedIds, $ids);


    $timestart = (!empty($_GET['start']) ? $_GET['start'] : NULL );
    $timeend = (!empty($_GET['end']) ? $_GET['end'] : NULL );


    $statement = $this->connection->prepare("SELECT name AS title, timestart AS start, timestart + timeduration AS end FROM event WHERE courseid IN(" . implode(",", $preparedIds) . ") AND timestart >= :timestart AND timestart + timeduration <= :timeend");
    $statement->setFetchMode(\PDO::FETCH_CLASS, get_class(new EventVO()));

    if($statement->execute(array_merge($preparedValues, ["timestart" => $timestart, "timeend" => $timeend]))) {
        return $statement->fetchAll();
    } else {
        return null;
    }

?>

此外,我认为您想在查询周围放置一个 if 语句,因为如果$timestartand的值为$timeendNULL,您的查询将不会运行。

于 2015-04-30T22:08:03.553 回答