post_ico4

MVC w praktyce – tworzymy system artykułów. cz. 2

W drugiej części artykułu o wzorcu MVC stworzymy część skryptu, odpowiedzialną za obsługę kategorii.

Uwaga. Pojawił się zaktualizowany cykl o MVC – przejdź

Tworzymy kontroler kategorii

Na początek stwórzmy plik index.php w głównym katalogu:

<?php
include 'controller/categories.php';
if($_GET['task']=='categories') {
    $ob = new CategoriesController();
    $ob->$_GET['action']();
}

Na podstawie zmiennej $_GET[‚task’] tworzony jest odpowiedni obiekt kontrolera (w tym wypadku CategoriesController). Zmienna $_GET[‚action’] określa z kolei akcję kontrolera.

Co robi kontroler? Na podstawie przekazanych wartości zmiennych (z adresu lub pól formularza) „wybiera” odpowiednią akcję skryptu oraz inicjuje odpowiednie modele i widoki. Kontroler nie powinien obrabiać danych. Ma on za zadanie tylko wywoływać odpowiednie reakcje logiki aplikacji oraz widoku odpowiedzialnego za wyświetlanie informacji. Przyjrzyjmy się plikowi controller/categories.php:

<?php
/**
 * @author Łukasz Socha <kontakt@lukasz-socha.pl>
 * @version: 1.0
 * @license http://www.gnu.org/copyleft/lesser.html
 */

include 'controller/controller.php';

class CategoriesController extends Controller{
    public function index() {
        $view=$this->loadView('categories');
        $view->index();
    }
    public function add() {
        $view=$this->loadView('categories');
        $view->add();
    }
    public function insert() {
        $model=$this->loadModel('categories');
        $model->insert($_POST);
        $this->redirect('?task=categories&action=index');
    }
    public function delete() {
        $model=$this->loadModel('categories');
        $model->delete($_GET['id']);;
        $this->redirect('?task=categories&action=index');
    }
}

Przeanalizujmy reakcje dla następujących adresów URL:

  • ?task=categories&action=index – zostanie wywołana metoda index(), która inicjuje obiekt widoku categories, następnie zostaje wywołana metoda index()
  • ?task=categories&action=add – zostanie wywołana metoda add(), która inicjuje obiekt widoku categories, następnie zostaje wywołana metoda add()
  • ?task=categories&action=insert – zostanie wywołana metoda insert(), która inicjuje obiekt modelu categories, następnie zostaje wywołana metoda insert()
  • ?task=categories&action=delete – zostanie wywołana metoda delete(), która inicjuje obiekt modelu categories, następnie zostaje wywołana metoda delete()

Mamy już utworzony kontroler. Przejdźmy teraz do modelu.

Tworzymy model kategorii

Model jest najbardziej istotnym elementem we wzorcu MVC – to on jest odpowiedzialny za logikę aplikacji. Ma za zadanie pobieranie/edycję danych z bazy danych (lub innych źródeł) oraz przetworzenie ich według wymagań skryptu, np: poddać filtracji, wykonać obliczenia itp.

Przeanalizujmy plik model/categories.php:

<?php
/**
 * @author Łukasz Socha <kontakt@lukasz-socha.pl>
 * @version: 1.0
 * @license http://www.gnu.org/copyleft/lesser.html
 */

include 'model/model.php';

class CategoriesModel extends Model{

    public function insert($data) {
        $ins=$this->pdo->prepare('INSERT INTO categories (name) VALUES (:name)');
        $ins->bindValue(':name', $data['name'], PDO::PARAM_STR);
        $ins->execute();
    }
    public function getAll() {
        return $this->select('categories');
    }
    public function delete($id) {
        $del=$this->pdo->prepare('DELETE FROM categories where id=:id');
        $del->bindValue(':id', $id, PDO::PARAM_INT);
        $del->execute();
    }
}

Wszystkie 3 metody mają za zadanie dodanie, usunięcie oraz pobranie danych z tabeli categories. Pozostaje nam jeszcze widok.

Tworzymy widok kategorii

Głównym zadaniem widoku jest odebranie przetworzonych danych od modelu i wyświetlenie ich w odpowiedni sposób. Wiele osób uważa widok za szablon HTML, ale nie jest to do końca prawdą. Równie dobrze widok może generować np. dokumenty PDF. Tak będzie wyglądać plik view/categories.php:

<?php
/**
 * @author Łukasz Socha <kontakt@lukasz-socha.pl>
 * @version: 1.0
 * @license http://www.gnu.org/copyleft/lesser.html
 */

include 'view/view.php';

class CategoriesView extends View{
    public function  index() {
        $cat=$this->loadModel('categories');
        $this->set('catsData', $cat->getAll());
        $this->render('indexCategory');
    }
    public function  add() {
        $this->render('addCategory');
    }
}

Metoda index() pobiera dane wszystkich kategorii z modelu za pomocą getAll() i renderuje odpowiedni plik z szablonem HTML. Z kolei add() renderuje plik HTML z formularzem dodawania kategorii.

Na koniec tej części stwórzmy jeszcze pliki szablonów.

templates/header.html.php:



<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<link href="css/style.css" rel="stylesheet" type="text/css" /></pre>
<ul>
	<li><a href="?task=categories&action=add">Dodaj kategorię</a></li>
	<li><a href="?task=categories&action=index">Lista kategorii</a></li>
</ul>
<pre>

templates/footer.html.php:



templates/indexCategory.html.php:

<? include 'templates/header.html.php'; ?></pre>
<h1>Lista kategorii</h1>
<? foreach($this->get('catsData') as $cats) { ?> <? } ?>
<table>
<tbody>
<tr>
<td>Nazwa</td>
<td></td>
</tr>
<tr>
<td></td>
<td><a href="?task=categories&action=delete&id=<?= $cats['id']; ?>">usuń</a></td>
</tr>
</tbody>
</table>
<pre>
<? include 'templates/footer.html.php'; ?>

templates/addCategory.html.php:

<? include 'templates/header.html.php'; ?></pre>
<h1>Dodaj kategorię</h1>
<form action="?task=categories&action=insert" method="post">Nazwa kategorii: <input type="text" name="name" />
 <input type="submit" value="Dodaj" /></form>
<pre>
<? include 'templates/footer.html.php'; ?>

Tak stworzyliśmy część kodu odpowiedzialną za kategorie artykułów. W trzeciej, ostatniej części zajmiemy się samymi artykułami.

Powiązane tematy

Co sądzisz o wpisie?
BeżnadziejnySłabyŚredniDobryBardzo dobry (Brak ocen, bądź pierwszy!)
Loading...
  • Przekazywanie przez referencję w PHP5? Serio?

  • http://php.net/manual/en/language.references.php
    Domyślnie obiekty są przekazywane własnie przez referencję :)

  • Tu chodzi o to, że uczysz ludzi głupot. PHP5 daje pełną gamę możliwości jeśli chodzi o programowanie obiektowe a Ty tworzysz metody z parametrami przekazywanymi przez referencję.

    Nie potrafisz to nie ucz.

  • Hmm racja, niepotrzebnie użyłem tutaj referencji. Co do „PHP5 daje pełną gamę możliwości jeśli chodzi o programowanie obiektowe” chciałem kod ograniczyć do „minimum” – grupą docelową tego artykułu są osoby, które coś już wiedzą o programowaniu obiektowym, ale mają problemy wykorzystania tego w praktyce. Dlatego też nie używam mechanizmów takich, jak np. spl_autoload_register.

    Moim zamiarem jest wyjaśnienie idei tego wzorca dość łopatologicznie, na prostym przykładzie. Gdy sam uczyłem się wzorca MVC brakowało mi właśnie jakiś prostych przykładów, by pojąć samą ideę.

  • dyziak

    Admin, w pełni popieram. Ja np nie wiem czym jest spl_autoload_register, natomiast referencje ogarniam. Potrzebuje zrozumieć mvc, a proste przykłady sa do tego idealne. Natomiast co to wypowiedzi uzytkownika – cypherq:

    „Nie potrafisz to nie ucz.”

    … to chamskie i niskie. W druga strone mozna powiedziec: nie masz zasad i kultury – nie mów.

  • Grzesiek

    Bardzo dobry artykuł. Znalazłem jeszcze małą literówkę do poprawienia. Zamiast „addCategory.index.php” powinno być „addCategory.html.php”

  • Damian

    W takim układzie nie możliwe jest pobranie danych z dwóch różnych modeli w jednej metodzie widoku :”Cannot redeclare class Model „. Jak pobrać jakieś dane z dwóch różnych modeli i „zrenderować” to do jednego widoku ?

    Np listę kategorii mam w modelu Kategorie
    a listę artykułów mam w modelu Artykuły
    Chciałbym móc wyświetlić całą listę dostępnych kategorii (jako lista rozwijana) by przypisać daną kategorię dla wszystkich dostępnych artykułów

    • Zamiast include ‚model.php’ spróbuj użyć include_once ‚model.php’

  • Piotrek

    Co oznacza tekst: „lewy_nawias_ostry myślnik myślnik znak_zapytania php lewy_nawias_ostrybr znak_zapytania myślnik myślnik prawy_nawias_ostry (<!–?php )” ??
    Oczywiście br to przejście do nowej linii, ale nie rozumiem tej kombinacji: użycia br, komentarza htmlowego i otworzenia składni php – czemu komentuje się początek składni php??

    • Edytor WordPressa dodał jakieś śmieci. Poprawione :) Powinno się komentować początek pliku PHP zgodnie ze wzorcem dokumentowania PHPDoc. Podaje się tam podstawowe informacje o autorze, wersji, licencji oraz krótki opis, do czego służy dany kod.

  • dusta

    W jaki sposób zaimplementować autoryzacje do danych funkcji w kontrolerze ?

  • Strone indexCategory.html.php nalezaloby calkowicie zmienic, bo nie wyswietla pozadanych kategorii. Chcialem wrzucic tu poprawna wersje, ale kod nie wyswietla sie poprawnie, a wiec opisze o co chodzi – blok petli foreach jest zamykany od razu po rozpoczeciu. nalezy zmodyfikowac petle, aby klamry obejmowaly cala (druga) sekcje oraz dodac zmienna $cats[‚name’];
    Pozdrawiam ;)