JustPaste.it

Stosy w PHP i ich wykorzystanie w zarządzaniu układem serwisu

Podczas składania witryny z rozmaitych bloków kodu wykonujących różne zadania, bardzo pomocne są stosy. Artykuł ten pokazuje, jak je zaimplementować w PHP.

Przyjrzyjmy się typowej stronie WWW i spróbujmy podzielić ją na elementy składowe. Mamy więc logo, menu, treść właściwą, jakąś sondę, no i stopkę. Ale jak właściwie zarządzać układem tych elementów? Co będzie, gdy zechcemy np. przenieść menu na prawą stronę treści, a sondę na lewą? Jak zrobimy dodawanie nowych bloków? Z pomocą przychodzą nam tu jedne ze struktur danych - stosy.

Stos (ang. stack) jest strukturą danych stosowaną bardzo często w programowaniu np. w C++. Strukturą, gdyż:

  1. Umożliwia przechowywanie praktycznie nieograniczonej ilości danych, w przeciwieństwie do np. tablic (w językach przystosowanych do kompilacji na kod maszynowy komputera tablice mają z góry określoną wielkość i nie można jej zmienić).
  2. Charakteryzuje się pewną zasadą ułożenia/dostępu do poszczególnych elementów.

W PHP punkt numer 1 jest całkowicie nieważny, bowiem już same zmienne interpreter gromadzi w odpowiednie struktury, natomiast tablice też są implementowane poprzez jedną z nich. Zastanówmy się natomiast nad punktem drugim - co oznacza ta zasada dostępu? Otóż teoretycznie to, dostęp do części elementów jest warunkowany przez wykonanie pewnych czynności. Jak to wygląda w stosie, już wyjaśniam.

Wyobraź sobie 10 talerzy ułożonych jeden na drugim, przy czym ten oznaczony numerem 1 jest na dole, a ten z 10, na szczycie. To jest właśnie stos! Załóżmy teraz, że chcemy się dostać do talerza numer 7. Nie możemy go ot-tak wziąść - musimy najpierw zdjąć element 8, a żeby zdjąć element 8, należy też zdjąć 9. Aby 9 zdjąć, należy wpierw zdjąć 10. Wychodzi więc, że możemy ściągać talerze jedynie w odwrotnej kolejności, niż zostały położone. Element pierwszy będzie zdjęty jako ostatni, a ostatni położony, zostanie zdjęty jako pierwszy.

Ze względu na swoją specyfikę, do implementacji stosu w PHP najlepiej nadają się zwykłe tablice. Pierwszy położony element będzie posiadał indeks 0, natomiast ostatni dostanie najwyższy indeks. Stos będzie przetwarzany od elementu najwyższego do najniższego. Oto klasa realizująca całe to zadanie:

<?php
 
class stack_manager{
var $stack;
var $i;

function stack_manager(&$stack){
$this -> stack = &$stack;
} // end __construct();

function push($module){
$this -> i++;
$this -> stack[$this -> i] = $module;
$this -> i++;
} // end push();

function execute(){
for($this -> i = count($this -> stack) - 1; $this -> i >= 0; $this -> i--){
$module = $this -> stack[$this -> i];
unset($this -> stack[$this -> i]);

require('./modules/'.$module);
}
} // end execute();

}
 
?>

Klasa jest bardzo krótka, ale doskonale spełni nasze potrzeby. Jako że posłuży nam ona do stworzenia prostego systemu zarządzania kolejnością wykonania poszczególnych elementów strony, na stos będą odkładane moduły do uruchomienia (przy czym ten uruchomiony jako pierwszy jest na szczycie stosu, a ostatni na dole). Konstruktor pozwala pobrać zewnętrzną tablicę stosu. Metoda execute() uruchamia wszystkie moduły odłożone na stos, natomiast push() daje nam możliwość dołożenia nowego modułu już w trakcie wykonywania stosu.

Oto przykład, jak tego używać. W jakimś pliku konfiguracyjnym (może on być częścią szablonu) tworzymy tablicę stosu:

<?php // stack.php
 
// prosze sie nie czepiac uzywania polskich liter w nazwach zmiennych, bo takie cos jest mozliwe
$mójstos[4] = 'naglowek.php';
$mójstos[3] = 'menu.php';
$mójstos[2] = $_GET['run'].'.php';
$mójstos[1] = 'sonda.php';
$mójstos[0] = 'stopka.php';
 
?>

Przypatrz się elementowi z numerem 2 (w samym środku) - w ten sposób zdefiniowałem, iż treść właściwa ma znajdować się między nagłówkiem i menu, oraz sondą i stopką. Teraz przyszedł czas na główny kod:

<?php
 
require('./libs/stack_manager.php'); // nasz plik z klasa stosu
require('./cfg/stack.php'); // plik informujacy o zawartosci stosu
 
$stos = new stack_manager;
$stos -> execute();
 
?>

I to w sumie tyle - wystarczy napisać odpowiednie moduły i zobaczyć, iż rzeczywiście zostaną one wyświetlone w zadanej kolejności. Przy okazji poruszę tu kwestię użycia metody push(). Załóżmy, że PHP jest w trakcie wykonywania treści strony i że moduł, który tam chcemy uruchomić, generuje jakiś błąd (np. stwierdza, że użytkownik nie ma uprawnień do oglądania materiałów). Wystarczy wtedy, że wywoła metodę push():

<?php // modul_tresci
 
$user_id = 0; // przykladowy stan ustawiony gdzies indziej
 
if($user_id == 1){
echo 'To jest tresc strony';
}else{
$this -> push('logowanie.php');
}
?>

Oto klasyczny przykład - moduł treści zakończy się, ale jako że wywołana w nim została metoda push() (zwróć uwagę na to, że wywołuję ją poprzez wskaźnik $this, ponieważ moduł jest uruchomiony wewnątrz metody execute()), na stosie pojawił się dodatkowy element ('logowanie.php'), który zostanie tak zinterpretowany, jakby w ogóle leżał między modułem treści, a naszą np. sondą, uruchamianą po nim. Spróbuj wrzucić poprzez push() dwa moduły i zaobserwuj, co się stanie. W ogóle naprawdę poeksperymentuj ze stosem i odkryj możliwości, jakie niesie jego zastosowanie w zarządzaniu układem strony.

Niekiedy spotkasz się też z wykorzystaniem KOLEJKI w zarządzaniu układem strony. Kolejka zachowuje się tak, jak kolejki w sklepach z czasów PRL - z jednej strony ludzie wchodzą, a z drugiej wychodzą z zakupami :).

Artykuł ten miał za zadanie tylko pokazać przykładowy, najprostszy stos, natomiast tylko od Ciebie zależy to, jak dostosujesz go do twojego serwisu (a będziesz chciał dostosować prawie na pewno). Fakt jest faktem - temat został tylko poruszony, a do napisania jest o wiele więcej.

 

Autor: Tomasz "Zyx" Jędrzejewski, www.zyxist.com

 

Źródło: http://webcity.pl/webcity/stosy_w_php_i_ich_wykorzystanie_w_zarzadzaniu_ukladem_serwisu

Licencja: Creative Commons - użycie niekomercyjne - bez utworów zależnych