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" => "", ); } }
错误原因
这个函数有两个致命问题:
- 没有任何
return语句,调用后返回null,导致foreach循环接收不到合法的遍历对象; - 循环内每次给
$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
相关产品推荐
相关产品推荐

