Unidad 2 - Desarrollo de Una Aplicación Web Siguiendo El Patrón MVC PDF
Unidad 2 - Desarrollo de Una Aplicación Web Siguiendo El Patrón MVC PDF
Unidad 2 - Desarrollo de Una Aplicación Web Siguiendo El Patrón MVC PDF
ElpatrnMVCeneldesarrollodeaplicacionesweb
Muchosdelosproblemasqueaparecenenlaingenieradelsoftwaresonsimilaresensuestructura.Y,portanto,seresuelvendemaneraparecida.Alolargodela
[1]
historiadeestadisciplinasehanelaboradounbuennmerodeesquemasresolutivosquesonconocidosconelnombredespatronesdediseo ycuyoconocimientoy
aplicacinsondeunainestimbleayudaalahoradedisearyconstruirunaaplicacininformtica.
Posiblemente uno de los ms conocidos y utilizados sea el patrn Modelo, Vista, Controlador (MVC),que propone organizar una aplicacin en tres partes bien
diferenciadasydbilmenteacopladasentres,demaneraqueloscambiosqueseproduzcanenunanoafectendemasiadoalasotras(idealmentenada).Elnombredel
patrnenumeracadaunadelaspartes:
ElControlador.Enesteartefactoseincluyetodoloreferentealalgicadecontroldelaaplicacin,quenotienenadaqueverconlascaractersticaspropiasdel
negocioparaelqueseestconstruyendolaaplicacin.Enelcasodeunaaplicacinweb,unejemploseralamanipulacindelarequestHTTP.
ElModelo. Donde se implementa todo lo relativo a la lgica de negocio, es decir, los aspectos particulares del problema que la aplicacin resuelve. Si, por
ejemploestamosdesarrollandounblog,unejemploseraunalibreradefuncionesparalagestindeloscomentarios.
LaVista.Aquseubicaelcdigoencargadodepintarelresultadodelosprocesosdelaaplicacin.Enunaaplicacinweblavistaseencargadeproducir
documentosHTML,XML,JSON,etctera,conlosdatosquesehayancalculadopreviamenteenlaaplicacin.
Paraqueelconjuntofuncione,laspartesdebeninteraccionarentres.Yenestepuntoencontramosenlaliteraturadistintassoluciones.Laqueproponemoseneste
cursoeslamostradaenlasiguientefigura:
DiagramadelmodeloMVC
Elcontroladorrecibelaordendeentradayseencargadeprocesarlautilizando,siespreciso,losserviciosdelmodeloparaello.Unavezqueharealizadoelclculo
entregalosdatoscrudosalavistayestaseencargadedecorarlosadecuadamente.Lacaractersticamsimportantedeestasolucinesquelavistanuncainteracciona
conelmodelo.
Lasaplicacioneswebmstpicaspuedenplantearsesegnestepatrn:elcontroladorrecibeunapeticinHTTPylaprocesa,haciendousodelmodelocalculalosdatos
desalidaylosentregaalavista,lacualseencargadeconstruirunarespuestaHTTPconlascabecerasadecuadasyunpayloadocuerpodelarespuestaquesueleserun
contenidoHTML,XMLoJSON.
Aunquenotodaslasaplicacioneswebsepuedenajustaraestemodelo,siesciertoquelaideadesepararresponsabilidadesolasdistintasareasdeunproblemaen
sistemasdbilmenteacoplados,esunaestrategiacomnenlasmetodologaqueutilizanelparadigmadeprogramacinorientadoaobjetos.Esloqueseconoceenla
terminologaanglosajonacomoSeparationOfConcerns[2].
Enestaunidadvamosaplantearydesarrollarunasencillaaplicacinwebutilizandocomoguadediseoestepatrn.Deestamanerailustraremossusventajasynos
servircomomaterialintroductorioalaarquitecturadesymfony1.4.
Descripcindelaaplicacin
Vamosaconstruirunaaplicacinwebparaelaboraryconsultarunrepositoriodealimentoscondatosacercadesuspropiedadesdietticas.Utilizaremosunabasede
datosparaalmacenardichosdatosqueconsistirenunasolatablaconlasiguienteinformacinsobrealimentos:
Elnombredelalimento,
laenergaenkilocaloras,
lacantidaddeprotenas,
lacantidadhidratosdecarbonoengramos
lacantidaddefibraengramosy
lacantidaddegrasaengramos,
todoelloporcada100gramosdealimento.
Aunquesetratadeunaaplicacinmuysencilla,cuentaconloselementossuficientesparatrabajarelaspectoquerealmentepretendemosestudiarenestaunidad:la
organizacin del cdigo siguiendo las directrices del patrn MVC. Comprobaremos como esta estrategia nos ayuda a mejorar las posibilidades de crecimiento
(escalabilidad)yelmantenimientodelasaplicacionesquedesarrollamos.
Diseodelaaplicacin(I).Organizacindelosarchivos
Laanatomadeunaaplicacinwebtpicaconsisteen:
1. Elcdigoqueserprocesadoenelservidor(PHP,Java,Python,etctera)paraconstruirdinmicamentelarespuesta.
2. LosAssets,quepodemostraducircomoactivosdelaaplicacin,yqueloconstituyentodosaquellosarchivosquesesirvendirectamentesinningntipode
proceso.Suelenserimgenes,CSSsycdigoJavascript.
ElservidorwebnicamentepuedeaccederaunapartedelsistemadeficherosquesedenominaDocumentRoot.Esahdondesebuscanlosrecursoscuandoserealiza
una peticin a la raz del servidor a travs de la URL http://el.servidor.que.sea/ . Sin embargo, el cdigo ejecutado para construir dinmicamente la
[3]
respuestapuedevivirencualquierotraparte,fueradelDocumentroot .
Todeestosugiereunamaneradeorganizarelcdigodelaaplicacinparaquenosepuedaaccederdesdeelnavegadormsquealcdigoestrictamenteimprescindible
para que esta funcione. Se trata, simplemente, de colocar en el Documentroot slo los activos y los scripts PHP de entrada a la aplicacin. El resto de archivos,
fundamentalmentelibrerasPHPsyficherosdeconfiguracin(XML,YAML,JSON,etctera),seubicarnfueradelDocumentRootysernincluidosporlosscripts
deiniciosegnlorequieran.
Siguiendoestasconclusiones,nuestraaplicacinpresentarlasiguienteestructuradedirectorio:
.
app
web
css
images
js
Diseodelaaplicacin(II).Elcontroladorfrontal
La manera ms directa y naf de construir una aplicacin en PHP consiste en escribir un script PHP para cada pgina de la aplicacin. Sin embargo esta prctica
presentaalgunosproblemas,especialmentecuandolaaplicacinquedesarrollamosadquiereciertotamaoypretendemosquesigacreciendo.Veamosalgunosdelos
problemasmssignificativosdeesteplanteamiento.
Por lo general, todos los scripts de una aplicacin realizan una serie de tareas que son comunes. Por ejemplo: interpretar y manipular la request, comprobar las
credencialesdeseguridadycargarlaconfiguracin.Estosignificaqueunabuenapartedelcdigopuedesercompartidoentrelosscripts.Paraellopodemosutilizarel
mecanismodeinclusindeficherosdePHPyfindelahistoria.Pero,quocurresienunmomentodado,cuandoyatengamosescritomuchocdigo,queremosaadir
atodaslaspginasdelaaplicacinunanuevacaractersticaquerequiere,porejemplo,elusodeunanuevalibrera?.Tenemos,entonces,queaadirdichamodificacin
atodoslosscriptsPHPdelaaplicacin.Locualsuponeunadegradacinenelmantenimientoyunmotivoqueaumentalaprobabilidaddefallosunavezqueelcambio
sehayarealizado.
OtroproblemaqueocurreconestaestrategiaesquesisesolicitaunapginaquenotieneningnscriptPHPasociado,elservidorarrojarunerror(404NotFound)
cuyoaspectonopodemoscontrolardentrodelapropiaaplicacin(esdecir,sintocarlaconfiguracindelservidorweb).
Comosesueledecir,agrandesmalesgrandesremedios!sielproblemalogeneraelhechodetenermuchosscripts,queademscompartenbastantecdigo,utilicemos
unosoloqueseencarguedeprocesartodaslaspeticiones.Aestenicoscriptdeentradaseleconocecomocontroladorfrontal.
Entonces,cmopuedocrearmuchaspginasdistintasconunsoloscript?.LaclaveestenutilizarlaquerystringdelaURLcomopartedelarutaquedefinelapgina
que se solicita. El controlador frontal, en funcin de los parmetro que lleguen en la query string determinar que acciones debe realizar para construir la pgina
solicidada.
Nota:LaquerystringeslapartedelaURLquecontienelosdatosquesepasarnalaaplicacinweb.Porejemlo,en:
http://tu.servidor/index.php?accion=hola ,laquerystringes: ?accion=hola .
Construccindelaaplicacin.Vamosallo.
Pueseso,vamosalloaplicandotodoloquellevamosdichohastaelmomento:
ElpatrndediseoMVC,
Laestructuradedirectoriosqueexponenicamentelosficherosindispensablesparaelservidorweby,
Laideadequetodaslapeticionespasenporunsoloscript,elcontroladorfrontal
Creacindelaestructuradedirectorios
Comenzamoscreandolaestructuradedirectoriospropuestaanteriormente.Porlopronto,ennuestroentornodedesarrolloyporcuestionesdecomodidad,crearemosla
estructuraenalgunaubicacindentrodelDocumentroot.
Nota:SiestsutilizandocomosistemaoperativoUbuntu,elDocumentrootseencuentraen /var/www ,esahdondedebescrearundirectoriodenominado
alimentos quealojarlaestructurapropuesta.SiestsutilizandoXAMPenWindows,seencuentraen C:/xampp/htdocs .
Esimportanteresaltarqueestonodeberahacerseenunentornodeproduccin,yaquedejamosalservidorwebaccederdirectamentealdirectorio app ,yes
algoquedeseamosevitar.Sinembargo,deestamanerapodemosaadirtodoslosproyectosquequeramossintenerquetocarlaconfiguracindelservidorweb.
Locualesalgomuyagradecidocuandoseestdesarrollando.Enunentornodeproduccindebemosasegurarnosdequeeldirectorio web eselDocument
rootdelservidor(odelVirtualHostdenuestraaplicacin,siesqueestamosalojandovariaswebsenunmismoservidor).
NuestraimplementacindelpatrnMVCsermuysencillacrearemosunaclaseparalapartedelcontroladorquedenominaremos Controller ,otraparaelmodelo
Elcontroladorfrontalyelmapeoderutas
EncualquieraplicacinwebsedebendefinirlasURLsasociadasacadaunadesuspginas.Paralanuestradefiniremoslassiguientes:
URL
Accin
http://tu.servidor/alimentos/index.php?ctl=inicio
mostrarpantallainicio
http://tu.servidor/alimentos/index.php?ctl=listar
listaralimentos
http://tu.servidor/alimentos/index.php?ctl=insertar
insertarunalimento
http://tu.servidor/alimentos/index.php?ctl=buscar
buscaralimentos
http://tu.servidor/alimentos/index.php?ctl=ver&id=x verelalimentox
AcadaunadeestasURLslesvamosaasociarunmtodopblicodelaclase Controller .Estosmtodossesuelendenominaracciones.Cadaaccinseencargade
calculardinmicamentelosdatosrequeridosparaconstruirsupgina.Podrutilizar,silehacefalta,loserviciosdelaclase Model .Unavezcalculadoslosdatos,se
lospasaraunaplantilladondeserealizar,finalmente,laconstruccindeldocumentoHTMLqueserdevueltoalcliente.
Todosestoselementossernorquestadosporelcontroladorfrontal,elcualloimplementaremosenunscriptllamado index.php ubicadoeneldirectorio web .
Enconcreto,laresponsabilidaddelcontroladorfrontalser:
cargarlaconfiguracindelproyectoylaslibrerasdondeimplementaremoslapartedelModelo,delControladorydelaVista.
AnalizarlosparmetrosdelapeticinHTTP(request)comprobandosilapginasolicitadaenellatieneasignadaalgunaaccindelControlador.Siesasla
ejecutar,sinodarunerror404(pagenotfound).
Llegadosaestepuntoesimportanteaclaraque,elcontroladorfrontalylaclase Controller ,sondistintascosasytienendistintasresponsabilidades.Elhechode
queambossellamencontroladorespuededarlugaraconfusiones.
Elcontroladorfrontaltieneelsiguienteaspecto.Creaelarchivo web/index.php ycopiaelsiguientecdigo.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?php
// web/index.php
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
if (method_exists($controlador['controller'],$controlador['action'])) {
call_user_func(array(new $controlador['controller'], $controlador['action']));
} else {
header('Status: 404 Not Found');
echo '<html><body><h1>Error 404: El controlador <i>' .
$controlador['controller'] .
'->' .
$controlador['action'] .
'</i> no existe</h1></body></html>';
}
Enlaslneas57serealizalacargadelaconfiguracindelmodeloydeloscontroladores.
Enlaslneas1016sedeclaraunarrayasociativocuyafuncinesdefinirunatablaparamapear(asociar),rutasenaccionesdeuncontrolador.Estatablaser
utilizadaacontinuacinparasaberquaccinsedebedisparar.
Enlaslneas1931sellevaacaboelparseodelaURLylacargadelaaccin,silarutaestdefinidaenlatabladerutas.Encasocontrariosedevuelveuna
pginadeerror.Observaquehemosutilizadolafuncin header() dePHPparaindicarenlacabeceraHTTPelcdigodeerrorcorrecto.Ademsenviamos
unpequeodocumentoHTMLqueinformadelerror.Tambindefinimosa inicio comounarutapordefecto,yaquesilaquerystringllegavaca,seopta
porcargarestaaccin.
Nota:EnhonoralaverdadtenemosquedecirqueloqueestamosllamandoparseodelaURL,noestal.Simplementeestamosextrayendoelvalordelavariable
ctl quesehapasadoatravsdelapeticinHTTP.Sinembargo,hemosutilizadoesteterminoporqueloidealseraque,enlugardeutilizarparmetrosdela
peticinHTTPpararesolverlaruta,pudisemosutilizarrutaslimpias(esdecir,sincaracteres ? ni & )deltipo:
http://tu.servidor/index.php/inicio
http://tu.servidor/index.php/buscar
http://tu.servidor/index.php/ver/5
EnestecasosesnecesarioprocederaunparseodelaURLparabuscarenlatabladerutaslaaccinquelecorresponde.Esto,obviamente,esmscomplejo.
Peroesloquehace(ymuchascosasms)elcomponenteRoutingdesymfony1.4.
LasaccionesdelControlador.Laclase Controller.
AhoravamosaimplementarlasaccionesasociadasalasURLsenlaclase Controllers .Creaelarchivo app/Controller.php ycopiaelsiguientecdigo:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<?php
class Controller
{
public function inicio()
{
$params = array(
'mensaje' => 'Bienvenido al curso de symfony 1.4',
'fecha' => date('d-m-yyy'),
);
require __DIR__ . '/templates/inicio.php';
}
public function listar()
{
$m = new Model(Config::$mvc_bd_nombre, Config::$mvc_bd_usuario,
Config::$mvc_bd_clave, Config::$mvc_bd_hostname);
$params = array(
'alimentos' => $m->dameAlimentos(),
);
require __DIR__ . '/templates/mostrarAlimentos.php';
}
public function insertar()
{
$params = array(
'nombre' => '',
'energia' => '',
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
Estaclaseimplementaunaseriedemtodospblicos,quehemosdenominadoaccionesparaindicarquesonmtodosasociadosaURLs.Fjatecomoencadaunadelas
accionessedeclaraunarrayasociativo( params )conlosdatosquesernpintadosenlaplantilla.Peroenningncasohayinformacinacercadecomosepintarn
dichosdatos.Porotrolado,casitodaslasaccionesutilizanunobjetodelaclase Models pararealizaroperacionesrelativasalalgicadenegocio,ennuestrocasoa
todolorelativoconlagestindelosalimentos.
Paracomprenderelfuncionamientodelasacciones,comencemosporAnalizarlafuncin listar() .Comienza declarando un objeto del modelo (lnea 17) para
pedirleposteriormenteelconjuntodealimentosalmacenadosenlabasededatos.Losdatosrecopiladossonalmacenadosenelarrayasociativo params (lneas20
22).Porltimoincluyeel archivo /templates/mostrarAlimentos.php (lnea24).Talarchivo,que denominamos plantilla,serelencargado de construir el
LaimplementacindelaVista.
LasplantillasPHP
AhoravamosapasaraestudiarlapartedelaVista,representadaennuestrasolucinporlasplantillas.Aunqueenelanlisisqueestamoshaciendoyahemosutilizado
lapalabraplantillaenvariasocasiones,annolahemosdefinidoconprecisin.Asquecomenzamosporah.
Unaplantillaesunficherodetextoconlainformacinnecesariaparagenerardocumentosencualquierformatodetexto(HTML,XML,CSV,LaTeX,JSON,etctera).
Cualquier tipo de plantilla consiste en un documento con el formato que se quiere generar, y con variables expresadas en el lenguaje propio de la plantilla y que
representasalovaloresquesoncalculadosdinmicamenteporlaaplicacin.
CuandodesarrollamosaplicacioneswebconPHP,laformamssencilladeimplementarplantillasesusandoelpropioPHPcomolenguajedeplantillas.Qusignifica
esto?Acudimosalrefraneropopularydecimosaquellodequeunaimagenvalemsquemilpalabras.ContodosvosotrosunejemplodeplantillaHTMLqueusaPHP
comolenguajedeplantillas(dedcaleunratitoaobservarlayanalizarla,quesloquetellamalaatencinenelaspectodelcdigoPHPqueaparece?)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<table>
<tr>
<th>alimento (por 100g)</th>
<th>energa (Kcal)</th>
<th>grasa (g)</th>
</tr>
<?php foreach ($params['alimentos'] as $alimento) :?>
<tr>
<td><a href="index.php?ctl=ver&id=<?php echo $alimento['id']?>">
<?php echo $alimento['nombre'] ?>
</a>
</td>
<td><?php echo $alimento['energia']?></td>
<td><?php echo $alimento['grasatotal']?></td>
</tr>
<?php endforeach; ?>
</table>
Esencialmente no es ms que un trozo de documento HTML donde la informacin dinmica se obtiene procesando cdigo PHP. La caracterstica principal de este
cdigoPHPesquedebeserescuetoycorto.DemaneraquenocontaminelaestructuradelHTML.PorellocadainstruccinPHPcomienzayterminaenlamisma
lnea.Lamayorpartedeestasinstruccionesson echo's devariablesescalares.Perotambinsonmuyusualeslautilizacindebucles foreach endforeach
pararecorrerarraysdedatos,ascomolosbloquescondicionales if endif parapintarbloquessegndeterminadascondiciones.
EnelejemplodemsarribasegeneraelcdigoHTMLdeunatablaquepuedetenerunnmerovariabledefilas.Serecojeenlaplantillaelparmetro alimentos ,
queesunarraycondatosdealimentos,ysegeneraunafilaporcadaelementodelarrayconinformacindelaURLdeunapginasobreelalimento(lnea9),ysu
nombre,energaygrasatotal(lneas1014).
Observatambinlaformadeconstruirelbucle foreach ,seabreenlalnea7ysecierraenla16.Loparticulardelasintaxisdeestetipodebucleparaplantillases
quelainstruccin foreach queloabreterminanconelcaracter : .Ylanecesidaddecerrarloconun <?php endforeach; ?> .
Ellayoutyelprocesodedecoracindeplantillas
Enunaaplicacinweb,muchasdelaspginastienenelementoscomunes.Porejemplo,uncasotpicoeslacabeceradondesecolocaelmensajedebienvenida,elmen
yelpiedepgina.Estehecho,ylaaplicacindelconocidoprincipiodebuenasprcticasdeprogramacinDRY(DontRepeatYourself,NoTeRepitas),llevaaque
[4]
cualquiersistemadeplantillasqueseutiliceparaimplementarlavistautiliceotroconocidopatrndediseo:ElDecorator,oDecorador .Aplicadoalageneracin
devistaslasolucinqueofrecedichopatrnesladeaadirfuncionalidadadicionalalasplantillas.Porejemplo,aadirelmenyelpiedepginaalasplantillasquelo
requieran, de manera que dichos elementos puedan reutilizarse en distintas plantillas. Literalmente se trata de decorar las plantillas con elementos adicionales
reutilizables.
NuestraimplementacindelpatrnDecoratoresmuysimpley,portantolimitada,perosuficienteparaasimilarlasbasesdelconceptoyayudarnosacomprenderms
adelantelafilosofadelsistemadeplantillasdesymfony1.4.
NuestrasplantillassernficherosPHPdeltipoqueacabamosdeexplicar,ylasubicaremoseneldirectorio app/templates .Comoyahasvistoenelcdigodel
controlador,lasaccionesfinalizanincluyendoalgunodeestosarchivos.Comencemosporestudiarlaplantilla app/templates/mostrarAlimentos.php ,queesla
queutilizalaaccin listar() parapintarlosalimentosqueobtienedelmodelo.Creaelarchivo app/templates/mostrarAlimentos.php conelsiguiente
cdigo:
app/templates/mostrarAlimentos.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Comoves,laslneas318sonlasquesehanpuestocomoejemplodeplantillaPHPhaceunmomento.Lanovedadsonlaslneas1y2123.Enellasestlaclavedel
nuestro proceso de decoracin. Para comprenderlo del todo es importante echarle un vistazo al fichero app/templates/layout.php , incluido al final de la
plantilla.Craloycopiaelsiguientecdigo:
app/templates/layout.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
El nombre del fichero es bastante ilustrativo, es un layoutHTML, es decir, un diseo de un documento HTML que incluye como elemento dinmico a la variable
$contenido (lnea26),lacualestadefinidaalfinaldelaplantilla mostrarAlimentos.php ,ycuyocontenidoesprecisamenteelresultadodeinterpretarlas
lneas comprendidas entre el
ob_start() y
$contenido = ob_get_clean() . En la documentacin de estas funciones
(http://php.net/manual/es/function.obstart.php)puedesverqueelefectode ob_start() esenviartodoslosresultadosdelscriptdesdelainvocacindelafuncin
aunbufferinterno.Dichosresultadosserecojenatravsdelafuncin ob_get_clean() .Deesamaneraconseguimosdecorarlaplantillaconellayout.Estatcnica
esutilizadaentodaslasplantillas,demaneraquetodosloselementoscomunesatodaslaspginassonescritosunaslavezen layout.php yreutilizadoscontodas
lasplantillasgeneradasconlosdatosdecadaaccin.
Observaqueellayoutquehemospropuestoincluye:
losestilosCSS(lnea6),
elmendelaaplicacin(lneas1423)
elpiedepgina(lneas2932)
Acontinuacinmostramoselcdigodelrestodelasplantillas:
app/templates/inicio.php
1
2
3
4
5
6
7
8
app/templates/formInsertar.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
app/templates/buscarPorNombre.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
</tr>
</table>
</table>
</form>
<?php if (count($params['resultado'])>0): ?>
<table>
<tr>
<th>alimento (por 100g)</th>
<th>energa (Kcal)</th>
<th>grasa (g)</th>
</tr>
<?php foreach ($params['resultado'] as $alimento) : ?>
<tr>
<td><a href="index.php?ctl=ver&id=<?php echo $alimento['id'] ?>">
<?php echo $alimento['nombre'] ?></a></td>
<td><?php echo $alimento['energia'] ?></td>
<td><?php echo $alimento['grasatotal'] ?></td>
</tr>
<?php endforeach; ?>
</table>
<?php endif; ?>
<?php $contenido = ob_get_clean() ?>
<?php include 'layout.php' ?>
app/templates/verAlimento.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
ElModelo.Accediendoalabasededatos
YaslonosquedapresentaralModelo.Ennuestraaplicacinsehaimplementadoenlaclase Model yestacompuestoporunaseriedefuncionesparapersistirdatos
enlabasededatos,recuperarlosyrealizarsuvalidacin.
Dependiendodelacomplejidaddelnegocioconelquetratemos,elmodelopuedesermsomenoscomplejoy,ademsdetratarconlapersistenciadelosdatospuede
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
<?php
class Model
{
protected $conexion;
public function __construct($dbname,$dbuser,$dbpass,$dbhost)
{
$mvc_bd_conexion = mysql_connect($dbhost, $dbuser, $dbpass);
if (!$mvc_bd_conexion) {
die('No ha sido posible realizar la conexin con la base de datos: ' . mysql_error());
}
mysql_select_db($dbname, $mvc_bd_conexion);
mysql_set_charset('utf8');
$this->conexion = $mvc_bd_conexion;
}
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
$f = htmlspecialchars($f);
$g = htmlspecialchars($g);
$sql = "insert into alimentos (nombre, energia, proteina, hidratocarbono, fibra, grasatotal) values ('" .
$n . "'," . $e . "," . $p . "," . $hc . "," . $f . "," . $g . ")";
$result = mysql_query($sql, $this->conexion);
return $result;
}
public function validarDatos($n, $e, $p, $hc, $f, $g)
{
return (is_string($n) &
is_numeric($e) &
is_numeric($p) &
is_numeric($hc) &
is_numeric($f) &
is_numeric($g));
}
}
Laconfiguracindelaaplicacin
A lo largo y ancho de todo el cdigo expuesto, aparece cada tanto una referencia a unos atributos estticos de la clase Config . Por ejemplo, en la lnea 10 del
archivo app/Model.php ,aparece Config::$mvc_bd_hostname , Config::$mvc_bd_usuario ,etctera.Setratadeparmetrosdeconfiguracinquehemos
definidoenunaclasedenominada Config :
app/Config.php
1
2
3
4
5
6
7
8
9
10
<?php
class Config
{
static public $mvc_bd_hostname = "localhost";
static public $mvc_bd_nombre = "alimentos";
static public $mvc_bd_usuario = "root";
static public $mvc_bd_clave
= "root";
static public $mvc_vis_css
= "estilo.css";
}
Estaclaseestdisponibledurantetodoelscriptdemaneraquesepuedenutilizarsusvaloresalolargodelcdigo,ycambiarlossinmsquemodificarestefichero.
Conestoyatenemostodoelcdigodelapartedeservidor.YaslonosfaltadarleuntoquedeestiloalosdocumentosHTMLqueenviamosalclienteycrearlabasede
datosquealmacenarlosdatospersistentessobrelosalimentos.
IncorporarlasCSSs
Creaeldirectorio web/css yenlcolocaunarchivollamado estilo.css conelsiguientecontenido:
web/css/estilo.css
body {
padding-left: 11em;
font-family: Georgia, "Times New Roman",
Times, serif;
color: purple;
background-color: #d8da3d }
ul.navbar {
list-style-type: none;
padding: 0;
margin: 0;
position: absolute;
top: 2em;
left: 1em;
width: 9em }
h1 {
font-family: Helvetica, Geneva, Arial,
SunSans-Regular, sans-serif }
ul.navbar li {
background: white;
margin: 0.5em 0;
padding: 0.3em;
border-right: 1em solid black }
ul.navbar a {
text-decoration: none }
a:link {
color: blue }
a:visited {
color: purple }
address {
margin-top: 1em;
padding-top: 1em;
border-top: thin dotted }
#contenido {
display: block;
margin: auto;
width: auto;
min-height:400px;
}
Labasededatos
EnelSistemaGestordeBasedeDatosMySQLquevayasautilizar,utilizandoalgnclienteMySQLcreaunabasededatosparaalmacenarlosalimentos.Introduce
algunosregistrosparaprobarlaaplicacin.
CREATE TABLE `alimentos` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`nombre` varchar(255) NOT NULL,
`energia` decimal(10,0) NOT NULL,
`proteina` decimal(10,0) NOT NULL,
`hidratocarbono` decimal(10,0) NOT NULL,
`fibra` decimal(10,0) NOT NULL,
`grasatotal` decimal(10,0) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Suerte!
Ejercicios
Ejercicio1.
Aadealmenunaopcinparamostrarunlistadocontodoslosalimentosconenlacesalosartculoscorrespodientesdelawikipediayconstruyedichafuncionalidad.
Consejo:LosartculosdelawikipediapresentanlasiguienteURL:
http://es.wikipedia.org/wiki/{trmino}, teniendo en cuenta las tildes, de manera que el artculo correspondiente a la fruta limn ser:
http://es.wikipedia.org/wiki/limn, puedes construir una tabla con dos columnas, en la primera muestras el nombre del alimento y en la segunda el enlace a la
wikipedia
Ejercicio2.
Enriquecelosenlacesdelejercicioanteriorconcajasmodales.
Consejo:LaspobresinterfacesHTMLdelasaplicacioneswebpuedenenriquecersegraciasalusodejavascriptenlapartedelcliente.Enesteejerciciose
proponealestudiantequeconviertalosenlacesdelejercicioanteriordemaneraquecuandosepiqueenelloselenlaceaparezcaenunaventanasituadaencimadela
pginaquemuestralosenlaces,esdecir,enunaventanamodal.Estoseconsigueutilizandojavascript.Vamosaesbozarunaposiblesolucinqueteayudearealizar
elejercicio:
Descargalassiguienteslibrerasjavascript:
jquery,http://jqueryjs.googlecode.com/files/jquery1.3.2.min.js
colorbox,http://colorpowered.com/colorbox/colorbox.zip
Elsiguientecdigoconviertetodoslosenlacescuyaclase(atributoclassdelelementoHTML)seacajamodal:
<script>
$(document).ready(function(){
$(".cajamodal").colorbox();
});
</script>
Para que dicho ejemplo funcione, el documento HTML debe incluir las libreras jquery-1.3.2.min.js y colorbox.js (en ese orden). Adems, si quieres
http://colorpowered.com/colorbox/core/example1/index.html
Tutareaconsisteenubicarenloslugaresquecorrespondalaslibrerasyelcdigoanteriorparaquelosenlacesalosartculosdelawikipediadelejercicioanteriorse
veanencajamodal.
Ejercicio3
Aadeallistadodealimentosdelejercicio1unacolumnamsdondeubicarsunenlacequeproporcioneunarchivoXMLconlosdatosdelalimento.
Consejo:UnposibleformatoparaelficheroXMLqueestafuncionalidaddebeentregarcomorespuestapuedeser(atencin,cualquierparecidoconlosdatos
dietticosrealesdeesteejemploespuracasualidad):
<?xml version="1.0"?>
<alimento>
<nombre>limn</nombre>
<energia>100</energia>
<proteinas>150</proteinas>
<hc>45</hc>
<fibra>24</fibra>
<grasa>10</grasa>
</alimento>
Adems,paraenviarcomorespuestaunXMLenlugardelHTML,puedesutilizarlafuncinheader()dePHPenlapropiaaccinqueimplementeestafuncionalidad,
yterminardichaaccinconunexit,demaneraquenoseutilicelaplantillaniellayoutquedanlugaralHTML.Miraladocumentacindelafuncinheader()enel
sitiowebdePHP.Tambinpodrasmejorarelsistemadelavista,agregandolaposibilidaddeutilizar,ademsdelHTML,unlayoutXML.Estaltimasolucines
mseleganteperomscomplejadeimplementar(nomuchomscompleja).
Ejercicio4
ParaterminareltemaexplicabrevementelasventajasquetuvesenlaorganizacindelcdigosegnelpatrnMVC.
[1] PatronesdeDiseodelosautoresErichGamma,RichardHelm,RalphJohnsonyJohnVlissides(conocidoscomoTheGunofFour)esunclsicoenla
literaturasobreestetema.
[2] http://en.wikipedia.org/wiki/Separation_of_concerns
[3] EnelcasodeApacheconPHP,queeselquenosinteresaenestecurso,elservidordebeestarconfiguradoadecuadamenteparaquesepuedanincluirarchivos
PHPqueestnfueradelDocumentroot*.Estosehaceconladirectiva open_basedir .
[4] http://es.wikipedia.org/wiki/Decorator_%28patr%C3%B3n_de_dise%C3%B1o%29
DesarrollodeAplicacioneswebconsymfony1.4porJuanDavidRodrguezGarca([email protected])
seencuentrabajounaLicenciaCreativeCommonsReconocimientoNoComercialCompartirIgual3.0Unported.