Implementarea unui modul de stiri in Zend Framework. Partea I - Structura aplicatiei
21.02.2010
In acest tutorial va voi prezenta cateva lucruri legate de arhitectura MVC si implementarea unui modul de stiri in Zend Framework. El reprezinta prima parte dintr-o serie de tutoriale pe aceasta tema, care vor descrie implementarea unui modul cu toate functionalitatile de baza precum adaugarea, modificarea, stergerea si vizualizarea inregistrarilor dintr-un tabel, dar si lucruri mai complicate cum ar fi incarcarea de fisiere pe server, validari si mesaje de eroare.
14530 afisari 7 Rating (9 voturi) 40 min

In acest tutorial va voi prezenta cateva lucruri legate de arhitectura MVC si implementarea unui modul de stiri in Zend Framework. Mi-am propus sa realizez o serie de tutoriale pe aceasta tema, care sa descrie implementarea unui modul cu toate functionalitatile de baza precum adaugarea, modificarea, stergerea si vizualizarea inregistrarilor dintr-un tabel, dar si lucruri mai complicate cum ar fi incarcarea de fisiere pe server, validari si mesaje de eroare.

Ce este Zend Framework?

Dupa cum ii spune si numele, Zend Framework este o platforma dezvoltata de Zend, compania ce a creat limbajul PHP. El consta intr-o colectie destul de voluminoasa de clase ajutatoare, cum ar fi cele pentru manipularea fisierelor, a template-urilor, formularelor, etc. Daca nu il aveti deja instalat, puteti citi aici mai multe. Nu va entuziasmati insa: desi framework-ul e ok ca structura si pachete, documentatia m-a dezamagit de multe ori. Exemplele sunt putine si, de cele mai multe ori, superficiale, astfel incat nu de putine ori a trebuit sa fac mai multe incercari pana cand am nimerit "combinatia" corecta. In concluzie, trecerea de la PHP-ul clasic la Zend Framework poate fi dificila chiar si pentru un programator experimentat.

Acest tutorial presupune ca:

  • aveti un server pe care ruleaza Apache, PHP si o baza de date MySQL;
  • ati instalat Zend Framework;
  • stapaniti bine limbajul PHP si in special programarea orientata pe obiecte.

Arhitectura MVC

Probabil ca nu este pentru prima data cand auziti termenul de arhitectura Model-View-Controller sau, pe scurt, MVC. Ca si alte platforme, cum ar fi Ruby-on-Rails, Zend Framework isi propune separarea completa intre baza de date (adica modele), template-uri (sau view-uri) si controllere (verbele aplicatiei). Nu vom pierde mult timp discutand despre arhitectura MVC, dar e bine sa retineti urmatoarele:

  • Un model va reprezenta o tabela MySQL si va contine functii cu ajutorul carora vom edita acea tabela.
  • Un view este de fapt un template html (sau o bucata dintr-un template) ce are drept scop afisarea informatiilor procesate de catre controllere.
  • Un controller este o colectie de actiuni organizate in functie de scopul lor. Ca exemplu, modulul de stiri pe care il vom implementa va contine un singur controller pentru manipularea tabelei de stiri, ce va grupa actiunile de: adaugare si modificare stire, afisarea tuturor stirilor, etc.
 SFAT   In general, daca un controller contine mai mult de 7 actiuni, ar trebui sa luati in considerare impartirea acestora in mai multe controllere.

Structura aplicatiei si baza de date

Deoarece vom folosi Zend Framework, structura modulului nostru trebuie sa reflecte arhitectura MVC. Pentru inceput, vom crea doua directoare:

  • application - va contine trei subdirectoare - models, views si controllers;
  • public - va contine toate resursele ce sunt disponibile utilizatorului (imagini, stiluri css, fisiere javascript,etc.), fisierul bootstrap si un fisier .htaccess.
 OBS.   Fisierul bootstrap este de fapt un fisier index.php care are rolul de a incarca framework-ul si de a initia un controller default. Toate interogarile catre alte fisiere se realizeaza prin intermediul acestui index.php.

In plus, in directorul application vom crea un fisier configuration.inc.php in care vom defini informatii generale cum ar fi numele bazei de date MySQL, datele de conectare la aceasta, numele domeniului pe care lucram, etc. Pentru inceput, vom crea urmatoarele constante:

<?php
define("DB_HOST","serverul de MySQL - localhost sau adresa IP");
define("DB_USERNAME","numele utilizatorului MySQL");
define("DB_PASSWORD","parola MySQL");
define("DB_DATABASE","numele bazei de date");
 
define("APPLICATION_PATH","calea pe server catre directorul in care lucram - ex. /home/elearnro/...");
define("DIR_LOCALPATH","numele domeniului - ex. http://www.e-learn.ro/stiri/");
?>

 OBS.   Valoarea APPLICATION_PATH o poti afla daca afisezi constanta globala $_SERVER['DOCUMENT_ROOT'].

Iata cum ar trebui sa arate structura aplicatiei tale pana la acest punct:

Implementarea unui modul de stiri in Zend Framework. Partea I - Structura aplicatiei

Structura aplicatiei

In plus, in baza de date va trebui sa creezi un tabel STIRI cu urmatoarele campuri:

Implementarea unui modul de stiri in Zend Framework. Partea I - Structura aplicatiei

Tabelul STIRI

Retine ca Id reprezinta cheia primara a tabelei si are setat atributul auto_increment.

Bootstrap si .htaccess

In fisierul .htaccess va trebui sa incluzi urmatorul cod:

SetEnv PHP_VER 5
 
RewriteEngine On
RewriteCond % -s [OR]
RewriteCond % -l [OR]
RewriteCond % -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]

Aceasta inseamna de fapt ca orice cerere va fi transmisa catre index.php. Nu te ingrijora daca nu intelegi exact fiecare linie de cod, nu va fi nevoie sa editezi acest fisier in viitorul prea apropiat.

In schimb, fisierul boostrap va fi modificat in functie de fiecare aplicatie pe care vrei sa o implementezi. Mai intai, el va incarca fisierul de configurare in care am definit constantele cu numele bazei de date si utilizatorul MySQL:

<?php // incarca fisierul de configurare
require_once('../application/configuration.inc.php');
?>

apoi va incarca clasa Zend_Loader si alte clase din Zend Framework, pe care le vom folosi pe parcurs la implementarea modulului de stiri:

<?php // incarca clasa Zend_Loader
require_once('Zend/Loader.php');
 
// incarca clasele zend framework cu ajutorul Zend_Loader
Zend_Loader::loadClass('Zend_Db');
Zend_Loader::loadClass('Zend_Db_Table_Abstract');
Zend_Loader::loadClass('Zend_Controller_Action');
Zend_Loader::loadClass('Zend_Controller_Front');
Zend_Loader::loadClass('Zend_Filter_Input');
Zend_Loader::loadClass('Zend_File_Transfer');
Zend_Loader::loadClass('Zend_View');
?>

Urmatorul pas este conectarea la baza de date. Bineinteles, aceasta poate fi inclusa in fiecare fisier in parte, dar eu iti recomand sa o lasi in bootstrap, astfel incat eventualele modificari sa fie realizate intr-un singur fisier:

<?php // conectarea la baza de date
 
$db = Zend_Db::factory('Pdo_Mysql',array( 'host' => DB_HOST,
            'username' => DB_USERNAME,
            'password' => DB_PASSWORD,
            'dbname' => DB_DATABASE));
 
$db->getProfiler()->setEnabled(true);
Zend_Db_Table_Abstract::setDefaultAdapter($db);
?>

Dupa cum poti observa, am apelat metoda factory a clasei Zend_Db, spunandu-i ca vrem sa ne conectam la o baza de date MySQL. Urmatoarea linie ($db->getProfiler()->setEnabled(true)) are rolul de a activa un tool al Zend_Db, si anume query profiler, care ne va ajuta sa afisam diferitele interogari realizate de MySQL si chiar sa aflam timpii de executie pentru fiecare.

Ultima parte a fisierului index, ce seteaza si porneste controller-ul default, este prezentata in continuare:

<?php // cream controller-ul default
$frontController = Zend_Controller_Front::getInstance();
 
// dezactivam aruncarea exceptiilor
$frontController->throwExceptions(false);
 
// dezactivam procesarea default a view-urilor 
$frontController->setParam('noViewRenderer',true);
 
// precizam ca vom folosi un controller de erori
$frontController->setParam('noErrorHandler',false);
 
// definim directorul default pt controllere
$frontController->setControllerDirectory(array( 'default' => APPLICATION_PATH.'controllers'));
 
// pornim controller-ul default
$frontController->dispatch();
?>

Controller-ul de erori

Ultimul lucru pe care va trebui sa-l facem inainte de a putea trece la implementarea propriu-zisa a aplicatiei este sa cream un controller de erori. Acesta va avea drept scop raportarea diferitelor erori care vor surveni pe parcursul implementarii. Iata structura fisierului ErrorController.php:

<?php class ErrorController extends Zend_Controller_Action { 
  
 public function init() {
  
  // Initializeaza view-ul
  $this->initView();
  
  // Seteaza calea catre fisierele .phtml
  $this->view->setScriptPath(APPLICATION_PATH.'views/');  
  
 }
 
 public function errorAction() {      
     
  $error = $this->_getParam('error_handler');
  
        switch ($error->type) { 
            case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER:  
            case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION:
       
                // eroare 404 - controller sau actiune inexistenta
                $this->getResponse()->setHttpResponseCode(404);
                $this->view->message = 'Pagina inexistenta';
                break;
            default:
                // eroare in cadrul aplicatiei
                $this->getResponse()->setHttpResponseCode(500);
                $this->view->message = 'Eroare in aplicatie';
                break;
        }
        
       $this->view->exception = $error->exception;
       $this->view->request = $error->request;
       
       // randeaza si afiseaza view-ul
       echo $this->view->render('error.phtml');
    }
}
?>

Dupa cum poti observa, clasa ErrorController extinde clasa Zend_Controller_Action, ce reprezinta clasa parinte pentru orice controller din Zend Framework. ErrorController cuprinde doua metode:

  • init() - ce joaca rolul de constructor si este apelata automat la crearea unui obiect de tipul ErrorController;
  • errorAction() - ce are rolul de a procesa si de a afisa diversele erori, dintre care eroarea 404 (pagina inexistenta) este tratata separat.

Pentru ca este primul nostru controller, trebuie sa mentionam cateva lucruri:

  • Orice actiune dintr-un controller trebuie sa fie denumita cu litere mici, urmate de cuvantul cheie Action. De exemplu, o actiune afisarestiriAction dintr-un controller Stiri va fi apelata in browser astfel:

    http://www.domeniu.ro/public/Stiri/afisarestiri

  • Template-urile din Zend Framework au extensia .phtml si sunt localizate in directorul views. Ele pot include cod php, cum ar fi instructiuni conditionale, bucle foreach, etc., dar scopul lor ar trebui sa se limiteze la afisarea informatiilor furnizate de catre actiunile din controllere.

  • Pentru a incarca un template trebuie sa cream un obiect de tipul Zend_View. Datele sunt transmise catre template prin setarea proprietatilor acestui obiect ($obiectView->numar_stiri = 5 inseamna ca in template vom putea afisa numarul de stiri astfel: echo $this->numar_stiri).

Iata cum ar trebui sa arate structura aplicatiei tale pana la acest punct:

Implementarea unui modul de stiri in Zend Framework. Partea I - Structura aplicatiei

Structura aplicatiei

Cam atat pentru acest prim tutorial. In urmatoarea parte vom trece la implementarea propriu-zisa a modului nostru, si anume adaugarea si afisarea stirilor in si din baza de date MySQL.

Copyright © 2008-2010 E-LEARN.ro. Toate drepturile rezervate. Conceput si realizat de Neokinetics Software.