Model View Controller (MVC) pattern

Info 
Door: Franky Braem Moeilijkheidsgraad: 3/3
Views:20.882Reacties: 3(Bekijken)
  Log in om zelf te reageren
 Waardering:10/10 (3 stemmen)



Het Model View Controller (MVC) pattern wordt veel gebruikt bij het maken van webapplicaties. De bedoeling van dit pattern is om de code in 3 verschillende niveau's te verdelen: Model, View en Controller.
Dit artikel probeert uit te leggen hoe je MVC kan toepassen in PHP. Enige kennis van OO is welkom.
Opgelet: dit artikel gebruikt PHP5 code (maar het is gemakkelijk om dit naar PHP4 te wijzigen) en de code uit het artikel ADOdb.

Model.
Model objecten bevatten de applicatie logica (ook wel business logica genoemd). De taak van deze objecten bestaat er in om de data een betekenis te geven. Meestal zullen deze objecten methodes bevatten om database queries uit te voeren. Het is een goed idee om alleen in deze objecten database queries te gebruiken.
Een voorbeeld:

#Code
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
class Gebruiker
{    
   private $naam;
   private $geboorte_datum;

   function __construct($id)
   {                       
     $db = DBMS::get_db(); // Zie ADOdb code
     $data = $db->Execute('SELECT *
                             FROM gebruiker
                            WHERE id = ?', array($id));
     if ( $data )
     {
        $this->naam = $data[0];
        $this->geboorte_datum = $data[1];
     }                            
   }
   
   public function get_naam()
   {
     return $this->naam;
   }
   
   public function get_geboorte_datum()
   {
     return $this->geboorte_datum;
   }
}


Het voordeel van een klasse Gebruiker is dat je dit overal kan hergebruiken. Gedaan met overal queries te plaatsen. Aan deze klasse kan je ook extra functionaliteiten toevoegen. Zo kan je een functie toevoegen die de leeftijd berekent van een gebruiker.

View.
View objecten bevatten de logica om een pagina op te bouwen. View objecten kunnen data opvragen van Model objecten, maar kunnen (mogen) de data niet wijzigen.
Een voorbeeldje:

#Code
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
class GebruikerView
{  
  private $data;
  
  function __construct()
  {
    $this->data = array();
  }

  function set_data($name, $model)
  {
    $this->data[$name] = $model;
  }
  
  function show()
  {
?>   
    <p>
     Dit zijn de gegevens van de gebruiker <br />
     Naam: 
<?php echo $this->data['gebruiker']->get_naam() ?> <br />
     Geboortedatum: 
<?php echo $this->data['gebruiker']->get_geboorte_datum() ?>
    </p>
<?php  
  
}
}

Wanneer je MVC goed toepast, dan zijn de View objecten de enige objecten die HMTL code bevatten. Dit verbetert de onderhoudbaarheid van de toepassing.

Controller.
Hoe krijgen de View objecten toegang tot de Model objecten? En wie roept de functie show op?
De taak van de controller is om aan de hand van het request te bepalen welke model objecten er nodig zijn en welke view er moet gebruikt worden.

Een voorbeeld van een controller:
#Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php                           
  
// gebruiker.php
  switch($_GET['view'])
  
{
    
case 'gebruiker':
      
include_once('gebruiker/models/gebruiker.php');
      
include_once('gebruiker/views/gebruiker.php');
      
$gebruiker = new Gebruiker($_GET['id']);
      
$view = new GebruikerView();
      
$view->set('gebruiker', $gebruiker);
      
$view->show();
      
break;
    
case ...
  
}
?>

website structuur
Om dit alles overzichtelijk te houden is het goed dat je even nadenkt over de folderstructuur van je website. Plaats de controllers in de root-directory. Maak voor iedere controller een folder met dezelfde naam. Onder deze folder maak je twee folders: models (voor de model klassen) en views (voor de view klassen). Een voorbeeldje:

#Code
1
2
3
4
5
6
gebruiker.php    
/gebruiker
/gebruiker/models
/gebruiker/models/gebruiker.php
/gebruiker/views
/gebruiker/views/gebruiker.php


Commands
Om te vermijden dat een controller onoverzichtlijk wordt, kan je het Commando pattern gebruiken. In plaats van de view door te geven die moet getoond worden, geven we de naam van het commando door.

Het commando om hetzelfde te bereiken als in het vorige voorbeeld ziet er zo uit:
#Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php 
  
include_once('gebruiker/models/gebruiker.php');
  
include_once('gebruiker/views/gebruiker.php');
  
  
// Toon de gebruiker
  class Toon
  
{
    
function execute()
    
{                 
      
if ( isset($_GET['id'] )
      
{
        
$gebruiker = new Gebruiker($_GET['id']);
        
$view = new GebruikerView();
        
$view->set('gebruiker', $gebruiker);
        
$view->show();
      
}
      
else
      
{
        
echo 'Onvoldoende gegevens';
      
}
    
}
  
}
?>

Maak voor de commando's ook een aparte folder onder de folder van de controller.

De controller kan nu veel eenvoudiger gemaakt worden:
#Code
1
2
3
4
5
6
7
8
9
<?php
  $if ( ! isset($_GET['cmd']) )
    
die('URL is niet correct');
  
  
$class_name = $_GET['cmd'];
  
include_once('gebruiker/cmd/' . $class_name . '.php');
  
$cmd = new $class_name();
  
$cmd->execute();
?>

Het uitvoeren van dit commando doe je als volgt:

#Code
1
gebruiker.php?cmd=toon&id=1

Nu kan je zoveel commando's maken als je wil, zonder dat je de controller moet wijzigen.

3 reacties
aymiphilm Geplaatst op 21-11-2010 om 13:10
 

Regular
hoi,

Bedankt voor de info. Ik ben wat aan het proberen mijn weg te vinden in het MVC pattern (php lukt op zich wel al) maar heb nog een probleem:

Ik heb een inlogpagina gemaakt in html die na het inloggen naar een php-pagina verwijst waar een controller wordt aangemaakt. In die controller wordt dan een model en view aangemaakt en in de view staat de html-code. Echter, hoe moet ik vanuit die view naar een functie verwijzen uit de controller? Daar ben ik nog niet helemaal in mee vrees ik.

Alvast bedankt!
Franky Braem Geplaatst op 25-08-2004 om 08:45
 

Regular
Bedankt sotto. Het artikel is aangepast.
sotto Geplaatst op 23-08-2004 om 12:23
 

Regular
Ik kan me vergissen ... ik heb nog geen php5 gedaan...maar,
in uw view:
function set_data($name, $model)
{
$data[$name] = $model;
}

moet dat niet $this->data[$name] zijn?

Pagina 1 

Om te reageren moet je ingelogd zijn.
Nog niet geregistreerd? Doe dat dan nu!


Terug naar gewone pagina

Websitemaken wordt gehost door Nucleus.be, uw Hosting Solution Builder