PiotrekM
20.02.2010, 22:47:18
Witam,
piszę mały silnik dla swojej aplikacji. Chcę go oprzeć o wzorzec MVC. Chciałbym zrobić ładowanie modelu podobnie jak w kohanie, tylko jest jeden problem.
Mam klase loader, metode model.
public function model( $name) {
//require
require MODELS_PATH . $name . '.php';
$this -> $name = new $name;
}
gdy w kontrolerze dziedzicze klase loader, to przy tworzeniu modelu pole tworzy się w klasie loader, więc z kontrolera nie mam bezpośredniego dostępu $this -> pole.
Jak można by to inaczej zrobić? Jestem otwarty na propozycje
darko
20.02.2010, 23:01:41
Jeśli dobrze zrozumiałem, to chcesz wywołać metodę klasy bazowej w klasie wyprowadzonej, rozwiązanie jest proste:
parent
PiotrekM
20.02.2010, 23:06:38
sory, troche w błąd wprowadziłem. nie chce dziedziczyć klasy, tylko w kontrolerze ją wywołać $this -> load = new loader;
i potem ładowac modele $this -> load -> model('model'); i chce by mi pole modelu tworzyło w kontrolerze, a nie w loaderze
darko
20.02.2010, 23:14:07
Magiczne setter i getter powinny wystarczyć.
ps. nie wiem, jak to dokładnie wygląda w Kohanie.
PiotrekM
20.02.2010, 23:20:02
nie wiem jak to można zastosować, szczerze mówiąc pierwszy raz sie z takim czymś spotykam. Jakaś mała podpowiedź?
darko
20.02.2010, 23:21:26
http://www.php.net/manual/en/language.oop5...loading.membersPokaż jeszcze swój kod, bo nie mam pewności czy rozmawiamy o tym samym.
PiotrekM
20.02.2010, 23:27:36
nie rozumiem jak chcesz to niby zastosować?
darko
20.02.2010, 23:52:24
Cytat(PiotrekM @ 20.02.2010, 23:27:36 )

nie rozumiem jak chcesz to niby zastosować?
Właśnie dlatego prosiłem o pokazanie kodu, bo nie mam pewności czy się rozumiemy. Zastosowanie magicznego settera w kontrolerze można byłoby połączyć z tablicą przechowującą modele, wystarczyłoby zwracać instancę tworzonego modelu w metodzie load klasy loader (jeśli Cię dobrze zrozumiałem).
Zresztą zerknij jeszcze tu
PiotrekM
21.02.2010, 00:02:54
<?php
//loader on controller
class loader {
/**
* method view
*
*/
public function view( $file, $array = true) {
//if second argument is array
foreach( $array as $item => $val) {
//this is vars
$$item = $val;
}
}
//display view
include VIEWS_PATH . $file . '.php';
}
/**
* method model
*
*/
public function model( $name) {
//require
require MODELS_PATH . $name . '.php';
$this -> $name = new $name;
}
}
class controller {
public function __construct() {
$this -> load = new loader;
$this -> load -> model('test');
echo $this -> test -> oki(); }
}
darko
21.02.2010, 00:17:37
class test {
public $test = 'test';
public function Test() {
return 'test method';
}
}
/////////////
//loader on controller
class loader {
/**
* method view
*
*/
public function view( $file, $array = true) {
//if second argument is array
foreach( $array as $item => $val) {
//this is vars
$$item = $val;
}
}
//display view
include VIEWS_PATH . $file . '.php';
}
/**
* method model
*
*/
public function model( $name) {
//require
require MODELS_PATH . '.' . $name . '.php';
//$this -> $name = new $name;
return new $name;
}
}
class controller {
private $_models = array(); protected $load = null;
public function __construct() {
$this -> load = new loader;
$this ->_models[] = $this->load -> model('test');
echo $this ->_models
[0
] ->Test(); }
}
$c = new controller();
PiotrekM
21.02.2010, 00:26:18
nie działa:
Notice: Undefined property: controller::$test in C:\xampp\htdocs\tomato\system\libraries\controller.php on line 68
Fatal error: Call to a member function oki() on a non-object in C:\xampp\htdocs\tomato\system\libraries\controller.php on line 59
Kod
napisz metodę do przechowywania modeli wewnątrz kontrolera, po co się tak męczyć, albo lepiej: $this->_models[] = $this -> load -> model('test');
nie ma jak.
napisze w konstruktorze, to zanim dodam model to mi już tablice spróbuje zapełni.
dam w destruktorze, to już mi będą dane zbędne :/
darko
21.02.2010, 00:27:28
Zedytowałem swojego poprzedniego posta zmieniając w ogóle koncepcję.
PiotrekM
21.02.2010, 00:33:30
działa, ale nie tak jak powinno. Chciałem przy ładowaniu modelu stworzyć też pole dla niego :/
darko
21.02.2010, 00:39:15
Cytat(PiotrekM @ 21.02.2010, 00:33:30 )

działa, ale nie tak jak powinno. Chciałem przy ładowaniu modelu stworzyć też pole dla niego :/
Cieszę się, że udało się dobrnąć do tego stwierdzenia

W tym momencie należałoby zaimplementować proponowane przeze mnie magiczne metody: setter i getter, np.
class controller {
private $_models = array(); protected $load = null;
public function __construct() {
$this -> load = new loader;
$this ->_models['test'] = $this->load -> model('test');
echo $this ->_models
['test'] ->Test(); }
public function __set($prop_name,$prop_value) {
$this->$prop_name = $prop_value;
}
public function __get($model_name) {
return $this->_models[$model_name];
}
}
$c = new controller();
PiotrekM
21.02.2010, 00:41:56
sęk w tym, że chce się do tego zwracać w konstruktorze w klasie, a nie poza nią.
echo $this -> test -> oki(); nie działa
darko
21.02.2010, 00:44:49
Myślałem, że już się sam domyślisz o co chodzi:
class test {
public $test = 'test';
public function Test() {
return 'test method';
}
}
class controller {
private $_models = array(); protected $load = null;
public function __construct() {
$this -> load = new loader;
$this ->_models['test'] = $this->load -> model('test');
//echo $this ->_models['test'] ->Test();
// Proszę bardzo, magiczny getter zadziałał:
echo $this->test->Test(); }
public function getModels() {
return $this->_models;
}
public function __set($prop_name,$prop_value) {
$this->$prop_name = $prop_value;
}
public function __get($model_name) {
return $this->_models[$model_name];
}
}
$c = new controller();
PiotrekM
21.02.2010, 00:50:57
Dzięki staruszku, w nocy się nie domyślam niczego także wybacz. Pewnie, ze działa.
darko
21.02.2010, 00:54:40
Cytat(PiotrekM @ 21.02.2010, 00:50:57 )

Dzięki staruszku, w nocy się nie domyślam niczego także wybacz. Pewnie, ze działa.
Staruszku? No dzięki

W ogóle proponuję coś takiego:
class test {
public $test = 'test';
public function Test() {
return 'test method';
}
}
class test2 {
public $test = 'test2';
public function Test2() {
return 'test method2';
}
}
/////////////
//loader on controller
class loader {
/**
* method view
*
*/
public function view( $file, $array = true) {
//if second argument is array
foreach( $array as $item => $val) {
//this is vars
$$item = $val;
}
}
//display view
include VIEWS_PATH . $file . '.php';
}
/**
* method model
*
*/
public function model( $name) {
//require
require MODELS_PATH . '.' . $name . '.php';
//$this -> $name = new $name;
return new $name;
}
}
class controller {
private $_models = array(); protected $load = null;
public function __construct() {
$this -> load = new loader;
$this->_loadModels
(array('test','test2')); echo $this->test->Test(); echo $this->test2->Test2(); }
public function __set($prop_name, $prop_value) {
$this->_models[$prop_name] = $prop_value;
//$prop_name = $prop_value;
}
public function __get($model_name) {
return $this->_models[$model_name];
}
private function _loadModels
(array $models) { foreach($models as $m) {
$this->_models[$m] = $this->load->model($m);
}
}
}
$c = new controller();
PiotrekM
21.02.2010, 00:58:50
czekaj, czekaj, bo o jednej rzeczy zapomnieliśmy

$this ->_models['test'] = $this->load -> model('test');
jak zrobić, bym nie musiał dawać tego $this ->_models['test'].
bo jak chce operować na metodach klasy, to mode dać load model i niech mi tworzy pole w klasie, co nie? :]
darko
21.02.2010, 01:01:53
O niczym nie zapomnieliśmy zerknij na metodę _loadModels oraz konstruktor

Tylko tak dla porządku to powinno to zostać przerzucone do samego loadera dla utrzymania jakichś podstaw logiki, no ale to już sobie poradzisz i posprzątasz w tych klasach. A tak już zupełnie profesjonalnie to powinien być dobrze napisany autoloader z jakimiś przejrzystymi regułami, który umożliwiałby lazy loading modeli.
PiotrekM
21.02.2010, 01:06:25
otóż to, chciałem ładować $this -> load -> model :] a nie $this -> loadmodel
edit:
jako iż rano włączam myślenie, tak więc poradziłem sobie. tablice dałem w klasie load w metodzie model.
starach
21.02.2010, 16:29:22
A nie lepiej przekazywać od razu instancje klas modelu?
Zadam może niewłaściwe pytanie, ale... dlaczego po prostu nie użyć autoloaderów? Ja tam wolę pisać po prostu
$jakisModel = new jakisModel();
a reszta robi się automagicznie sama, włącznie z require i podobnymi...
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.