Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Prosta klasa styli
Forum PHP.pl > Inne > Oceny
Jifer
Jako początkujący programista-pasjonat PHP prosiłbym bardziej doświadczonych użytkowników o skrytykowanie mojej pracy, pokazanie mi błędów lub wyjaśnienie jak poprawić poniższy skrypt (inne metody robienia tego samego, szybkosć i funkcjonalność)

Co chciałem osiągnąć:
-całkowicie oddzielić PHP od (X)HTML.
-by uzupełniane były fragmenty pomiędzy {}
  1. Nick: {MY_NICK}

-by sekcje kodu mogły się powtarzać na podstawie elementów tablicy ( również zagnieżdżone )
  1. <!--BEGIN REPEAT_SECTION-->
  2. {REPEAT_ELEMENT}
  3. <!--END REPEAT_SECTION-->

-by w zależnosci od parametru można było włączać/wyłączać pewne sekcje (np. w zależności od tego czy zalogowany jest admin)
  1. <!--ON BLOCK-->
  2. Jakiś fragment strony.
  3. <!--OFF BLOCK-->


Dlaczego nie użyłem 'gotowych' rozwiązań:
-nie chciałem mieć w plikach stylów żadnych dodatkowych form sterujących (nie licząc 2 wymienionych) jak to np. jest w smartach i większości podobnych klas
-chciałem żeby kod mógł być zaimplementowany na serverach w których nie mam dostępu do plików konfiguracyjnych

Założenia:
-klasa wykorzystywana przez jedną osobę, nie stosowana w wielkich projektach, w których uczestniczą zespoły.
-łatwa w obsłudze
-w miarę szybka
-do obsługi raczej małych stron

Klasa:
  1. <?php
  2. class temp{
  3.    private $t_name;
  4.    private $temp_name;
  5.    private $temp_array;
  6.    //$t_name - nazwa pliku ze stylem lub gotowy styl (string)
  7.    //$t_array - tablica z danymi
  8.    //$t_type - 0=plik 1=string
  9.    public function __construct($t_name,$t_array,$t_type){        
  10.        if($t_type == 0){
  11.            $this->t_name = $t_name;
  12.            $this->temp_name = $this->GetFile();
  13.        } else {
  14.            $this->temp_name = $t_name;
  15.        }        
  16.        $this->temp_array = $t_array;    
  17.    }
  18.    //pobieranie pliku (domyœlnie zakładam 'templates/*.tpl'
  19.    public function GetFile(){
  20.        $fr = fopen('templates/'.$this->t_name.'.tpl', "r");
  21.            if(!$fr){
  22.                $content = "Nie wczytano pliku";
  23.            } else {
  24.                $content = fread($fr, filesize('templates/'.$this->t_name.'.tpl'));
  25.            }
  26.            @fclose($fr);
  27.        return $content;
  28.    }
  29.    
  30.    private function repl($str){    
  31.        $output = preg_replace_callback("/({)([A-Z_]*)(})/",array($this,'check_key'),$str);
  32.        return $output;
  33.    }
  34.    private function repl_ar($str){
  35.        $output = preg_replace_callback('/<!--BEGIN ([A-Z_]*)-->([dDs]*)<!--END [A-Z_]*-->/',array($this,'check_key_array'),$str);
  36.        return $output;
  37.    }
  38.    private function repl_on_off($str){    
  39.        $output = preg_replace_callback('/<!--ON ([A-Z_]*)-->([dDs]*)<!--OFF [A-Z_]*-->/',array($this,'check_key_on_off'),$str);
  40.        return $output;
  41.    }    
  42.    
  43.    private function check_key_on_off($param){
  44.        //TRUE - włšcza
  45.        //FALSE lub brak - Wyłšcza
  46.        if(isset($this->temp_array[$param[1]]) && $this->temp_array[$param[1]]) $send = $param[2];
  47.        else $send = '';
  48.        return $send;
  49.    }
  50.    private function check_key($param){
  51.        if(isset($this->temp_array[$param[2]])) $send = $this->temp_array[$param[2]];
  52.        else $send = '';
  53.        return $send;
  54.    }
  55.    private function check_key_array($param){
  56.        if(isset($this->temp_array[$param[1]])){            
  57.            foreach($this->temp_array[$param[1]] as $lp=>$v_arr){
  58.                $repe = new temp($param[2],$v_arr,1);
  59.                $send = $send.$repe->ret();
  60.            }
  61.            return $send;
  62.        }
  63.    }
  64.    
  65.    private function change(){
  66.        $first = $this->temp_name;
  67.        while(preg_match('/<!--ON ([A-Z_]*)-->([dDs]*)<!--OFF [A-Z_]*-->/',$first)){
  68.            $first = $this->repl_on_off($first);
  69.        }        
  70.        while(preg_match('/<!--BEGIN ([A-Z_]*)-->([dDs]*)<!--END [A-Z_]*-->/',$first)){
  71.            $first = $this->repl_ar($first);
  72.        }        
  73.        while(preg_match("/({)([A-Z_]*)(})/",$first)){
  74.            $first = $this->repl($first);
  75.        }
  76.        return $first;
  77.    }
  78.    //zwracanie zamienionego stylu
  79.    public function ret(){
  80.        $out = $this->change();
  81.        return $out;        
  82.    }    
  83. }
  84. ?>


Kod wykonujący:
  1. <?php
  2. include("class/mytpl.php");
  3. $y_repeat_tpl[1] = array(
  4.    'OPT' => 'test_1'
  5.    );
  6. $y_repeat_tpl[2] = array(
  7.    'OPT' => 'test_2'
  8.    );
  9. $z_repeat_tpl[1] = array(
  10.    'OPT' => 'Test_01'
  11.    );
  12. $z_repeat_tpl[2] = array(
  13.    'OPT' => 'Test_02'
  14.    );
  15. $z_repeat_tpl[3] = array(
  16.    'OPT' => 'Test_03'
  17.    );
  18.        
  19. $x_repeat_tpl[2] = array(
  20.    'CL' => 'Pierwszy',
  21.    'OPTION' => $z_repeat_tpl
  22.    );
  23. $x_repeat_tpl[3] = array(
  24.    'CL' => 'Drugi',
  25.    'OPTION' => $y_repeat_tpl
  26.    );
  27.  
  28. $ar['SECTION'] = 'Sekcja';    
  29. $ar['START_REPEAT'] = $x_repeat_tpl;
  30. $ar['ALLOW'] = TRUE; //FALSE wylacza
  31.  
  32. //Utworzenie klasy
  33. $test = new temp('test_template',$ar,0);
  34. //wyświetlenie wygenerowanego kodu
  35. echo $test->ret();
  36. ?>


Plik 'test_template.tpl'
  1. <?php
  2. Poczatek<br><br>
  3. <!--ON ALLOW-->
  4.    {SECTION} on/off<br><br>
  5. <!--OFF ALLOW-->
  6.  
  7. <!--BEGIN START_REPEAT-->
  8. Nazwa testu: {CL}<br>    
  9.    <!--BEGIN OPTION-->
  10.        -{OPT}<br>
  11.    <!--END OPTION-->    
  12. <!--END START_REPEAT-->
  13. <br>
  14. Koniec
  15. ?>


Tekst wyświetlany:
  1. Poczatek
  2.  
  3. Sekcja on/off
  4.  
  5. Nazwa testu: Pierwszy
  6. -Test_01
  7. -Test_02
  8. -Test_03
  9. Nazwa testu: Drugi
  10. -Test_1
  11. -Test_2
  12.  
  13. Koniec


Cierpliwym, którzy przeczytali całość i są gotowi ocenić moją pracę i pomóc w poprawieniu ewentualnych niedociągnięć lub udoskonalić tę klasę,
bardzo dziękuję.
erix
A zastanów się, co jest wydajniejsze w celach produkcyjnych - prekompilowanie szablonów, czy obrabianie wszystkiego wyrażeniami regularnymi?
Jifer
Zapewne prekompilowanie szablonów, bo w innym przypadku nie zadawał byś mi tego pytania :]
Będzie mi jednak miło, jeśli wyjaśnisz mi to pierwsze pojęcie. Być może wtedy zrozumiem na czym polega mój błąd.

Przeglądałem sporą ilość różnych klas służących do tego celu 1 w 95% przypadków opierają się one na rekurencji i właśnie wyrażeniach regularnych.
erix
To chyba jakieś pamięciożerne klasy widziałeś. tongue.gif

Przejrzyj sobie źródła np. Smarty.
dr_bonzo
Kompilacja to przetwarzanie szablonow w 2ch etapach:
1. z ladniutkiego kodu szablonu z tymi wszystkimi {wow} i {ah} i {oh} zamieniasz na kod php - to moze byc dowolnie powolne bo robisz to raz (dopoki szablon sie nie zmieni)
2. majac juz prosty kod php - podstawiasz wartosci pod zmienne i includujesz ten plik - wszystko sie ladnie wypelni, masz petelki itp - to juz ma byc szybkie/bedzie
Jifer
Dobra, załapałem. Chodzi o wielokrotne wywoływanie funkcji przeczesującej plik preg_ która przy większych szablonach będzie wolna.

Smarty przeglądałem i... no własnie, to co napisałem wyżej.
Smarty to nowy język szablonów. Wymaga wpakowania do szablonu tony dodatkowych znaczników. Taka nowa odsłona PHP.
Nie oddzielają kodu zupełnie. Wolę podać na szablon tablicę z wynikami, niż w szablonie pisać funkcje np. powtarzające fragment skryptu.
Dokładnie mi o to chodzi.

Dodatkowy problem jest taki, że jak mam zainstalować skrypt smartów na serverze w którym nie mam dostępu do katalogów konfiguracyjnych?
Chociażby '/usr/local/lib/php/Smarty/Smarty.class.php'.

Dlatego stworzyłem taką klasę. Stąd pytam: czy nie ma czegoś adekwatnego do smart, które będzie działało podobnie jak napisana przeze mnie klasa, tyle że szybciej.

Poza tym, o jakiej my szybkości mówimy. Często słyszę, że to jest szybsze od tamtego.
Przy jakich projektach i ilu odwiedzających zaczyna mieć to znaczenie? Ile potrzeba, żeby to 'wolniej' zacząć odczuwać?
(nie pracowałem na masowych projektach, więc nie wiem)
dr_bonzo
Cytat
Dodatkowy problem jest taki, że jak mam zainstalować skrypt smartów na serverze w którym nie mam dostępu do katalogów konfiguracyjnych?
Chociażby '/usr/local/lib/php/Smarty/Smarty.class.php'.

A kto ci kaze tutaj trzymac smartiego? trzymasz go w swoim katalogu + ew. poprawiasz set_include_path().
Jifer
No dobra... minęło trochę czasu od ostatniego posta.
Przekonaliście mnie do tego bym usiadł i trochę więcej popracował na smartach.

....i niestety, ale powoli zaczynam się przekonywać dlaczego tak mnie do nich wszyscy nakłaniają. Może nawet je polubię.
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-2019 Invision Power Services, Inc.