这个函数给了我一个无限循环
function getCats($parent,$level){
// retrieve all children of $parent
$result = "";
$query = "SELECT title,parent_id from t_cats where parent_id = '$parent'";
if($rs = C_DB::fetchRecordset($query)){
while($row = C_DB::fetchRow($rs)){
$result .= str_repeat($parent,$level).$row['title']."\n";
getCats($row['parent_id'],$level+1);
}
}
return $result;
}
这是我的数据库表
CREATE TABLE `db`.`t_cats` (
`ID` int(10) unsigned NOT NULL auto_increment,
`datasource_id` int(10) unsigned default '0',
`version` char(10) character set latin1 default 'edit',
`status` char(10) character set latin1 default 'new',
`modified_date` datetime default NULL,
`modified_by` int(10) unsigned default '0',
`title` char(255) character set latin1 default NULL,
`parent_id` int(11) default NULL,
PRIMARY KEY (`ID`),
KEY `idx_datasource_id` (`datasource_id`)
) ENGINE=MyISAM AUTO_INCREMENT=50 DEFAULT CHARSET=utf8;
我只是希望能够递归我的类别列表。
但是我做错了什么?
修改
function getCats($parent,$level){
// retrieve all children of $parent
$result ="";
$query = "SELECT title,parent_id from t_cats where parent_id = '$parent'";
if($rs = C_DB::fetchRecordset($query)){
while($row = C_DB::fetchRow($rs)){
$result.= str_repeat($parent,$level).$row['title']."\n";
getCats($row['id'],$level + 1 );
}
}
return $result;
}
答案 0 :(得分:5)
这一行看起来不对:
getCats($row['parent_id'],$level+1);
您应该使用当前子ID调用它 - 在您使用相同的ID一遍又一遍地调用它时。这样的事情(你需要从表中选择id):
getCats($row['id'], $level + 1);
修改:您需要更新查询以选择id
:
$query = "SELECT id, title, parent_id from t_cats where parent_id = '$parent' AND id != parent_id";
如果一个项目是它自己的父项,我还添加了一点来阻止它进入循环。
答案 1 :(得分:2)
我发现这篇关于“Storing Hierarchical Data in a Database”的SitePoint文章非常有帮助。这是所有PHP示例,它将提高您正在尝试显着的性能。
答案 2 :(得分:1)
也许数据库中的一个项目本身就是父项?
答案 3 :(得分:0)
我不知道C_DB,但我敢打赌fetchrecordset返回的$ rs是一个引用,这意味着每次调用getCats都使用相同的$ rs。它究竟会做什么是不可预测的,这取决于fetchRow的实现方式。
如果你想这样做(并且我知道,递归闭包很麻烦),你应该在getCats中打开一个新连接。并为每次访问使用单独的连接。
答案 4 :(得分:0)
greg提供的正确答案......
2旁注:
在无限循环的情况下,跟踪递归深度(这里可以方便地使用$level
)或整体调用计数(如果你是懒惰的,因为这是访问全局计数器的oneliner),并且当一个异常达到一个最大值时(通常,10已经足以看到问题,但当然可能会有所不同)终止递归,然后得到一些调试输出...例如{{1}或类似$query
之类的东西......在这种情况下会立刻向你展示问题......:)
你应该尽可能减少查询量...遍历这样的树是非常低效的......尤其是,如果数据库在另一台机器上......
格尔茨
back2dos
答案 5 :(得分:-1)
$query = "SELECT title,parent_id from t_cats where id = '$parent'";
而不是:
$query = "SELECT title,parent_id from t_cats where parent_id = '$parent'";