Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Zalążek frameworka z MVC, Proszę, zweryfikujcie moje podejście
Prph
post
Post #1





Grupa: Zarejestrowani
Postów: 338
Pomógł: 2
Dołączył: 4.03.2006
Skąd: Łódź

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


Witam wszystkich,

Ostatnio zacząłem czytać o obiektowym php5, MVC, frameworkach i postanowiłem zacząć pisać kod, który byłby dla mnie wygodny oraz co ważne - nadawał się do powtórnego wykorzystania.

Opiszę to co do tej pory zrobiłem. Proszę Was, znaczniej bardziej doświadczonych programistów, o uwagi na temat mojego podejścia.

Zaznacze, że swoją pracę oparłem do tej pory na artykule Frameworki z php.pl, framework CakePHP oraz o wypowiedzi forumowiczach w topikach MVC.

Charakterystyka ogólna:
Drzewo projektu

Kod
|- actions/ (tu wrzucam kontrolery w postaci class.NazwaKontrolera.php)
|- conf/
|- models/ (tu będą modele, do tej pory nic tam nie mam)
|- lib/
|  +-- core/ - tu są moje pliki wykorzystywane w całej aplikacji
|        +-- class.Dispatcher.php
|        +-- class.Controller.php
|- templates/ - szablony Smarty  
|
|- index.php


Oczywiście nie jest to finalny widok drzewa projektu. Ale nie to jest ważne.

Jak działa mój framework?
index.php uruchamia Dispatcher, który parsuje URL. Jeżeli następuje zgłoszenie index.php/Akcja1/Parametr1/Parametr2/, to dispatcher załącza kontroler Akcja1, a następnie kontroler tej akcji wywołuje na sobie (w zasadzie na potomku) metodę Parametr1 z parametrem Parametr2.

Przykład: strona.pl/index.php/Uzytkownik/Pokaz/1234. Dispatcher przekaże kontrolę do kontrolera Uzytkownik. Ten natomiast włączy metodę Pokaz(1234);

Generalnie wygląda to właśnie tak. Z tego co czytałem, to chyba całkiem logiczne rozwiązanie. Oczywiście mogę się mylić...

Pliki
  1. Plik index.php
  2. <?php
  3. require_once('conf/conf.Core.php');
  4. require_once('lib/core/Logger/class.Logger.php'); // to nas nie interesuje - zwyklu silnik logowania
  5. require_once('lib/core/class.Dispatcher.php');
  6.  
  7. try
  8. {
  9. Logger::register('file:///tmp/log.core.txt');
  10.  
  11. $objDispatcher = new Dispatcher();
  12. $objDispatcher->handle();
  13. }
  14. catch (Exception $exception)
  15. {
  16. echo $exception->getMessage();
  17. }
  18.  
  19. ?>



  1.  Plik class.Dispatcher.php
  2.  
  3. <?php
  4.  
  5. require_once('lib/core/class.Controller.php');
  6. require_once('Smarty.class.php');
  7.  
  8. class Dispatcher
  9. {
  10.  
  11. private $_strUrlParameters; // zawiera parametry url, np: dla strona.pl/index/a/b/c/d zawiera a/b/c/d/
  12. private $_arrUrlParameters; // tutaj parametry juz są w tablicy 
  13.  
  14. public function __construct()
  15. {
  16. $strUrlParameters = $_SERVER['PATH_INFO'];
  17. $this->_strUrlParameters = substr($strUrlParameters, 1);
  18. }
  19.  
  20. public function handle()
  21. {
  22. $this->_parsePath(); // zapusuje parametry url do tablicy
  23.  
  24. $strControllerName = $this->_getControllerName(); // zwroci pierwszy elementy w tablicy parametrow (indeks w tablicy oczywiscie 0)
  25. //Następnie tworzy kontroler na podstawie nazwy akcji i go uruchamia
  26. $strControllerFile = 'actions/class.'.$this->_getControllerName().'Controller.php'; 
  27. if(file_exists($strControllerFile))
  28. {
  29. require_once($strControllerFile);
  30. $strControllerClasName = $this->_getControllerName().'Controller';
  31. $objController = new $strControllerClasName($this->_getParametersForController());
  32. $objController->run();
  33.  
  34. $objSmarty = new Smarty();
  35. $objSmarty->tempalte_dir = 'templates';
  36. $objSmarty->compile_dir = 'var';
  37.  
  38. $objSmarty->assign($objController->getModelData()); // kontroler powinien zwrocic dane dla Smarty.
  39. $objSmarty->display($objController->getView());
  40. }
  41. else
  42. {
  43. throw new Exception('Core, dispatcher: Action '.$strActionToRun.' does not exist');
  44. }
  45. }
  46.  
  47. private function _parsePath() // rozbija parametry url na tablice
  48. {
  49.  $arrParameters = explode('/', $this->_strUrlParameters);
  50.  if($arrParameters[count($arrParameters) - 1] == '')
  51.  array_pop($arrParameters);
  52.  
  53.  $this->_arrUrlParameters = $arrParameters;
  54. }
  55.  
  56. private function _getControllerName() // zwraca nazwe akcji ktora nalezy wykonac - tutaj to pierwsza pozycja w tablicy zawierajacej parametry url
  57. {
  58. $strControllerName = $this->_arrUrlParameters[0];
  59.  
  60. if(strlen($strControllerName))
  61. return $strControllerName;
  62. else
  63. throw new Exception('Core, dispatcher: There is not action to run');
  64. }
  65.  
  66. private function _getParametersForController()
  67. {
  68. $intNumOfPathParameters = count($this->_arrUrlParameters);
  69. $arrPrametersForController = array();
  70.  
  71. for($i = 1; $i < $intNumOfPathParameters; $i++)
  72. $arrPrametersForController[] = $this->_arrUrlParameters[$i];
  73.  
  74. return $arrPrametersForController;
  75. }
  76. }
  77.  
  78. ?>


  1. Plik class.Controller.php
  2. <?php
  3.  
  4. require_once('Collection/class.Collection.php');
  5.  
  6. class Controller
  7. {
  8. private $_strControllerName = null; // nazwa kontrolera - wyorzystuje sie do wybrania widoku i modelu
  9. private $_arrControllerParameters = array(); // parametry dla kontrolera. jezeli url wygladal nastepujaco: strona.pl/index.php/Uzytkownik/Pokaz/12345 to zawiera tablice [Pokaz][1234]
  10.  
  11. protected $_strPageName; // tytul strony (dla htmla)
  12.  
  13. private $_objModelsCollection; // kolekcja modeli, dziala jak tablica asocjacyjna - malo wazne
  14. private $_strView; // widok - tutaj to nazwa szablonu smarty
  15.  
  16. private $_arrViewVars = array();
  17.  
  18. public function __construct($arrParameters = null)
  19. {
  20. if(!isset($this->_strControllerName)) // pobiera nazwe swojej klasy - wykorzystuje sie to do wyboru widoku oraz modelu
  21. {
  22. $arrResults = array();
  23.  
  24. if(!preg_match('/(.*)Controller/i', get_class($this), $arrResults))
  25. {
  26. die('Controller: Can not get my class name');
  27. }
  28.  
  29. $this->_strControllerName = $arrResults[1];
  30. }
  31.  
  32. if(count($arrParameters))
  33. $this->_arrControllerParameters = $arrParameters;
  34.  
  35. $this->_objModelsCollection = new Collection();
  36.  
  37. $this->_objModelsCollection->addItem($this->_strControllerName.'Model');
  38. $this->_strView = $this->_toLowerCase($this->_strControllerName).'.tpl';
  39. }
  40.  
  41. public function getModelData() // zwraca tablice dla Smarty->assign()
  42. {
  43. if(count($this->_arrViewVars))
  44. return $this->_arrViewVars;
  45. }
  46.  
  47. public function getView() // zwraca szablon dla smarty->display();
  48. {
  49. return $this->_strView;
  50. }
  51.  
  52. public function run() // sedno kontrolera. Jezeli przekazano dodatkowy parametr w url, np: strona.pl/index.php/Uzytkownik/Pokaz to wywola sie funkcja Pokaz, jezeli nie wywola funckje domysla, ktora defi
    niuje juz potomek tej klasy
  53. {
  54. if($this->_getMethodToRun())
  55. {
  56. if(is_callable(array($this, $this->_getMethodToRun()), $this->_getParameterForMethod()))
  57. call_user_func_array(array($this, $this->_getMethodToRun()), $this->_getParameterForMethod());
  58. }
  59. else
  60. $this->runDefaultMethod();
  61. }
  62.  
  63. protected function _setPageTitle($strTitle)
  64. {
  65. $this->_strPageTitle = $strTitle;
  66. $this->_setVar('TITLE', $strTitle);
  67. }
  68.  
  69. protected function _setVar($strVarName, $mixValue)
  70. {
  71. $this->_arrViewVars[$strVarName] = $mixValue;
  72. }
  73.  
  74. private function _toLowerCase($strString)
  75. {
  76. return strtolower(substr($strString, 0, 1)).substr($strString, 1);
  77. }
  78.  
  79. private function _getMethodToRun() // sprawdza parametr url, czy ma wykonac jakas metode - patrz wyzej
  80. {
  81. if(isset($this->_arrControllerParameters))
  82. {
  83. if(method_exists($this, $this->_arrControllerParameters[0]))
  84. return($this->_arrControllerParameters[0]);
  85. }
  86. return false;
  87. }
  88.  
  89. private function _getParameterForMethod() // zwraca tablice parametrow dla metody ktora nalezy wykonac. Jezeli url wygldal: 
    strona.pl/index.php/uzytkownik/pokaz/12345 to wykona metode pokaz kontrolera uzytkownik przekazujac do pokaz() 12345.
  90. {
  91. if(isset($this->_arrControllerParameters))
  92. {
  93. if(count($this->_arrControllerParameters) > 1)
  94. {
  95. $intNumOfParameters = count($this->_arrControllerParameters);
  96. $arrPrametersForMethod = array();
  97.  
  98. for($i = 1; $i < $intNumOfParameters; $i++)
  99. $arrPrametersForMethod[] = $this->_arrControllerParameters[$i];
  100.  
  101. return $arrPrametersForMethod;
  102. }
  103. }
  104. }
  105. }
  106.  
  107. ?>


  1. Plik class.HelloController.php - przykładowy kontroler dla akcji Hello
  2. <?php
  3.  
  4. // To jest przykladowy kontroler. Jak widac mozna wywolac strone tak: strona.pl/index.php/Hello/Hi albo Hello/Bye. Mozna przekazac argument: Hello/Bye/Adrian przez co akcja porzegna Adriana.
  5.  
  6. class HelloController extends Controller
  7. {
  8. public function hi()
  9. {
  10. $this->_setPageTitle('Witamy Cię');
  11. $this->_setVar('HEADER', 'Witaj, to działa!');
  12. }
  13.  
  14. public function bye($strName)
  15. {
  16. $this->_setPageTitle('Pa pa pa');
  17. $this->_setVar('HEADER', 'Pa pa '.$strName.', do następnego razu!');
  18. }
  19.  
  20. public function runDefaultMethod()
  21. {
  22. $this->hi();
  23. }
  24. }
  25.  
  26. ?>


Będę Wam ogromnie wdzięczny za uwagi. Pozdrawiam serdecznie,
Adrian.

Ten post edytował Prph 4.03.2006, 19:40:41
Go to the top of the page
+Quote Post

Posty w temacie
- Prph   Zalążek frameworka z MVC   4.03.2006, 16:02:14
- - sf   Brak komentarzy, miales jakis pomysl, ale nie kazd...   4.03.2006, 18:07:56
- - matid   Cytat(sf @ 2006-03-04 18:07:56)Pozatym nie ba...   4.03.2006, 18:56:02
- - Prph   Diękują za uwagi. Co do die() - faktycznie nie p...   4.03.2006, 19:52:05
- - Fipaj   Ten pomysł z Dispatcherem mi się nie podoba. Czem...   4.03.2006, 19:58:25
- - Prph   Ale przeciez w praktyce to tak działa Ale chyba ...   4.03.2006, 20:26:36
- - matid   We wzorcu MVC kontroler to część aplikacji odpowie...   4.03.2006, 20:51:50
- - Ociu   Ja sobie podzieliłem to tak: Kodframework - Web ...   5.03.2006, 09:12:40
- - Prph   Teraz raz jeszcze przeczytalem Wprowadzenie do MVC...   5.03.2006, 10:14:11
- - hwao   W ogole brak Ci widoku w tym frameworku. Glupio j...   5.03.2006, 10:24:42
- - matid   U mnie to wygląda tak: index.php: W tym pliku two...   5.03.2006, 10:51:08
- - Prph   Witam Widzę, że niechętnie podchodzicie do mojej...   5.03.2006, 16:47:05
- - Ociu   Widze, że czekasz aż ktoś rzuci kodem.[PHP] pobier...   7.03.2006, 14:59:34
- - Prph   Przejrzałem kod Phienda, poczytałem dokumentacje, ...   9.03.2006, 23:24:05
- - hwao   czemu u Ciebie akcja wlacza Model i Widok? Pr...   10.03.2006, 06:48:18
- - Prph   Yyyyy? A to co ma włączać model i widok? Ludzie cz...   10.03.2006, 07:54:17
- - sf   Hyh, w ostatnim php Solutions jest fajnie napisane...   10.03.2006, 09:03:36
- - mike_mech   Cytat(Prph @ 2006-03-10 07:54:17)Yyyyy? A to ...   10.03.2006, 09:09:42
- - Martio   Cytat(mike_mech @ 2006-03-10 10:09:42)Hyh, w ...   10.03.2006, 12:28:05
- - hawk   Żaden nie trzymał się zasad wzorca MVC? Bo to zale...   10.03.2006, 14:51:59
- - Martio   CytatI dlaczego to, że jakiś framework nie trzyma ...   10.03.2006, 15:40:32
- - Vengeance   Akcja to po prostu część kontrolera. Ponieważ kont...   10.03.2006, 15:57:25
- - Martio   Dobra, ale jak obiektowo w takim bądź razie zakodo...   10.03.2006, 20:41:56
- - DeyV   W takim momencie okazuje, się, że wydzielenie z ko...   10.03.2006, 22:34:27
- - Prph   No proszę... Najpierw ktoś mówi, że akcja nie ster...   11.03.2006, 00:51:03
- - DeyV   Pamiętaj o jednej rzeczy. MVC nie mówi, jak ma b...   11.03.2006, 01:57:31
- - Prph   No dobrze, a teraz juz troche idac w przyszlosc......   11.03.2006, 10:42:13
- - eMartio   Zerknijcie na to. Czeskie, ale myślę, że dobre roz...   11.03.2006, 13:14:35
- - Martio   Chciałbym jeszcze powrócić do akcji. Powiedzmy, że...   11.03.2006, 14:04:49
- - aleksander   [PHP] pobierz, plaintext <?phpclass Kontroler...   11.03.2006, 14:39:03
- - Prph   Ha! A to całkiem ciekawe rozwiązanie. A jeszc...   11.03.2006, 18:01:49
- - hwao   zalezy jakie to dane... konfiguracja aplikacji de...   11.03.2006, 18:34:17
- - Prph   Cytat(hwao @ 2006-03-11 17:34:17)konfiguracja...   11.03.2006, 20:07:57
- - hwao   Cytat(Prph @ 2006-03-11 20:07:57)Cytat(hwao ...   11.03.2006, 21:11:28
- - hawk   Cytat(Martio @ 2006-03-11 14:04:49)[PHP] pobi...   11.03.2006, 22:46:08
- - eMartio   Postanowiłem odejść od wzorca MVC, realizując apli...   12.03.2006, 10:42:33
- - Ociu   Ja podzieliłem sobie kontroler na FrontController ...   12.03.2006, 11:35:35
- - eMartio   Analizując wszystkie wątki o MVC na tym forum zgłu...   13.03.2006, 14:17:03
- - Vengeance   "Czy możecie zrobić malutkie podsumowanie...   13.03.2006, 15:38:35
- - hawk   Cytat(Vengeance @ 2006-03-13 15:38:35)MVC mów...   13.03.2006, 16:27:47
- - aleksander   @eMartio: http://php.pl/wortal/artykuly/php/archit...   13.03.2006, 16:44:31
- - eMartio   Cytat(aleksander @ 2006-03-13 15:44:31)@eMart...   13.03.2006, 21:15:27
- - Prph   Przeczytajcie na końcu!. Jak rozwiąć Widok? W...   17.03.2006, 07:56:14


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 Aktualny czas: 20.08.2025 - 05:11