Upload
cata-castillo
View
3.250
Download
0
Embed Size (px)
DESCRIPTION
El desenvolupament d’aplicacions web està sofrint una evolució constant, actualment apareixen multitut de frameworks de desenvolupament àgil. En aquesta xerrada esposarem el funcionament d’un framework web desenvolupat amb llibreries i components lliures, orientat a arquitectura Model Vista Controlador. El desenvolupament s’ha realitzat utilitzant les llibreries Pear::Dataobject (abstracció de la base de dades), Smarty (aïllament de PHP i HTML).
Citation preview
● Programació en PHP● Jordi Catà
●
Cas d'us de Framework web
desenvolupat amb llibreries Lliures
Jordi Catà Castillo - [email protected]
Grup Freelance Girona – 13 Febrer 2008
Sala d'actes P4, Escola Politècnica Superior – Universitat de Girona
Objectius
Antecedents
Disseny a 3 capes
Introducció Arquitectura Model-Vista-Controlador
Llibreries abstracció de la base de dades (Pear::DataObject) -> Model
Llibreries separació lògica de negoci de HTML (Smarty) -> Vista
Controlador
Funcionament del “framework”
Millores
Altres Frameworks MVC lliures
Taula de continguts
Veure algunes llibreries estandars que ens permeten organitzar el codi de maneres més “interessants” per arribar a tenir un codi escalable, mantenible, robust, etc.
Exemple “adaptat” d'arquitectura Model – Vista – Controlador
Entendre el que és un framework i que ens pot aportar.
Algunes Llibreries com:
-Smarty: Motor de plantilles que ens permet separar l'HTML del PHP.
-Pear Dataobject: Classes que ens permet “abstreure/encapsular” la base de dades d'una forma cómode.
Objectius de la Xerrada
Antecedents
Que és/pot ser desenvolupar en PHP ?
- Programació sense ordre, sense cap tipus “d'enginyeria”- Les modificacions en el codi son lentes.- La reutilització de codi és fa pràcticament impossible. - Codi rebuscat -> codi Spaggethi
Desenvolupament d'aplicacions des del punt de vista de l'Enginyeria del Software garanteixen:
- Manteniment- Escalabilitat- Reutilització- Robustesa i Lliure d'errors
-> Estructurar el codi a 3 nivells per tal de facilitar aquests punts.
HTML + Smarty Tags
HTML + JavaScript
Físic
Negoci
Presentació
Disseny 3 capes
- Física: formada per la llibreria Pear i les classes que accediran a les dades, garantint la independència del Sistema Gestor de Bases de Dades.
- Negoci: s'encarrega de gestionar, manipular les dades que li passa la capa física.
- Presentació: presenta les dades a la interfície d'usuari. Utilitza les llibreries Smarty.
Disseny 3 capes
CONTROLLER
MODEL
Arquitectura Model – Vista - Controlador
VISTA
Petició
Resposta
Controlador: Respón als events d'un usuari i executa els models necesaris i mostra les vistes que han de presentar les dades.
Model: Es la representació específica de la informació. Un model es pot encarregar de calcular el preu d'una compra, afegir un nou usuari, etc
Vista: Presenta el model en un format adecuat, habitualment es la interficie d'usuari, en el cas web per exemple HTML, XML, etc.
Base dades
Arquitectura Model – Vista - Controlador
CONTROLLER
MODEL
VISTAPetició
Resposta
Pear::DataObject
Smarty
HTML
el “Framework” MVC, objectius
Un framework pot ser considerat com el conjunt de processos i tecnologies utilitzats per a resoldre problemes complexes.
Un framework és un espai de treball on s'intenta automatitzar tasques repetitives i s'assumeixen uns convenis de desenvolupament.
Son dissenyats amb l'intent de facilitar el desenvolupament de Software, encapsulant detalls de baix nivell i permetent enfocar-nos en les funcionalitats importants.
Frameworks MVC, objectius
Ara bé, hi ha un debat obert amb que el us de frameworks afegeix codi innecessari en el projecte, son pesats d'execució, no son escalables, etc.
-> Que és més important centrar-se en detalls de baix nivell o centrar-se en funcionalitats d'alt nivell ?
Opinió personal: Per la meva part prefereixo treballar a alt nivell i aprofitar llibreries existents, framework que m'encapsulin el baix nivell, i centrar-me amb funcionalitats
desenvolupament ràpid -> - cost -> + benefici + robustesa
Per tal d'explicar el funcionament del framework, explicarem les llibreries que formen part d'aquest framework:
Llibreries PEAR::DataObject
-generació de classes de mapping base de dades
-us d'aquests models
Smarty
-separació de PHP del HTML
el “framework”
Pear :PHP Extension and Aplication Repository, és un framework i sistema de distribució per crear components de PHP reutilitzables.
D'entre d'altres funcionalitats destaquem la d'independitzar i encapsular la base de dades:
-Mysql-Postgres-Oracle-Sqlite- ...
pear.php.net
Llibreries abstracció de la base de dades (Pear::DataObject) -> Model
Exemple de codi sense utilitzar Pear
$query = 'SELECT * FROM my_table';
$link = mysql_connect('my_host', 'my_user', 'my_password');mysql_select_db('my_database');
$result = mysql_query($query);$line = mysql_fetch_array($result)
$link = pg_pconnect('host=host port=5432 dbname=database user=user password=pwd');
$result = pg_query($link, $query); $line = pg_fetch_result($result)
$link = Ora_Logon("my_user", "my_password");$result = ora_do( $ora_conn, $query);ora_fetch_into( $result, $line);
Llibreries abstracció de la base de dades (Pear::DataObject) -> Model
Exemple de codi utilitzant Pear:
$dbh = DB::connect('mysql://my_user:my_pass@my_host/my_database);
$dbh = DB::connect('pgsql://my_user:my_pass@my_host/my_database);
$dbh = DB::connect('oracle://my_user:my_pass@my_host/my_database);
$result = $dbh->Query ( 'SELECT * FROM * my_table');$line = $result->fetchRow();
Llibreries abstracció de la base de dades (Pear::DataObject) -> Model
Dataobject permet utilitzar “objectes” per poder treballar amb les diferents taules de la base de dades.
Per exemple:
$usuari = DB_DataObject::factory('tusuaris');$usuari->NOM = “Pepet”;$usuari->insert ();
Per tal de poder treballar d'aquesta forma cal generar les classes que mapeigen les taules de la base de dades.
Llibreries abstracció de la base de dades (Pear::DataObject) -> Model
Fitxer de configuració:
/projecte/generate_do.ini
[DB_DataObject]
database = mysql://root:@localhost/basededadesschema_location = classes/dbmappingclass_location = classes/dbmappingrequire_prefix = DataObjects/class_prefix = DataObjects_extends_location = DataObject.phpextends = DB_DataObject
Executem el procés de generació
php libs/DB/DataObject/createTables.php generate_do.ini
Llibreries abstracció de la base de dades (Pear::DataObject) -> Model
El codi que ens genera el procés es com el següent:
class DataObjects_Tusuaris extends DB_DataObject{ ###START_AUTOCODE /* the code below is auto generated do not remove the above tag */
public $__table = 'tusuaris'; // table name public $CODI_USUARI; // int(10) not_null primary_key public $NOM; // string(50) public $COGNOM; // string(50) public $USUARI; // string(50) public $CLAU; // string(50) public $PERMISOS; // string(50)
/* Static get */ function staticGet($k,$v=NULL) { return DB_DataObject::staticGet('DataObjec
/* the code above is auto generated do not remove the tag below */ ###END_AUTOCODE}
Llibreries abstracció de la base de dades (Pear::DataObject) -> Model
<?php
$opts = &PEAR::getStaticProperty('DB_DataObject','options');
$opts = array(
'class_location' => '/var/www/html/projects/classes/dbmapping',
'class_prefix' => 'DataObjects_',
'database' => 'mysql://usuari:password@localhost/basededades'
);
$usuari = DB_DataObject::factory('tusuaris');
if ($usuari->get(12))
{
echo "<br> usuari trobat";
}
else
{
echo "No s'ha trobat el registre d'usuari amb id 12";
}
Llibreries abstracció de la base de dades (Pear::DataObject) -> Model
$usuari = DB_DataObject::factory("tusuaris")$usuari->find();
->executa "SELECT * FROM tusuaris";
$usuari = DB_DataObject::factory("tusuaris")$usuari->USUARI = "nom_usuari";$usuari->CLAU = "contrasenya";$usuari->find();
->executa "SELECT * FROM tusuaris whereUSUARI = "nom_usuari" AND CLAU = "contrasenya";
$usuari = DB_DataObject::factory("tusuaris")$usuari->find();while ($usuari->fetch ()){
echo "<br> nom usuari: " .$usuari->NOM_USUARI;}
Llibreries abstracció de la base de dades (Pear::DataObject) -> Model
insert
$usuari = DB_DataObject::factory("tusuaris")$usuari->NOM = “Pepet”;$usuari->COGNOM = “Boch”;$usuari->USUARI = “pboch”;$usuari->CLAU = “2323”;$usuari->insert ();
->INSERT INTO tusuaris (NOM,COGNOM,USUARI,CLAU) VALUES ('Pepet', 'Boch', 'pboch', '2323');
update
$usuari = DB_DataObject::factory("tusuaris")$usuari->get(1); -> SELECT * FROM tusuaris WHERE CODI_USUARI = 1
$usuari->CLAU = “1234”;$usuari->update ();
->UPDATE tusuaris SET CLAU = '1234' WHERE CODI_USUARI = 1 AND NOM = 'Pepet' AND COGNOM = 'Boch' AND USUARI = 'pboch';
Llibreries abstracció de la base de dades (Pear::DataObject) -> Model
delete
$usuari = DB_DataObject::factory("tusuaris")$usuari->USUARI = “pboch”;$usuari->delete ();
->DELETE FROM tusuaris WHERE USUARI = 'pboch';
orderBy
$usuari = DB_DataObject::factory("tusuaris")$usuari->orderBy (“NOM, COGNOM”);$usuari->find ();
->SELECT * FROM tusuaris order by NOM, COGNOM
Llibreries abstracció de la base de dades (Pear::DataObject) -> Model
setFrom
assigna de forma automàtica valors del REQUEST a camps de l'objecte Dataobject
if ($_REQUEST[“submit”] == “”){
?>NOM USUARI: <input type=”text” name=”NOM”>COGNOM USUARI: <input type=”text” name=”COGNOM”><?
}else{
$usuari = DB_DataObject::factory("tusuaris")$usuari->setFrom ($_REQUEST);
$usuari->insert ();
--> INSERT INTO tusuaris (NOM, COGNOM) VALUES (NOM_INTRODUIT, COGNOM_INTRODUIT)
}
Llibreries abstracció de la base de dades (Pear::DataObject) -> Model
getLink
retorna el registre relacionat d'una altra taula, per exemple
USUARI --> COTXE
USUARI COTXEID CODI_USUARI nom ID CODI_USUARI_FK MARCA1 2 pepet 1 2 RENAULT
Un usuari té associat 1 cotxes
$usuari->get (1);
-> SELECT * FROM USUARIS WHERE ID = 1; -> retorna el registre del usuari
$cotxe = $usuari->getLink (“CODI_USUARI”, “COTXE”, “CODI_USUARI_FK”);
-> SELECT * FROM COTXE WHERE CODI_USUARI_FK = 2;
Llibreries abstracció de la base de dades (Pear::DataObject) -> Model
getLinks
retorna els registres relacionats d'una forma automàtica a partir del fitxer
databasename.links.ini
[COTXE]CODI_USUARI_FK = USUARI:CODI_USUARI
USUARI --> COTXE
USUARI COTXEID CODI_USUARI NOM ID CODI_USUARI_FK MARCA1 2 pepet 1 2 RENAULT
$cotxe = DB_DataObject::factory("COTXE")$cotxe->get (1); -> SELECT * FROM COTXE WHERE ID = 1;
$cotxe->getLinks ();
echo $cotxe->_USUARI->_NOM; -> Mostra el nom del usuari Associat al registre cotxe
Llibreries abstracció de la base de dades (Pear::DataObject) -> Model
whereAdd, Count
$person->name = "test";
$person->whereAdd("name like '%test%");
$person->whereAdd(" edat > 24”);
$total = $person->count(DB_DATAOBJECT_WHEREADD_ONLY);
echo "There are {$total} names in the database";
SELECT count(person.id) AS DATAOBJECT_NUM
FROM person
WHERE name like '%test%' AND edat > 24;
Llibreries abstracció de la base de dades (Pear::DataObject) -> Model
Altres métodes
Limit -> SELECT * FROM usuaris LIMIT 0,30
GroupBy
escape
joinAdd -> per fer joins entre dos objectes dataobject
toArray -> converteix un objecte a array
validate -> comprova que els camps de l'objecte tingui valors vàlids
DB_DataObject::debugLevel(5); -> IMPORTANTISIM Per Debugar Dataobject !!!
Llibreries abstracció de la base de dades (Pear::DataObject) -> Model
Smarty: motor de plantilles fàcilment extensible via plugins. Ens permet separar l'HTML del codi PHP
Format per Tags que dins plantilla/fitxer HTML ens indiquen els paràmetres a substituir.
Variables instanciades des de PHP: {$variable}
Constants instanciades des de fitxer de configuració: {#constant#}
Estructures de Control: {if}{/if}, {section} {/section}
Template: HTML + Smarty Tags
Smarty PHP
Sortida: HTML
Llibreries separació lògica de negoci de HTML (Smarty) -> Vista
smarty.php.net
plantilla.tpl
Nom Usuari: {$NOM},{$COGNOM}
<br>Contactes{section name=line loop=$DADES}<br>{$DADES[line].nom}, {$DADES[line].cognom}{/section}
Sortida navegador
Nom Usuari: Josep<br>Cognom Usuari: Foix
<br>Contactes<br>Jordi, Mata<br>David, Folch<br>
Smarty (Vista), exemple
Smarty, configuració
Smarty requereix 4 directoris per poder treballar:
-TEMPLATE_DIR: directori on tenim els fitxers de “plantilles”.
-COMPILE_DIR: directori on es “compila” les plantilles per poder-se “executar” de forma ràpida
-CONFIG_DIR: directori on troba fitxers de configuració (constants smarty)
-CACHE_DIR: directori de cache per les plantilles compilades
Es important tenir permisos 777 ( a+wrx) en CACHE_DIR, COMPILE_DIR
include 'Smarty.class.php';
define ('DIR_TEMPLATES' , ROOT_PATH .'templates/');define ('DIR_CACHE' , ROOT_PATH .'cache/');define ('DIR_TEMPLATES_C' , ROOT_PATH .'templates_c/');define ('DIR_CONFIG' , ROOT_PATH .'config/');
class Smarty_template extends Smarty{
function Smarty_template(){
$this->Smarty();$this->template_dir = DIR_TEMPLATES;$this->compile_dir = DIR_TEMPLATES_C;$this->config_dir = DIR_CONFIG;$this->cache_dir = DIR_CACHE;$this->caching = false;
}}
Smarty, configuració
prova.php
include “Smarty_template.php”;
$smarty = new Smarty_template;$smarty->assign('NOM','Josep');$smarty->assign('COGNOM','Pepet');
$smarty->display('plantilla.tpl'); -> mostrem la plantilla
plantilla.tpl
<html><body>
Nom: {$NOM}<br>Cognom: {$COGNOM}
</body></html>
Smarty, Utilització, Variables
Smarty, Utilització, Exemple
plantilla.tpl
prova.php
Sortida
<html><body>
Nom: {$NOM}<br>Cognom: {$COGNOM}
</body></html>
$smarty = new Smarty_template ;$smarty->assign (“NOM”, “Josep”);$smarty->assign (“COGNOM”, “Foix”);$smarty->display (“plantilla.tpl”);
<html><body>
Nom: Josep<br>Cognom: Cognom
</body></html>
Smarty, Utilització, If
La sentència IF d'smarty es molt similar a la sentencia IF de PHP.
La seva sintaxis és:
{if condicio}codi a mostrar si es compleix la condició
{elseif condicio2}codi a mostrar si es compleix la condició 2
{/if}
Exemples
{if $NOM == “Josep”} Soc en Josep{elseif $NOM == “Jordi”} Soc en Jordi{/if}
{if $NOM == “Josep” || $NOM == “Jordi”} Soc en Josep o en Jordi
Smarty, Utilització, If
plantilla.tpl
prova.php
Sortida
{if $USUARI_ADMIN} Ets un admin{else} Usuari normal{/if}<br>
Nom: {$NOM}<br>Cognom: {$COGNOM}
$smarty = new Smarty_template ;$smarty->assign (“USUARI_ADMIN”, true);$smarty->assign (“NOM”, “Josep”);$smarty->assign (“COGNOM”, “Foix”);$smarty->display (“plantilla.tpl”);
<html><body>Ets un admin
Nom: Josep<br>Cognom: Cognom
</body></html>
Smarty, Utilització, Section
La sentència SECTION d'smarty es molt similar a la sentencia FOR de php.
La seva sintaxis és:
{section name=INDEX loop=$DADES}mostrem dada actual[INDEX]
{/section}
Exemples
plantilla.tpl
{section name=line loop=$DADES}<br>{$DADES[line].nom}, {$DADES[line].cognom}
{/section}
Smarty, Utilització, Section
plantilla.tpl
prova.php
Sortida
{section name=line loop=$DADES}<br>{$DADES[line][0]}, {$DADES[line][1]}
{/section}
$smarty = new Smarty_template ;$smarty->assign (“USUARI_ADMIN”, true);$smarty->assign (“DADES”,
array (array(“Josep”, “Pepet”), array(“Jordi”, “Bosc”))
);$smarty->display (“plantilla.tpl”);
<br>Josep, Pepet<br>Jordi, Bosc
Smarty, Utilització, fitxers de configuració
Smarty permet carregar “constants” directament a les plantilles, a través del tag {#NOM_CONSTANT#}. Aquests fitxers son interessants pel tema d'idiomes...
Per exemple
{#NOM#}
Aquestes constants es troben dins dels fitxers ubicats en /projecte/config/, per exemple:
/projecte/config/catala.confNOM = “Nom”
Per indicar a Smarty que carregi un d'aquest fitxers en la plantilla s'utilitza
plantilla.tpl{config_load file=”catala.conf”}{#NOM#}: {$NOM}
Smarty, Utilització, fitxers de configuració
/projecte/config/catala.conf /projecte/config/castella.conf
NOM=”Nom” NOM”Nombre”TELEFON=”Telefon” TELEFON=”Telefono”
{config_load file=”catala.conf”}<html><body>
{#NOM#}: {$NOM}<br>{#TELEFON#}: {$TELEFON}
</body></html>
plantilla.tpl
config
{config_load file=”castella.conf”}<html><body>
{#NOM#}: {$NOM}<br>{#TELEFON#}: {$TELEFON}
</body></html>
Sortida
<html><body>
Nom: Josep<br>Telefon: Pepet
</body></html>
<html><body>
Nombre: Josep<br>Apellido: Pepet
</body></html>
Smarty, Utilització, includes
El funcionament es similar a la comanda include de php, ens permet incloure el codi html d'un altre fitxer.
La sintaxis es la següent:
{include file='NOM_PLANTILLA.tpl'}
Per exemple
plantilla.tpl
<body>Nom {$NOM}, Cognom: {$COGNOM}
{include file=”peu_pagina.tpl”}</body>
peu_pagina.tpl
<div align=”center”> Peu de pàgina </div>
<body>Nom Pepet, Cognom: Pepe
<div align=”center”> Peu de pàgina </div></body>
plantilla.tpl
prova.php
Sortida
<body>Nom {$NOM}, Cognom: {$COGNOM}
{include file=”peu_pagina.tpl”}</body>
$smarty = new Smarty_template ;$smarty->display (“plantilla.tpl”);
Smarty, Utilització, includes
peu_pagina.tpl<div align=”center”> Peu de pàgina </div>
Smarty, temes interessants
Es important tenir present que les coses que es pugin fer a nivell de Smarty, ens poden facilitar molt la vida a nivell de Negoci:
{if $smarty.constant.ADMINISTRADOR == $smarty.session.GRUPUSUARI}Es usuari administrador
{else if $smarty.constant.REGISTRAT == $smarty.session.GRUPUSUARI}Es registrat
{/if}
http://servidor/index.php?ACCIO=llistar
{if $smarty.get.ACCIO == “Afegir”}Estem Afegint -> Mostrem formular d'afegir
{else}Estem llistant -> mostrem llistat
{/if}
aillar la presentació del negoci !!!
el “Framework”: Controlador, funcionament
Respon als events d'un usuari i executa els models necessaris i mostra les vistes que han de presentar les dades.
De forma simple el controller té una lògica com:
switch ($_REQUEST[‘action’]) {
case ‘llibre’: $action_class = ‘Llibre’; break;case ‘user’: $action_class = ‘User’; break;case ‘show’:default: $action_class = ‘Inici’;
}
require_once ‘actions/’.$action_class.’.php’
$action = $ACTION_FACTORY->factory ($action_class);
$action->Perform();
$vista = $VIEW_FACTORY->factory (“VISTA_A_MOSTRAR”);
$vista->Show($action);
El “Framework”, estructura
Com utilitzem en “Framework”.
Configuració general
Configuració de controller
Generació de models
Generació d'accions
Generació de vistes
Generació de templates
El “Framework”, convenis
classes/action/Gestion[NOM_ACCIO]Action.php
exemple: classes/action/GestionHotelAction.php
-> acció encarregada de mostrar llistat de dades d'hotels
classes/view/Gestion[NOM_ACCIO]View.php
exemple: classes/view/GestionHotelView.php
-> vista encarregada de mostrar llistat de dades d'hotels
El “Framework”, convenis
classes/action/Process[NOM_ACCIO]Action.php
exemple: classes/action/ProcessHotelAction.php
-> acció encarregada de gestionar, altes, baixes i modificacions
Sempre deriven de la classe Process que s'encarrega d'executar les mètodes per Afegir, modificar o esborrar
classes/view/Process[NOM_ACCIO]HotelView.php
exemple: classes/view/ProcessHotelHotelView.php
-> vista encarregada de gestionar, altes, baixes i modificacions
El “Framework”, convenis
templates/tpl_main.php
plantilla general
Capçalera
{include file=nom_plantilla.php}
peu
El “Framework”, Diagrama classes
Controller
ActionFactory
ViewFactory
Action
View
Process ProcessSub
Singleton
Log SmartyRequest Utils
Pear::Dataobject ...
GestionHotelAction
GestionHotelView
ProcessHotelAction
ProcessHotelView
ProcessFotoHotelAction
El “Framework”, estructura
Configuració del Framework
-> Generació de dbmappings -> PEAR::Dataobject-> creació controller.php -> definició de models,vistes i templates-> creació de model-> creació de vista i template
Estructura de Directoris:
projecte/classes/action/ -> Accionsclasses/view/ -> vistesclasses/dbmapping/ -> classes de mapping BD “Models”classes/utils/ -> classes d'utilitatsconfig/ -> fitxers de configuraciólibs/ -> llibreries PEAR, Smarty, etctemplates/ -> templates d'smartycontroller.php
El “Framework”, configuració general
config/config.php
define('HOSTNAME_DB', “servidor_base_de_dades”); define('DATABASE', “nom_base_de_dades”;define('USERNAME_DB', “usuari_base_de_dades”);define('PASSWORD_DB', “password_base_de_dades”);
El “Framework”, configuració controller
Controller.php
include_once 'config/config.php';include_once 'config/path.php';include_once 'config/includes.php';
-> estem a punt per treballar amb el framework
$actions = array(array(“GestionHotelAction", "LlistatGenericaView" , "tpl_lista.php"),array("ProcessHotelAction", "ProcessHotelView", "tpl_afegirmodificarhotel.php"),
);
$CONTROLLER = &singleton::getInstance ('Controller');$CONTROLLER->SetActionMap ($actions);
$CONTROLLER->Exec ();
--> Executarà l'accio a realitzar i després passarà dades a la Vista corresponent
el “Framework”: Application controllerApplication Controller classes/utils/inc_controller.php
class Controller{
public function Exec() {
//Get the action to exec
$ACTION_FACTORY = &singleton::getInstance ('ActionFactory');
$action = $ACTION_FACTORY->factory ($this->actions[$key]);
$action->Perform();
//Get the view and show it
$VIEW_FACTORY = &singleton::getInstance ('ViewFactory');
$view = $VIEW_FACTORY->factory ($this->views[$key]);
$view->SetTemplate ($this->templates[$key]);$view->Show($action);
}}
el “Framework”: Funcionament
LlistatGenericaView
Petició
Resposta
APPLICATIONCONTROLLER
GestionHotelAction
CONTROLLERFRONTAL
tpl_llista.php
Es crida a partir de la URL:
http://servidor/controller.php?page=GestionHotelAction
$actions = array(array(“GestionHotelAction", "LlistatGenericaView" , "tpl_lista.php"),),
);
el “Framework”: Acció i Model
classes/action/GestionHotelAction.php
class GestionHotelAction extends Action{
function Perform(){
$entidadHotelera = DB_DataObject::factory("entidadHotelera");$data = $entidadHotelera->getList ();$this->toview[“DATOS”] = $data;
}}
Es crida a partir de la URL:
http://servidor/controller.php?page=GestionHotelAction
el “Framework”: Vista
classes/view/LlistaGenericaView.php
class LlistatGenericaView extends View{
function LlistatGenericaView (){
View::View ();}
function Show($action = ''){
$this->smarty->assign ("DATOS", $action->toview["DATOS"]);$this->AssignDefaults();
}}
el “Framework”: Template
templates/tpl_lista.php
{section name=line loop=$DATOS}<tr>
<td><a href='{$PAGE_ANADIR}&id={$DATOS[line][0]}&type={$smarty.const.MOD}'>
<img src='img/editar.png'>Editar</a>
</td>
<td><a href="{$PAGE_ANADIR}&id={$DATOS[line][0]}&type={$smarty.const.DEL}"
onclick="return confirm('Seguro que quiere borrar?')"><img src='img/borrar.png'>Borrar</a>
</td>
{section name=line2 loop=$CAPCALERA[0]}
<td>{$DATOS[line][line2]|capitalize:true}
</td>{/section}
</tr>
{/section}
{$NUM_REGISTRES} registros
el “Framework”: Exemple
controller.php?page=GestionHotelAction
controller.php?page=ProcessHotelAction&type=add
controller.php?page=ProcessHotelAction&type=del&id=9198
controller.php?page=ProcessHotelAction&type=mod&id=9198
el “Framework”: Exemple
controller.php?page=ProcessHotelAction&type=add
->es crida el métode PrepareData (o getData si es modificació) per generar dades com desplegables, idiomes, consultar les dades del registre, etc
el “Framework”: Accions
classes/action/ProcessHotelAction.php
class ProcessHotelAction extends Process{
function PrepareData () //prepara dades per a mostrar un formulari //per afegir un nou registre
function getData ($id_hotel) //obte les dades del registre per mostrar //un formulari per modificar registre
function Add () //s'encarrega de afegir un nou registre
function Update ($id_hotel) //s'encarrega d'actualizar el registre
function Delete ($id_hotel) //esborrar el registre }
Els mètodes es criden de forma automàtica per la classe Process segons els parametres de la URL, per exemple:
http://servidor/controller.php?page=ProcessHotelAction&type=addhttp://servidor/controller.php?page=ProcessHotelAction&type=mod&id=9198http://servidor/controller.php?page=ProcessHotelAction&type=del&id=9198
el “Framework”: Accions
classes/action/ProcessHotelAction.php
class ProcessHotelAction extends Process{ function Redirect ($id = '') {
if ($id == '') Process::Redirect (URL_CONTROLLER."GestionHotelAction");Process::Redirect (URL_CONTROLLER."ProcessHotelAction&type=mod&id=$id");
}}
Es crida automàticament un cop s'executat el mètode d'afegir/modificar o esborrar
el “Framework”: Accionsclasses/action/ProcessHotelAction.php
class ProcessHotelAction extends Process{
function PrepareData (){
$hotel = array();$hotel["monedas"] = DataObjects_Moneda::getMonedas ();$hotel["resorts"] = DataObjects_EntidadHotelera::getResorts ();$hotel["paisos"] = array (“Colombia”, “Espanya”, “Costa Rica”);$this->toview["datos"] = $hotel; -> aquest array arribarà a la vista
}}
class DataObjects_EntidadHotelera extends DB_DataObject {
public function getResorts () { $num = $eh->find ();
$datos = array ();
while ($eh->fetch ()) $datos[$eh->id] = $eh->nombre;
return $datos;}
}
el “Framework”: Accions
classes/action/ProcessHotelAction.php
class ProcessHotelAction extends Process{
function getData ($id_hotel) //obte les dades del registre per mostrar //un formulari per modificar registre
{$dades = DataObjects_EntidadHotelera::getHotel ($id_hotel);$dades["monedas"] = DataObjects_Moneda::getMonedas ();
$dades["fotos"] = DataObjects_Foto::getFotosEntidadHotelera ($id_hotel);
$this->toview[“datos”] = $dades; -> aquest array arribarà a la vista
}}
el “Framework”: Vista
classes/view/ProcessHotelView.php
class ProcesshotelView extends ProcessEditorView{ function Show($action = '')
{ProcessEditorView::Show($action);
}}
class ProcessEditorView extends View -> mostra un editor HTML{
public function Show($action = ''){
$this->smarty->assign ("DATOS", $action->toview["datos"]);}
}
el “Framework”: Template
templates/tpl_afegirmodificarhotel.php
<form name="form1" method="post" action="{$PAGE}">
{$PAGE} s'instació directament per Process, en el nostre cas es controller.php?page=ProcessHotelAction
Codigo: <input type='text' name='codigo' value='{$DATOS.codigo}'>
Nombre: <input type='text' name='nombre' value='{$DATOS.nombre}'>
Moneda: <select name="moneda">
{html_options options=$DATOS.monedas selected=$DATOS.moneda}</selected>
</form>
el “Framework”: Exemple
controller.php?page=ProcessHotelAction&type=add
Al guardar es crida de forma automàtica el mètode Add (o update si és el cas) de la classe ProcessHotelAction
i després de processar l'actualització es crida al mètode Redirect per redirigir la petició o bé a la llista o bé a la edició del registre (si hem fet afegir)
el “Framework”: Accionsclasses/action/ProcessHotelAction.php
class ProcessHotelAction extends Process{
function Add (){
$eh = DB_DataObject::factory("entidadHotelera");$eh->setFrom (Request::Get());$eh->insert ();
}
function Update ($id_hotel){
$eh = DB_DataObject::factory("entidadHotelera");$eh->setFrom (Request::Get());$eh->update ();
}
function Delete ($id_hotel){
$eh = DB_DataObject::factory("entidadHotelera");$eh->get ($id_hotel);$eh->delete ();
}}
el “Framework”: Millores
Creació de Filtres en el Frontal Controller per exemple
HtmlCommentFilter
per poder filtar continguts, preprocessar/postprocessar dades.
Generació de codi de funcionalitats: Alta, Baixa, Modificació, llistat de Registre, paginació de llistats, etc
Creació de sistema de “plugins” per poder extendre funcionalitats de forma ràpida.
Creació automàtica de sistema de Menús, permisos d'usuaris, etc, llistats automàtics
Integració fàcil d'AJAX a nivell de framework.
Publicar el Framework en Sourceforge
Hi ha multitud de Frameworks lliures en diferents tecnologies com poden ser:
PHP:-Symfony-CakePHP-Akelos-...
Python:-Django-Pylons-Zope-...
Ruby on Rails
Java -Struts-Spring-...
Frameworks MVC Lliures
● Programació en PHP● Jordi Catà
●
Gracies per la vostra atenció
Cas d'us de Framework web
desenvolupat amb llibreries LliuresJordi Catà Castillo - [email protected]
Freelance Girona – 13 Febrer 2008