php sonsuz döngü

6 Cevap php

Bu fonksiyon, bana sonsuz bir döngü verir

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

burada benim db tablo

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;

Ben sadece özyinelemeli kategorilerin listemi elde edebilmek istiyorum.

Ama ne yanlış yapıyorum?


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 Cevap

Bu çizgi yanlış görünüyor:

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

Sen geçerli alt kimliği ile çağrı olmalıdır - anda ve üzerinde aynı kimliğe sahip diyorlar. Böyle bir şey (Eğer tablodan id seçmek gerekir):

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

Düzenleme: seçmek için sorguyu güncelleştirmek gerekir id:

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

Ben de bir öğesi kendi ebeveyn ise, bir döngü içine almak durdurmak için biraz ekledik.

Ben "Storing Hierarchical Data in a Database" çok yararlı Bu SitePoint makale bulundu. Tüm PHP örnekler, ve bu dramatically yapmaya çalışıyoruz ne performansını artıracaktır.

Belki db öğelerden biri ebeveyn olarak kendini var?

Ben C_DB bilmiyorum, ama ben fetchrecordset tarafından döndürülen $ rs getCats her çağırma aynı $ rs kullanıyor demektir ki, bir referans olduğunu bahse girerim. Tam olarak ne yapacağız o zaman fetchRow nasıl uygulanır bağlı olarak önceden kestirilemez.

Eğer (ve özyinelemeli kapanışları biliyorum, SQL bir ağrı vardır) bunu yapmak istiyorsanız, getCats içinde yeni bir bağlantı açmak gerekir. ve her erişim için ayrı bir bağlantı kullanıyor olması.

greg tarafından sağlanan doğru cevap ...

2 yan notlar:

  1. sonsuz döngü, parça yineleme derinliği (tembel ise bu küresel bir sayaç erişen bir oneliner olduğundan,) ya da genel çağrı sayısı (size uygun $level burada kullanabilirsiniz), ve bir özyineleme ile sonlandırmak durumunda istisna, o (genel olarak, 10 zaten sorunu görmek için yeterli, ama tabii ki değişebilir) ... ve daha sonra örneğin ... bazı hata ayıklama çıktısını almak bir maksimum değere ulaştığı zaman $query veya gibi bir şey "calling getCats($parent,$level)" ... bu durumda hiçbir zaman size sorun göstermiştir olurdu ... :)

  2. Eğer veritabanı başka bir makinede olduğu takdirde, oldukça verimsiz ... özellikle gibi bir ağaç geçme ... sorgularının miktarını en aza indirmek gerekir ...

Erm olmamalı:

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

Ve:

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