El paradigma de la Programación Orientada a Objetos en PHP y el patrón de arquitectura de Software MVC (página 2)
Por otro lado, por cuestiones de seguridad, se
hacía necesario no permitir instanciar esta clase
desde ningún lugar de la aplicación y controlar con
mucha precaución, el acceso a sus métodos y
propiedades, ya que una base de datos, es el "alma" de toda
aplicación.
1.2 ¿Para qué declarar
propiedades estáticas?
En principio, tanto el host como el usuario y
contraseña de la base de datos, en esta
aplicación, son únicos. No varían. De
allí, que como característica se les asignó
ser estáticos, a fin de, por cuestiones de
seguridad, no puedan ser modificados dinámicamente
(tengamos en cuenta que una clase abstracta debe ser heredada
sí o sí para ser utilizada).
1.3 ¿Por qué propiedades
estáticas y no constantes de clase?
Porque a las constantes, aunque lógicamente
guardan en sí mismas la condición de
"estáticas" en el sentido de que "no pueden ser
modificadas", pueden ser accedidas desde cualquier clase
que herede de la clase que las declare. Pues entonces, la
pregunta es ¿Para qué querría una clase
"hija" conocer el host, usuario y contraseña de una base
de datos? Es una cuestión nétamente de
seguridad, ya que a una constante no se la puede definir como
privada y si se la quiere ocultar a las clases "hijas", no
quedará otra alternativa que declararlas como propiedades
estáticas.
1.4 ¿Por qué propiedades
estáticas y a la vez privadas?
(ver respuestas anteriores)
1.5 ¿Con qué sentido
declarar las propiedades como protegidas?
Es simple. Algunos módulos pueden necesitar
utilizar una base de datos diferente. Todos los módulos,
necesitarán queries personalizados para sus
consultas. Y lógicamente, todos necesitarán acceder
y conocer los resultados de los datos arrojados por una consulta.
Es decir, que tanto la propiedad db_name como query y
rows, deben tener permisos para ser leídas y
modificadas, pero ¡Ojo! Solo por las clases hijas de
DBAbstractModel ¿Qué sentido tendría
permitir a un programador acceder a estas propiedades si puede
ser la clase hija, quien las controle?
1.6 ¿Por qué los
métodos open y close_connection son
privados?
Pues porque la clase es la única con permiso para
abrir y cerrar conexiones a la base de datos. Es una
cuestión de control y seguridad. Si necesitas insertar
datos, consultarlos o hacer con ellos otras actividades, tienes
métodos protegidos pero no privados, que te permiten
hacerlo.
1.7 ¿Por qué los
métodos de consulta y ejecución son protegidos y no
públicos?
Consultar una base de datos, modificar o eliminar sus
datos, así como insertar nuevos, no puede ser una tarea
que se deje librada al azar y al libre acceso de cualquiera. Es
necesario "proteger" los datos a fin de resguardar su integridad
y, la forma de hacerlo, es "proteger" los métodos que se
encuentran al servicio de dichos datos.
1.8 ¿Por qué hay
métodos declarados como abstractos y además
protegidos?
Esta pregunta, en gran parte, la responde la respuesta
de la pregunta 1.1. El hecho de que se definan como abstractos,
es porque necesariamente DEBEN ser métodos comunes a toda
clase que los hereden. Pero solo la clase hija, podrá
definirlos (re-definirlos técnicamente hablando) ya que
tal cual se explicó en la pregunta 1.1., solo ellas
conocen los requerimientos específicos.
Se declaran además como protegidos, por una
cuestión de seguridad ("por las dudas" para que solo
puedan ser vistos por clases heredadas). Esto, da lugar a las
clases hijas, a que modifiquen su visibilidad de acuerdo al
criterio de cada una de ellas.
- 2. Respuestas a preguntas sobre la clase
Usuario
2.1 ¿Por qué la clase
Usuario es una extensión de
DBAbstractModel?
La clase usuario TIENE necesariamente que heredar de
DBAbstractModel ya que DEBE utilizar sus métodos (propios
y definidos para acceder a la base de datos) y redefinir
obligadamente aquellos declarados como abstractos, a fin de
continuar un modelo de administración de los ABM (altas,
bajas y modificaciones).
2.2 ¿Con qué fin nombre,
apellido e e-mail son propiedades públicas mientras que
clave es privada y id, protegida?
Pensemos esto como en la vida real: tu nombre,
apellido e e-mail, puede ser necesario para cientos de
"trámites" y acciones de tu vida diaria y no andas por la
vida negándolos a todo quien te los pida. Podríamos
decir, que no tiene nada de malo que facilites
públicamente estos datos, a quien decidas.
Ahora bien ¿le das tu contraseña a
cualquiera? Si lo haces, deja de hacerlo. La
contraseña es un dato que debe ser privado. Nadie
puede tener acceso a él. Es una cuestión de
seguirdad.
El número de ID, sería como tu
número de documento o pasaporte. Es un dato que debes
mantener protegido pero que en algunos casos, te
será requerido y necesitarás darlo obligadamente.
Por ejemplo, no podrías negarte a mostrar tu pasaporte en
migraciones. Sin embargo, DEBES negarte a decirle el PIN de tu
tarjeta de crédito a cualquier persona.
2.3 ¿Por qué se utiliza el
método __construct() para modificar el nombre de la base
de datos? ¿Por qué no se encarga la clase madre de
modificar ese valor?
El nombre de la base de datos, es algo que
variará de acuerdo al módulo que lo
esté trabajando. Seguramente, de existir en el futuro una
clase llamada Producto, ésta, sobreescribirá el
valor de db_name. Modificarlo automáticamente
utilizando un cosntructor, nos asegura instanciar el objeto con
un valor de propiedad adecuado.
2.4 ¿Por qué se utiliza
require_once y no include_once?
La diferencia entre include y require es que require, si
no puede incluir el archivo al que se está importando,
frena la ejecución del script, siendo que include,
solo arroja un error, pero continúa la ejecución.
Al tratarse de una clase que "requiere" sí o sí, de
su clase madre, no tendría sentido permitir que se
continúe ejecutando, si no ha podido cargarse el
archivo.
- 3. Respuestas a preguntas sobre el archivo de
instancias
3.1 ¿Por qué el archivo
tiene cuatro instancias al mismo objeto?
Es necesario hacer notar que si bien los objetos
comparten propiedades y métodos en común, no todos
son idénticos. Es decir, todos los seres humanos
tenemos ciertas características en común y
realizamos acciones similares. Pero cada uno de nosotros, tiene
una única identidad. Por eso, no puede decirse que
se instancia cuadro veces el mismo objeto, porque en realidad,
son cuatro objetos diferentes donde cada uno de ellos, tiene una
identidad propia.
CAPÍTULO III
Introducción al patrón
Arquitectónico MVC
MVC, son las siglas de modelo-vista-controlador
(o en inglés, model-view-controller), que es uno de los
tantos patrones de arquitectura de software.
Antes de abordar de lleno este patrón, vamos a
intentar hacer una introducción a la arquitectura de
software, desmembrándola de lo general hacia lo
particular, para al fin llegar al detalle, procurando entender
exactamente de que se trata, en el contexto adecuado.
Probablemente, este capítulo sea el más
complejo (y mucho más extenso en relación al
Capítulo I). Pero si quieres poder aplicar de forma
decuada el patrón MVC, debes hacer el esfuerzo de seguirlo
con especial interés y actitud "entuciasta".
Introducción a la Arquitectura de
Software
¿Qué es la arquitectura de
software?
Es necesario aclarar, que no existe una
definición única, exacta, abarcativa e
inequívoca de "arquitectura de software". La
bibliografía sobre el tema es tan extensa como la cantidad
de definiciones que en ella se puede encontrar. Por lo tanto
trataré, no de definir la arquitectura de software, sino
más bien, de introducir a un concepto simple y sencillo
que permita comprender el punto de vista desde el cual, este
libro abarca a la arquitectura de software pero, sin ánimo
de que ello represente "una definición
más".
A grandes rasgos, puede decirse que "la
Arquitectura de Software es la forma en la que se organizan los
componentes de un sistema, interactúan y se relacionan
entre sí y con el contexto, aplicando normas y principios
de diseño y calidad, que fortalezcan y fomenten la
usabilidad a la vez que dejan preparado el sistema, para su
propia evolución".
Tal vez estés pensando "…al fin y al
cabo, me haz dado una definición más…". La
respuesta es sí. Probablemente no pude contenerme de
hacerlo – no lo niego -. Pero, no debes tomar lo
anterior como una definición, sino como la forma en
la que en este libro, se abarca la arquitectura de
software.
Tendencias de la Arquitectura de Software
Si bien no puede decirse o mejor dicho, no es muy
académico decirlo, voy a tomarme el atrevimiento de
mencionar solo dos tendencias arquitectónicas,
claramente diferenciadas entre sí:
La Arquitectura de Software Orientada a
Objetos (como "ingeniría" de sistemas)La Arquitectura Estructurada (como
"desarrollo" de una aplicación)
Como podemos ver, en este libro, es a la primera a la
cual nos enfocamos.
A fin de satisfacer la inquietud de curiosos (y de paso,
no ocultar que existen), voy a mencionar la existencia de otras
dos corrientes: la arquitectura basada en patrones y la
arquitectura basada en procesos y
metodologías.
Personalmente, no las considero como cuatro
corrientes ¿Por qué? Porque independientemente
de cual te agrade más, si la AS orientada o objetos o la
AS estructural, implican necesariamente dos corrientes que deben
aplicarse de forma optativa (o utilizas una o la otra pero no las
dos simultáneamente), mientras que la AS basada en
patrones y la AS basada en procesos, pueden utilizarse como
complemento de las dos primeras. Pero esto, es mera
filosofía propia, con la cual, no he encontrado
demasiado consenso. Pues no los aburriré con ello e iremos
a lo práctico.
Características de la Arquitectura de Software:
Atributos de calidad
La Calidad del Software puede definirse como
los atributos implícitamente requeridos en un sistema
que deben ser satisfechos. Cuando estos atributos son
satisfechos, puede decirse (aunque en forma objetable), que la
calidad del software es satisfactoria.
Estos atributos, se gestan desde la arquitectura de
software que se emplea, ya sea cumpliendo con aquellos requeridos
durante la ejecución del software, como con aquellos que
forman parte del proceso de desarrollo de éste.
- Atributos de calidad que pueden observarse
durante la ejecución del software
Disponibilidad de uso
Confidencialidad, puesto que se
debe evitar el acceso no autorizado al sistemaCumplimiento de la Funcionalidad
requeridaDesempeño del sistema con
respecto a factores tales como la capacidad de
respuestaConfiabilidad dada por la
constancia operativa y permanente del sistemaSeguridad externa evitando la
pérdida de información debido a errores del
sistemaSeguridad interna siendo capaz
de impedir ataques, usos no autorizados, etc.
- Atributos de calidad inherentes al proceso de
desarrollo del software
Capacidad de Configurabilidad
que el sistema otorga al usuario a fin de realizar ciertos
cambiosIntegrabilidad de los
módulos independientes del sistemaIntegridad de la
información asociadaCapacidad de Interoperar con
otros sistemas (interoperabilidad)Capacidad de permitir ser
Modificable a futuro (modificabilidad)Ser fácilmente Mantenible
(mantenibilidad)Capacidad de Portabilidad, es
decir que pueda ser ejecutado en diversos ambientes tanto de
software como de hardwareTener una estructura que facilite la
Reusabilidad de la misma en futuros
sistemasMantener un diseño
arquitectónico Escalable que permita su
ampliación (escalabilidad)Facilidad de ser Sometido a
Pruebas que aseguren que el sistema falla cuando es lo
que se espera (testeabilidad)
De lo general a lo particular: del estilo
arquitectónico al patrón de
diseño
Existe una diferencia entre Estilo
Arquitectónico, Patrón Arquitectónico y
Patrón de Diseño, que debe marcarse a fin de
evitar las grandes confusiones que inevitablemente, concluyen en
el mal entendimiento y en los resultados poco satisfactorios.
Éstos, son los que en definitiva, aportarán
"calidad" al sistema resultante. En lo sucesivo, trataremos de
establecer la diferencia entre estos tres conceptos, viendo como
los mismos, se relacionan entre sí, formando parte de un
todo: la arquitectura de software.
Relación y Diferencia
Estilo Arquitectónico, Patrón
Arquitectónico y Patrón de Diseño,
representan, de lo general a lo particular, los niveles de
abstracción que componen la Arquitectura de Software. En
este sentido, puede decirse que:
El Estilo Arquitectónico
es el encargado de:
Describir la estructura
general de un sistema, independientemente de otros
estilosDefinir los componentes del sistema, su
relación e interactividadEjemplos: flujo de datos, llamada y
retorno, etc.
El Patrón
Arquitectónico es el nivel en el cual la
arquitectura de software:
Define la estructura
básica de un sistema, pudiendo estar
relacionado con otros patronesRepresenta una plantilla de
construcción que provee un conjunto de
subsistemas aportando las normas para su
organizaciónEjemplos: Capas, MVC,
Tuberías y Filtros, Pizarra, etc.
El Patrón de
Diseño es el tercer nivel de abstracción de
la arquitectura de software, cuya finalidad es la de
precisar en detalle los subsistemas y componentes de
la aplicación
Ejemplos: Proxy, Command, Factory,
etc..
El Patrón Arquitectónico
modelo-vista-controlador (MVC)
Habiendo dejado en claro de qué hablamos
exactamente cuando nos referimos a "patrón
arquitectónico", estamos en condiciones de ahondar en los
detalles del patrón MVC.
Aclarciones previas
Antes de caer inmersos en el conocimiento sobre el
patrón MVC, quiero dejar en claro que en este libro, no
hará referencia a ningún framework.
El objetivo de POO y MVC en PHP no es el de
formar a programadores en el uso de frameworks, sino que el
mismo, parte de una clara pregunta ¿a caso los frameworks
no han sido desarrollados por programadores? Tenemos la
alternativa de utilizar frameworks para ahorrar tiempo de
programación o, si realmente nos apasiona programar,
adquirimos los conocimientos necesarios, tenemos la capacidad y
nos animamos, podemos crear nuestros propios frameworks. De
hecho, no se trata de reinventar la rueda, sino de crear una,
adaptada a nuestras necesidades. Y si lo que necesitamos es
una rueda para acoplar a un mueble que acabamos de crear
¿cuál sería el sentido de intentar modificar
una rueda de camión si tenemos todas las herramientas
necesarias para ser "creadores" y no "modificadores"?
Claro que esto, depende de la pasión, gusto,
capacidad y por qué no, de la ambición de cada uno.
El tiempo, es discutible. Pues puede demandarte más tiempo
modificar algo que ya existe, que crearlo. Si quieres reparar un
mueble te llevará más tiempo repararlo que ir a
comprar uno nuevo. Y si eres ebanista, seguramente te
llevará menos tiempo hacer un nuevo mueble que ir a
comprarlo. Pues sabes exactamente lo que necesitas y como hacerlo
y eso, hará que ahorres el tiempo de recorrer todas las
mueblerías y termines comprando "el mueble que más
se asemeje al que quieres". El mueble, será similar, pero
no exactamente igual al que tu imaginaste. De todas formas, la
alternativa de modificar, siempre la tienes… al igual que
también tienes la de crear. Todo dependerá del
criterio de elección que apliques y sea cual sea, tu
elección será la correcta, justamente porque
habrás "elegido" y eso, es lo más
importante.
¿Qué es el patrón MVC?
El patrón MVC es un patrón de
arquitectura de software encargado de separar la lógica de
negocio de la interfaz del usuario y es el más
utilizado en aplicaciones Web, ya que facilita la funcionalidad,
mantenibilidad y escalabilidad del sistema, de forma simple y
sencilla, a la vez que permite "no mezclar lenguajes
de programación en el mismo
código".
MVC divide las aplicaciones en tres niveles de
abstracción:
Modelo: representa la lógica de
negocios. Es el encargado de accesar de forma directa a los
datos actuando como "intermediario" con la base de datos. Lo
que en nuestro ejemplo de programación orientada a
objetos, serían las clases DBAbstractModel y
Usuario.Vista: es la encargada de mostrar la
información al usuario de forma gráfica y
"humanamente legible".Controlador: es el intermediario entre la
vista y el modelo. Es quien controla las interacciones del
usuario solicitando los datos al modelo y
entregándolos a la vista para que ésta, lo
presente al usuario, de forma "humanamente
legible".
¿Cómo funciona el patrón
MVC?
El funcionamiento básico del patrón
MVC, puede resumirse en:
El usuario realiza una
peticiónEl controlador captura el evento (puede
hacerlo mediante un manejador de eventos –
handler -, por ejemplo)Hace la llamada al modelo/modelos
correspondientes (por ejemplo, mediante una llamada de
retorno – callback -) efectuando las
modificaciones pertinentes sobre el modeloEl modelo será el encargado de interactuar
con la base de datos, ya sea en forma directa, con una
capa de abstracción para ello, un Web Service, etc. y
retornará esta información al
controladorEl controlador recibe la información y la
envía a la vistaLa vista, procesa esta información pudiendo
hacerlo desde el enfoque que veremos en este libro, creando
una capa de abstracción para la lógica (quien
se encargará de procesar los datos) y otra para el
diseño de la interfaz gráfica o GUI. La
lógica de la vista, una vez procesados los datos, los
"acomodará" en base al diseño de la GUI –
layout – y los entregará al usuario
de forma "humanamente legible".
Funcionamiento del patrón
modelo-vista-controlador
Hasta quí, hemos hablado de estilos
arquitectónicos, nos hemos introducido en uno de los
patrones arquitectónicos (MVC) pero, en todo esto
¿en qué momento intervienen los patrones de
diseño?
Es aquí donde debemos notar que éstos,
intervienen en la forma en la que cada capa (modelo, vista y
controlador), "diseña" su estructura. El controlador
decidirá (aunque en realidad, nosotros lo haremos) si
utilizará un handler para manejar los eventos del
usuario. En ese caso, estaría optando por un
patrón de diseño. Si para llamar al modelo,
utiliza un callback, estaría utilizando otro, y
así en lo sucesivo.
Personalmente, sugiero que, a no ser que se trate de
sistemas realmente robustos y complejos, no se compliquen
demasiado – por ahora – en "aplicar" todos y cada
uno de los patrones de diseño que encuentren en el camino.
La forma de hacerlo bien, es:
Sencillez y simplicidad
Fácil mantenibilidad
Practicidad para evolucionar
Si se tienen en cuenta estas tres premisas, el resultado
de un código limpio, legible y fácil de interpretar
para cualquier programador, estará 90%
asegurado.
CAPÍTULO IV
El Patrón MVC en PHP
Para que el concepto de modelo-vista-controlador nos
queda más claro, vamos a ir analizándolo con
ejemplos concretos, en el lenguaje que impulsa este libro:
PHP.
Al final de este capítulo, vamos a encontrar
ejercicios prácticos de autoevaluación y luego,
continuaremos transformando y ampliando nuestro primer ejemplo
del Capítulo II, siguiendo el patrón
arquitectónico MVC, con sus correspondientes comentarios y
aclaraciones.
El modelo
Con respecto al modelo, no tenemos demasiada novedad. El
modelo, no es más que el conjunto de clases con las que
hemos trabajado hasta ahora, incluyendo entre ellas, la capa de
abstracción de la base de datos.
Interfaces en PHP: un nuevo concepto para crear
modelos
En esta etapa, podemos ampliar las referencias de PHP,
incorporando un nuevo concepto: las interfaces.
El Manual Oficial de PHP describe las interfaces
de la siguiente forma:
"Las interfaces de objetos permiten crear
código con el cual especificar qué métodos
deben ser implementados por una clase, sin tener que definir
cómo estos métodos son manipulados. Las interfaces
son definidas utilizando la palabra clave interface, de la misma
forma que con clases estándar, pero sin métodos que
tengan su contenido definido. Todos los métodos declarados
en una interfaz deben ser public, ya que ésta es la
naturaleza de una
interfaz."[8][…]
Una interface se define utilizando la palabra clave
interface y se la implementa utilizando la
palabra clave implements.
En varias ocasiones, las interfaces nos servirán
para ampliar los modelos.
Generamos la interface:
interface Postre {
public function
set_ingredientes();
}
Implementamos la interface:
class Bizcochuelo implements
Postre {
var $ingredientes =
array();
public function set_ingredientes()
{
$this->ingredientes =
array('harina'=>'2 tazas', 'leche'=>'1 taza',
'azucar'=>'1 taza',
'huevo'=>1
);
}
}
Extendemos una clase (que por defecto,
implementará la interface):
class BizcochueloVainilla
extends Bizcochuelo {
public function set_ingredientes()
{
$this->ingredientes['escencia de
vainilla'] = 'a gusto';
}
function __construct() {
parent::set_ingredientes();
$this->set_ingredientes();
}
}
También podemos crear otra clase que
implemente la interface:
class Alfajor implements
Postre {
public function set_ingredientes()
{
$this->ingredientes = array('Tapas de
maizena' => 2,
'dulce de leche'=>'1 cda.
sopera',
'coco rallado'=>'1 cdta. de
te');
}
function __construct() {
$this->set_ingredientes();
}
}
- Diferencia entre Interfaces y Clases abstractas
Probablemente te preguntes ¿cuál es la
diferencia entre una interface y una clase abstracta?
Créeme: todos nos lo hemos preguntado alguna vez
🙂
En principio, existe una diferencia conceptual
que a niveles "prácticos" tal vez no es del todo
clarificadora. Esta diferencia, radica en que las clases
abstractas, no dejan de ser "clases", las cuales representan la
"abstracción de un objeto" siguiendo un orden de
"relación jerarquíca" entre ellas: Clase B
hereda de Clase A y Clase C hereda de Clase B, pero no puede
tener herencias múltiples, es decir no puede heredar de
más de una clase, ya que ellas, guardan una
relación de orden jerárquico entre
sí.
class A { }
class B extends class A { }
#correcto
class C extends class B { }
#correcto
class D { }
#correcto
class E extends class A,
class D { } # incorrecto!!! no se puede
hacer!!!
# lo correcto
sería:
class D extends class A {
}
class E extends class D {
}
A diferencia de las clases abstractas, conceptualmente,
las interfaces son solo un conjunto de métodos
característicos de diversas clases,
independientemente de la relación que dichas clases
mantengan entre sí. De hecho, una misma clase, puede
implementar múltiples interfaces:
interface A { }
interface B { }
interface C { }
class MiClase implements A,
B, C { }
No obstante la diferencia conceptual, podemos
establecer claras diferencias prácticas, que nos
ayudarán a asimilar mejor estos conceptos:
Las interfaces no pueden definir propiedades
(de hecho, no poseen propiedades porque a diferencia de las
clases abstractas no tienen relación con un objeto, y
solo los objetos tienen propiedades)Las interfaces no pueden tener métodos
definidos con su algoritmo correspondiente (solo pueden
declarar los métodos pero no pueden indicar el
"qué" ni el "cómo" hacerlo, mientras que las
clases abstractas, sí pueden)Las interfaces no pueden instanciarse porque no
tienen referencias asociadas a objetos, mientras que las
clases abstractas no pueden instanciarse, porque sus objetos
son "entes abstractos" que necesitan de una clase no
abstracta para definirse con exactitud y poder ser
instanciados.Todos los métodos declarados en una
interface deben ser públicos, puesto que la
finalidad de una interface, es brindar un "ámbito
público de un modelo". Las clases abstractas, pueden
tener métodos abstractos tanto públicos como
protegidos (aquellos que deberán ser obligatoriamente
redefenidos por las clases que la hereden) y métodos
privados que solo ella utilice.
- Lo que NO deben hacer las insterfaces
Las interfaces no pueden:
Tener el mismo nombre que una clase (PHP las
interpreta como una clase más. Crear una interface con
el mismo nombre que una clase, sería interpretado por
PHP como una "re-declaración de clase")Diferentes interfaces no pueden tener nombres de
métodos idénticos si serán
implementadas por la misma clase
La vista
Como hemos visto anteriormente, la vista representa la
interfaz gráfica del usuario (GUI), es decir, es la
encargada de mostrar la información al usuario de manera
"humanamente legible".
A tal fin, divideremos la vista en dos sub-capas: la GUI
propiamente dicha y su lógica.
Vista: la interfaz gráfica
Generalmente, en la práctica, no somos los
programadores quienes nos hemos de encargar de la GUI. Es tarea
que corresponde a diseñadores Web o gráficos,
según aplique.
Como "arquitectos", debemos tener preparada la
estructura de nuestra aplicación, para que
diseñadores puedan trabajar libremente en la GUI, sin
tener que acceder al código PHP. En este libro,
veremos además, como evitar por completo que los
diseñadores tengan que implementar código PHP en
sus GUI y que programadores, tengamos que implementar
código HTML en nuestras lógicas.
En principio, la parte gráfica de las
vistas (archivos HTML, imágenes, CSS, etc.),
deberá tener un directorio reservado solo para
ella. De esta forma, obtenemos varias ventajas de trabajar con el
patrón MVC:
Los archivos estáticos (HTML, CSS,
imágenes e incluso JavaScript) pueden almacenarse
en un servidor independiente con todos los beneficios que
esto conlleva (al igual que sucede con las bases de datos,
los archivos estáticos también pueden
independizarse)Nos aseguramos de que el código
estático (aquel desarrollado por
diseñadores), no "rompa" el núcleo de la
aplicaciónPermitimos a los diseñadores trabajar
cómodamente en la libertad de aplicar todos los
conocimientos y herramientas inherentes a su área de
conocimiento, sin la presión de tener que implementar
un lenguaje de programación que desconocen, les es
poco familiar o simplemente, la herramienta que utilizan para
diseñar, suele dañarles el código
no-estático
En segundo lugar, cada plantilla – template
– o archivo HTML, deberá hacer referencia
"estática" a los datos que se quieran reemplazar
dinámicamente. Para esto, no será necesario
implementar código que no sea HTML.
Veremos aquí como hacer referencia a estos datos,
y más adelante, veremos como la lógica de la vista
se encargará de renderizarlos.
Supongamos que tenemos una plantilla HTML, donde lo que
necesitamos reemplazar de manera dinámica, es:
título de la página, keywords y
descripción. La mejor manera de referenciar a estos
datos, facilitando la tarea a un diseñador, es haciendo
una referencia textual a éstos. Para que a la vez, los
programadores logremos diferenciar que allí se incluyen
datos dinámicos, una buena práctica, es encerrar
esa referencia textual entre llaves.
Veamos un ejemplo:
HTML PUBLIC "-//W3C//DTD HTML 4.01
Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<<b>html
lang="es">
<<b>head>
<<b>meta
http-equiv="Content-Type" content="text/html;
charset=utf-8">
Título de la
Página}
<<b>meta name="title"
content="{Título de la Página}">
<<b>meta name="keywords"
content="{keywords}">
<<b>meta name="description"
content="{descripción}">
</<b>head>
<<b>body>
<<b>div id="page">
<<b>div id="cab">
<<b>img alt="home page"
src="img/logo.gif"></<b>a>
</<b>div>
<<b>div
id="contenido">
<<b>h1>{Título
de la Página}</<b>h1>
</<b>div>
</<b>div>
</<b>body>
</<b>html>
Como podemos ver, en la plantilla HTML solo hay
código HTML. Para un diseñador, será una
tarea sencilla.
Veremos en el siguiente paso, como la lógica de
la vista, se encargará de reemplazar estos
datos.
La Lógica de la Vista
Tenemos la plantilla que creó nuestro
diseñador. Es hora de reemplazar dinámicamente los
datos referenciados. Haremos esto, paso a paso, como si de una
receta de cocina se tratara.
- Primer paso: crear un diccionario de datos
El diccionario de datos es el que contendrá,
literalmente hablando, un diccionario, indicando cuales
referencias deben ser reemplazadas por cuáles datos, en
forma dinámica.
$diccionario = array(
'Título de la
Página'=>'POO y MVC en PHP',
'keywords'=>'poo, mvc, php, arquitectura
de software',
'description'=>'El paradigma de la
programación orientada a objetos con el patrón
arquitectónico MVC en PHP'
);
- Segundo paso: obtener la plantilla HTML
Para traer la plantilla HTML, vamos a utilizar la
función file_get_contents() de PHP, y almacenar el
contenido de ella, en una variable.
$template =
file_get_contents('/carpeta/template.html');
- Tercer paso: reemplazar el contenido
En el anteúltimo paso, reemplazaremos los datos,
utilizando el bucle foreach de PHP para recorrer el
diccionario, y la función str_replace() de PHP,
para reemplazar los mismos.
foreach ($diccionario as $clave=>$valor)
{
$template = str_replace('{'.$clave.'}',
$valor, $template);
}
- Cuarto paso: mostrar el contenido final al
usuario
Por último, imprimiremos el resultado obtenido en
pantalla.
print $template;
Y con esto, habremos concluido la lógica de la
vista, obteniendo en el navegador del usuario, la siguiente
salida (vista de código fuente):
HTML PUBLIC "-//W3C//DTD HTML 4.01
Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<<b>html
lang="es">
<<b>head>
<<b>meta
http-equiv="Content-Type" content="text/html;
charset=utf-8">
<<b>meta name="title"
content="POO y MVC en PHP">
<<b>meta name="keywords"
content="poo, mvc, php, arquitectura de software">
<<b>meta name="description"
content="El paradigma de la programación orientada a
objetos con el
patrón
arquitectónico MVC en PHP">
</<b>head>
<<b>body>
<<b>div id="page">
<<b>div id="cab">
<<b>img alt="home page"
src="img/logo.gif"></<b>a>
</<b>div>
<<b>div
id="contenido">
<<b>h1>POO y MVC en
PHP</<b>h1>
</<b>div>
</<b>div>
</<b>body>
</<b>html>
El controlador
El controlador, aunque muchos de ustedes no lo crean, es
quien tal vez, lleva "la peor parte". En muchas ocasiones, es
complicado programar el controlador de manera previsible para que
pueda evolucionar, y generalmente, es sometido a
refactorizaciones constantes, incluso mayores que las que puede
sufrir el modelo.
Recordemos que el controlador, es quien debe interactuar
con el modelo y con la vista. Para hacerlo, deberá
previamente reconocer y manejar los distintos eventos del
usuario, para saber:
A qué modelo / modelos invocar
Qué y cuáles propiedades o atributos
del modelo/modelos modificar o parámetros
deberá entregar a sus métodosA qué vista entregar la
información
¡Pobre hombre! Le toca una tarea extenuante.
Veamos paso a paso, como ayudar a este pobre "controller-man" en
su tarea.
Supongamos entonces, que tenemos dos modelos:
Archivo models.php
class ModeloUno {
var $propiedad;
function a($parametro) {
$this->propiedad =
$parametro;
}
}
class ModeloDos {
var $propiedad_1;
var $propiedad_2;
function b($param1, $param2)
{
$this->propiedad_1 = $param1;
$this->propiedad_2 = $param2;
}
}
Y a la vez, tenemos dos vistas:
Template vista_1.html
HTML PUBLIC "-//W3C//DTD HTML 4.01
Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<<b>html
lang="es">
<<b>head>
<<b>meta
http-equiv="Content-Type" content="text/html;
charset=utf-8">
</<b>head>
<<b>body>
<<b>div id="page">
<<b>p>El valor de la
<<b>b>propiedad</<b>b> es
<<b>b>{propiedad}</<b>b></<b>p>
</<b>div>
</<b>body>
</<b>html>
Template vista_2.html
HTML PUBLIC "-//W3C//DTD HTML 4.01
Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<<b>html
lang="es">
<<b>head>
<<b>meta
http-equiv="Content-Type" content="text/html;
charset=utf-8">
</<b>head>
<<b>body>
<<b>div id="page">
<<b>p>El valor de
<<b>b>propiedad_1</<b>b> es
<<b>b>{propiedad_1}</<b>b> mientras que
el
de
<<b>b>propiedad_2</<b>b> es
<<b>b>{propiedad_2}</<b>b></<b>p>
</<b>div>
</<b>body>
</<b>html>
Y la lógica de éstas, es la
siguiente:
Archivo view.php
function set_identificadores($vista)
{
$identificadores = array();
if($vista) {
switch ($vista) {
case 'vista_1':
$identificadores =
array('propiedad');
break;
case 'vista_2':
$identificadores = array('propiedad_1',
'propiedad_2');
break;
}
return $identificadores;
}
}
function armar_diccionario($vista,
$data) {
$diccionario = array();
$identificadores =
set_identificadores($vista);
if($identificadores) {
foreach ($identificadores as
$identificador) {
if(array_key_exists($identificador, $data))
{
$diccionario[$identificador] =
$data[$identificador];
}
}
}
return $diccionario;
}
function render_data($vista, $data)
{
$html = '';
if(($vista)&&($data)) {
$diccionario = armar_diccionario($vista,
$data);
if($diccionario) {
$html =
file_get_contents('html/'.$vista.'.html');
foreach ($diccionario as $clave=>$valor)
{
$html = str_replace('{'.$clave.'}', $valor,
$html);
}
}
}
print $html;
}
Entonces, nuestro controlador procederá de la
siguiente forma:
- Primer paso: identificar el modelo
Para esto, el controlador previamente, tendrá que
reconocer el evento que ejecuta el usuario y saber como
manejarlo. Para ello, la forma de pensarlo
"informáticamente" sería:
si usuario [evento] entonces
[realizar acción]
En nuestro caso, los eventos admitidos, serán
llamdas por URL mediante el método $_GET.
Primero, identificará el evento respondiendo a
las siguientes preguntas:
¿existe el evento de llamada mediante
"$_GET"?Si existe ¿a qué evento, el usuario,
quiere que responda?
Para esto, utilizará la siguiente
función:
function capturar_evento()
{
$vista = '';
if($_GET) {
if(array_key_exists('vista', $_GET))
{
$vista = $_GET['vista'];
}
}
return $vista;
}
Devolviendo así, el evento capturado a
través de la variable "$vista".
Con el evento "en la mano", se ocupará ahora de
identificar el modelo:
function identificar_modelo($vista)
{
if($vista) {
switch ($vista) {
case 'vista_1':
$modelo = 'ModeloUno';
break;
case 'vista_2':
$modelo = 'ModeloDos';
break;
default:
exit();
}
}
return $modelo;
}
- Segundo paso: invocar al modelo efectuando los
cambios adecuados
Nuestro controlador, ya sabe a que modelo recurrir.
Ahora, solo resta invocarlo y modificarlo si es
necesario:
function invocar_modelo($modelo)
{
if($modelo) {
require_once('models.php');
$data = new $modelo();
settype($data, 'array');
return $data;
}
#las modificaciones al modelo se
harían aquí
}
- Tercer paso: enviar la información a la
vista
Finalmente, nuestro controlador, enviará la
información obtenida del modelo, a la vista. Para hacerlo,
utilizará una función donde preparará esta
información para al fin enviarla:
function enviar_data() {
$vista = capturar_evento();
if($vista) {
$modelo =
identificar_modelo($vista);
if($modelo) {
$data = invocar_modelo($modelo);
if($data) {
require_once('view.php');
render_data($vista, $data);
}
}
}
}
El controlador, solo deberá llamar a su propia
función enviar_data() y la vista automáticamente,
estará en condiciones de mostrar los resultados en
pantalla al usuario:
enviar_data();
Si el usuario ingresara en la URL http://servidor/controller.php
no verá nada en pantalla.
Si ingresara en http://servidor/controller.php?vista=vista_2
verá lo siguiente:
Ahora, es momento de auto-evaluar lo que hemos aprendido
y luego, completar nuestro primer ejemplo para finalizar nuestro
aprendizaje.
Ejercicios Prácticos
Veamos cuanto aprendimos sobre los capítulos III
y IV.
Ejercicio Nº3: Conceptos de Arquitectura,
MVC y PHP
3.1) ¿Qué es
MVC?
a) Un patrón de
diseño
b) Un patrón
arquitectónico
c) Un paradigma de
programación
d) Un estilo
arquitectónico
3.2) ¿Cuál de las
siguientes opciones, corresponde a atributos de calidad
implícitos en la arquitectura de
software?
a) Polimorfismo, herencia,
encapsulamiento y disponibilidad
b) Herencia, abstracción,
seguridad y aislamiento
c) Disponibilidad, funcionalidad,
seguridad, interoperabilidad y portabilidad
d) Todas las anteriores
3.3) Indica V (verdadero) o F
(falso) según corresponda
a) [ ] Un patrón
arquitectónico es el encargado de describir la
arquitectura general de un sistema
b) [ ] Un patrón
arquitectónico representa una plantilla de
construcción que provee un conjunto de subsistemas y su
forma de organización
c) [ ] Estilo arquitectónico y
patrón arquitectónico son dos niveles de
abstracción diferentes de la arquitectura de
software
d) [ ] En MVC, el modelo es un
intermediario entre la vista y el controlador
e) [ ] En MVC el controlador es el
encargado de capturar los eventos del usuario
f) [ ] En MVC es recomendable mezclar
código PHP y HTML
g) [ ] Una interface en PHP es lo mismo
que una clase abstracta
h) [ ] Las clases abstractas en PHP
cuplen la misma función que las interfaces
i) [ ] Una interface solo debe declarar
los métodos pero éstos, no deben estar
codificados
j) [ ] Las propiedades declaradas en
las interfaces deben tener visibilidad
pública
3.4) ¿Cuál de las siguientes
afirmaciones es verdadera?
a) Las interfaces no pueden definir
propiedades
b) Todos los métodos declarados
en una interface deben ser públicos
c) Las interfaces no pueden
instanciarse porque no tienen referencias asociadas a
objetos
d) Las interfaces no pueden tener
métodos definidos con su algoritmo
correspondiente
e) Todas las opciones son
correctas
En MVC, el usuario realiza una
petición y el _____________ captura el evento,
identificando el _____________ al que debe invocar y al cual
realizar las modificaciones. Luego, envía esta
información a _____________.
Ejercicio Nº4: Revisando
código
4.1) ¿Cuál de las siguientes
declaraciones es incorrectas?
a) class Gaseosa
extends Bebida implements Producto,
BebidaSinAlcohol
b) class Gaseosa
extends BebidaSinAlcohol, BebidaGasificada
implements Bebida, Producto
d) class Gaseosa
implements Bebida
4.2) ¿Cuál es el error del
siguiente código?
interface Producto { }
class Producto implements
Producto { }
a) La clase no puede tener el mismo
nombre que la interface
b) Ni la clase ni la interface tienen
código
c) No hay errores
4.3) ¿Cuál es el error en el
siguiente código?
interface Producto { }
class Bebida extends Producto
{ }
a) Ni la clase ni la interface tienen
código
b) Donde utiliza "extends"
debería utilizar "implements"
c) No hay errores
Soluciones a los ejercicios 3 y 4
Ejercicio Nº3
Pregunta 3.1: respuesta b
Pregunta 3.2: respuesta c
Pregunta 3.3:
A | B | C | D | E | F | G | H | I | J | ||
Verdadera | X | X | X | X | |||||||
False | X | X | X | X | X | X |
Pregunta 3.4: respuesta e
Pregunta 3.5:
En MVC, el usuario realiza una petición y el
controlador captura el evento, identificando el
modelo al que debe invocar y al cual realizar las
modificaciones. Luego, envía esta información a
la vista.
Ejercicio Nº4
Pregunta 4.1: respuesta b
Pregunta 4.2: respuesta a
Pregunta 4.3: respuesta c
Programación Real Con el patrón
MVC
Vamos a retormar ahora, nuestro ejemplo del
ABM de usuarios que comenzamos a programar en el
capítulo II. Procederemos a ampliarlo y adaptarlo,
seguiendo la estructura del patrón MVC.
Nótese que los
métodos respectivos han sido resumidos no
encontrándose en éstos, extensos algoritmos de
validación de datos. Se ejemplifica todo aquello que es
relevante en la POO bajo el el patrón
arquitectónico MVC.
Estructura de directorios
Ya estamos en una etapa más avanzada, donde no
basta con crear archivos. Nuestro primer ejemplo de
"programación real" del capítulo II, será
ampliado; agregaremos más archivos y se hace necesario
organizarlos de forma tal, que pueda respetarse la sencillez y
los beneficios que el patrón MVC nos brinda.
Es necesario que tengamos en cuenta, que NO SIEMPRE
la estructura y organización de directorios y archivos
puede predecirse. Por el contrario, a medida que una
aplicación avanza, SIEMPRE es recomendable refactorizar el
código al mismo ritmo que el sistema
evoluciona.
Por eso, no se debe tener miedo de comenzar programando
con grandes estructuras de código y hasta incluso, por
qué no, "desprolijas".
Piensa en cuando vas al supermercado.
Realizas las compras de todo lo que necesitas y las llevas a tu
casa en bolsas y generalmente, con la mercadería
desorganizada. Pero tienes todo lo que necesitas. Una vez que lo
tienes, comienzas a organizarlo. Guardarás los alimentos
que requieran refrigeración, en la heladera; los
congelados en el freezer; los artículos de tocador en tu
WC; etc.
No se debe tener miedo de agilizar la arquitectura de
software y pensarla adaptativamente. Y aquí, es
donde debemos considerar, la metodología que utilizaremos
para gestionar nuestro proyecto.
Una de las prácticas técnicas propuesta
por Extreme Programming, nos induce a realizar una
refactorización constante del código, algo que,
desde mi punto de vista, nos dará mejores resultados a la
hora de pensar una arquitectura adecuada.
La siguiente estructura de directorios que
propondré para adaptar nuestro ejemplo, puede servir de
punto de partida para la arquitectura de una aplicación
compleja de gran robustez.
Comenzaremos entonces, por crear la siguiente
estructura de directorios:
core: el propósito de este directorio, site_media: será el directorio exclusivo para nuestros usuarios: éste, será el directorio de nuestro |
Bajo el supuesto de que los modelos DBAbstractModel y
Usuario se conservan y, simplemente a modo de ejercicio
¿en qué directorio crees que se debería
almacenar cada uno de estos dos modelos?
Archivos del Modelo
Los archivos de nuestro "modelo", serán ahora
nuestros viejos db_abstract_model.php y
usuarios_model.php a los cuales, haremos algunas
modificaciones.
Archivo ./core/db_abstract_model.php
- Modificaciones incorporadas
Agregaremos la propiedad $mensaje, a fin de que el
objeto, pueda comunicarse a través de mensajes con el
resto de la aplicación.El método execute_single_query()
incorporará una validación que solo
permitirá proceder con sus funciones, si recibe sus
parámetros a través variables
$_POST.
- Código fuente del archivo
Archivo ./usuarios/model.php
- Modificaciones incorporadas
El nombre del archivo cambia a model.php.
Se agrega una emisión de mensaje por cada
acción concluyente de cada uno de los
métodosSin influencia práctica, el método
constructor aparece debajo de los métodos propios de
la clase (una simple cuestión organizativa)
- Código fuente del archivo
Archivos de la Vista
En esta etapa, crearemos los archivos correspondientes a
la GUI y su lógica.
Los primeros, serán los archivos que
crearán nuestros diseñadores (5 archivos HTML y 1
archivo CSS, que se expondrán a modo práctico, sin
ánimo de servir de ejemplo como interfaces
gráficas).
La lógica de la vista, estará en nuestras
manos.
Comencemos.
Archivos de la GUI
Recordemos que se trataba de un ABM de Usuarios, donde
teníamos la posibilidad de:
Mostrar los datos de un usuario
Agregar un nuevo usuario
Modificar un usuario existente
Eliminar un usuario de la base de datos
Todos estos archivos, se almacenarán en nuestro
directorio estático site_media.
Crearemos una plantilla HTML general, cuatro plantillas
de formularios y un archivo CSS. Los 5 primeros se
almacenarán en ./site_media/html/ con el prefijo usuario_
que identificará el módulo (también
podrían almacenarse en un subdirectorio llamado usuario.
Eso lo dejo a vuestra libre elección). El archivo CSS,
lógicamente se almacenará en
./site_media/css/.
- Archivo ./site_media/html/usuario_template.html
(plantilla HTML general)
HTML PUBLIC "-//W3C//DTD HTML 4.01
Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<<b>html
lang="es">
<<b>head>
<<b>meta
http-equiv="Content-Type" content="text/html;
charset=utf-8">
</<b>head>
<<b>body>
<<b>div
id="cabecera">
<<b>h1>Administrador de
usuarios</<b>h1>
<<b>h2>{subtitulo}</<b>h2>
</<b>div>
<<b>div id="menu">
<<b>a
href="/mvc/{VIEW_SET_USER}" title="Nuevo usuario">Agregar
usuario</<b>a>
<<b>a
href="/mvc/{VIEW_GET_USER}" title="Buscar
usuario">Buscar/editar usuario</<b>a>
<<b>a
href="/mvc/{VIEW_DELETE_USER}" title="Borrar usuario">Borrar
usuario</<b>a>
</<b>div>
<<b>div
id="mensaje">
{mensaje}
</<b>div>
<<b>div
id="formulario">
{formulario}
</<b>div>
</<b>body>
</<b>html>
Por favor, obsérvese que en este archivo, se
deberán reemplazar dinámicamente: el
subtítulo del módulo (método), las URL de
los enlaces de las vistas, el mensaje emitido por el sistema y el
formulario correspondiente al método/vista solicitado por
el usuario.
- Archivo ./site_media/html/usuario_agregar.html
(formulario para agregar un nuevo usuario)
<<b>form id="alta_usuario"
action="{SET}" method="POST">
<<b>div
class="item_requerid">E-mail</<b>div>
<<b>div
class="form_requerid"><<b>input type="text"
name="email"
id="email"></<b>div>
<<b>div
class="item_requerid">Clave</<b>div>
<<b>div
class="form_requerid"><<b>input type="password"
name="clave"
id="clave"></<b>div>
<<b>div
class="item_requerid">Nombre</<b>div>
<<b>div
class="form_requerid"><<b>input type="text"
name="nombre"
id="nombre"></<b>div>
<<b>div
class="item_requerid">Apellido</<b>div>
<<b>div
class="form_requerid"><<b>input type="text"
name="apellido"
id="apellido"></<b>div>
<<b>div
class="form_button"><<b>input type="submit"
name="enviar"
id="enviar"
value="Agregar"></<b>div>
</<b>form>
Nótese que este archivo no posee datos
dinámicos que deban ser reemplazados.
- Archivo ./site_media/html/usuario_borrar.html
(formulario para eliminar un usuario identificado por su
e-mail)
<<b>form id="alta_usuario"
action="{DELETE}" method="POST">
<<b>div
class="item_requerid">E-mail</<b>div>
<<b>div
class="form_requerid"><<b>input type="text"
name="email"
id="email"></<b>div>
<<b>div
class="form_button"><<b>input type="submit"
name="enviar"
id="enviar"
value="Eliminar"></<b>div>
</<b>form>
Nótese que al igual que el archivo anterior,
éste, tampoco contiene datos dinámicos que deban
ser reemplazados.
- Archivo ./site_media/html/usuario_buscar.html
(archivo que permite buscar un usuario por su e-mail
para luego mostrarlo en el formulario de edición, ya sea
para editarlo o solo para ver sus datos)
<<b>form id="alta_usuario"
action="{GET}" method="GET">
<<b>div
class="item_requerid">E-mail</<b>div>
<<b>div
class="form_requerid"><<b>input type="text"
name="email"
id="email"></<b>div>
<<b>div
class="form_button"><<b>input type="submit"
id="enviar"
value="Buscar"></<b>div>
</<b>form>
Nótese que al igual que los dos archivos
anteriores, éste, tampoco contiene datos dinámicos
que deban ser reemplazados.
- Archivo ./site_media/html/usuario_modificar.html
(archivo para visualizar los datos de un usuario y
modificarlos)
<<b>form id="alta_usuario"
action="{EDIT}" method="POST">
<<b>div
class="item_requerid">E-mail</<b>div>
<<b>div
class="form_requerid"><<b>input type="text"
name="email"
id="email" value="{email}"
readonly></<b>div>
<<b>div
class="item_requerid">Nombre</<b>div>
<<b>div
class="form_requerid"><<b>input type="text"
name="nombre"
id="nombre"
value="{nombre}"></<b>div>
<<b>div
class="item_requerid">Apellido</<b>div>
<<b>div
class="form_requerid"><<b>input type="text"
name="apellido"
id="apellido"
value="{apellido}"></<b>div>
<<b>div
class="form_button"><<b>input type="submit"
name="enviar"
id="enviar"
value="Guardar"></<b>div>
</<b>form>
Por favor, nótese que en este archivo
deberán reemplazarse dinámicamente los datos del
usuario en los campos de formulario correspondientes.
Obsérvese que el campo "email" es de solo
lectura.
- Archivo ./site_media/css/base_template.css
(hoja de estilos en cascada)
body {
margin: 0px 0px 0px 0px;
background-color:
#ffffff;
color: #666666;
font-family: sans-serif;
font-size: 12px;
}
#cabecera {
padding: 6px 6px 8px 6px;
background-color:
#6699FF;
color: #ffffff;
}
#cabecera h1, h2 {
margin: 0px 0px 0px 0px;
}
#menu {
background-color:
#000000;
color: #ffffff;
padding: 4px 0px 4px 0px;
}
#menu a {
width: 100px;
background-color:
#000000;
padding: 4px 8px 4px 8px;
color: #f4f4f4;
text-decoration: none;
font-size: 13px;
font-weight: bold;
}
#menu a:hover {
background-color:
#6699FF;
color: #ffffff;
}
#mensaje {
margin: 20px;
border: 1px solid
#990033;
background-color:
#f4f4f4;
padding: 8px;
color: #990033;
font-size: 15px;
font-weight: bold;
text-align: justify;
}
#formulario {
margin: 0px 20px 10px
20px;
border: 1px solid
#c0c0c0;
background-color:
#f9f9f9;
padding: 8px;
text-align: left;
}
item_requerid {
width: 150px;
height: 22px;
padding-right: 4px;
font-weight: bold;
float: left;
clear: left;
text-align: right;
}
form_requerid {
height: 22px;
float: left;
clear: right;
}
input {
border: 1px solid
#c0c0c0;
}
form_button {
padding-top: 15px;
margin-left: 154px;
clear: both;
}
#enviar {
padding: 5px 10px 5px
10px;
border: 2px solid
#ffffff;
background-color:
#000000;
color: #ffffff;
font-family: sans-serif;
font-size: 14px;
font-weight: bold;
cursor: pointer;
}
#enviar:hover {
background-color:
#6699FF;
}
Archivo ./usuarios/view.php
Lógica de la vista
Por favor, nótese que este archivo, utiliza
constantes. Las mismas, y a fin de otorgar mayor legibilidad y
organización al código, serán definidas en
un archivo independiente almacenado en ./usuarios/, llamado
constants.php que será expuesto más
adelante.
El controlador
Archivo ./usuarios/controller.php
Por favor, obsérvese que el controlador importa
el archivo constants.php y utiliza constantes que
serán definidas en dicho archivo (veremos éste
más adelante).
Por otro lado, el handler del controlador,
maneja las peticiones del usuario sobre la base de la URI
detectada. Este ejemplo, maneja "URL amigables" (friendly
url), que serán tratadas más adelante,
configurando las mismas en el archivo .htaccess de la
aplicación.
Archivos de configuración
complementarios
Archivo ./usuarios/constants.php
Este archivo contiene todas las constantes del
módulo y no se le debería agregar ningún
dato que no fuese una constante.
Archivo .htaccess
Agregar al archivo .htaccess de la aplicación,
las siguientes líneas:
RewriteEngine on
RewriteRule ^usuarios/
usuarios/controller.php
Nótese que dependiendo del directorio raíz
de la aplicación, probablemente se deba modificar la
línea RewriteRule ^usuarios/
usuarios/controller.php
Nota Final
Hemos llegado al final de este libro. Espero que todo lo
aquí expuesto, les haya sido de utilidad y los invito a
hacerme llegar sus dudas, sugerencias y comentarios
através de mi e-mail o visitando la página del
libro:
http://eugeniabahit.blogspot.com/2011/07/poo-y-mvc-en-php.html
¡Gracias por el tiempo que han
dedicado!
¡Éxitos en tu
carrera!
Autor:
Eugenia Bahit
AVISO LEGAL
"POO y MVC en PHP" de Eugenia Bahit se distribuye bajo
una Licencia Creative Commons
Atribución-NoComercial-SinDerivadas 3.0
Unported.
Usted es libre de:
Compartir, copiar, distribuir, ejecutar y comunicar
públicamente la obra.
Bajo las condiciones siguientes:
Atribución. Debe reconocer los créditos de
la obra de la manera especificada por el autor o el licenciante
(pero no de una manera que sugiera que tiene su apoyo o que
apoyan el uso que hace de su obra).
No Comercial. No puede utilizar esta obra para fines
comerciales.
Sin Obras Derivadas. No se puede alterar, transformar o
generar una obra derivada a partir de esta obra.
[1] http://www.maestrosdelweb.com/
[2] tunait nos ofrece una de las mejores
colecciones de códigos JavaScript, en su sitio Web
http://tunait.com/javascript/
[3] http://www.desarrolloweb.com Portal de
desarrollo Web y programación, de la comunidad
hispanoparlante
[4] Este libro ha sido editado utilizando
OpenOffice Writer 3.2 con el plug-in COOoder para el coloreado
de sintaxis
[5] Fuente de la cita:
http://php.net/manual/es/keyword.class.php
[6] Fuente de la cita:
http://www.php.net/manual/es/language.oop5.basic.php
[7] Fuente de la cita:
http://www.php.net/manual/es/language.oop5.abstract.php
[8] Fuente de la cita:
http://php.net/manual/es/language.oop5.interfaces.php
Página anterior | Volver al principio del trabajo | Página siguiente |