2. Hispavista: Introducción a Zend Framework
¿Por qué usar un Framework?
Frame = marco
Work = trabajo
Cualquier que haya pretendido construir una aplicación
de envegadura media, ha creado su propio “framework”:
Reutilización de código
Fácil Mantenimiento / legibilidad
Abstración en la capa de acceso a datos
Utilizar una librería de funciones es utilizar un Framework.
3. Hispavista: Introducción a Zend Framework
¿Qué Framework utilizar?
Utilización de framework propio (generalmente)
Pros:
Agilidad de uso
Alto conocimiento de la estructura
Flexibilidad
Seguridad (por ocultación)
Contras
Desarrollado por un grupo reducido (lento)
Poco testing
Estructura desorganizada
4. Hispavista: Introducción a Zend Framework
¿Qué Framework utilizar?
Symphony
(mvc, orm, ajax, caching, NO templates...)
Bastante soporte
Prado
(mvc, orm, ajax, caching, templates, EDP)
Complejo
CakePHP
(mvc, orm, ajax, caching, NO templates...)
Fácil aprendizaje
Zend Framework
(mvc, ajax, caching, NO templates, components)
Muy Flexible y fácil aprendizaje
5. Hispavista: Introducción a Zend Framework
¿Por qué Zend Framework?
Zend Framework es un framework híbrido
Componentes usables de modo stand-alone
Es fácil empezar a utilizar Zend al estilo PEAR. Sin cambiar el paradigma
de la aplicación existente.
Core MVC
Implementación completa del Modelo-Vista-Controlador
Amplio soporte de la comunidad
Existen más colaboradores libres, que trabajando para Zend.
La comunidad libera componentes que pasan a la incubadora.
Utilización de PHPUnit para testing (calidad).
Zend es la empresa detrás del engine PHP
Soporte de otras grande empresas como IBM o Google.
6. Hispavista: Introducción a Zend Framework
Historia de Zend Framework
Junio 2005
Comenzó oficialmente el desarrollo
Abril 2006
Primera beta pública (0.1.3)
Junio 2007
Ver 1.0.0
Actualmente (30 Marzo 2009)
Ver 1.7.8
7. Hispavista: Introducción a Zend Framework
Licencia y Propiedad Intelectual
Licencia estilo BSD (estilo Apache):
Permite desarrollar proyectos opensource.
Permite desarrollar aplicaciones comerciales.
Cada persona que desarrolle para Zend framework, tiene
que firmar un Acuerdo de Licencia de Contribuidor, lo
que garantiza que el código estará limpio de direcciones
IP.
http://framework.zend.com/license
8. Hispavista: Introducción a Zend Framework
Conceptos Básicos: Excepciones I
Excepciones
Peor que una aplicación tenga un error en tiempo de ejecución, es
que el usuario vea en su navegador dicho error, mostrando a veces
información comprometida con consecuencias para la seguridad.
Desde PHP5 se implementaron excepciones en PHP de manera
muy similar a otros lenguajes de programación.
Clase incorporada en PHP extensible para implementar funciones
concretas.
9. Hispavista: Introducción a Zend Framework
Conceptos Básicos: Excepciones II
<?php
class Exception
{
protected $message = 'Unknown exception';
protected $code = 0;
protected $file;
protected $line;
function __construct($message = null, $code = 0);
final function getMessage();
final function getCode();
final function getFile();
final function getLine();
final function getTrace();
final function getTraceAsString();
function __toString();
}
?>
10. Hispavista: Introducción a Zend Framework
Conceptos Básicos: Excepciones III
try {
$error = 'Siempre lanzar la excepción';
throw new Exception($error);
Echo “No se ejecuta”;
} catch (Exception $e) {
echo 'Excp. Capturada: ' . $e>getMessage() . quot;nquot;;
}
class miExcepcion extends Exception {
public function mailAdmin();
}
try {
$error = 'Siempre lanzar la excepción';
throw new miExcepcion($error);
Echo “No se ejecuta”;
} catch (Exception $e) {
echo 'Excp. Capturada: ' . $e>getMessage() . quot;nquot;;
$e>mailAdmin();
}
11. Hispavista: Introducción a Zend Framework
Conceptos Básicos: MVC I
MVC
Paradigma de programación nacido en 1978 de la mano de Xerox
PARC.
Separa el código en 3 partes lógicas:
Modelo
Representa el modelo de datos que va a utilizar la aplicación.
El “sujeto” en una aplicación.
Debe contener toda la lógica de negocio de la aplicación.
Vista
Contiene la lógica de visualización (XHTML para aplicaciones web).
Mezcla la lógica de datos con las acciones en el controlador, para devolver
la salida al usuario.
12. Hispavista: Introducción a Zend Framework
Conceptos Básicos: MVC II
Controlador
Representa la acción a ejecutar el modelo de datos que va a utilizar la
aplicación.
El controlador para un modelo, podría considerarse como el “verbo”
Desde aquí se invocará la lógica de negocio contenida en el modelo.
13. Hispavista: Introducción a Zend Framework
Conceptos básicos: Patrón de diseño singleton I
Paradigma de diseño que se asegura de que solamente
exista una instancia en ejecución de una clase
determinada.
Se basa en definir un método estático (getInstance por
ejemplo), que a su vez devuelva una variable estática de la
misma clase, conteniendo (por referencia), el objeto
instanciado.
Al tratarse de un método estático, tendremos el mismo
objeto en cualquier ámbito de ejecución.
14. Hispavista: Introducción a Zend Framework
Conceptos básicos: Patrón de diseño singleton II
class ejemplo {
private static $object = NULL;
public static function getInstance() {
if (self::$object == NULL) {
self::$object = new ejemplo();
}
return self::object;
}
}
$a = ejemplo::getInstance();
15. Hispavista: Introducción a Zend Framework
Conceptos básicos: Interfaces fluidas
Práctica en programación OO que consiste en devolver el
objeto en sí en algunos métodos, con el objetivo de
“ahorrar” líneas de código.
Las llamadas a varios métodos quedarán encadenados (al
estilo jQuery por ejemplo).
/* .... */
public function getRequest() {
/* codigo */
return $this;
}
/* .... */
$obj>getRequest()>getPost(“name”);
16. Hispavista: Introducción a Zend Framework
Instalación Zend Framework
Descarga de Zend Framework
Modo descarga
http://framework.zend.com/download
Descargarse la última versión estable (1.7.8)
El contenido dentro de la carpeta “library” será el framework propiamente
dicho.
Modo SVN
Checkout del último tag disponible
svn co
http://framework.zend.com/svn/framework/standard/tags/
release1.7.8/library/Zend/ Zend
17. Hispavista: Introducción a Zend Framework
Estructura de directorios
Partimos de un directorio donde estarán todos los ficheros web
(/var/www por ejemplo)
/var/www/
/var/www/lib/ < Contendrá ficheros de terceros
/var/www/lib/Zend < Zend Framework
/var/www/app1/ < Ficheros de nuestra aplicación
/var/www/app1/controllers <Controladores
/var/www/app1/models < Modelos
/var/www/app1/views < Vistas
/var/www/app1/views/scripts/ < contenedora de las vistas
/var/www/app1/views/scripts/index < un dir / controlador
/var/www/app1/views/helpers/ < dir para helpers de views
/var/www/htdocs/ < Document Root del Apache
/var/www/htdocs/images/ < directorios web “normales”
/var/www/htdocs/css/
18. Hispavista: Introducción a Zend Framework
Bootstrap I
Fichero que se encarga de redirigir todas las peticiones
HTTP a nuestra aplicación.
/var/www/htdocs/index.php
Bootstrap básico:
Especificar include path (librerias y aplicación)
Esto sólo para entornos en desarrollo; en producción sería deseable que
estuviera incluido en el php.ini para temas de rendimiento.
Incluir ficheros principales
require_once 'Zend/Loader.php';
require_once 'Zend/Controller/Front.php';
19. Hispavista: Introducción a Zend Framework
Bootstrap II
Añadir un try/catch a toda la ejecución
Instanciar la clase del controlador principal
Configurar el objeto controlador principal
try {
Zend_Loader::loadClass('Zend_Controller_Front');
$front = Zend_Controller_Front::getInstance();
$front>throwExceptions(true);
// En este ejemplo no utilizaremos views
$front>setParam('noViewRendered',true);
$front>setParam('noErrorHandler',true);
$front>setControllerDirectory('/ruta/controllers');
$front>dispatch();
} catch (Exception $e) {
header(quot;Contenttype: text/html; charset=utf8quot;);
echo quot;<p>EXCEPCIÓN: quot;.$exp>getMessage().quot;</p>quot;;
echo quot;<pre>quot;.$exp>getTraceAsString().quot;</pre>quot;;
}
20. Hispavista: Introducción a Zend Framework
Reescritura de peticiones HTTP I
Es necesario pasar a nuestro bootstrap todas la peticiones
de HTTP dinámicas (que deban ser tratadas por nuestra
aplicación).
Debemos asegurarnos de que modrewrite está activado en
nuestro Apache2
# a2enmod rewrite
# /etc/init.d/apache restart
En desarrollo será suficiente con tener un fichero .htaccess
ocupándose de esta tarea.
En producción deberemos especificarlo en el fichero de
configuración de apache, para mejorar considerablemente
el rendimiento.
21. Hispavista: Introducción a Zend Framework
Reescritura de peticiones HTTP II
Fichero .htaccess sencillo (pero funcional)
/var/www/htdocs/.htaccess
# Nos aseguramos de activar el módulo rewrite
RewriteEngine On
# Si el fichero existe, que sea la última petición
RewriteCond %{REQUEST_FILENAME} f
RewriteRule .* [L]
# Si el directorio existe, que sea la última petición
RewriteCond %{REQUEST_FILENAME} d
RewriteRule .* [L]
# También podíamos resumirlo con una sóla línea
# Si la petición NO termina($) por . seguido de una de esas
extensiones, redirigir al bootstrap
RewriteRule !.(js|css|jpg|jpeg|png|gif|ico)$ index.php
22. Hispavista: Introducción a Zend Framework
Controlador I
Será necesario crear el controlador para que el bootstrap
anterior funcione correctamente.
El controlador se guardará en el directorio controllers de la
aplicación.
/var/www/app1/controllers/BuscarController.php
El controlador será una clase extendida de
Zend_Controller_Action
class BuscarController extends Zend_Controller_Action
Un controlador es entre otras cosas un contenedor de
acciones. La acción será un método público dentro de la
clase del controlador.
public function reservasAction()
23. Hispavista: Introducción a Zend Framework
Controlador II
Tanto el controlador como la acción se especificarán en la
URL.
http://www.example.com/buscar/reservas
Se usará el controlador buscar, y dentro de éste, la acción
reservas.
El controlador por defecto, se denominará index.
/var/www/app1/controllers/IndexController.php
La acción por defecto se llamará index.
<?php
// Debemos incluir la clase Zend_Controller_Action
Zend_Loader::loadClass('Zend_Controller_Action');
class IndexController extends Zend_Controller_Action {
public function indexAction() {
Echo “hola mundo”;
}
}
24. Hispavista: Introducción a Zend Framework
Controlador III
Los métodos en Zend se escriben utilizando camel-case
Comenzando en minúscula, las palabras se separan poniendo la
primera letra en mayúscula.
El siguiente método dentro de un controlador llamado viajes
(ViajesController.php), sería algo así:
class ViajesController extends Zend_Controler_Action {
public function reservarVueloAction() {}
}
La URL que invocaría dicha acción en el controlador sería, sin
embargo, deberá ser e minúsculas, separando las palabras con
un guión:
http://example.com/viajes/reservarvuelo
25. Hispavista: Introducción a Zend Framework
Vistas I
Una vista especifica normalmente el contenido XHTML
que se utilizará para renderizar la página.
También es posible que el resultado sea XML, JSON o
incluso contenido binario como una imagen o un PDF.
Las vistas serán específicas para cada *Action de un
Controlador.
Las vistas se guardarán dentro del directorio views/scripts/,
donde crearemos un directorio con el nombre del
controlador, para finalmente poner la vista, con la
extensión “.phtml”.
/var/www/app1/views/scripts/index/index.phtml
26. Hispavista: Introducción a Zend Framework
Vistas II
El vista como “objeto”, estará disponible dentro como la
propiedad “view” dentro del controlador.
IndexController.php
public function IndexController() {
$this>view>titulo = “Hola Mundo”;
}
Mediante el método mágico __set se creará la propiedad
aunque no exista, y estará disponible dentro de la vista.
index.phtml
<?php echo $this>titulo ?>
En la vista se puede programar PHP de manera normal,
aunque por concepto, no debe contener lógica de
negocio.
27. Hispavista: Introducción a Zend Framework
Vistas III
Escape()
Función disponible en la vista, que deberá usarse para evitar
valores malicioso en las variables que llegan a la vista.
$this>escape($valor);
Por defecto, llamará a la función htmlentities.
Es configurable desde el controlador mediante el método de la
vista setEscape.
$this>view>setEscape('funcion_a_medida');
$this>view>setEscape(array($obj,'metodo_publico');
$this>view>setEscape(array('clase','metodo_estatico');
28. Hispavista: Introducción a Zend Framework
Helpers :: Vistas IV
Helpers, o “ayudadores” de vistas, son utilizados para
encapsular funciones complejas y/o repetitivas dentro
de las vistas.
Existen varios helpers instanciados incialmente en la clase
Zend_View
FormText();
FormSubmit();
FormLabel();
HtmlList();
Etc...
29. Hispavista: Introducción a Zend Framework
Helpers :: Vistas V
Es posible crear nuestros propios helpers a nuestra
medida.
Deben (no siempre) almacenarse siempre en un
directorio establecido:
/var/www/app1/views/helpers/NombreDelHelper.php
La clase debe denominarse con el prefijo
Zend_View_Helper_NombreDelHelper, y el método
que se invocará se llamara “NombreDelHelper”.
Class Zend_View_Helper_NombreDelHelper {
public function NombreDelHelper($param) {}
}
30. Hispavista: Introducción a Zend Framework
Modelo
Existen varias tendencias a la hora de entender e
implementar un modelo de datos:
Sin Modelo: donde la lógica de negocio estará encapsulada
dentro del controlador (desaconsejada para aplicaciones de
tamaño considerable).
Modelo Ligero: implementa funciones básicas basándose en
datos introducidos desde el controlador.
Modelo Pesado: encapsula la lógica de los datos además de la
lógica de negocio.
31. Hispavista: Introducción a Zend Framework
Modelo II
Un Modelo será una clase en el siguiente directorio de
nuestro árbol de directorios:
/var/www/app1/models/Modelo.php
Esta vez, no tiene que “necesariamente” heredar de
ninguna clase del Framework para funcionar.
La estructura de herencias de los modelos será tan
compleja como el programador quiera hacerla.
Simplemente debemos añadir la requerir el fichero en el
controlador que vaya a utilizar el modelo:
require_once 'models/Member.php';
32. Hispavista: Introducción a Zend Framework
Globals.php I
Clase estática (que sólo contendrá métodos estáticos),
que contiene configuraciones globales para toda la
aplicación.
Zend Framework reserva un directorio oficial para esta
clase:
/var/www/app1/config/Globals.php
Deberemos incluirla en el bootstrap para que esté
accesible en todos los ámbitos de la aplicación.
require_once 'config/Globals.php';
Esta clase sirve como contenedor de objetos globales
implementando el patrón singleton.
33. Hispavista: Introducción a Zend Framework
Globals.php II
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Db');
class Globals {
private static $_db = NULL;
static public function getDBConnection() {
if (self::$_db === null) {
self::$_db = Zend_Db::factory('Pdo_Mysql',
array('host'=>'localhost',
'username'=>'user',
'password'=>pass',
'dbname'=>'db'));
}
return self::$_db;
}
}
// Recuperamos la conexión desde cualquier ámbito:
$db = Globals::getDBConnection();
34. Hispavista: Introducción a Zend Framework
Sesiones
Zend utiliza su propia implementación de variables de
sesión.
Utiliza un método que delimita un namespace (un índice
dentro de $_SESSION), devolviendo en un objeto
automático el contenido de esa sesión.
Zend_Loader::loadClass(“Zend_Session_Namespace”);
/* … */
public funcion *Action() {
$myData = new Zend_Session_Namespace('myData');
$myData>nombre = array(1,2,3);
}