Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Tworzenie tablic i funkcja eval
Forum PHP.pl > Forum > PHP
PiotrekM
Witam,
piszę sobie klasę, do generowania drzewek, ale mam problem. Mam funkcję, która wyszukuje mi rodziców. np: Rodzic <- dziecko <- młodsze dziecko
chcę z takiej hierarchii utworzyć tablice. $arr['rodzic']['dziecko']['mlodsze dziecko'] = array().

Funkcja zwraca mi moją hierarchię gotową, by wpleść ją w tablice
  1. 'rodzic']['dziecko']['mlodsze dziecko'

bez [ oraz ]

wszystko fajnie, ale jak mogę z tego zrobić tablicę? eval!
  1. $toParents = $this -> getParents($tree, $name);
  2. eval("$this -> structure[$tree][$toParents] = array()");

i co? błąd!
kohany wyjątek
Cytat
ErrorException [ Recoverable Error ]: Object of class Trees could not be converted to string

ze wskazaniem na eval
jeśli dam na sztywno
  1. eval("$this -> structure['menu']['rodzic']['dziecko']['mlodsze dziecko] = array()");
[/php] to dalej widzę błąd, lecz bez eval - błąd znika :|
zeulus
eval()? Naprawdę nie widzisz żadnego innego sposobu? Żadnego? Jeżeli już korzystasz z obiektowości warto byłoby mieć rozwiązanie, które nie korzysta z eval. Eval to zło.

Jeżeli chodzi o odpowiedź stricte na Twoje pytanie - parser mówi Ci, że nie może przekonwertować obiektu do stringa - ale nie masz tam konwersji obiektu.. prawda? Może jednak masz? "$this -> blabla()" spójrz w dokumentację, może jedna trzeba użyć nawiasów klamrowych (dokumentacja).

BTW, w przykładzie, który podałeś na końcu, brakuje jednego nawiasu ' po "młodsze dziecko".
PiotrekM
próbowałem używać nawiasów klamrowych, lecz nie pomogło.
Cytat
BTW, w przykładzie, który podałeś na końcu, brakuje jednego nawiasu ' po "młodsze dziecko".

parser ipb usunął, nie wiedzieć czemu?

nie mam pomysłu jakby można to inaczej obsłużyć :/
zeulus
Gdzieś to menu masz zdefiniowane. Gdzieś ten string jest generowany. Dlaczego, zamiast generować stringa nie utworzysz od razu tej tablicy? Trochę nie rozumiem tej koncepcji i dlatego ciężko jest cokolwiek pomóc. Aczkolwiek wiem jedno - można to zrobić na pewno i to bez użycia eval. Chociażby zamiast stringa zwracając tablicę z trzema elementami i zrobić list($rodzic, $dziecko, $ml_dziecko) = $this->getParents(), a następnie $this->struktura[$rodzic][$dziecko][$ml_dziecko] = array();. Nie używaj eval(), w ogóle smile.gif
PiotrekM
to czym piszesz nie ma sensu, jeżeli dla będzie 10 poziomow, to co?
moja koncepcja ma generować sama tablie wielopoziomową... tylko eval mi na myśl przychodzi.
Bags_Bunny
http://kohanaframework.org/3.0/guide/api/Arr#path

A taki kod sobie napisałem przed wielu laty:

  1. public static function arrayPath(array $array, array $path, $data = null)
  2. {
  3. if(($count = count($path)) == 0)
  4. {
  5. return $array;
  6. }
  7. elseif($count === 1)
  8. {
  9. if($data === null)
  10. {
  11. $tmp = $data[$path[0]];
  12. }
  13. else
  14. {
  15. $array[$path[0]] = $data;
  16. }
  17. }
  18. elseif($count > 1)
  19. {
  20. $tmp = &$array;
  21.  
  22. foreach($path as $item)
  23. {
  24. if(!isset($tmp[$item]) || !is_array($tmp))
  25. {
  26. if($data === null)
  27. {
  28. return false;
  29. }
  30. else
  31. {
  32. $tmp[$item] = array();
  33. }
  34. }
  35.  
  36. $tmp = &$tmp[$item];
  37. }
  38.  
  39. if($data !== null)
  40. {
  41. $tmp = $data;
  42. }
  43. }
  44.  
  45. return $data === null ? $tmp : $array;
  46. }


Może to nie są perfekcyjne rozwiązania, ale jak widać można się dostać do dowolnego elementu tablicy bez eval.
W sumie teraz średnio mi się to podoba i bym to zrobił inaczej, ale działać - działa.
PiotrekM
problem w tym, że ja nie chce odszukać, tylko utworzyć klucz :/
Bags_Bunny
To żadna różnica. Jak umiesz znaleźć, to i umiesz utworzyć. Moja metoda, o ile pamiętam, robi i jedno i drugie. Chyba coś takiego:
  1. $sciezka = array( 'rodzic', 'dziecko', 'mlodsze dziecko' );
  2. $tablica = arrayPath( $tablica, $sciezka, $wartosc_do_przypisania )

Zupełnie bez sensu, muszę to przepisać wink.gif
thek
Pytanie... Czy w tym drzewku może dziecko mieć wielu rodziców czy tylko jednego? Poza tym skoro się interpreter burzy, że nie może stworzyć z obiektu stringa, to czemu nie użyjesz magii w tym wypadku? __toString() wink.gif Zdefiniuj sobie tę metodę. Choć ja osobiście użyłbym rekurencji. W funkcji przekazującej strukturę, budowałbym ją. Na jej poziomie bowiem ładnie wiemy co jest dzieckiem czego i jaki efekt? Przypuśćmy, że mamy: rodzic->dziecko->wnuczek, więc robimy:
1. $arr[] = array();
2. Sprawdzamy czy mamy potomka. Jeśli nie to zwrot tablicy.
3. Jeśli tak to tworzymy w rodzicu element o nazwie dziecka i przypisujemy mu array();
4. Wracamy do 2.

Jaki efekt? proszę zobaczyć smile.gif Może niezbyt ładnie napisane ale o to lotto wink.gif
  1. <?php
  2. $sciezka = '[rodzic][dziecko][wnuczek][prawnuczek][praprawnuczek][prapraprawnuczek]'; //przyjąłem jako bazowy string z nazwami, bo nie wiedziałem jak Ty masz to rozwiązane
  3. $sciezka = substr( $sciezka, 1, -1); //usuwamy pierwszy i ostatni znak nawiasu ze stringa - są zbędne
  4. $sciezka = explode( '][', $sciezka ); //robimy z tego co zostało płaską tablicę, gdzie kolejne elementy to zagnieżdżenia
  5. var_dump( $sciezka ); //sam zobacz jak ta tablica wygląda
  6. function make_arr( $tab, $index = 0 ) { //parametrami są tablica uzyskana i index kolejnego elementu (do rekurencji)
  7. if( array_key_exists( $index+1, $tab ) ) { //sprawdzamy czy jest następny element...
  8. return array( $tab[ $index ] => make_arr( $tab, $index+1 ) ); //jeśli tak to zwracamy obecny element z rekurencją kolejnego :)
  9. } else {
  10. if( array_key_exists( $index, $tab ) ) { //jeśli nie to sprawdzamy czy ktoś nie przeskoczył sobie tablicy i...
  11. return array( $tab[ $index ] => array() ); //...jeśli nie to zwracamy pustą tablicę...
  12. } else {
  13. throw new Exception( 'Index out of bound!' ); //...albo rzucamy wyjątek :)
  14. }
  15. }
  16. }
  17. $result = null; //ustawiamy zmienną
  18. try {
  19. $result = make_arr( $sciezka, 8 ); //to powinno rzucić wyjątek, bo w przykładzie index osiąga góra 5
  20. } catch (Exception $e) {
  21. echo 'Exception caught: ', $e->getMessage(), "\n";
  22. }
  23. var_dump( $result );
  24. $result = null;
  25. try {
  26. $result = make_arr( $sciezka, 3 ); //to powinno stworzyć tablice licząc od $index = 3 do 5, a więc od prawnuczka do prapraprawnuczka
  27. } catch (Exception $e) {
  28. echo 'Exception caught: ', $e->getMessage(), "\n";
  29. }
  30. var_dump( $result );
  31. $result = null;
  32. try {
  33. $result = make_arr( $sciezka ); //a to zrobi tablicę od rodzica, roota
  34. } catch (Exception $e) {
  35. echo 'Exception caught: ', $e->getMessage(), "\n";
  36. }
  37. var_dump( $result );


Zapomniałem dodac co dostajemy w wyniku wink.gif
Kod
array
  0 => string 'rodzic' (length=6)
  1 => string 'dziecko' (length=7)
  2 => string 'wnuczek' (length=7)
  3 => string 'prawnuczek' (length=10)
  4 => string 'praprawnuczek' (length=13)
  5 => string 'prapraprawnuczek' (length=16)

Exception caught: Index out of bound!

null

array
  'prawnuczek' =>
    array
      'praprawnuczek' =>
        array
          'prapraprawnuczek' =>
            array
              empty

array
  'rodzic' =>
    array
      'dziecko' =>
        array
          'wnuczek' =>
            array
              'prawnuczek' =>
                array
                  'praprawnuczek' =>
                    array
                      'prapraprawnuczek' =>
                        array
                          empty
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.