home_site

Lab09 - Wzorzec MVC i PDO [ ver. TI.2025.11.27.003 ]

Zawartość strony

Plan zajęć

Wzorzec MVC

W ramach zajęć zostanie przedstawiona konstrukcja aplikacji w oparciu o wzorzec MVC. Wzorzec MVC składa się z trzech komponentów programowych - modelu, widoku i kontrolera. Komponent kontrolera odpowiedzialny jest za sterowanie aplikacją, powinien zawierać kod php, brak zapytań do bazy danych oraz brak kodu HTML. Komponent szablonów odpowiedzialny jest za przygotowanie stron przesyłanych do użytkownika. Zawiera on skrypty wprowadzające wartości zmiennych do odpowiednich szablonów przygotowanych w języku HTML. Na koniec komponent modelu zawiera interfejs połączenia z źródłem danych, zawiera on instrukcje względnie polecenia przetwarzające dane w źródle. Komponent ten nie powinien zawierać kodu HTML. Na rys.1 przedstawiono przykładowy diagram sekwencji prezentujący przepływ danych w ramach modelu MVC.

Lab10_MVC
Rys.1 Przykładowy diagram sekwencji realizowany w modelu MVC.

W ramach zajęć zostanie opracowana prosta aplikacja spełniające przedstwione powyżej kryteria. Struktura plików w opracowanym projekcie została przedstawiona poniżej.

mvc2/
  ├──▻ appl/  { View.php, Controller.php }
  ├──▻ template/ { hello.tpl, table.tpl, main.tpl, listall.tpl, form.tpl, menu.tpl }
  ├──▻ test/ { Test.php }
  ├──▻ info/ { Model.php, Info.php }
  ├──▻ baza/ { Model.php, Baza.php }
  ├──▻ sql/ { baza.sql, baza.db }
  ├──▻ css/  { main.css }
{ test_hello.php, test_view.php, test_controller.php, index.php }

Szablon i jego obsługa

W ramach tego zadania przedstawione zostaną skrypty realizujące funkcjonalność widoku w naszej prostej aplikacji zrealizowanej zgodnie z wzorcem MVC. Na początek prosty szablon, w którym będziemy modyfikować niektóre fragmenty kodu. Wykorzystamy język php i polecenia echo lub print.

  1. Szablon w HTML. Tworzymy plik hello.tpl i umieszczamy w katalogu template.

    Plik hello.tpl - ( [listing dokumentu] [link do dokumentu] )

       <!DOCTYPE html>
     
    <html>
        <head>
            <title>Simple MVC</title>
        </head>
        <body>   
            <header><?php echo $title; ?></header>
            <section>
              <header><?php echo $header; ?></header>
              <article><?php echo $content; ?></article> 
            </section>
            <footer>Techniki internetowe &copy; 2023</footer> 
        </body>
    </html>
      
  2. Sprawdzamy poprawność działania naszego szablonu poniższym skryptem testowym (plik test_hello.php).

    Plik test_hello.php - ( [listing dokumentu] [link do dokumentu] )

    <?php
    
    $title = 'Simple MVC' ;
    $header = 'Test template' ;
    $content = '<p>Hello, World</p>' ;
    include ('template/hello.tpl') ;
    
    ?>  
  3. W kolejnym punkcie zadania opracujemy klasę do obsługi wykorzystywanych w projekcie szablonów. Klasa ta będzie wykorzystywana w naszym projekcie "Simple MVC" do obsługi widoku. Klasę View zapisujemy w pliku View.php i umieszczamy w katalogu appl.

    Plik View.php - ( [listing dokumentu] [link do dokumentu] )

    <?php
    
    namespace appl  ;
     
    class View
    {
        protected $_file;
        protected $_data = array();
         
        public function __construct($template)
        {
            $file = 'template/'.strtolower($template).'.tpl' ;
            if ( file_exists($file) )  
             { $this->_file =  $file ; }
            else 
             { throw new Exception("Template " . $file . " doesn't exist.") ; }
        }
         
        public function __set($key, $value)
        {
            $this->_data[$key] = $value;
        }
         
        public function __get($key) 
        {
            return $this->_data[$key];
        }
         
        public function __toString()
        {         
            extract($this->_data);
            ob_start();
            include($this->_file);
            $output = ob_get_contents();
            ob_end_clean();
            return $output;
        }
    }
    
    ?>  
  4. Opracowaną klasę przetestujemy przy pomocy poniższego skryptu testowego. (plik test_view.php w głównym katalogu).

    Plik test_view.php - ( [listing dokumentu] [link do dokumentu] )

    <?php
    
    include 'appl/View.php' ;
    
    use appl\View ;
    
    $view = new view('hello');
    
    $view->title = 'Simple MVC' ;
    $view->header = 'Test template' ;
    $view->content = '<p>Hello, World</p>' ;
    
    echo $view ;
    
    ?>  

Kontroler naszej aplikacji

Zadaniem kontrolera jest odbiór żądań klienta i odpowiednia ich obsługa. W przypadku prostego żądania wystarczy pobrać odpowiedni szablon i wysłać odpowiedź do klienta poprzez widok, w bardziej złożonej sytuacji, należy pobrać dane np. z bazy danych i po przetworzeniu wysłać informację do klinta. Ten element zadania najczęciej wykonuje w wzorcu MVC komponent modelu. W ramach tego punktu opracujemy prosty kontroler dla naszej aplikacji. Do sterowania wykorzystamy parametry przesyłane w części QUERY_STRING adresu URL'u wywołania. Schematycznie można to przedstawić następująco:

index.php?sub=zadanie&action=polecenie 

gdzie poprzez zmienną sub wybierzemy zadanie, a poprzez action wybierzemy odpowiednie polecenie.

W ramach naszego projektu kolejne funkcjonalności aplikacji będą umieszczane w osobnych katalogach. Każda funkcjonalność będzie obsługiwana przez swój kontroler, który będzie rozszerzał funkcjonalność głównego kontrolera.

  1. Klasa głównego kontrolera Controller została umieszczona w pliku Controller.php w katalogu appl.

    Plik Controller.php - ( [listing dokumentu] [link do dokumentu] )

    <?php
    
    namespace appl  ;
    
    abstract class Controller {
     
       protected $css ; 
       protected $menu ; 
    
       function __construct() {
          $this->css  = "<link rel=\"stylesheet\" href=\"css/main.css\" type=\"text/css\" media=\"screen\" >" ;
          $this->menu = file_get_contents ('template/menu.tpl') ;
          //$this->css = '' ;
          //$this->menu = '' ;
       }
    
       static function http404() {
          header('HTTP/1.1 404 Not Found') ;
          print '<!doctype html><html><head><title>404 Not Found</title></head><body><p>Invalid URL</p></body></html>' ;
          exit ;
       }
    
       function __call($name, $arguments)
       {
            self::http404();
       }
    
    }
    
    ?>  
  2. Na początek opracujemy klasę kontrolera Test testującą poprawność naszego rozwiązania. Klasa ta dziedziczy po klasie Controller. Odpowiedni skrypt umieścimy w katalogu test/ pod nazwą Test.php.

    Plik Test.php - ( [listing dokumentu] [link do dokumentu] )

    <?php
    
    namespace test ;
    
    use appl\ { View, Controller } ;
    // use appl\Controller ;
    
    class Test extends Controller {
    
       protected $layout ;
    
       function __construct() {
          $this->layout = new View('hello') ;    
          $this->layout->title = 'Test view' ;
          $this->layout->content = 'Hello, World !' ;
       }
    
      function index() {
          return $this->layout ;
      }
    }
    
    ?>  
  3. Poprawność opracowanych skryptów sprawdzimy wykorzystując przedstawiony poniżej skrypt (test_controller.php).

    Plik test_controller.php - ( [listing dokumentu] [link do dokumentu] )

    <?php
    
    include 'appl/View.php' ;
    include 'appl/Controller.php' ;
    include 'test/Test.php' ;
    
    use test\Test ;
    
    $obj = new Test() ;
    echo $obj->index() ;
    
    ?>  

Komponent model i jego implementacja w projekcie

Na początek opracujemy prosty model dostarczający dane z zawartej w nim tabeli. W kolejnym etapie zrealizujemy część aplikacji, wyświetlającą dane zawarte w tabeli. Opracowane w ramach tego punktu skrypty będą już fragmentem naszej docelowej aplikacji, będzie to część informacyjna. Odpowiednie skrypty i klasy zostaną umieszczone w katalogu info.

  1. Na początek tworzymy klasę modelu - Model i umieszczamy ją w pliku Model.php w katalogu info/.

    Plik Model.php - ( [listing dokumentu] [link do dokumentu] )

    <?php
    
    namespace info ;
    
    class Model 
    {
    
       private $table = array() ;
    
       function __construct() {
          $this->table['main'] = '/ , /index.php, /index.php?sub=Info, /index.php?sub=Info&action=main' ;
          $this->table['info'] = '/index.php?sub=Info&action=help' ;
          $this->table['list'] = '/index.php?sub=Baza, /index.php?sub=Baza&action=list' ;
          $this->table['form'] = '/index.php?sub=Baza&action=form' ;      
       }
    
       function getTable() {
         // return 'test - table' ;
         // print 'xxx' ;
         // print_r($table) ;
         return $this->table ;
       }
    
    }
    
    ?>  
  2. Kolejnym elementem, który należy przygotować jest klasa kontrolera Info, którą umieszczamy w pliku Info.php w katalogu info.

    Plik Info.php - ( [listing dokumentu] [link do dokumentu] )

    <?php
    
    namespace info ;
    
    use appl\ { View, Controller } ;
    // use appl\Controller ;
    
    class Info extends Controller {
    
       protected $layout ;
       protected $model ;
    
       function __construct() {
          parent::__construct();
          $this->layout = new View('main') ;   
          $this->layout->css = $this->css ;
          // $this->layout->css = "<link rel=\"stylesheet\" href=\"css/main.css\" type=\"text/css\" media=\"screen\" >" ;  
          $this->layout->menu = $this->menu ;
          // $this->layout->menu = file_get_contents ('template/menu.tpl') ;
          $this->layout->title = 'Simple MVC' ;
       }
    
      function index() {
          $this->layout->header  = 'Simple MVC' ;
          $this->layout->content = 'Template - test !' ;
          return $this->layout ;
      }
    
      function help() {
          $this->model = new Model();
          $this->layout->header  = 'Simple MVC' ;
          $this->view = new View('table') ;
          $this->view->data = $this->model->getTable() ;
          $this->layout->content = $this->view ;
          return $this->layout ;
      }
    
      function error( $text ) {
          $this->layout->content = $text ;
          return $this->layout ;       
      }
    }
    
    ?>  
  3. Tworząc widok wykorzystujemy szablony main.tpl i table.tpl. Szablon main.tpl jest kopią szablonu hello.tpl natomiast zawartość szablonu table.tpl przedstawia poniższy skrypt.

    Plik table.tpl - ( [listing dokumentu] [link do dokumentu] )

    <table border="1">
      <?php 
        if ($data) { 
          foreach ( $data as $key => $value ) { 
            echo '<tr><td>'.$key.'</td><td>'.$value.'</td></tr>' ; }
          //print_r($data) ;
          }
      ?> 
    </table>   
  4. Ostatnim elementem naszej aplikacji wymaganym do poprawnego działania jest przygotowanie odpowiedniego pliku index.php. Przedstawiony poniżej plik zawiera funkcje __autoload() oraz prostą logikę przetwarzającą żądanie przesłane przez klienta.

    Plik index.php - ( [listing dokumentu] [link do dokumentu] )

    <?php
    /***************
     * 
     * 
     ****************/
    function my_autoloader($class_name) {
       // print '{'.$class_name.'}' ;
       $path_to_class = __DIR__. '/' . str_replace('\\', DIRECTORY_SEPARATOR, $class_name) . '.php';
       if ( file_exists($path_to_class) )  
          { require_once($path_to_class); }
       else {
          header('HTTP/1.1 404 Not Found') ;
          print '<!doctype html><html><head><title>404 Not Found</title></head><body><p>Invalid URL</p></body></html>' ;
       }   
    }
    
    spl_autoload_register('my_autoloader');
                   
    use info\Info ;
    use baza\Baza ;
    use test\Test ;
    
    try {
    
      if (empty ($_GET['sub']))    { $contr = 'Info' ;   }
      else                         { $contr = $_GET['sub'] ; }
    
      if (empty ($_GET['action'])) { $action     = 'index' ;  }
      else                         { $action     = $_GET['action'] ; } 
      
      //print $contr. ' ' . $action .' - ';
      
      switch ($contr) {           
         case 'Info' :
           $contr = "info\\".$contr ;                      
           break ;
         case 'Baza' :
           $contr = "baza\\" . $contr ;
           break ;  
      }
      $controller = new $contr ;
      echo $controller->$action() ;
    }
    catch (Exception $e) {
      // echo 'Blad -.- : [' . $e->getCode() . '] ' . $e->getMessage() . '</br>' ;
      // echo __CLASS__.':'.__LINE__.':'.__FILE__ ;
      // $contr = new info() ;
      // echo $contr->error ( $e->getMessage() ) ;
      echo 'Error: [' . $e->getCode() . '] ' . $e->getMessage() ;
    
    }
    
    ?>
      

Baza danych w projekcie

Do realizacji projektu wymagana jest baza danych. Przykładową bazę danych utworzymy w katalogu sql nadając mu uprawnienia: u+r+w+x g+r a+r+w+x. W katalogu tym utworzymy bazę danych baza.db wykorzystując poniższy skrypt sql.

 
create table osoba ( imie char(20), nazwisko char(20), miejscowosc char(20) ) ;
insert into osoba ( imie, nazwisko, miejscowosc ) values ('Adam', 'Kowalski','Krakow');
insert into osoba ( imie, nazwisko, miejscowosc ) values ('Marek','Babacki','Zakopane') ;
insert into osoba ( imie, nazwisko, miejscowosc ) values ('Zofia','Cabacka','Warszawa') ;
insert into osoba ( imie, nazwisko, miejscowosc ) values ('Marta','Dadacka','Olsztyn') ;
insert into osoba ( imie, nazwisko, miejscowosc ) values ('Michal','Zawadzki','Katowice') ;

Polecenie budujące bazę danych - sqlite3 baza.db < baza.sql. Uprawnienia do pliku u+r+w g+r a+r+w.

Wydruk rekordów zawartych w bazie danych - klasa PDO

Do realizacji tego zadania wymagane jest opracowanie następujących skryptów: skrypt modelu do obsługi bazy danych, skrypt kontrolera oraz pliku szablonu.

  1. Na początek przedstawiona zostanie klasa Model zawierająca obsługę bazy danych. Klasa ta została zawarta w pliku baza/Model.php.

    Plik Model.php - ( [listing dokumentu] [link do dokumentu] )

    <?php
    
    namespace baza ;
    use PDO ;
    
    class Model 
    {  
       static $dsn = 'sqlite:sql/baza.db'  ;
       protected static $db ;
       private $sth ;
    
       function __construct()
       {
         $data = explode(':',self::$dsn) ;
         if ( ! file_exists ( $data[1] ) ) { throw new Exception ( "Database file doesn't exist." ) ;  }
         self::$db = new PDO ( self::$dsn ) ;
         self::$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION) ; 
       }
    
    
       public function listAll()
       {
         $this->sth = self::$db->prepare('SELECT * FROM osoba') ;
         $this->sth->execute() ;
         $result = $this->sth->fetchAll() ;
         return $result ;
       }
    
    }
    
    ?>  
  2. Plik szablonu, który umożliwi wyświetlenie zawartości tabeli osoba, przedstawia poniższy kod.(template/listall.tpl).

    Plik listall.tpl - ( [listing dokumentu] [link do dokumentu] )

    <table border="1">
     <?php 
        if ($data) { 
           foreach ( $data as $row ) { 
           echo '<tr><td>'.$row['imie'].'</td><td>'.$row['nazwisko'].'</td><td>'.$row['miejscowosc'].'</td></tr>' ;
        }}
     ?> 
    </table> 
      
  3. Na koniec klasa kontrolera Baza. Klasa znajduje się w pliku baza/Baza.php.

    Plik Baza.php - ( [listing dokumentu] [link do dokumentu] )

    <?php
    
    namespace baza   ;
    
    use appl\ { View, Controller } ;
    // use appl\Controller ;
    
    class Baza extends Controller 
    {
    
        protected $layout ;
        protected $model ;
    
        function __construct() {
           parent::__construct();
           $this->layout = new View('main') ;
           $this->layout->css = $this->css ;
           // $this->layout->css = "<link rel=\"stylesheet\" href=\"css/main.css\" type=\"text/css\" media=\"screen\" >" ; 
           $this->layout->title  = 'Baza danych SQL' ;
           $this->layout->menu = $this->menu ;
           // $this->layout->menu = file_get_contents ('template/menu.tpl') ;
           $this->model  = new Model() ;
        }
    
    
        function listAll() {     
           $this->layout->header = 'Lista wszystkich rekordow' ;
           $this->view = new View('listAll') ;
           $this->view->data = $this->model->listAll() ;
           $this->layout->content = $this->view ; 
           return $this->layout ;
        }
        
        function info ( $text ) {
           $this->layout->content = $text ;
           return $this->layout ; 
        }
    
    
    
        function index ()  {
           // $this->layout->content = $text ;
           return $this->layout ; 
        }
    
    } 
    
    ?>  

Wprowadzanie danych do bazy

Kolejnym elementem tworzonego serwisu będzie opracowanie formularza do wprowadzania danych. W tym celu dodamy do klasy kontrolera dwie metody: pierwsza wywołuje formularz natomiast druga zapisuje dane do bazy danych. Dodatkowo należy dodać metodę zapisującą dane do bazy danych w modelu oraz na koniec opracować odpowiednie szalony.

Na początek dodajemy odpowiednie metody do klasy kontrolera (plik baza/class/Baza.php). Wymagane są dwie metody: insertRec() - metoda wyświetlająca odpowiedni formularz do wprowadzania danych oraz saveRec() - metoda umożliwiająca zapis danych do bazy danych. Po uzupełnieniu metod klasa kontrolera została przedstawiona poniżej.

  1. Plik zawierający klasę Baza (Baza.php) (po modyfikacji).

    Plik Baza.php - ( [listing dokumentu] [link do dokumentu] )

    <?php
    
    namespace baza   ;
    
    use appl\ { View, Controller } ;
    // use appl\Controller ;
    
    class Baza extends Controller 
    {
    
        protected $layout ;
        protected $model ;
    
        function __construct() {
           parent::__construct();
           $this->layout = new View('main') ;
           $this->layout->css = $this->css ;
           // $this->layout->css = "<link rel=\"stylesheet\" href=\"css/main.css\" type=\"text/css\" media=\"screen\" >" ; 
           $this->layout->title  = 'Baza danych SQL' ;
           $this->layout->menu = $this->menu ;
           // $this->layout->menu = file_get_contents ('template/menu.tpl') ;
           $this->model  = new Model() ;
        }
    
    
        function listAll() {     
           $this->layout->header = 'Lista wszystkich rekordow' ;
           $this->view = new View('listAll') ;
           $this->view->data = $this->model->listAll() ;
           $this->layout->content = $this->view ; 
           return $this->layout ;
        }
        
        function insertRec() {
           $this->layout->header = 'Wprowadzanie danych do bazy' ;
           $this->view = new View('form') ;
           $this->layout->content = $this->view ;
           return $this->layout ;
        }
    
        function saveRec() {
           $data = $_POST['data'] ;
           $obj  = json_decode($data) ;
           if ( isset($obj->fname) and isset($obj->lname) and isset($obj->city)  ) {
           //     echo "fn= ".$obj->fname." ln= ".$obj->lname." city= ".$obj->city ;      
              $response = $this->model->saveRec($obj) ;
           }
           return ( $response ? "Dodano rekord" : "Blad " ) ;
        }
    
        function info ( $text ) {
           $this->layout->content = $text ;
           return $this->layout ; 
        }
    
    
    
        function index ()  {
           // $this->layout->content = $text ;
           return $this->layout ; 
        }
    
    } 
    
    ?>  
  2. Kolejnym etapem tego zadania jest modyfikacja komponentu modelu. Do kodu modelu - klasa Model dodajemy metodę saveRec(). Po uzupełnieniu zawartość klasy modelu przedstawiono poniżej.

    Plik Model.php - ( [listing dokumentu] [link do dokumentu] )

    <?php
    
    namespace baza ;
    use PDO ;
    
    class Model 
    {  
       static $dsn = 'sqlite:sql/baza.db'  ;
       protected static $db ;
       private $sth ;
    
       function __construct()
       {
         $data = explode(':',self::$dsn) ;
         if ( ! file_exists ( $data[1] ) ) { throw new Exception ( "Database file doesn't exist." ) ;  }
         self::$db = new PDO ( self::$dsn ) ;
         self::$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION) ; 
       }
    
    
       public function listAll()
       {
         $this->sth = self::$db->prepare('SELECT * FROM osoba') ;
         $this->sth->execute() ;
         $result = $this->sth->fetchAll() ;
         return $result ;
       }
    
       public function saveRec($obj)
       {
          $this->sth = self::$db->prepare('INSERT INTO osoba VALUES ( :fname, :lname, :city) ') ;
          $this->sth->bindValue(':fname',$obj->fname,PDO::PARAM_STR) ; 
          $this->sth->bindValue(':lname',$obj->lname,PDO::PARAM_STR) ; 
          $this->sth->bindValue(':city',$obj->city,PDO::PARAM_STR) ; 
          $resp = ( $this->sth->execute() ? 'true' : 'false' ) ;
          return $resp ; 
       }
    
    }
    
    ?>  
  3. Do zrealizowania tego zadania należy jeszcze opracować: szablon formularza (form.tpl) oraz wysyłanie danych z przeglądarki z wykorzystaniem skryptów w JavaScript i technologii AJAX'a. Na początek szablon formularza.

    Plik form.tpl - ( [listing dokumentu] [link do dokumentu] )

          <form name="form">            
                <table>
                    <tr><td><label for="fname">Imie:</label></td>
                    <td><input value="<?php if(isset($formData)) echo $formData['fname']; ?>" type="text" id="fname" name="fname" /></td></tr>
                    <tr><td><label for="lname">Nazwisko:</label></td>
                    <td><input value="<?php if(isset($formData)) echo $formData['lname']; ?>" type="text" id="lname" name="lname" /></td></tr>
                    <tr><td><label for="city">Miejscowosc:</label></td>
                    <td><input value="<?php if(isset($formData)) echo $formData['city']; ?>" type="text" id="city" name="city" /></td></tr>
                    <tr><td><span id="data"><input type="button" value="Zapisz" onclick="fn_save()" /></span></td>
                    <td><span id="response"></span></td></tr>
                </table>
            </form>   
  4. Skrypt w języku JavaScript realizujący funckjonalość zapisu do bazy danych o nazwie baza.js umieszczamy w katalogu js. Należy również dodać odpowiedni wpis w szablonie main.tpl: <script src="js/baza.js"></script>.

    Plik baza.js - ( [listing dokumentu] [link do dokumentu] )

    
    function fn_save()
     {
         var fname = document.getElementById("fname").value ;
         var lname = document.getElementById("lname").value ;
         var city  = document.getElementById("city").value ;
         document.getElementById("data").style.display = "none" ;
         json_data = "{\"fname\":\"" + fname + "\",\"lname\":\"" + lname + "\",\"city\":\"" + city + "\"}" ;
         var msg = "data=" + encodeURIComponent(json_data) ;                                    
         // alert ( '['+msg+']' ) ; 
         url = "index.php?sub=Baza&action=saveRec" ;
         resp = function(response) {
            document.getElementById("response").innerHTML = response ; 
          }
          xmlhttpPost (url, msg, resp) ;                          
    }   
    function xmlhttpPost(strURL, mess, respFunc) {
        var xhr = new XMLHttpRequest();;
        xhr.open('POST', strURL);
    	xhr.addEventListener("load", e => {
          if ( xhr.status == 200 )  {
             respFunc ( xhr.response ) ;
          }
        })
        xhr.setRequestHeader("X-Requested-With","XMLHttpRequest");
        xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded; ");
        xhr.send(mess);        
    }  

Modyfikacja szablonu głównego

Na koniec zmodyfikujemy wygląd naszej prostej aplikacji. Przygotujemy plik arkuszy styli baza.css, który umieścimy w katalogu css oraz przygotujemy plik szablonu menu.tpl umożliwiający nawigację po opracowanej aplikacji.

  1. Plik arkuszy styli - baza.css.

    Plik baza.css - ( [listing dokumentu] [link do dokumentu]

    body  { width:860px; }
    header { width:858px; height: 80px; text-align:center }
     
    nav { height : 500px; width:200px; float:left;  }
    nav p { padding:5px; margin:0px }
    
    section { display:block; float:left; height:500px; width:656px; color:navy; }
    section header { font-weight: bold;  text-align:center; width:656px; height:20px; }
    section h1 { color:navy; font-size:12pt; text-align:center }
    section h2 { color:green; font-size:12pt; text-align:center}
    section p.italic { font-style:italic }
    
    footer { clear:both; text-align:center; color:blue }
    
    dt { font-weight: bold; }
    dd { font-style: italic; }
    div.main { padding-left: 15px; }
    p.point { font-weight: bold; }
    p.text { padding-left: 30px; }   
  2. Plik szablonu zawierający nawigację po aplikacji - menu.tpl.

    Plik menu.tpl - ( [listing dokumentu] [link do dokumentu]

    <a href="index.php" >Strona główna</a><br/>
    <a href="index.php?sub=Info&action=help" >Opis serwisu</a><br />
    <a href="index.php?sub=Baza&action=listAll" >Zawartosc bazy</a><br />
    <a href="index.php?sub=Baza&action=insertRec" >Wprowadzanie danych</a><br />      
      
  3. Dodatkowo należy zmienić wpisy w kostruktorze klasy controller wprowadzając, odpowiednie wskazania do opracowanych przez nas plików: baza.css i menu.tpl. Poprawną modyfikację przedstawia poniższy fragment kodu.
       function __construct() {
          $this->css  = "<link rel=\"stylesheet\" href=\"css/main.css\" type=\"text/css\" media=\"screen\" >" ;
          $this->menu = file_get_contents ('template/menu.tpl') ;
       }
    

    W pliku szablonu main.tpl należy dodać wpisy umożliwiające podłączenie styli i pliku z kodem JavaScript obsługującego wpisywanie danych do bazy danych.

      <head>
         <meta http-equiv="content-type" content="text/html; charset=UTF-8">
         <title>Simple MVC</title>
         <?php echo $css ; ?>   
         <script  src="js/baza.js"></script> 
      </head>
    

Linki do uruchomionych przykładów na serwerze Pascal

Linki dostępne z sieci wydziałowej.