Geçenlerde benzer kubbe şey tek bir sorgu ve tek bir döngü while kullanarak ettik. Bu, düz bir (dizi) vasıtasıyla bir ağaç veri yapıları (dizi) oluşturmak için başvurular kullanır. Ben bunun için bir ihtiyaç olduğunu hissettim çünkü dahil hiçbir SPL yok. a gist on GitHub a> iyi bir renk düzeni ile var :)
/**
* Each element in the return array has a 'data' key, holding category data,
* like name, and a 'children' key holding its subcategories.
*
* @param resource $resource MySQL resource resulted from mysql_query
* @param string $id_key Name of the 'id' field
* @param string $parent_id_key Name of the 'parent_id' field
* @param boolean $use_cache Use cached result from previous calls. Defaults to TRUE
* @return array
*/
function categories($resource, $id_key, $parent_id_key, $use_cache = true) {
// Cache the categories in a static local variable. This way, the query
// will be executed just for the first function call. Subsequent calls
// will return imediatelly, unless you tell it not to.
static $tree = array();
if ($tree && $use_cache) {
return $tree;
}
// Flat representation of the categories for fast retrieval using array
// keys. Each element will be referenced in the $tree array. This
// allows to build a tree data structure using a flat one.
$flat = array();
// Reset the $tree, in case $use_cache=false in a subsequent call
$tree = array();
while ($row = mysql_fetch_object($resource)) {
$flat[$row->$id_key] = array(
'data' => $row,
'children' => array(),
);
if (array_key_exists($row->$parent_id_key, $flat)) {
// Assign children by reference so that possible subcategories of
// this one will appear in the tree structure ($tree)
$flat[$row->$parent_id_key]['children'][] =& $flat[$row->$id_key];
}
if ($row->$parent_id_key == 0) {
// Assign by reference for synchronizing $flat with $tree;
$tree[] =& $flat[$row->$id_key];
}
}
return $tree;
}
Ayrıca, işlev veritabanının yapısından ayrılmış edilir. Bunu bir mysql_query kaynak, id alanını temsil eden bir dize ve parent_id alanını temsil eden bir dize geçmek gerekir. Kötü kısmı mysql_fetch_object bir çağrı kullanır çünkü PHP mysql uzantısı bağlanmış olmasıdır. Muhtemelen geliştirilebilir.
Diğer bazı avantajı dördüncü (boolean) parametresi önbelleği, geçersiz kılmak için bunu söylemek sürece, sonucu aramalar için sonuç önbelleğe olmasıdır.
Bir göz atın ve size yardımcı olmadığını görmek.