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

PHP读取MongoDB数据为数组展示文章及跳转问题与解决

PHP MongoDB 新闻列表展示问题解决及详情跳转实现

问题背景

我开发新闻网站时,首页index.php需要展示MongoDB里的文章数据。原本代码基于数组记录集开发,改成MongoDB连接版本后,出现报错:Warning: foreach() argument must be of type array|object, null given,同时还需要实现点击文章跳转到详情页的功能。

原错误代码

首页index.php代码

$ARR_articles = article_recordset();

$STR_article = NULL;

foreach($ARR_articles as $index => $article){
    $STR_article .= get_article_item_html(
        $img_path = "img/article/".$index.".jpg", 
        $title = $article["title"], 
        $description = $article["content"]
    );
}

最初修改的article_recordset()函数(有问题)

function article_recordset(){
   

require 'vendor/autoload.php';

$client = new MongoDB\Client("mongodb://localhost:27017");

$SiteArticles = $client->SiteArticles;
$articoli=$SiteArticles->Articles;
$cursor = $articoli->find();

    foreach ($cursor as $articolo) {
        $recordset = array(
                "title" => $articolo["title"],
                "description" => $articolo["content"],
                "article" => "",
        );

    }
}    

错误原因

这个函数有两个致命问题:

  1. 没有任何return语句,调用后返回null,导致foreach循环接收不到合法的遍历对象;
  2. 循环内每次给$recordset赋值都会覆盖之前的内容,就算最后return也只能拿到最后一条数据。

解决后的展示代码

我通过添加return $cursor;解决了遍历问题,修改后的函数如下:

function article_recordset(){
require 'vendor/autoload.php';

$client = new MongoDB\Client("mongodb://localhost:27017");
$i = 0;
$SiteArticles = $client->SiteArticles;
$articoli=$SiteArticles->Articles;
$cursor = $articoli->find();
return $cursor;

    foreach ($cursor as $articolo) {      
        $recordset = array(
            $i=$i+1 => array(
                "title" => $articolo["title"],
                "description" => $articolo["content"],
                "article" => "",
            )
        );
    }

} 

注:函数里return $cursor;之后的循环代码不会执行,实际生效的是直接返回MongoDB的游标——游标本身支持foreach遍历,所以解决了null报错问题。图片只要按img/article/[索引].jpg命名(从0开始)就能匹配上。

补充:文章跳转详情页实现

要实现跳转,需要利用MongoDB文档的唯一_id字段传递参数,具体步骤如下:

1. 优化article_recordset()函数

确保返回的游标包含_id字段(默认find()会返回),简化函数:

function article_recordset(){
require 'vendor/autoload.php';

$client = new MongoDB\Client("mongodb://localhost:27017");
$SiteArticles = $client->SiteArticles;
$articoli=$SiteArticles->Articles;
return $articoli->find();
}

2. 修改首页循环逻辑

单独维护图片索引(避免游标遍历的键可能不是连续数字的问题),并传递文章_id:

$ARR_articles = article_recordset();

$STR_article = NULL;
$img_index = 0;

foreach($ARR_articles as $article){
    $STR_article .= get_article_item_html(
        "img/article/".$img_index.".jpg", 
        $article["title"], 
        $article["content"],
        $article["_id"]
    );
    $img_index++;
}

3. 生成带跳转链接的文章项

修改get_article_item_html函数,给标题添加跳转链接:

function get_article_item_html($img_path, $title, $description, $article_id){
    // 将MongoDB的ObjectId转为字符串,避免传递异常
    $article_id_str = (string)$article_id;
    return <<<HTML
    <div class="article-item">
        <img src="{$img_path}" alt="{$title}">
        <h3><a href="article_detail.php?id={$article_id_str}">{$title}</a></h3>
        <p>{$description}</p>
    </div>
HTML;
}

4. 详情页article_detail.php实现

根据传递的ID查询并展示文章:

require 'vendor/autoload.php';

$client = new MongoDB\Client("mongodb://localhost:27017");
$SiteArticles = $client->SiteArticles;
$articoli = $SiteArticles->Articles;

// 获取URL参数中的文章ID,并转为MongoDB可识别的ObjectId
if(!isset($_GET['id']) || empty($_GET['id'])){
    die("文章ID不存在");
}

try {
    $article_id = new MongoDB\BSON\ObjectId($_GET['id']);
    $article = $articoli->findOne(['_id' => $article_id]);

    if($article){
        echo "<h1>{$article['title']}</h1>";
        echo "<div class='article-content'>{$article['content']}</div>";
    } else {
        echo "该文章不存在";
    }
} catch(Exception $e){
    echo "无效的文章ID";
}

内容的提问来源于stack exchange,提问作者LoquenLucas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 20:06:19