php无限循环

时间:2009-08-19 15:07:51

标签: php recursion

这个函数给了我一个无限循环

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;
    } 

6 个答案:

答案 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旁注:

  1. 在无限循环的情况下,跟踪递归深度(这里可以方便地使用$level)或整体调用计数(如果你是懒惰的,因为这是访问全局计数器的oneliner),并且当一个异常达到一个最大值时(通常,10已经足以看到问题,但当然可能会有所不同)终止递归,然后得到一些调试输出...例如{{1}或类似$query之类的东西......在这种情况下会立刻向你展示问题......:)

  2. 你应该尽可能减少查询量...遍历这样的树是非常低效的......尤其是,如果数据库在另一台机器上......

  3. 格尔茨

    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'";