Php PDO递归查询
我已经发现了这一点,尽管我还不能对所选择的答案进行思考,或者确定它是否适用于我的情况 我有图像库的以下表格:Php PDO递归查询,php,mysql,recursion,pdo,Php,Mysql,Recursion,Pdo,我已经发现了这一点,尽管我还不能对所选择的答案进行思考,或者确定它是否适用于我的情况 我有图像库的以下表格: CREATE TABLE image_categories ( cat_id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, parent_id INTEGER UNSIGNED DEFAULT NULL, title VARCHAR(100) NOT NULL, valid TINYINT(1) UNSIGNED NOT NULL D
CREATE TABLE image_categories (
cat_id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
parent_id INTEGER UNSIGNED DEFAULT NULL,
title VARCHAR(100) NOT NULL,
valid TINYINT(1) UNSIGNED NOT NULL DEFAULT 1,
PRIMARY KEY(cat_id),
FOREIGN KEY (parent_id)
REFERENCES image_categories(cat_id)
);
CREATE TABLE image_gallery (
img_id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
cat_id INTEGER UNSIGNED NOT NULL,
fname CHAR(45) NOT NULL,
title VARCHAR(100) DEFAULT NULL,
description VARCHAR(256) DEFAULT NULL,
create_date DATETIME NOT NULL,
valid TINYINT(1) UNSIGNED NOT NULL DEFAULT 1,
PRIMARY KEY(img_id),
FOREIGN KEY (cat_id)
REFERENCES image_categories(cat_id)
);
与文件树目录类似,类别类似于文件夹,因为它们可以有子目录,而这些子目录可以有更多的子目录,从而创建无限层次结构
给定一个特定的cat_id
,我可以按如下方式提取图像:
$sql = "SELECT * FROM image_gallery WHERE cat_id = :cat_id AND valid = TRUE";
$sth = $this->db->prepare($sql);
$sth->execute(array(':cat_id' => $cat_id));
$images = array();
while ($row = $sth->fetch(PDO::FETCH_ASSOC)) {
$images[$row['img_id']]['cat_id'] = $row['cat_id'];
$images[$row['img_id']]['fname'] = $row['fname'];
$images[$row['img_id']]['title'] = $row['title'];
$images[$row['img_id']]['description'] = $row['description'];
$images[$row['img_id']]['create_date'] = $row['create_date'];
$images[$row['img_id']]['valid'] = $row['valid'];
}
然而,我想做的是,除了任何子类别之外,还拉取指定类别的图像,直到找不到更多的子类别
我如何才能取得这些成果?使用修改后的查询或某种类型的递归函数?您必须检查代码,但类似的操作应该允许您显示父类别的图像。首先,将所有相关类别ID保存到一个数组中:
function get_cat_id($parent_id) {
$sql = "SELECT cat_id FROM image_categories WHERE parent_id = :parent_id AND valid = TRUE";
$sth = $this->db->prepare($sql);
$sth->execute(array(':parent_id' => $parent_id));
$category = $sth->fetch(PDO::FETCH_ASSOC);
if ($sth->rowCount() > 0) {
return $category['cat_id'];
} else {
return FALSE;
}
}
$cat_ids = array();
$parent_id = $cat_id; /* This is the $cat_id you are using now... */
while ($cat_id = get_cat_id($parent_id)) {
$cat_ids[] = $cat_id;
$parent_id = $cat_id;
}
然后,修改SQL查询(您可以在这里看到一个示例):
编辑:对不起,我的代码只抱怨一个子类别。只需将函数get_cat_id和while循环替换为以下代码。我对它进行了测试,我认为它可能会起作用:
function get_subcategories($parent_id) {
global $cat_ids;
$sth = $this->db->prepare($sql);
$sth->execute(array(':parent_id' => $parent_id));
$categories = $sth->fetchAll(PDO::FETCH_ASSOC);
foreach ($categories as $category) {
$cat_ids[] = $category['cat_id'];
get_subcategories($category['cat_id']);
}
}
/* This is the $cat_id you are using now... */
$cat_ids = array($cat_id);
get_subcategories($cat_id);
代码的其余部分(IN子句)不会改变。在每个
cat\u id
中添加一个parent\u id
,然后当您检查cat\u id
时,您可以通过引用其“parent”来查找该id的任何“children”。对于这种查询行为,我不相信您的模式(邻接列表)将允许您有效地查询树结构(您需要使用一个固定的深度,或者递归地查询,直到您理解所讨论的整个路径)。我认为您需要采用嵌套集方法。请参阅这篇优秀的文章进行讨论-特别要注意“检索单一路径”部分,因为这本质上是确定查询图像的类别所要做的,但是,示例中的get\u cat\u id
函数没有考虑到父级可能有多个子级。修复后,while
循环方法不再有效。我编辑了我的答案,其中包含了一个新的函数来实现这一点。谢谢,我根据您的示例提出了一个解决方案,主要区别在于我通过引用传递$cat_id
,而不是将其声明为全局。这可能不是最优雅的解决方案,但它确实有效!我还认为通过引用传递var比将其声明为全局要好得多。我很高兴它起作用了。
function get_subcategories($parent_id) {
global $cat_ids;
$sth = $this->db->prepare($sql);
$sth->execute(array(':parent_id' => $parent_id));
$categories = $sth->fetchAll(PDO::FETCH_ASSOC);
foreach ($categories as $category) {
$cat_ids[] = $category['cat_id'];
get_subcategories($category['cat_id']);
}
}
/* This is the $cat_id you are using now... */
$cat_ids = array($cat_id);
get_subcategories($cat_id);