2013-09-05 12 views
9

Po prostu chcę się upewnić, że robię to dobrze, a to nie spowoduje żadnych konflik.Funkcja rekurencyjna: wywołaj samą funkcję php.

Mam funkcję, która wywołuje samą siebie i wymaga Twojej zgody, jeśli jest ona poprawna lub nie?

<?php 

function determine($the_array){ 
    foreach ($the_array as $key => $value) { 
     switch ($key) { 
      case 'in': 
        echo $value; 
       break; 

      case 'out': 
        echo $value; 
       break; 

      case 'level': 
        echo '<ul>'; 
        determine($value); 
        echo '</ul>'; 
       break; 

     } 
    } 

} 

Jest to tablica:

$the_array = array(
    'in' => '<li>Simple IN</li>', 
    'out' => '<li>Simple OUT</li>', 
    'level' => array(
      'in' => '<li>Simple IN 2</li>', 
      'out' => '<li>Simple OUT 2</li>', 
      'level' => array(
       'in' => '<li>Simple IN 3</li>', 
       'out' => '<li>Simple OUT 3</li>' 
      ), 
     ), 
); 

A oto końcowy startowych:

echo '<ul>'; 
determine($the_array); 
echo '</ul>'; 

Wynik jest po prostu jak chciałem być, to działa świetnie, ale ja don nie wiem, czy to dobra praktyka.

Odpowiedz

26

Funkcje rekurencyjne są OK - ale niebezpieczne, jeśli nie jesteś pewien, że wiesz, co robisz. Jeśli jest jakakolwiek szansa, że ​​dana funkcja znajdzie się w pętli rekursywnej (w której ciągle się powtarza), albo skończy się limit czasu, skończy się pamięć, albo wywoła apokalipsę zombie.

Pomyśl o rekursywnych połączeniach jako naprawdę, naprawdę ostrym nożu - w rękach doświadczonego szefa kuchni, to połączenie wykonane w niebie, w rękach zmywarki, to zagubiony palec, który czeka, aby się wydarzyć.

PHP próbuje grać ładnie i ogranicza domyślną głębokość rekursywną do 100 (choć można to zmienić), ale prawie we wszystkich przypadkach, jeśli głębokość rekursywna osiągnie 100, wypadek już się zdarzył i PHP reaguje zatrzymując się wszelkich dodatkowych pieszych od błądzenia do ruchu. :)

+2

Lub krótszy: funkcje rekurencyjne nie są złą praktyką. :) – Virus721

+1

@ Virus721 Tak i nie, jeśli nie wiesz, co robisz, to one są Złą praktyką :) – Fluffeh

+1

Zła praktyka w tym przypadku polega na tym, żeby nie wiedzieć, co robisz, a nie używać funkcja rekursywna. – Virus721

3

Fluffeh dostarczył wystarczającą odpowiedź, jeśli chodzi o funkcje rekurencyjne. Ale używając rekursji z dużymi tablicami/obiektami/etc, powinieneś obserwować optymalizację swojego kodu, tak aby nie trzeba było dużo pamięci ani mocy procesora do wykonania.

Możesz z łatwością optymalizować kod, aby był czystszy, zajmował mniej pamięci i był bardziej odporny na nieoczekiwane dane. Zwróć uwagę na & na liście argumentów funkcji (eliminuje to tworzenie kopii tablicy za każdym razem, gdy wywoływana jest funkcja zagnieżdżona).

function determine(& $the_array){ 
foreach ($the_array as $key => $value) { 
    switch ($key) { 
     case 'in': 
     case 'out': 
       echo $value; 
      break; 

     case 'level': 
      if (!is_array($value)) break; 
       echo '<ul>'; 
       determine($value); 
       echo '</ul>'; 
      break; 

     } 
    } 
} 
0

myślę, że jeśli wiesz głębokość tablicy dobrze jest używać

$list = ""; 
foreach ($the_array as $array) { 
    if(is_array($array)) { 
     foreach($array as $sub_array) { 
      if(is_array($sub_array)) { 
       foreach($sub_array as $sub_array_2) { 
        $list .= "$sub_array_2"; 
       } 
      } else { 
      $list .= "$sub_array"; 
      } 
     } 
    } else { 
     $list .= "$array"; 
    } 
} 

echo "<ul>$list</ul>"; 
1

nie wiem, czy jest to dobre rozwiązanie, ale używam tego jednego do wywołania funkcji od wewnątrz siebie:

function my_calucar(){ 
    $arrayy= array('mine' => '1', 'yours' => '24', 'her' => '34'); 
    foreach ($arrayy as $each=>$value) { 
     switch ($each) { 
     default: 
       my_calucar($value); 
     } 
    } 
} 
Powiązane problemy