Ankündigung

Einklappen
Keine Ankündigung bisher.

MVC - Skript anpassen

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • MVC - Skript anpassen

    Hi,

    habe eine Verständnisfrage zu MVC. Ich habe einen Skript, bei dem ich gerne die MVC-Struktur anwenden würde. Ich habe die meisten Klassen, die Daten aus der Datenbank benötigen etwa so aufgebaut:

    PHP-Code:

    class Page_News_Entry
    {

        protected 
    $title;
        protected 
    $content;
        ...

        public function 
    __construct()
        {
             
    $this->db_connection Page_Registry::get_('db_connection_news');
        }

        public function 
    init($entry_id)
        {
             
    //Holt Infos aus der Datenbank
        
    }

        
    //Methoden zum erstellen von neuen Einträgen, bearbeiten, ...

        //Getter und Settermethoden 
    Die Dateien, die aufgerufen werden sehen etwa so aus:

    PHP-Code:

    //Autoloader initialisieren, configs einbinden, session starten,...
    //Smarty initialisieren

    switch($_GET['mode'])
    {

        case 
    'overview':
        {
             
    $overview = new Page_News_Overview();
             
    $overview->init();
             
    $smarty->assign('news'$overview->get_news());
             
    $smarty->display('overview.tpl');
             break;
        }
        ...


    Wenn ich jetzt Einen Controller einfüge muss ich das ganze dann folgendermaßen machen??

    PHP-Code:
    class Page_News_Controller
    {
         protected 
    $view//Smarty  in meinem fall
         
    protected $data// Das Page_News_Overview oder News_... Objekt??
         
    protected $request;

         public function 
    __construct($request)
         {
              
    $this->request $request;
         }

         public function 
    display($view)
         {
              
    $this->view $view;
              
    $this->view->assign('header'$this->view->fetch('header.tpl'));
              
    $this->view->assign('footer'$this->view->fetch('footer.tpl'));
              switch(
    $this->request['mode'])
              {
                   case 
    'overview':
                   {
                       
    $this->data = new Page_News_Overview();
                       
    $this->data->init();
                       
    $this->view->assign('news'$this->data->get_news());
                       
    $this->view->assign('content'$this->view->fetch('overview.tpl'));
                       break;
                   }
              }
              
    $this->view->display('default_template.tpl');
          } 
    Und aufrufen dann folgendermaßen??

    PHP-Code:

    //Autoloader initialisieren, configs einbinden, session starten,...
    //Smarty initialisieren

    $controller = new Page_News_Controller($_GET);

    $controller->display($smarty); 
    Also nochmal kurz und knapp:

    1. Kann ich meine Klassen in der Struktur wie oben weiterverwenden oder sollte ich nochmal komplett von vorne beginnen?? Also muss ich umbedingt neuanfangen oder reicht es bei den nächsten Projekten etwas anders an die Sache rangehen??

    2. Habe ich es einigermaßen korrekt verstanden oder lebe ich in meiner eigenen Welt

    Hoffe das die Fragen gut verständlich formuliert sind!

    Thx und mfg

    Yanko

  • #2
    Hallo,

    üblicherweise hast du eine Bootstrap-Datei, also eine zentrale index.php, die mit Hilfe eines FrontControllers den Request zerlegt und an den aufzurufenden Controller übergibt.

    Deinen Page_News_Controller kannst du also im Prinzip so lassen. Nur was ist display(), hast du nicht mehrere Actions pro Controller? Wenn ja, häng noch ein Postfix oder Prefix an den Methodennamen dran, sonst bekommst du Probleme mit reservierten Wörtern in PHP (Function, Class, ..). Sprich statt display() einfach displayAction() z.B.

    Deinen Page_News_Entry solltest du so umbauen, dass du die Datenbankverbindung nicht einfach über die Registry aus dem Nichts holst, sondern übergibst (so wie du es mit $_GET schon für den Controller machst). Sprich deine Controller-Action holt sich die Datenbankverbindung (z.B. über eine Registry) und übergibt sie der Page_News_Entry. So bist du etwas flexibler, koppelst Page_News_Entry nicht an die Registry.
    "[URL="http://www.youtube.com/watch?v=yMAa_t9k2VA&feature=youtu.be&t=25s"]Mein Name ist Lohse, ich kaufe hier ein.[/URL]"

    Kommentar


    • #3
      Die Actions regele ich über switch anhand der requests, wie sollte den der Controller mit mehreren Actions aussehen? Um die richtigen auszuwählen bräuchte man doch switch in der index.php wenn es nicht in der Actionmethode steht.

      E: Sonst is an der Page_News_Entry alles in Ordnung, weil ich habe die Klasse bereits entworfen bevor ich mich mit MVC beschäftigt habe.

      Kommentar


      • #4
        PHP-Code:
        <?php
        class MyController
        {
          public function 
        displayAction() {}
          public function 
        editAction() {}
          public function 
        deleteAction() {}
        }
        ?>
        Das sind mehrere Controller-Actions.
        "[URL="http://www.youtube.com/watch?v=yMAa_t9k2VA&feature=youtu.be&t=25s"]Mein Name ist Lohse, ich kaufe hier ein.[/URL]"

        Kommentar


        • #5
          Also auf dein Beispiel bezogen mit FrontController:

          So bearbeite ich einen Newseintrag

          PHP-Code:
          $controller = new FrontController($_GET); 
          Dieser entscheidet dann mit switch:

          PHP-Code:
          case 'edit':
          {
              
          $mycontroller = new MyController($this->data);  //Übergibt $_GET das mitlerweile im Frontcontroller ist
              
          $mycontroller->editAction();
              
          $mycontroller->displayAction();
              break;

          Also nur in der displayAction wird ein View verwendet und editAction speichert z.B nur die Daten und gibt ne Meldung über Erfolg ans Objekt zurück?

          Kommentar


          • #6
            Nein, deine editAction() sollte entscheiden, ob displayAction() ausgeführt wird oder nicht. Denn nur die weiß, was nach der erfolgreichen/erfolglosen Speicherung zu tun ist: "Danke"-Seite, "Fehler im Formular" anzeigen und Edit-Formular nochmal aufrufen, ... etc.

            Sprich besser:
            PHP-Code:
            <?php
            $myController 
            = new MyController($this->data);
            $myController->editAction();

            // ..
            class MyController {
              public function 
            editAction() {
                if (
            $this->saveFormData()) {
                  return 
            $this->displayAction();
                } else {
                  
            $this->view->form = new MyNewsForm();
                  
            $this->view->error "Das Speichern hat nicht geklappt";
                  
            $this->renderScript("edit-form.tpl");
                }
              }
            }
            ?>
            Im übrigen solltest du einen generischeren Ansatz verwenden, so dass du nicht für jede Aktion ein neues (switch-)case-Konstrukt bauen musst. Wenn deine URL sich parsen lässt, also http://example.com/news/edit dann kannst du die URL ($_SERVER["REQUEST_URI"]) zerlegen und dann mit $controller = "news", $action = "edit" einfach ein $instance = new $controller();
            $instance->{$action}(); die entsprechende Methode aufrufen. Der Code hier von mir ist nur ein Beispiel, du solltest vorher natürlich prüfen, ob in $controller auch ein erlaubter Aufruf erfolgt, ob die Klasse existiert, ob die Methode existiert etc. Schau dir dazu mal: method_exists, call_user_func und die Reflection API an.

            Natürlich gibts auch schon fertige Lösungen. Unter anderem Zend.
            "[URL="http://www.youtube.com/watch?v=yMAa_t9k2VA&feature=youtu.be&t=25s"]Mein Name ist Lohse, ich kaufe hier ein.[/URL]"

            Kommentar

            Lädt...
            X