PHP бесконечный цикл - PullRequest
       11

PHP бесконечный цикл

0 голосов
/ 19 августа 2009

Эта функция дает мне бесконечный цикл

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;

Я просто хочу получить рекурсивный список категорий.

Но что я делаю не так?


EDIT:

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 ]

5 голосов
/ 19 августа 2009

Эта строка выглядит неправильно:

getCats($row['parent_id'],$level+1);

Вы должны звонить с текущим дочерним идентификатором - в тот момент, когда вы звоните с одним и тем же идентификатором снова и снова. Примерно так (нужно выбрать идентификатор из таблицы):

getCats($row['id'], $level + 1);

Редактировать: вам нужно обновить ваш запрос, чтобы выбрать id:

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

Я также добавил немного, чтобы он не попадал в цикл, если элемент является его собственным родителем.

2 голосов
/ 19 августа 2009

Я нашел эту статью SitePoint " Хранение иерархических данных в базе данных " очень полезной. Это все примеры PHP, и это улучшит производительность того, что вы пытаетесь сделать значительно .

1 голос
/ 19 августа 2009

Может быть, один из элементов в БД имеет себя в качестве родителя?

0 голосов
/ 19 августа 2009

правильный ответ предоставлен Грег ...

2 примечания:

  1. в случае бесконечных циклов, отслеживать глубину рекурсии (вы можете удобно использовать $level здесь) или общее количество вызовов (если вы ленивы, так как это единый доступ к глобальному счетчику) и завершить рекурсию за исключением случаев, когда оно достигает максимального значения (в общем случае 10 уже достаточно, чтобы увидеть проблему, но, конечно, это может варьироваться) ... и затем получить некоторый вывод отладки ... например $query или что-то вроде "calling getCats($parent,$level)" ... в этом случае мгновенно показал бы вам проблему ...:)

  2. вам следует минимизировать количество запросов ... обход такого дерева весьма неэффективен ... особенно, если база данных находится на другом компьютере ...

Greetz

back2dos

0 голосов
/ 19 августа 2009

Эмм, не должно быть:

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

А не:

$query = "SELECT title,parent_id from t_cats where parent_id = '$parent'";
0 голосов
/ 19 августа 2009

Я не знаю C_DB, но могу поспорить, что $ rs, возвращаемый fetchrecordset, является ссылкой, что означает, что при каждом вызове getCats используются одни и те же $ rs. То, что он будет делать, непредсказуемо, в зависимости от того, как реализован fetchRow.

Если вы хотите сделать это (и я знаю, что рекурсивные замыкания являются проблемой в SQL), вам следует открыть новое соединение внутри getCats. и использовать отдельное соединение для каждого доступа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...