Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Using $this when not in object context - ale $this jest w klasie. :/
Forum PHP.pl > Forum > PHP > Object-oriented programming
Meares
  1. class Controller_Core {
  2. function view($ViewName, $ViewData = array()) {
  3. if(empty($ViewName)) return;
  4. extract($ViewData, EXTR_SKIP);
  5. include('mainview.html');
  6. }
  7. }
  8.  
  9. class Main_Controller extends Controller_Core {
  10. function index() {
  11. $this->view('mainview.html');
  12. }
  13. }

Cytat
Fatal error: Using $this when not in object context.

Powyższy błąd występuje w jedynej linijce z $this ($this->view('mainview.html');), w kodzie podanym powyżej.
Ogólnie błąd wydaje się dziwny i nie na miejscu, w końcu używam tego $this w klasie. -.- Wie ktoś jaka jest przyczyna problemu?
darko
w konstruktorze klasy Main_Controller powinieneś wywołać konstruktor rodzica parent::__construct() (chociaż go nie ma jawnie zdefiniowanego) Pokaż jeszcze jak wywołujesz.
Meares
Wywołuję za pomocą call_user_func_array(); (i __autoload();). (Framework piszę i nie chcę tu wklejać całego, praktycznie gotowego, kodu.) Main_Controller nie ma konstruktora, bo ma go Controller_Core, a dodanie parent::__construct(); do metody index klasy Main_Controller owocuje poniższym błędem:
Cytat
Fatal error: Non-static method Controller_Core::__construct() cannot be called statically.


PS. Controller_Core ma konstruktor, tylko go tu nie wklejałem, bo moim zdaniem nie ma po co. Ale na wszelki - pełny kod, włącznie z konstruktorem:
  1. class Controller_Core {
  2. function __construct() {
  3. $this->uri = new Uri_Helper();
  4. }
  5.  
  6. function view($ViewName, $ViewData = array()) {
  7. if(empty($ViewName)) return;
  8. extract($ViewData, EXTR_SKIP);
  9. include('mainview.html');
  10. }
  11. }
  12.  
  13. class Main_Controller extends Controller_Core {
  14. function index() {
  15. $this->view('mainview.html');
  16. }
  17. }
darko
Pokaż jeszcze całe wywołanie za pomocą call_user_func_array bo coś mi tu nie gra, powinno być coś takiego:

  1. $foo = new Main_Controller();
  2. call_user_func_array(array($foo, "index"), array());


A ten błąd:
Cytat
Fatal error: Non-static method Controller_Core::__construct() cannot be called statically.

Na pewno powstał po dodaniu:
parent::__construct()
?
Meares
Ehh...
  1. class Vihroll {
  2. private $qs;
  3. private $segments;
  4. private $controller;
  5. private $action;
  6. private $arguments;
  7. public $nextclass;
  8.  
  9. public function __construct() {
  10. $this->qs = $_SERVER['QUERY_STRING'];
  11. $this->segments = $this->_GetUriSegments($this->qs);
  12.  
  13. if(!empty($this->segments[0])) {
  14. $this->controller = ucfirst(array_shift($this->segments)).'_'.ucfirst('controller');
  15. } else {
  16. $this->controller = 'Main_Controller';
  17. array_shift($this->segments);
  18. }
  19.  
  20. if(!empty($this->segments[0])) {
  21. $this->action = array_shift($this->segments);
  22. } else {
  23. $this->action = 'index';
  24. array_shift($this->segments);
  25. }
  26.  
  27. $this->arguments = $this->segments;
  28. call_user_func_array(array($this->controller, $this->action), $this->arguments);
  29. }
  30.  
  31. private function _GetUriSegments($qs) {
  32. $qs = explode('/', $qs);
  33. return $qs;
  34. }
  35. }


1. Tak, na pewno.
2. Powinna być jeszcze deklaracja klasy ($class = new Main_Controller();), ale od tego mam __autoload();.
3. Jeśli dam w Main_Controller::index(); echo 'x'; zamiast $this->view('mainview.html'); to hula i ten x się wyświetla.
darko
No i masz odpowiedź, wywołujesz bez utworzenia instancji, zobacz:

$foo = new Main_Controller();
call_user_func_array(array($foo, "index"), array());
Domyślam się że zamiast
call_user_func_array(array($this->controller, $this->action), $this->arguments);
powinno byc:
  1. $temp = new $this->controller;
  2. call_user_func_array(array($temp, $this->action), $this->arguments);
Meares
Cytat(Meares @ 5.01.2010, 03:32:39 ) *
2. Powinna być jeszcze deklaracja klasy ($class = new Main_Controller();), ale od tego mam __autoload();.

Tia...
Dodam jeszce, że __autoload działa prawidłowo, bo jak napisałem wcześniej:
Cytat(Meares @ 5.01.2010, 03:32:39 ) *
3. Jeśli dam w Main_Controller::index(); echo 'x'; zamiast $this->view('mainview.html'); to hula i ten x się wyświetla.


Źle się domyślasz. Cała klasa Vihroll działa prawidłowo. __autoload(); również.
darko
Nie wiem jak to do końca jest z wywołaniami za pomocą call_user_func_array ale może spróbuj zrobić z metody view metodę statyczną i statycznie się do niej odwołuj za pomocą parent::view(); w metodzie index. To rozwiązanie jest właściwie pozbawione sensu, ale w tym momencie tylko to mi przychodzi do głowy. Będę musiał to sprawdzić jak to wygląda w praktyce, dziś już za późno, chwilowo poddaję się smile.gif
Meares
Ehh... Niby przeszło bez błędu, ale nadal jestem ciekaw czemu wcześniej go wypluło. W końcu kod był w porządku. :/

Apeluję do każdej osoby, która ma jakiś pomył, by go tu opisała. Zachowam aktualne wersje plików coby móc później pokombinować, a tymczasem rozwiążę cały system szablonów w zupełnie inny sposób.
dr4ko
Darko dobrze napisał.

  1. call_user_func_array(array($this->controller, $this->action), $this->arguments);


powoduje wywołanie statyczne metody ($this->controller to string). Dynamicznie się wywoła jak przekażesz do funkcji obiekt (czyli $this->controller musi być instancją).I __autoload() nie ma tu nic do rzeczy.
Meares
Ahh... Faktycznie. :/
  1. class foo {
  2. function bar($arg, $arg2) {
  3. echo __METHOD__, " got $arg and $arg2\n";
  4. }
  5. }
  6. $foo = new foo;
  7. call_user_func_array(array($foo, "bar"), array("three", "four"));
  8. // Zwróci: foo::bar got three and four
  9.  
  10. class Foo {
  11. static public function test($name) {
  12. print "Hello '.$name.'!';
  13. }
  14. }
  15. call_user_func_array(array('Foo', 'test'), array('Meares'));
  16. // Zwróci: Hello Meares!

Czyli faktycznie - błędem było nie tworzenie instancji klasy w Vihroll::__construct();. :/

@darko: wybacz niedowiarkowi. smile.gif
@dr4ko: podziekował.
Plusy idą do obu panów.

PS. Nie sądzicie, że taka treść błędu trochę dezorientuje? Powinien chyba wyskoczyć jakiś w stylu:
Cytat
Fatal error: Non-static method Controller_Core::view cannot be called statically.
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.