php无限循环

php无限循环,php,recursion,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 =

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

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;
} 
这是我的db表

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;
    } 
这一行看起来不对:

getCats($row['parent_id'],$level+1);
您应该使用当前的子ID调用它-此时您正在使用相同的ID反复调用它。类似这样的内容(您需要从表中选择id):

编辑:您需要更新查询以选择
id

$query = "SELECT id, title, parent_id from t_cats where parent_id = '$parent' AND id != parent_id";

我还添加了一点,以防止在某个项是它自己的父项时它进入循环。

我不知道C_DB,但我敢打赌fetchrecordset返回的$rs是一个引用,这意味着每次调用getCats都使用相同的$rs。它将执行的操作是不可预测的,具体取决于fetchRow的实现方式


如果您想这样做(我知道递归闭包是SQL中的一个难题),您应该在getCats中打开一个新连接。并为每个访问使用单独的连接

数据库中的某个项目本身可能是父项?

呃,它不应该是:

$query = "SELECT title,parent_id from t_cats where id = '$parent'";
而不是:

$query = "SELECT title,parent_id from t_cats where parent_id = '$parent'";

我发现这篇关于“”的SitePoint文章非常有用。这些都是PHP示例,它将显著提高您尝试执行的操作的性能。

greg提供的正确答案

2旁注:

  • 在无限循环的情况下,跟踪递归深度(您可以在这里方便地使用
    $level
    )或整体调用计数(如果您是惰性的,因为这是一个访问全局计数器的单行程序),并在递归达到最大值时,异常终止递归(一般来说,10已经足以看到问题,但这当然可能会有所不同)…然后获得一些调试输出…例如
    $query
    或类似
    “调用getCats($parent,$level)”
    …在这种情况下会立即向您显示问题…:)

  • 您应该尽量减少查询量。。。像那样遍历一棵树效率很低。。。特别是,如果数据库在另一台计算机上

  • 格里茨


    back2dos

    这个:getCats($row['parent_id',$level++);也以无限循环结束。这是正确的答案。抱歉,我的快速反应和没有完全阅读代码。抱歉,但仍然是无限循环。
    id!=parent_id
    很好,但实际上,在插入时应该以某种方式加以控制……感谢您的反应,我决定尝试修改的前序树遍历模型。这种方法对于数据库来说似乎更好,而对于应用程序来说则更轻。无论如何谢谢你!显示一些示例数据,数据可能是问题所在。我不认为这是真正的递归。对我来说没有意义。如果您检索父id,然后根据它查询行,那么它显然是递归的。i、 e.如果我确实从一个where Id=1中选择了*,然后检索该Id并继续从一个where Id=1调用select*,我每次都会得到相同的行。这似乎是正在发生的事情,只是父母的id。我累了,所以可能我错过了什么。我现在正在努力解决这个问题。刚刚开始一个新问题,关于如何在
      $query = "SELECT title,parent_id from t_cats where parent_id = '$parent'";