Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Tworzenie tablic i funkcja eval
PiotrekM
post 25.04.2011, 12:06:04
Post #1





Grupa: Zarejestrowani
Postów: 130
Pomógł: 6
Dołączył: 20.12.2009

Ostrzeżenie: (0%)
-----


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 :|
Go to the top of the page
+Quote Post
zeulus
post 25.04.2011, 14:42:05
Post #2





Grupa: Zarejestrowani
Postów: 25
Pomógł: 3
Dołączył: 17.05.2004
Skąd: Nowhere Land

Ostrzeżenie: (0%)
-----


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".


--------------------
Google prawdę mówi, względów się wyrzeka...
Go to the top of the page
+Quote Post
PiotrekM
post 25.04.2011, 14:47:28
Post #3





Grupa: Zarejestrowani
Postów: 130
Pomógł: 6
Dołączył: 20.12.2009

Ostrzeżenie: (0%)
-----


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ć :/
Go to the top of the page
+Quote Post
zeulus
post 25.04.2011, 21:44:33
Post #4





Grupa: Zarejestrowani
Postów: 25
Pomógł: 3
Dołączył: 17.05.2004
Skąd: Nowhere Land

Ostrzeżenie: (0%)
-----


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


--------------------
Google prawdę mówi, względów się wyrzeka...
Go to the top of the page
+Quote Post
PiotrekM
post 25.04.2011, 22:44:35
Post #5





Grupa: Zarejestrowani
Postów: 130
Pomógł: 6
Dołączył: 20.12.2009

Ostrzeżenie: (0%)
-----


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.

Ten post edytował PiotrekM 25.04.2011, 22:45:42
Go to the top of the page
+Quote Post
Bags_Bunny
post 25.04.2011, 22:54:02
Post #6





Grupa: Zarejestrowani
Postów: 262
Pomógł: 39
Dołączył: 12.04.2004

Ostrzeżenie: (0%)
-----


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.


--------------------
rm -rf /*
Go to the top of the page
+Quote Post
PiotrekM
post 26.04.2011, 08:58:41
Post #7





Grupa: Zarejestrowani
Postów: 130
Pomógł: 6
Dołączył: 20.12.2009

Ostrzeżenie: (0%)
-----


problem w tym, że ja nie chce odszukać, tylko utworzyć klucz :/
Go to the top of the page
+Quote Post
Bags_Bunny
post 26.04.2011, 09:53:43
Post #8





Grupa: Zarejestrowani
Postów: 262
Pomógł: 39
Dołączył: 12.04.2004

Ostrzeżenie: (0%)
-----


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


--------------------
rm -rf /*
Go to the top of the page
+Quote Post
thek
post 26.04.2011, 11:33:16
Post #9





Grupa: Moderatorzy
Postów: 4 362
Pomógł: 714
Dołączył: 12.02.2009
Skąd: Jak się położę tak leżę :D




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


--------------------
Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 19.07.2025 - 04:16