Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MVC] Widok i wyświetlanie danych
Forum PHP.pl > Forum > Przedszkole
Asmox
Otóż mam taki problem. Jest sobie klasa widoku HTML (w odróżnieniu od np. XML)
  1. class html
  2. {
  3. private $_templateSrc;
  4. private $_contents;
  5.  
  6. public function __construct($templateSrc, $contents) {
  7. $this->_templateSrc = $templateSrc;
  8. $this->_contents = $contents;
  9. }
  10.  
  11. public function insertCSS($src, $type=null) {
  12. if(empty($type)) $type = 'all';
  13. echo '<link href="'.$src.'" media="'.$type.'" rel="stylesheet" type="text/css">'."\n";
  14. }
  15.  
  16. public function insertJS($src) {
  17. echo '<script type="text/javascript" src="'.$src.'"> </script>'."\n";
  18. }
  19.  
  20. public function show() {
  21. Core::loadFile($this->_templateSrc);
  22. }
  23. }

I w szablonie jest coś takiego
  1. <?php $this->insertCSS(Core::DEFAULT_VIEWS_SRC . $this->_view . '/' . 'uklad.css'); ?>

Ale niestety to wywala błąd:
Cytat
Fatal error: Using $this when not in object context in [ścieżka]\views\html\templates\default\default.html on line 6

Czy da się to jakoś załatwić, żeby informacje były wyciągane bezpośrednio z widoku? Czyli innymi słowy, żeby nie było tego błędu i wszystko działało :-) ?
potreb
$this stosujesz poza klasą? Nie widzę, żebyś tworzył nową instancję klasy
Asmox
Jest jeszcze kontroler czy coś takiego articles.
  1. Core::loadFile('./controllers/controllerInterface.php');
  2.  
  3. class articles implements controllerInterface
  4. {
  5. private $_router;
  6. private $_action;
  7. private $_dataTransfer;
  8. private $_model;
  9. private $_modelObj;
  10. private $_view;
  11. private $_viewObj;
  12. private $_template;
  13. private $_artID;
  14. private $_contents;
  15.  
  16. public function __construct(router $router) {
  17. $this->_router = $router;
  18. $this->_action = ifNotNull($this->_router->fromRequest('action'), 'view');
  19. $this->_dataTransfer = ifNotNull($this->_router->fromRequest('dataTransfer'), 'as');
  20. $this->_artID = ifNotNull($this->_router->fromRequest('id'), 1);
  21.  
  22. $this->_model = Core::DEFAULT_MODEL_NAME;
  23. $this->_view = Core::DEFAULT_VIEW_NAME;
  24. $this->_template = Core::DEFAULT_TEMPLATE_NAME;
  25.  
  26. //$this->viewAction();
  27. call_user_method($this->_action . 'Action', $this);
  28. }
  29.  
  30. public function setModel($model) {
  31. $this->_model = $model;
  32. }
  33.  
  34. public function setView($view) {
  35. $this->_view = $view;
  36. }
  37.  
  38. public function setTemplate($tpl) {
  39. $this->_template = $tpl;
  40. }
  41.  
  42. public function loadModel() {
  43. Core::loadClass($this->_model, Core::DEFAULT_MODELS_SRC . $this->_model . '/' . $this->_model . '.php');
  44. $this->_modelObj = new $this->_model();
  45. }
  46.  
  47. public function loadView() {
  48. Core::loadClass($this->_view, Core::DEFAULT_VIEWS_SRC . $this->_view . '/' . $this->_view . '.php');
  49. $templateSrc = Core::DEFAULT_VIEWS_SRC . $this->_view . '/' . 'templates/' . $this->_template . '/' . $this->_template . '.html';
  50. echo $templateSrc;
  51. //print_r($this->_contents);
  52. $this->_viewObj = new $this->_view($templateSrc, $this->_contents); // Tu jest tworzony nowy obiekt
  53. }
  54.  
  55. public function loadContents($arrConditions) {
  56. $this->_contents = $this->_modelObj->getContents($arrConditions);
  57. }
  58.  
  59. public function escape() {
  60. $this->_viewObj->show();
  61. }
  62.  
  63. public function viewAction() {
  64. $this->loadModel();
  65. $this->loadContents(array('id' => $this->_artID));
  66. $this->loadView();
  67. $this->escape();
  68. }
  69. }
Berg
Nie da się, starasz się wywołać obiekt z poziomu metody statycznej. Są 2 obejścia problemu (przynajmniej takie o których wiem smile.gif).

Po pierwsze rozwiązanie niezbyt dobre, możesz w metodzie statycznej utworzyć kod PHP (w Stringu) w którym tworzysz klasę która dziedziczy po klasie html, natomiast w konstruktorze tej klasy umieścić kod z szablonu. Potem inicjujesz taką klasę i po sprawie. Oczywiście ten kod PHP wykonujesz w klasie statycznej za pomocą evala.

Drugie rozwiązanie jest o niebo lepsze - możesz z klasy Core zrobić Singletona, umieścić tam kod metodę magiczną __call która będzie sprawdzała czy dana metoda należy do klasy html i w razie czego ją wywoływał. Oczywiście w takim przypadku w loadFile trzeba będzie przesyłać obiekt klasy html aby klasa Core mogła sprawdzić czy dana metoda znajduje się w klasie i ewentualnie ją wywolać. Metoda show będzie wtedy wyglądała tak:
  1. public function show() {
  2. Core::getInstance()->loadFile($this->_templateSrc, $this);
  3. }

W ogóle na Twoim miejscu zastanowiłbym się czy jest jakiś sens korzystania w tym przypadku z Core, nie możesz dołączyć kodu szablonu bezpośrednio w metodzie show?
Asmox
Zapomniałem wspomnieć, że loadClass to tylko loadFile, oraz sprawdzenie, czy klasa istnieje.
Nie wiem tylko, czy wywoływanie z szablonu danych strony z obiektu (czyli używanie $this->content) jest ogólnie nie możliwe, czy to ja gdzieś popełniłem błąd. Bo mam ochotę napisać wszystko od początku. Powód? Nie trzyma się metody KISS i to w takim stopniu, że sam się gubię biggrin.gif
Berg
Jeśli wczytujesz szablon z poziomu metody obiektu to nie ma problemu z używanie $this, Twój błąd ewidentnie świadczy o tym że robisz to gdzieś gdzie nie masz dostępu do $this (czyli pewnie w metodzie statycznej).
Kod z szablonu nie musi być nawet wykonywany bezpośrednio w klasie do której chcesz uzyskać dostęp do metody/pobrać zmienną o ile złapiesz metodę za pomocą __call (lub analogicznie zmienną za pomocą __get) i przekierujesz ją do poprawnej referencji do obiektu. Najlepiej gdybyś wrzucil wycinek kodu w którym następuje wczytanie szablonu, wtedy prawdopodobnie będzie można znaleźć jakieś obejście smile.gif
Asmox
  1. class Core
  2. {
  3. /*rożny kod*/
  4. public static function loadFile($src) {
  5. if(file_exists($src)) require_once($src);
  6. else {
  7. $exc = new cannotLoadException('Nie mozna zaladowac pliku.');
  8. $exc->setSrc($src);
  9. throw $exc;
  10. }
  11. }
  12. }

Zazwyczaj to było robione w ten sposób, (loadFIle jako loadTemplate)ale zrobiłem do widoku własną funkcję i jest spoko, dzięki :-)
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-2025 Invision Power Services, Inc.