php - 如何获取类别、文章和子类别及其文章?
问题描述
我想输出类别名称,每个类别中的子类别名称,以及每个类别和每个子类别中的文章。
输出应该是 HTML 中的 in<ul>
和 inner<ul>
标记。
以下是输出的样子:
我有这 5 张桌子:
table_article_categories(articlecat_id, parent_id, articlecat_status, ...)
table_article_to_article_categories(articlecat_id, articles_id)
table_articles(articles_id, articles_status, ...)
table_articles_description(articles_id, language_id, articles_heading_title, ...)
table_article_categories_description(articlecat_id, articlecat_name, language_id, ...)
到目前为止,我已经制作了这个 SQL:
SELECT
ac.parent_id,
ac.articlecat_id,
a.articles_id,
ad.articles_heading_title AS article_name,
acd.articlecat_name
FROM
table_article_categories AS ac
LEFT JOIN
table_article_to_article_categories AS atac
ON
atac.articlecat_id = ac.articlecat_id
LEFT JOIN
table_articles AS a
ON
a.articles_id = atac.articles_id
AND
a.articles_status = 1
LEFT JOIN
table_articles_description AS ad
ON
ad.articles_id = a.articles_id
AND
ad.language_id = 1
INNER JOIN
table_article_categories_description AS acd
ON
acd.articlecat_id = ac.articlecat_id
AND
acd.language_id = 1
WHERE
ac.parent_id = 99 # --- This is the root article-categori-id ---
AND
ac.articlecat_status = 1
AND
ac.articlecat_id != 77 # --- This is an excluded article-categori-id ---
ORDER BY
acd.articlecat_name ASC,
article_name ASC
解决方案
当我查看您想要的输出时,我看到的是一棵带有叶子的树,它可能链接到一篇文章,也可能不链接到一篇文章。没有附加文章的叶子可以被认为是一个类别。有文章的叶子可以被认为是文章。
有了这个假设,您可以构建您的架构:
Category_Tree Category Article
------------ -------- -------
id id id
pid category_id article_id
article_id language_id language_id
category_id title title
(当然,这不是第 4 范式。如果需要,您可以进行归一化,但现在这将是过早的优化)
现在,应该更容易看到如何解决您的问题:您所要做的就是首先在 php 数组中构建树;然后遍历该数组并单独查询每个叶子的详细信息(或至少查询链接的 href 和文本所需的内容)。
一个简单的递归入门:
<?php
/*
Category_Tree
id pid name article_id category_id
1 0 Category 1 ... ...
2 1 Article 1
3 0 Category 2
4 3 SubCategory 1
5 4 Article 7
6 4 Article 8
7 3 Article 2
8 3 Article 3
9 0 Category 3
10 9 Article 4
11 9 Article 5
12 0 Article 6
*/
function getRecord($pid) : array
{
// database access is left to the reader
// $db->run('SELECT * FROM CATEGORY_TREE WHERE PID=?',[$pid]);
// $rows = [];
// while($row = $db->getRow()) {
// $rows[] = $row;
// }
return $rows;
}
function makeTree($pid) : array
{
static $idList = [];
static $indent = 0;
$rows = getRecord($pid);
foreach ($rows as $row) {
$idList[] = [
'id' => $row->id,
'indent' => $indent,
'articleId' => $row->articleId,
'categoryId' => $row->categoryId,
];
$indent++;
makeTree($row->id);
$indent--;
}
return $idList;
}
$idList = makeTree(0);
*警告:这不会直接转化为无序列表。我不喜欢混合 html 和逻辑,但在这种情况下,您需要在递归中构建一个字符串。这是您可以提出或研究的更集中的问题。
现在,您遍历$idList
并查找所需的信息以填写您想要的标题
伪代码(数据库检索再次留给读者):
// $languageId is already assigned as you see fit
// add title to $idList
foreach($idList as $index => $row) {
if($row->articleId ?? FALSE) {
$db->run('SELECT TITLE FROM ARTICLE WHERE ARTICLE_ID=? AND LANGUAGE_ID=?', [$row->articleId, $languageID]);
} else {
$db->run('SELECT TITLE FROM CATEGORY WHERE CATEGORY_ID=? AND LANGUAGE_ID=?', [$row->categoryId, $languageId]);
}
$row->title = $db->get('title');
$idList[$index] = $row;
}
然后,当您输出 html 时,您只需$idList
再次遍历并根据需要输入值。
显然,这不是一个剪切和粘贴的答案。有太多的编码要做。但希望这能为您指明一个可行的方向。
推荐阅读
- javascript - 在父道具值更改时更新子道具值
- python-3.x - 如何确定数字在列和行中的位置
- javascript - 如何在不丢失一些数据的情况下将 Javascript 中的数据从数组重塑为对象
- java - 尝试连接到 H2 数据库时出错
- python - 如何在单个 tensorflow 会话中运行多个分类模型(keras、caffe 等)?
- jmeter - cookie的JMeter正则表达式:转义加字符
- javascript - 如何在 Javascript 中的 responseText 中设置 HTML 中的 img.src?
- google-apps-script - 在 Google Apps 脚本上运行时更改后获取页面 URL 的问题
- apache - 尝试允许使用 .htaccess 从特定链接访问我的网站
- c# - C# 正则表达式匹配具有不在引号中的双条的字符串