[PHP] MVC implementatie vragen

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • Gehakt
  • Registratie: Juli 2002
  • Laatst online: 12-09 08:01
Ik heb altijd al eens het idee gehad om een simpele website te maken.
Voor dat ik verder met mijn vraagstelling kom wil ik vast zeggen dat dat het doel van deze website maken niet de website zelf is. Het doel is door te krijgen hoe de MVC architectuur toegepast in PHP werkt.
Antwoorden als "gebruik gewoon een CMS/Framework als CakePHP of Joomla" heb ik dus niet zoveel aan :) Dit leek mij namelijk wel een goede manier om de html en php code gescheiden te houden.
Nu kan ik wel een beetje programmeren maar en ik weet ook wel wat classes zijn en constructors etc maar echt OOP programmeren is voor mij nog nieuw omdat ik begonnen ben met C. Daarom wil ik graag advies en correcties waar mijn aannames niet kloppen.

Dat gezegd hebbende en een hoop te hebben gelezen heb ik nu de volgende opzet in gedachte:
Ik wil alles op een punt binnen laten komen.
Bij index.php.

Dit verwarde mij een beetje omdat ik dacht dat dit al de controller was maar uiteindelijk kreeg ik door dat index.php ook wel de "front controller" of "router" genoemd word?

Het doorsturen doe ik met mod_rewrite:
code:
1
2
3
4
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]


Vervolgens laad ik de juiste controller in index.php:
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
<?php
session_start();
error_reporting  (E_ALL);

/*
Hier splits ik de aanroep url en zet alle stukken in de array 'url'
*/
$_SESSION['url'] = explode("/", $_SERVER['REQUEST_URI']);

function __autoload($class_name)
{
    require_once "lib/" . $class_name . ".php";
}

switch($_SESSION['url'][1])
{
    case "news":
        require  "lib/NewsController.php";
        break;
/*
      case "etc":
                require "lib/Etc.php";
                break;
*/
    default:
        break;
}

Ik heb in een boek gelezen dat als er alleen php code in je bestand staat het handig is om de sluit tag "?>" weg te laten. Hierdoor zou je voorkomen dat er al een spatie verstuur word en je daardoor de fout kan krijgen dat de headers al verstuurd zouden zijn. Volgens het boek was de sluittag optioneel, klopt dit en word dit vaak toegepast?

Het enige wat ik niet snap is hoe ik de controller in een class onder kan brengen. Is dit ook wel nodig want ik heb volgens mij ook voorbeelden gezien waar de controller gewoon procedureel word geprogrammeerd.
NewsController
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
$model = new NewsModel($dataBaseObject);

//Stel de paginatitel in
$model->title = "paginatitel";

// Haal nieuws op uit database en sla het op in een array in het modelobject.
$model->GetNews();

//Geef view toegang tot het model
$view = new NewsView($model);

//Geef de data uit het model weer met html
$view->Header();
$view->ViewNewsTable()


Dit zou dan het de model en view class 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
<?php
class NewsModel extends BaseModel
{
    var $news = NULL;
    var $databaseObject = NULL;
    
    function __construct(&$databaseObject)
    {
                $this->databaseObject =& $databaseObject;
    }

        function GetNews()
    {
              //sql
        }       
    function DeleteNews($id)
    {
              //sql
        }
    
    function CreateNews()
    {
              //sql
        }
}

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
<?php
class NewsView extends BaseView
{

       // var $model staat in de basisview
    
    function __construct(&$model)
    {
        $this->model =& $model;
    }

    
    function Header()
    {
    echo<<<HTML
    //header html
HTML;
    }   
    
    
    function ViewNewsTable()
    {
    echo<<<HTML
    //html & loop over  model news array
HTML;
    }
}

Let alsjeblieft niet op kleine syntax fouten en vergeten $ tekens etc, daar gaat het mij niet om.
Nou ik heb dan nog een boel vragen waar ik geen antwoord op heb :*)
  1. Wat mij in verwarring brengt is dat je in veel modellen het volgende ziet:
    Controller->Model->View. Waarbij er gezegd word dat de controller het model aanpast. Dit is logisch maar geeft de controller vervolgens ook het commando aan View voor de weergave? Zoals in mijn voorbeeldcode.
    Oftewel waar roep ik de View aan om aan het werk te gaan en eens wat te laten zien.
  2. Wat als ik bijvoorbeeld in plaats van html LaTeX output wil. Dus dat ik een popup krijg met een aangeboden latex tekstbestand. Schrijf ik hier dan een aparte View class voor of prop ik dat in 1 view class waar ik voor html en latex andere methoden aanroep?
  3. Klopt het dat de php "?>" sluittag optioneel is en is het standaard om deze weg te laten in php only bestanden of word deze eigenlijk altijd geschreven?
  4. Word de controller procedureel geprogrammeerd of is ook die onder te vangen in een class.
    Zo ja hoe ziet die class er ongeveer uit en wat voor methoden kan ik hier in verwachten.
    Aangezien mijn index.php eigenlijk alleen doorstuurt naar een andere controller zou ik denken dat deze dan zijn eigen methodes vanuit zijn construct aan zou moeten gaan roepen.
    Dit lijkt mij nogal een vreemde manier van programmeren.
Graag antwoorden en op/aanmerkingen op de door mij geproduceerde code. :+ 8)

Acties:
  • 0 Henk 'm!

  • dev10
  • Registratie: April 2005
  • Laatst online: 09-09 15:21
Gehakt schreef op maandag 09 februari 2009 @ 15:41:
Wat mij in verwarring brengt is dat je in veel modellen het volgende ziet:
Controller->Model->View. Waarbij er gezegd word dat de controller het model aanpast. Dit is logisch maar geeft de controller vervolgens ook het commando aan View voor de weergave? Zoals in mijn voorbeeldcode.
Oftewel waar roep ik de View aan om aan het werk te gaan en eens wat te laten zien.
Ja, dat doet de controller inderdaad zoals te zien is in onderstaand plaatje:
Afbeeldingslocatie: http://book.cakephp.org/img/basic_mvc.png
Wat als ik bijvoorbeeld in plaats van html LaTeX output wil. Dus dat ik een popup krijg met een aangeboden latex tekstbestand. Schrijf ik hier dan een aparte View class voor of prop ik dat in 1 view class waar ik voor html en latex andere methoden aanroep?
Dan zou je een andere view moeten hebben.

- view.html > HTML
- view.json > JSON
- view.xml > XML
- view.latex > LaTeX

Ruby on Rails handelt dit heel netjes af.
Klopt het dat de php "?>" sluittag optioneel is en is het standaard om deze weg te laten in php only bestanden of word deze eigenlijk altijd geschreven?
Geen idee eigenlijk. Ik sluit altijd alles netjes af. :+
Word de controller procedureel geprogrammeerd of is ook die onder te vangen in een class.
Zo ja hoe ziet die class er ongeveer uit en wat voor methoden kan ik hier in verwachten.
Aangezien mijn index.php eigenlijk alleen doorstuurt naar een andere controller zou ik denken dat deze dan zijn eigen methodes vanuit zijn construct aan zou moeten gaan roepen.
Dit lijkt mij nogal een vreemde manier van programmeren.
Een voorbeeldje wat ik gebruik in m'n eigen framework in ontwikkeling:

- Ik heb een abstracte class Controller met een volgende constructor

PHP:
1
2
3
4
5
6
7
8
9
10
11
public function __construct() {
        $controller_method = (URL::section(2) === null) ? 'index' : (string) URL::section(2);

        $controller_method = (empty($controller_method)) ? 'index' : $controller_method;

        if (method_exists($this, $controller_method)) {
            call_user_func(array($this, $controller_method));
        } else {
            Site::set_404();
        }
    }



Mijn controllers zijn als volgt opgebouwd:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
ApplicationController extends Controller {
  public function index()
  {

  }

  public function edit()
  {

  }

  // Enzovoort. 
}


Dit in combinatie met m'n __autoload() werkt erg goed.

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
function __autoload($class_name) {
    static $files = null;

    $succes = false;
    $class_file = strtolower($class_name) . '.php';
    $dirs = array(APPLICATION_PATH . '/lib/classes',
                  APPLICATION_PATH . '/lib/controllers',
                  APPLICATION_PATH . '/lib/models');

    if (empty($files)) {
        $files = array();

        foreach ($dirs as $dir) {
            $glob = glob( $dir . '/*.php' );
            if ( $glob === false || empty( $glob ) ) continue;
            $fnames = array_map(create_function('$a', 'return strtolower(basename($a));'), $glob);
            $files = array_merge($files, array_combine($fnames, $glob));
        }
    }

    if(isset($files[$class_file])) {
        require_once $files[$class_file];
        // If the class has a static method named __static(), execute it now, on initial load.
        if(class_exists($class_name, false) && method_exists($class_name, '__static') ) {
            call_user_func(array($class_name, '__static'));
        }
        $success= true;
    }
}


M'n models zijn op een zelfde manier opgebouwd als de controllers. Dus met een abstracte class en classen die erven van de abstracte class.
Graag antwoorden en op/aanmerkingen op de door mij geproduceerde code. :+ 8)
Serious? Ik vind het er IMHO een beetje ranzig uit zien.

Dingetjes die me opvallen:
- Je hebt wat HTML en PHP gemixt in je view bestand.
- Je slaat je URL op in je $_SESSION.
- Je autoload is wat simpel. Wat als een bestand niet bestaat? Dan krijg je natuurlijk een Fatal error. 8)7

[ Voor 0% gewijzigd door dev10 op 09-02-2009 16:23 . Reden: Domme opmerking doorgestreept ]


Acties:
  • 0 Henk 'm!

  • LuCarD
  • Registratie: Januari 2000
  • Niet online

LuCarD

Certified BUFH

Gehakt schreef op maandag 09 februari 2009 @ 15:41:
Ik heb altijd al eens het idee gehad om een simpele website te maken.
Voor dat ik verder met mijn vraagstelling kom wil ik vast zeggen dat dat het doel van deze website maken niet de website zelf is. Het doel is door te krijgen hoe de MVC architectuur toegepast in PHP werkt.
Antwoorden als "gebruik gewoon een CMS/Framework als CakePHP of Joomla" heb ik dus niet zoveel aan :)
Niet om een betweter te lijken. Maar kijk toch eens naar CakePHP ( ken ik persoonlijk niet ) of Zend. Niet omdat jij die moet gaan gebruiken, maar daar word wel duidelijke voorbeelden gegeven van MVC applicaties en complete structuur is al redelijk af.
Joomla is als Framework niet echt handig, deze is IMHO erg geschreven voor een bepaald doel, het joomla CMS.
Dit verwarde mij een beetje omdat ik dacht dat dit al de controller was maar uiteindelijk kreeg ik door dat index.php ook wel de "front controller" of "router" genoemd word?
Zend noemt het een front-controller en Joomla een router. In essentie het ongeveer het zelfde. De enige logica die hierin zou mogen voorkomen is de juiste controller aan roepen.
Ik heb in een boek gelezen dat als er alleen php code in je bestand staat het handig is om de sluit tag "?>" weg te laten. Hierdoor zou je voorkomen dat er al een spatie verstuur word en je daardoor de fout kan krijgen dat de headers al verstuurd zouden zijn. Volgens het boek was de sluittag optioneel, klopt dit en word dit vaak toegepast?
Ja, dat klopt. Of het moet gebruiken, dat hangt eigenlijk van je eigen stijl af. Het is toegestaan, persoonlijk vindt ik het lelijk staan, en gebruik ik het nooit.

Het zend framework doet het wel in zijn eigen bestanden.
Het enige wat ik niet snap is hoe ik de controller in een class onder kan brengen. Is dit ook wel nodig want ik heb volgens mij ook voorbeelden gezien waar de controller gewoon procedureel word geprogrammeerd.
Natuurlijk kan dat, maar is dat netjes? NEE. Dan zou je eigenlijk helemaal geen MVC moeten doen. Want hoe zou jij nu een andere actie willen doen op dezelfde controller? Bijvoorbeeld in plaats van tonen van het nieuws wil jij het nieuws bewerken.

Verder heb je binnen de MVC 2 kampen, die beide trouwens imho niet fout zijn. Je hebt of een zware controller, of een zware model. De logica van de applicatie wordt of in de Controller gedaan of de logica in de Model.
Bij een zware Controller, word er een uitgebreide validatie gedaan op de input. Aan de hand van de input word er besloten of de model en welke actie word aan geroepen of dat er een foutmelding word gegeven.
Bij een zware Model, word er nagenoeg geen validatie gedaan in de controller. Er word alleen gekeken welke model en welke actie er word aan geroepen. De model geeft dan een foutmelding terug aan de hand daarvan word er een beslissing genomen om een fout pagina te tonen of niet.

De zware controller optie kom je voor mijn gevoel het meeste tegen, terwijl een zware model imho eigenlijk beter is.
Wat mij in verwarring brengt is dat je in veel modellen het volgende ziet:
Controller->Model->View. Waarbij er gezegd word dat de controller het model aanpast. Dit is logisch maar geeft de controller vervolgens ook het commando aan View voor de weergave? Zoals in mijn voorbeeldcode.
Oftewel waar roep ik de View aan om aan het werk te gaan en eens wat te laten zien.
Ja, en dan haalt de view data uit het model.
Wat als ik bijvoorbeeld in plaats van html LaTeX output wil. Dus dat ik een popup krijg met een aangeboden latex tekstbestand. Schrijf ik hier dan een aparte View class voor of prop ik dat in 1 view class waar ik voor html en latex andere methoden aanroep?
Daar ben jij inprincipe vrij in. Maar als jij met een template engine werkt dan is dat vaak niet eens nodig.
Aangezien je achter de view ook nog een keer een template engine kan hebben draaien.
Klopt het dat de php "?>" sluittag optioneel is en is het standaard om deze weg te laten in php only bestanden of word deze eigenlijk altijd geschreven?
Er is geen standaard, hij mag weg gelaten worden
Word de controller procedureel geprogrammeerd of is ook die onder te vangen in een class.
Zo ja hoe ziet die class er ongeveer uit en wat voor methoden kan ik hier in verwachten.
Aangezien mijn index.php eigenlijk alleen doorstuurt naar een andere controller zou ik denken dat deze dan zijn eigen methodes vanuit zijn construct aan zou moeten gaan roepen.
Dit lijkt mij nogal een vreemde manier van programmeren.
Zoek eens een mooie tutorial van Zend op :P
Nee, zonder gekheid. Het zend framework ( hoogst waarschijnlijk Cake ook ) heeft hele mooie tutorials over MVC gebruik. Die zijn uitgebreider dan ik hier kan en wil tikken ( programmeurs zijn lui :P ).

[ Voor 3% gewijzigd door LuCarD op 09-02-2009 16:32 ]

Programmer - an organism that turns coffee into software.


Acties:
  • 0 Henk 'm!

  • dev10
  • Registratie: April 2005
  • Laatst online: 09-09 15:21
LuCarD schreef op maandag 09 februari 2009 @ 16:32:
De zware controller optie kom je voor mijn gevoel het meeste tegen, terwijl een zware model imho eigenlijk beter is.
Ruby on Rails is zo'n framework met een zwaar model. De validaties van RoR vind ik echt schitterend.

Voorbeeldje:
code:
1
2
3
4
5
validates_uniqueness_of :username, :email
validates_confirmation_of :password
validates_size_of :password, :within => 8..15
validates_size_of :username, within => 3..25
validates_presence_of: username, :email, :password


Ik ben zo gek op dat framework. O-)