Здравствуйте, натолкните на мысль по реализации. Задача такова. Есть элементы, у которых есть массив родителей Код (Text): Элемент 4 ( [0] => Элемент 1 [1] => Элемент 2 [2] => Элемент 3 ) Код (Text): Элемент 6 ( [0] => Элемент 1 [1] => Элемент 2 [2] => Элемент 5 ) Должно выглядеть это так: Код (Text): Элемент 1--Элемент 2--Элемент 3--Элемент 4 | Элемент 5 -- Элемент N | Элемент 6 Вложенность неизвестна. Как зная что родитель элемента 6 - элемент 5 добавить к нему потомка, ведь мы не знаем полный путь? Или как найти полный путь к текущему элементу? Заранее спасибо.
что же вы такие ленивые то, не ищите нифига, перед тем как темы клепать. http://www.php.ru/forum/viewtopic.php?f=2&t=41345
А я разве что-то писал о MySQL? Причем тут Nested sets? Пытался обойти массив через array_walk_recursive, сравнивая текущий ключ с известным родителем, но не знаю как положить элемент в нужное место, а на сервере с php 5.4 нельзя использовать ссылки, да с вложенными массивами он не работает... Добавлено спустя 35 минут 55 секунд: Немного упрощу. Дано: Код (Text): $hierarchy = array( 'Элемент 1'=>array( 'Элемент 2'=>array(), 'Элемент 3'=>array(), ), ); $element = 'Элемент 4'; $parent = 'Элемент 3'; Надо пройтись по массиву $hierarchy и получить такое: Код (Text): $hierarchy = array( 'Элемент 1'=>array( 'Элемент 2'=>array(), 'Элемент 3'=>array( 'Элемент 4'=>array() ), ), );
Советую написать класс узла, а там дальше использовать рекурсивный поиск и добавление новых элементов.
По сути ваша задача к поиску элемента в дереве и добавления к нему листа, теория графов. Мне эти пары не нравились, потому что были скучными, и я ничерта не запомнил Накатал маленько, посмотрите (в листинге все объяснено и вроде бы предельно понятно Код (PHP): <?php class Element { public $name; public $father; public $sons; public function __construct($n, $f = false) { $this->name = $n; $this->father = $f; $this->sons = array(); if($f !== false) { $f->addSon($this); } } public function addSon($t) { array_push($this->sons, $t); } } // функция принимает имя для поиска и стартовый элемент. обход по детям function SearchByName($sname, Element $elem) { if($elem->name == $sname) { return $elem; } else { foreach($elem->sons as $val) { return SearchByName($sname, $val); } } } /* Ситуация такая: 1 - самый главный папочка, 2, 3, 4 - его дети, причему 2 есть дети: 5 и 6, а у 3 - сынок 7. Пусть у нас есть непосредственная ссылка на главного папочку, $god Хотим заделать ребеночка элементу 7 с именем Новорожденный. */ $list = array(); $list['a'] = new Element('1'); // Отец Всех на Свете $list['b'] = new Element('2', $list['a']); $list['c'] = new Element('3', $list['a']); $list['d'] = new Element('4', $list['a']); $list['e'] = new Element('5', $list['b']); $list['f'] = new Element('6', $list['b']); $list['g'] = new Element('7', $list['c']); $god = $list['a']; $found = SearchByName('7', $god); $littleboy = new Element('Новорожденный', $found);
Долго ковырялся с ссылками, но вроде получилось с массивами, как вы описывали в своем посте Код (PHP): <?php $content = array ( '1' => array ( '2' => array ( '7' => array(), ), '3' => array(), ), '4' => array ( '5' => array(), ), '6' => array(), ); /* нулевое поколение пусто первое поколение 1 4 6 второе поколение 2 3 5 третье поколение 7 */ function &SearchByName($sname, &$array) { if($array != false) { foreach($array as $key => $val) { if($key == $sname) { return $array[$key]; } else { return SearchByName($sname, $array[$key]); } } } else { return false; } } $found = &SearchByName('7', $content); $found['8'] = array(); print_r($content); Амперсанды перед функцией означают, что функция вернет ссылку на элемент. Амперсанды перед массивом - ну понятно
Все чуть чуть сложнее. Если бы были ссылки, все элементарно делается через array_walk_recursive, но на сервере php 5.4, где передача по ссылке уже убрана...
странно, но работаеть ведь: Код (PHP): % php --version PHP 5.4.4--pl0-gentoo (cli) (built: Jun 15 2012 11:01:47) Copyright (c) 1997-2012 The PHP Group Zend Engine v2.4.0, Copyright (c) 1998-2012 Zend Technologies % cat shit.php <?php function foo(&$var) { $var++; } $a = 5; foo($a); echo $a . "\n"; % php shit.php 6 кто-то обманывает, ибо Call-time pass by reference это несколько другой случай
ZeiN, а кто вообще сказал, что ссылки отменены или что их собираются отменять? Не слышал такого. И на оф. сайте - никакой информации об этом не вижу. Вроде никто и не собирался отменять ссылки...
php сказал Код (Text): Fatal error: Call-time pass-by-reference has been removed in /path/test.php on line 11
как нада: Код (PHP): function myFunc(&$arg) { } myFunc($var); как НЕ нада: Код (PHP): function myFunc($arg) { } myFunc(&$arg); вот второй пример и есть call-time pass-by-reference.