[PHP] MVC-Model toepassen

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • basvd
  • Registratie: December 2007
  • Laatst online: 20-09 14:48
In hoeverre het mogelijk is (in PHP4) zou ik graag een aantal zaken objectgeoriënteerd willen programmeren. Om eerlijk te zeggen ben ik redelijk op weg om dit om te delen in verschillende klasses/methoden etc.

Nu bedacht ik mij vandaag opeens of het niet interessant is om gebruik te maken van het 3 lagenmodel (MVC), met name de scheiding van Model&Contoller leek mij wel een goed idee.

Ter info;
- Het gaat om een website (PHP4/MySQL)
- PHP5 voorlopig even geen optie.

Gelezen topics:
[Alg] 3-lagenmodel
[PHP] OOP: Abstract Classes
Abstract class versus Interface
[Alg] Abstract vs. interface

Nu zit het zo in elkaar:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class News {
    // constructor
    function News($id) {}
    
    // return true; setting where filter
    function setFilter() {}
    // return: true; record insert
    function addNewsItem() {}   
    // return: true; record update
    function updateNewsItem() {}
    // return: true; record delete
    function delNewsItem() {}
    // return: true; if valid dbase record id
    function isValidItem() {}
    
    // return: title of article
    function getTitle() {}
    // return: date of article
    function getDate() {}
    // return: full text article
    function getFullArticle() {}
    // return: attachments  of article
    function getAttachments() {}
}


Nu heb ik even een opzetje gemaakt, alleen heb ik het idee dat dit niet geheel het principe is wat ze bij het MVC-model bedoelen:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class NewsGUI extends NewsManager {
    function NewsItem($id) {}
    function NewsCollection() {}
}

class NewsManager extends News {
    // Staat dit hier goed? of moet dit naar 'View'-layer?
    function isValidItem() {}
    function getTitle() {}
    function getFullArticle() {}
    function getDate() {}
    function getAttachments() {}

    // 'set' for updates
    function setTitle() {}
    function setFullArticle() {}
    function setDate() {}
    function setAttachment() {} 

    // Staan deze goed? of horen deze te zamen thuis in 'Model'-layer?
    function setFilter() {}
    function updateNewsItem() {}
    function deleteNewsItem() {}
    function insertNewsItem() {}
}

class News {
    function getNews($filter) { SQL }
    function insertNews($id,$data) { SQL }
    function updateNews($id,$data) { SQL }
    function deleteNews($id) { SQL }
}


De vraag is even, ben ik hier op de goede weg met bovenstaand voorbeeld?
Of heeft iemand misschien een voorbeeld van zijn/haar code?

Alvast bedankt!

Acties:
  • 0 Henk 'm!

  • AaroN
  • Registratie: Februari 2001
  • Laatst online: 16-08-2023

AaroN

JayGTeam (213177)

je hebt een controller class. Deze roept een model en de bijbehorende view aan. De view haalt haar data op uit het model en maakt deze beschikbaar voor de gui / template wat je maar gebruikt om het op het scherm te toveren.

controller - model
_ _ _ _ _ \ view

controller handelt input af en selecteert het juiste model en de bijbehorende view.

kijk eens naar de MVC van Joomla, die gaat vrij ver maar is een mooi voorbeeld: http://dev.joomla.org/com...model%20view%20controller ( dan bij Model-view-controller kijken)

JayGTeam (213177)


Acties:
  • 0 Henk 'm!

Verwijderd

AaroN schreef op vrijdag 18 april 2008 @ 14:31:
[...] De view haalt haar data op uit het model [...]
In mijn ervaring haalt de controller de data op uit het model en geeft die data door aan de view.

Acties:
  • 0 Henk 'm!

  • WouZz
  • Registratie: Mei 2000
  • Niet online

WouZz

Elvis is alive!

Een opzet zou kunnen zijn:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
class Controller {

    function Controller() {}

    function dispatch($path) {
        trigger_error(__CLASS__.'::'.__FUNCTION__.' should be implemented in subclass');
    }

    function send404()
    {
        header(' ', true,  404);
        exit('Page Not Found');
    }

    function loadView($path, $data) {
        ob_start();
        
        extract($data);     

        include('views/'.$path);

        $content = ob_get_contents();
        
        ob_end_clean();
        
        return $content;
    }
}


class NewsController extends Controller {

    var $manager;

    function NewsController() {
        parent::Controller()

        $this->manager = new NewsManager();
    }

    function dispatch($path) {
        if(isset($path[2]))
            return $this->viewItem($path[2]);
        
        return $this->viewList();
    }   

    function viewList() {
        $items = $this->manager->getItems();

        $data = array(
            'items' => $items
        );

        $view = 'news/list.php';

        return $this->loadView($view, $data);
    }

    function viewItem($id) {
        $item = $this->manager->getItem($id);

        if(!$item)
            $this->send404();
        
        $data = array(
            'item' => $item
        );

        $view = 'news/item.php';

        return $this->loadView($view, $data);
    }

}


class NewsManager {

    function getItem($id) {
        // SQL ...
    }

    function getItems($offset = 0, $limit = 10) {
        // SQL ...
    }

    function createItem($data) {
        // ...
    }

    function editItem($id, $data) {
        // ...
    }

    function deleteItem($id) {
        // ...
    }
}


en dan in je index.php:

PHP:
1
2
3
4
5
6
7
8
9
10
$path = explode('/', $_SERVER['REQUEST_URI']);

if(isset($path[1]) && $path[1] == 'news') {
    $controller = new NewsController();
}
else {
    $controller = new HomeController();
}

print $controller->dispatch($path);


Dit zou je nog verder kunnen abstraheren door een aparte View classe aan te maken die de rendering doet, en/of een ModelAndView object die je terug geeft uit je controller en doorgeeft aan de FrontController die dan weer pre / post processing doet.

Wel zorgen dat alles op je index.php uitkomt m.b.v. een .htaccess en rewriterules

[ Voor 6% gewijzigd door WouZz op 18-04-2008 15:55 ]

On track


Acties:
  • 0 Henk 'm!

  • Hydra
  • Registratie: September 2000
  • Laatst online: 21-08 17:09
Verwijderd schreef op vrijdag 18 april 2008 @ 15:00:
In mijn ervaring haalt de controller de data op uit het model en geeft die data door aan de view.
Nee. Het is een kringloop. View > Controller > Model > View.

De view haalt data op uit het model, input op deze view wordt door de controller naar het model gestuurd. Het model geeft een "DataChanged" event indien nodig. De view haalt de nieuwe data uit het model.

Binnen het model heb je over het algemeen een bussiness laag (je bussiness objecten) en een data laag welke bussiness objecten mapped op je onderliggende database.

In PHP lijkt het me dit wat lastiger aangezien je niet echt met events kunt werken, in princiepe verwerk je op elke page eerst input (dus via je controller > model) en haalt dan data op om deze weer te geven (model > view).

[ Voor 29% gewijzigd door Hydra op 18-04-2008 16:01 ]

https://niels.nu


Acties:
  • 0 Henk 'm!

  • neothor
  • Registratie: Oktober 2004
  • Laatst online: 02-10-2023
basvd schreef op vrijdag 18 april 2008 @ 14:14:
Nu bedacht ik mij vandaag opeens of het niet interessant is om gebruik te maken van het 3 lagenmodel (MVC), met name de scheiding van Model&Contoller leek mij wel een goed idee.
Ik zou ook de View scheiden van de de Model en Controller. Uit ervaring kan ik zeggen dat je er heel blij mee bent wanneer je later er weer mee moet werken.

Verder zag ik dat je PHP4 moet/wil gebruiken. Dan wens ik je succes want je zal denk ik snel tegen de beperkingen aan gaan lopen. Dus wanneer je kan zou ik overschakelen op PHP5

Last.fm | LinkedIn | Twitter


Acties:
  • 0 Henk 'm!

  • Y0ur1
  • Registratie: Oktober 2000
  • Niet online
Waarom geen bestaand framework gebruiken zoals CakePHP of Symfony? Gebaseerd op resp. PHP4 en PHP5

Acties:
  • 0 Henk 'm!

Verwijderd

Wat je zou kunnen doen is een reeds bestaand framework gebruiken, denk bijvoorbeeld aan het Zend Framework.

Wat je ook kunt doen is een eigen framework maken(Heb ik ook gedaan, leek me leuker, handiger en leerzamer).
  1. Je gaat allereerst uitdenken van hoe je je applicatie wil opzetten.
  2. Bedenk een goede mappenstructuur waarin overzicht een belangrijke rol speelt.
  3. Je begint met het opstarten en afsluiten van de applicatie. Ik doe dat zo: Main::init() en Main::close(). Daartussen staat dan Router::dispatch(). daar kom ik zo op.
  4. Maak een Registry class, zie daarvoor het Registry pattern en het Singleton pattern. Dit register zal objecten gaan houden die je zo gemakkelijk in heel je applicatie kunt opvragen.
  5. Je gaat je router maken, het lijkt me dat je zulke URLS wil: http://www.jewebsite.nl/controller/method/param1/param2. Ik zou hiervoor multiviews gaan gebruiken. Je kijkt dan met je router waar je heen moet. De startpagina? De 404 pagina? Of de opgevraagde pagina. Je roept de gevraagde controller aan.
  6. De gevraagde controller wordt opgestart. Ik zou dan nog een base controller maken. De 'normale' controllers overerven de base controller. Het beste lijkt me hier om een base controller voor 'nomale' pagina's te maken en een base controllers voor beheerpagina's. Zorg dat de base-controllers abstract zijn, een interface zou kunnen maar lijkt mij in dit opzicht minder geschikt omdat je in je base controller toch wat code zal moeten uitvoeren en dat niet in een interface kan.
  7. Je controller gaat met het model communiceren, vragen om bepaalde gegevens bijvoorbeeld.
  8. Je controller gaat met de view communiceren, hij heeft bepaalde data.
  9. Je template parser gooit alles op het scherm.
Een handige template parser hiervoor is Smarty of Template lite.

PHP 4 lijkt me trouwens buitengewoon onhandig hiervoor, als de host (nog steeds) geen PHP 5 gebruikt zou ik dat toch wel gaan afdwingen nu, PHP 5 wordt inmiddels veel gebruikt en PHP 6 is alweer opweg.

Ik hoop dat je wat aan mijn post hebt gehad & succes!

[ Voor 5% gewijzigd door Verwijderd op 20-04-2008 19:15 ]


Acties:
  • 0 Henk 'm!

  • basvd
  • Registratie: December 2007
  • Laatst online: 20-09 14:48
Een beetje een late reactie..., het idee van het MVC-model is me vanaf nu een stuk duidelijker geworden. Nu alleen nog even een juiste template-engine kiezen.

WouZz bedankt voor je voorbeeld, ivovanbeek(en de rest) ook bedankt voor de heldere uitleg :)

...'Keuze' voor PHP4 heeft trouwens te maken met het feit er op de (eigen-)server applicaties draaien die momenteel alleen onder PHP4 werkzaam zijn(we zijn al aan het testen op PHP5...).

[ Voor 4% gewijzigd door basvd op 23-04-2008 10:27 ]

Pagina: 1