【问题标题】:Can’t get all the results using fetch(PDO::FETCH_ASSOC);使用 fetch(PDO::FETCH_ASSOC) 无法获得所有结果;
【发布时间】:2021-10-14 01:48:53
【问题描述】:

我正在尝试根据用户 ID 获取网站 ID 列表。

这是我到目前为止所得到的。

public function getSites() {
    $stmt = $this->db->prepare("SELECT Sites_idSites FROM favorites WHERE User_idUser=:idUser");
    $userId = $_SESSION['user_session']['idUser'];
    $stmt->bindparam(":idUser", $userId);
    $stmt->execute();
    $siteList = $stmt->fetchAll(PDO::FETCH_ASSOC);

    foreach($siteList as $value) {
        foreach($value as $key) {
        $stmt = $this->db->prepare("SELECT * FROM sites WHERE idSites=:siteList");
        $stmt->bindparam(":siteList", $key);
    }
    $stmt->execute();
    $userSites = $stmt->fetch(PDO::FETCH_ASSOC);
}

return $userSites;

这是我转到“收藏夹”表并获取与用户 ID 对应的所有站点 ID 的部分。

$stmt = $this->db->prepare("SELECT Sites_idSites FROM favorites WHERE User_idUser=:idUser");
$userId = $_SESSION['user_session']['idUser'];
$stmt->bindparam(":idUser", $userId);
$stmt->execute();
$siteList = $stmt->fetchAll(PDO::FETCH_ASSOC);

$siteList 以这样的数组形式返回:

Array
(
    [0] => Array
        (
            [Sites_idSites] => 20
        )

    [1] => Array
    (
        [Sites_idSites] => 21
    )

    [2] => Array
    (
        [Sites_idSites] => 22
    )
 )

现在,我想转到所有站点所在的表,并且只获取具有这些 id 的站点。

这是我正在使用的,但它只获取最后一个:

foreach($siteList as $value) {
    foreach($value as $key) {
        $stmt = $this->db->prepare("SELECT * FROM sites WHERE idSites=:siteList");
        $stmt->bindparam(":siteList", $key);
    }
    $stmt->execute();
    $userSites = $stmt->fetch(PDO::FETCH_ASSOC);
 }

如果我这样做print_r($userSites),我会返回:

Array
(
    [idSites] => 22
    [name] => rwrwer
    [url] => werwerwerwer
    [Category_idCategory] => 1
)

如您所见,它只返回最后一个。如何让它返回一个包含所有站点的数组?我做错了吗?


我终于修好了:

public function getSites() {
    $stmt = $this->db->prepare("SELECT sites.* FROM favorites INNER JOIN sites ON favorites.Sites_idSites = sites.idSites WHERE favorites.User_idUser = :idUser");
    $userId = $_SESSION['user_session']['idUser'];
    $stmt->bindparam(":idUser", $userId);
    $stmt->execute();
    $siteList = $stmt->fetchAll(PDO::FETCH_ASSOC);

    return $siteList;
}

【问题讨论】:

    标签: php pdo


    【解决方案1】:

    这是因为您在绑定值的内部循环之外运行查询。

    foreach($siteList as $value){
        foreach($value as $key){
            $stmt = $this->db->prepare("SELECT * FROM sites WHERE idSites=:siteList");
            $stmt->bindparam(":siteList",$key);
            // Bind and rebind, so only the last one "Sticks"
        }
        // Run the query after the loop
        $stmt->execute();
        $userSites = $stmt->fetch(PDO::FETCH_ASSOC);
    }
    

    您基本上是在每次迭代中重新绑定:siteList。然后当你运行它时,只有你最后一次绑定它时才会“粘住”。 fetch 也只会返回一行(至少不会循环)。

    您可以将它移到循环内部,然后执行fetchAll,但更好的方法是构建一个列表,然后像这样使用IN()

    foreach($siteList as $value){
        $i = 0;
        $ids = [];
        $where = [];
        $sql = 'SELECT * FROM sites WHERE';
        foreach($value as $key){
            $placeholder = ":id_{$i}";
            $where[] = $placeholder;
            $ids[$placeholder] = $key;
            ++$i;
        }
        $this->db->prepare($sql . ' idSites IN( ' . implode(',', $where) . ' )');
        $stmt->execute($ids);
        $userSites = $stmt->fetchAll(PDO::FETCH_ASSOC);
     }
    

    SQL 应该如下所示:

    SELECT * FROM sites WHERE idSites IN( :id_1,:id_2,:id_3 )
    

    $ids 数组应该是这样的

    $ids = [':id_1'=>1,':id_2'=>53,':id_3'=>1239];
    

    除了,我只是编造了那些数字(显然)。

    这样,您可以减少执行的查询数量。您甚至可以将其完全放在循环之外,但是如果没有更多上下文,我真的不能这么说。最基本的一点是,调用数据库的成本很高,您应该尽量减少调用次数。

    【讨论】:

    • 它现在正在工作,我非常感谢您的回答,不仅因为您解决了我的问题,而且您让我理解它!代码中只有一个注释我替换了你的 $stmt->execute($ids);对于 $stmt->execute();它给了我一个错误,但它现在正在工作!
    • 嗯..它应该可以工作,但无论如何很高兴你把它整理好了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-19
    • 1970-01-01
    • 2013-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多