Introducción a PHP Zend Framework
Ernesto Anaya Ruiz [email protected]
AGENDA
Agenda
Definiciones
Comparaciones con otros Frameworks
Anatomía de una Aplicación Zend
Recomendaciones para lograr Mantenibilidad
Recomendaciones para lograr Alta Disponibilidad
Recomendaciones de Seguridad
DEFINICIONES
Agenda
Definiciones • Framework
• ¿Qué es un Framework? • Problemas comunes que resuelven los Frameworks • Tipos
• Zend • Componentes • Filosofía • Proceso de Calidad ZF • Usos
• MVC Comparativas otros Frameworks Anatomía de una Aplicación Zend Recomendaciones para lograr Mantenibilidad Recomendaciones para lograr Alta Disponibilidad Recomendaciones de Seguridad
¿Qué es un Framework?
¿Qué es un Framework?
¿Qué es un Framework?
• Herramientas
• Conceptos
• Prácticas
• Criterios
Enfocados en resolver ciertos tipos de problemas
Framework
• Un conjunto estandarizado de conceptos, prácticas y criterios para enfocar un tipo de problemática particular, que sirve como referencia para enfrentar y resolver nuevos problemas de índole similar.
Problemas comunes
• Persistencia de Datos
• Validación de Formularios
• Autenticación
• E-mailing
• Seguridad
• Routing
• Cache
• Log
• WebServices
• Manejo de Sesión
• ACL
• Configuración
• Manejo de Excepciones
• Búsquedas
• Paginado
• Etc…
No Reinventemos la rueda
• Zend Framework es un framework de código abierto para desarrollar aplicaciones web, servicios web, scripts con PHP5.
• Zend Framework es una implementación que usa código 100% orientado a objetos.
• Cada componente está construido con una baja dependencia de otros componentes.
• Zend Framework ofrece un gran rendimiento y una robusta implementación MVC.
• Licencia BSD. Business friendly
• Documentación en muchos idiomas
• >80% code covered por pruebas unitarias
Componentes de ZF
• MVC
• Database
• I18N
• Auth y ACL
• Web Services
• Mail, Formats, Search
• Utilitarios
• Zend_Controller – Front Controller – Router – Dispatcher – Action Controller – Plugins y Helpers – Request y Response
• Zend_View – PHP-based views – Helpers
• Zend_Layout • Zend_Form
Componentes de ZF
• MVC
• Database
• I18N
• Auth y ACL
• Web Services
• Mail, Formats, Search
• Utilitarios
• Zend_Db_Adapter
– Adaptadores para la mayoría de extensiones de PHP
• Zend_Db_Profiler
• Zend_Db_Select
• Zend_Db_Table
– Zend_Db_Table_Rowset
– Zend_Db_Table_Row
Componentes de ZF
• MVC
• Database
• I18N
• Auth y ACL
• Web Services
• Mail, Formats, Search
• Utilitarios
• Zend_Locale
• Zend_Date
• Zend_Measure
• Zend_Currency
• Zend_Translate – Adaptadores
• PHP Arrays
• CVS
• Gettext
• Qt
• Tmx
• Xliff
Componentes de ZF
• MVC
• Database
• I18N
• Auth y ACL
• Web Services
• Mail, Formats, Search
• Utilitarios
• Zend_Auth – Zend_Db_Table Adapter – HTTP Digest – Ldap – Escribe tu propio
adaptador
• Zend_Sesion – Zend_Sesion_Storage
• Zend_Acl – Roles – Resources – Rights (Privilegios)
Componentes de ZF
• MVC
• Database
• I18N
• Auth y ACL
• Web Services
• Mail, Formats, Search
• Utilitarios
• Zend_Http_Client • Zend_Rest_Client • Zend_Services
– Amazon ,Delicious, Ebay, Flickr, ReCaptcha, ShortUrl, Technorati, Twitter, WindowsAzure, Yahoo, etc.
• Zend_Feed – Rss y Atom
• Zend_Gdata – Books, Docs, Calendar, Picasa,
Youtube
• Zend_Soap • Zend_Json_Server • Zend_XmlRpc
Componentes de ZF
• MVC
• Database
• I18N
• Auth y ACL
• Web Services
• Mail, Formats, Search
• Utilitarios
• Zend_Mail
• Zend_Mime
• Zend_Pdf
• Zend_Search_Lucene
– Compatibilidad con Apache Lucene
Componentes de ZF
• MVC
• Database
• I18N
• Auth y ACL
• Web Services
• Mail, Formats, Search
• Utilitarios
• Zend_Cache
• Zend_Config
• Zend_Console_Getopt
• Zend_Filter
• Zend_Loader
• Zend_Log
• Zend_Registry
• Zend_Validate
Componentes de ZF
• MVC
• Database
• I18N
• Auth y ACL
• Web Services
• Mail, Formats, Search
• Utilitarios
Y mucho más
• Frameworks
• Full Stack
• Microframeworks • Component Library
• Content Management System
Sepamos diferenciar:
• Frameworks
• Full Stack
• Zend Framework
• Symfony
• CakePHP
• CodeIgniter
• Etc…
• Microframeworks
• Limonade - http://limonade-php.github.com/
• Slim - http://www.slimframework.com/
• Flight - http://flightphp.com/
• Silex - http://silex.sensiolabs.org/
• Component Library
• PEAR
• Zend Framework
• Symfony (v2)
• eZ Components
• Content Management System
• Drupal
• Joomla
Ejemplos
Filosofía de Zend Framework • Simplicidad y Extensibilidad
– Soluciones fáciles para el 80% de la funcionalidad comúnmente requerida en una aplicación web.
– La extensibilidad nos posibilita una fácil adecuación al 20% restante
– No hay complejos archivos XML de configuración
• Buenas practicas Ágiles y Orientadas a Objetos – Arquitectura Use-at-Will
– Full Stack Framework
– Diseñado para Extensibilidad
– Unit tested
Proceso de Calidad ZF 1. Cuéntanos que es lo que propones
1. Redactar el Proposal Document
2. Impleméntalo 1. Escribe código OO que implemente tu propuesta
2. Escribe las pruebas unitarias, Si usas TDD, aun mejor
3. Documenta cómo funciona
3. Verifica que cumple con la propuesta 1. Publica tu implementación para la revisión de la comunidad
2. Obtener Feedback e introducir mejoras.
3. Revisión del Zend-Team para validar conformidad
Enlace Proposals: http://framework.zend.com/wiki/display/ZFPROP/Home
Usos de ZF • Como Full Stack web framework
– Aplicaciones web
• Como Component Library – Cron Jobs
• cron_importar_adecsys.php
• cron_despublicar_avisos.php
– Tools
• zf.php
• sync.php
• test_ws.php
• scrapers
http://www.slideshare.net/shahar/zend-framework-components-for-nonframework-use
Lectura Recomendada:
Shahar Evron 2008 – colaborador de ZF
Patrón MVC
COMPARACIONES CON OTROS FRAMEWORKS
Agenda
Definiciones
Comparaciones con otros Frameworks
• Cuadro Comparativo
• Pros & Cons ZF
Anatomía de una Aplicación Zend
Recomendaciones para lograr Mantenibilidad
Recomendaciones para lograr Alta Disponibilidad
Recomendaciones de Seguridad
CakePHP CodeIgniter Symfony Yii ZF
Licencia MIT OSL MIT New BSD BSD
Inicio 2005-08 2006-01 2005-10 2008-01 2006-03
PHP 5.2+ 5.1+ 5 5.1+ 5.2.4+
MVC Si Si Si Si Si
I18n Si Incompleto Si Si Si
ORM Active Record Data Maper
Third Party Only Doctrine, Propel DAO, Active Record
Zend_Db
Testing Si Next Release Si Si
Si
Seguridad ACL Si Plugin ACL, RBAC. Plugins
ACL
Templates Si Si Si Si Si
Caché Si Si Si Si Si
Scaffolding Si No Si Si No
Fuente: http://en.wikipedia.org/wiki/Comparison_of_web_application_frameworks
CakePHP CodeIgniter Symfony Yii ZF
PHP4 SI SI NO NO NO
PHP5 SI SI SI SI SI
Multiple DB SI SI SI SI SI
Validation SI SI SI SI SI
Ajax SI NO SI SI SI
Auth SI NO SI SI SI
Modular SI NO SI SI SI
Fuente: http:///www.phpframeworks.com
PROS CONS • Open Source
• Bajo acoplamiento
• Flexibilidad
• Buena Documentación
• 100% OO
• Uso de Patrones
• Amplia Librería
• Business – friendly – Licencia
– Soporte
• Zend Server
• Certificable
• Menos CoC que otros FWs
• Menos RAD que otros FWs
• Pocos ejemplos, tutoriales
• Mayor curva de aprendizaje
• No hay scaffolding
ANATOMÍA DE UNA APLICACIÓN ZEND
Agenda
Definiciones Comparaciones con otros Frameworks Anatomía de una Aplicación Zend
Estructura de directorios public/index.php application.ini Bootstrap Controllers Views Models
Recomendaciones para lograr Mantenibilidad Recomendaciones para lograr Alta Disponibilidad Recomendaciones de Seguridad
Forms
Layouts
Módulos
View Helpers
Orden de ejecución
Plugins
Action Helpers
Estructura de directorios
Directorio public
DocumentRoot
MVC
Relación entre Controladores y Vistas
<?php
// index.php
// ...
/** Zend_Application */
require_once 'Zend/Application.php';
// Create application, bootstrap, and run
$application = new Zend_Application(
APPLICATION_ENV,
APPLICATION_PATH . '/configs/application.ini'
);
$application->bootstrap()
->run();
?>
public/index.php
application/configs/application.ini
Bootstrap
• La clase Bootstrap define que recursos y componentes que se deben inicializar.
• De forma predeterminada, el Front Controller es inicializado (Zend_Controller_Front), y configura por defecto el directorio “application/controllers/” para manejar los Controladores (Action Controllers).
Bootstrap por defecto
<?php
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
}
?>
al crear un proyecto
Bootstrap con métodos _init* <?php
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
protected function _initFoo()
{
// ...
}
protected function _initBar()
{
// ...
}
protected function _initBaz()
{
// ...
}
}
?>
Ejemplos de métodos de Bootstrap
Ejemplos de métodos de Bootstrap
Controllers
Controlador Zend
<?php
class IndexController extends Zend_Controller_Action
{
public function init()
{
}
public function indexAction()
{
}
public function arraydataAction()
{
$this->view->users = array(
array('nombre'=>'Carlos'),
array('nombre'=>'Pedro'),
array('nombre'=>'Juan'),
array('nombre'=>'José')
);
}
}
A través de $this->view->var = „valor„;
$this->asign(„var„, „valor');
<?php
class IndexController extends Zend_Controller_Action
{
public function seeRequestAction()
{
$this->view->username = ”eanaya”;
}
}
Usuario: <?=$this->username?> <br />
Pasar variables del controlador a la vista
Front Controller • Zend_Controller_Front implementa el patrón Front
Controller usado en aplicaciones MVC .
• También implementa el patrón Singleton
• Su propósito es:
– inicializar el entorno de la solicitud
– rutear la solicitud (Request) entrante
– y luego hacer un envío de cualquier de las acciones descubiertas
– le agrega las respuestas y las regresa cuando se completa el proceso.
http://en.wikipedia.org/wiki/Front_Controller_pattern Ref.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]
.htaccess
¿Cómo es posible que capture todas las peticiones?
Views
Vista
<?php
// recibe variables del controlador
echo $this->variable;
?>
<?=$this->variable?>
Es correcto usar short_open_tag=On?
<?=$this->variable?>
Es correcto usar short_open_tag=On?
short_open_tag = On
PROS CONS
• Legibilidad
• Rapidez
• Menos Portabilidad
• Podría llegar a hacer conflictos si es que se configura el servidor web para que mod_php procese archivos xml
<?xml version="1.0" encoding="UTF-8"?>
<feed>…</feed>
<? foreach ($this->categorias as $categoria): ?>
<tr> … … … </tr>
<? endforeach; ?>
Escapar cadenas en la vista <?php
// mala idea
echo $this->variable;
// buena práctica
echo $this->escape($this->variable);
?>
• No ‘escapar’ las vistas puede ocasionar fallos de seguridad como Cross Site Scripting[1].
• Se deben escapar las cadenas que fueron ingresadas por usuarios.
[1] http://es.wikipedia.org/wiki/Cross-site_scripting
<?php foreach ($this->categorias as $categoria): ?>
<tr>
<td><?php echo $this->escape($categoria[„nombre']) ?></td>
<td><?php echo $this->escape($categoria[„descripcion']) ?></td>
</tr>
<?php endforeach; ?>
Models
Models
No existe Zend_Model
No existe una forma específica de implementar modelos
Qué hacen los modelos?
• Persistencia de datos • Obtener • Guardar • Modificar • Borrar
Cómo?
• Bases de datos • Web Services • Feeds • Archivos • Enumeraciones • Etc.
Cómo?
• Bases de datos • Web Services • Feeds • Archivos • Enumeraciones • Etc.
Escenario Común
Zend_Db
• Zend_Db_Adapter
• Zend_Db_Statement
• Zend_Db_Profiler
• Zend_Db_Select
• Zend_Db_Table
• Zend_Db_Table_Row
• Zend_Db_Table_Rowset
• Zend_Db_Table Relationships
• Zend_Db_Table_Definition
Zend_Db_Adapter
resources.db.adapter = 'pdo_mysql'
resources.db.isDefaultAdapter = true
resources.db.params.host = '192.168.1.88'
resources.db.params.dbname = 'czpls_devel'
resources.db.params.username = 'czpls_devel'
resources.db.params.password = 'm83o823nkdnakh'
resources.db.params.charset = 'utf-8'
resources.db.params.profiler.enabled = true
resources.db.params.profiler.class = 'Zend_Db_Profiler_Firebug'
Configuracion en application.ini
Zend_Db_Table
Zend_Db_Select public function listar() {
$db = $this->getAdapter();
$filas = $db->select()
->from($this->_name)
->join(
'categoria',
'producto.id_categoria=categoria.id',
array('categoria'=>'nombre')
)
->join(
'fabricante',
'producto.id_fabricante=fabricante.id',
array('fabricante'=>'nombre')
)
->query();
return $filas;
}
Zend_Db_Select $filas = $db->select()
->from(
$this->_name,
array('id_producto'=>'id',
'producto'=>'nombre', 'precio')
)
->joinLeft(
'categoria',
'producto.id_categoria=categoria.id',
array('categoria' => 'nombre‟)
)
->joinLeft(
'fabricante',
'producto.id_fabricante=fabricante.id',
array('fabricante' => 'nombre„)
)->query();
Forms
Zend_Form simplifica la creación y manejo de formularios en nuestra aplicación web. Realiza las siguientes tareas:
• Agregar, eliminar, modificar Elementos
• Filtrar y Validar Elementos
• Ordenamiento de Elementos
• Renderizado de Elementos y Formularios, incluyendo escape
• Agrupamientos de Elementos
• Configuración a nivel de Formulario y Elemento configuration
Layout
Configurar el LayoutPath
Módulos
Misma estructura de una app Dentro de cada Modulo.
Podemos setear configs de módulo application.ini
View Helpers
View Helpers
• En los templates es frecuente hacer acciones varias veces: • Formatear fechas • Bloques • Widgets • Etc.
• Pincipio de funcionamiento: “Desacoplar la data de la presentación”
View Helpers
• En los templates es frecuente hacer acciones varias veces: • Formatear fechas • Bloques • Widgets • Etc.
• Pincipio de funcionamiento: “Desacoplar la data de la presentación” • Zend viene con algunos View Helpers • Tambien podemos construir los nuestros
Zend_View_Helper_*
• url(); • partial() • partialLoop(); • placeHolder(); • doctype(); • headTitle(); • headMeta(); • headLink(); • headStyle(); • headScript(); • Etc…
Nuestros propios View Helpers
View Helpers de Módulo
View Helpers de Aplicación
Registrar View Helpers de Aplicación en Bootstrap
En que orden ocurren las cosas detrás de Zend?
Plugins
class My_Controller_Plugin_Routes extends Zend_Controller_Plugin_Abstract
{
public function routeStartup(Zend_Controller_Request_Abstract $request) {
$routes = array(
'login' => new Zend_Controller_Router_Route(
'login',
array(
'controller' => 'test',
'action' => 'login'
)
),
'logout' => new Zend_Controller_Router_Route(
'logout',
array(
'controller' => 'index',
'action' => 'logout'
)
)
);
$router = Zend_Controller_Front::getInstance()->getRouter();
$router->addRoutes($routes);
parent::routeStartup($request);
}
}
Ejemplos Plugins: Router
Ejemplos Plugins: ACL
class My_Controller_Plugin_Acl extends Zend_Controller_Plugin_Abstract
{
public function preDispatch(Zend_Controller_Request_Abstract $request) {
$acl = new Zend_Acl();
$acl->addRole('admin');
$acl->addRole('ventas');
$acl->addRole('supervisor_ventas','ventas');
$acl->addRole('logistica');
$acl->addResource('productos');
$acl->addResource('categorias');
$acl->addResource('fabricantes');
$acl->addResource('reportes');
$acl->allow('ventas','productos','vender');
$acl->allow('logistica','reportes','ultimos10');
$acl->allow('supervisor_ventas','reportes','ultimos10');
$acl->allow('admin');
// guardamos la ACL en sesión
$regAcl = Zend_Registry::get('acl');
$regAcl->acl = $acl;
parent::preDispatch($request);
}
}
Registramos los plugins en el bootstrap
protected function _initPlugins()
{
Zend_Controller_Front::getInstance()->registerPlugin(
new My_Controller_Plugin_Acl()
);
Zend_Controller_Front::getInstance()->registerPlugin(
new My_Controller_Plugin_Routes()
);
}
Action Helpers
Action Helpers
• Permite a los desarrolladores injectar funcionalidad ya sea en tiempo de ejecución o a demanda a los controladores.
Ejemplo Action Helper class My_Controller_Action_Helper_Auth
extends Zend_Controller_Action_Helper_Abstract {
protected $view;
public function preDispatch() {
$view = $this->getView();
$controller = $this->getActionController();
if(Zend_Auth::getInstance()->hasIdentity()){
$view->isAuth = $controller->isAuth = true;
$authData = Zend_Auth::getInstance()->getStorage()->read();
$view->auth = $controller->auth = $authData;
}else{
$view->isAuth = $controller->isAuth = false;
}
parent::preDispatch();
}
private function getView() {
if($this->view !== null){
return $this->view;
}
$controller = $this->getActionController();
$this->view = $controller->view;
return $this->view;
}
}
Registrando los Action Helpers en el bootstrap
;Application.ini resources.frontController.actionhelperpaths.App_Controller_Action_Helper =
"App/Controller/Action/Helper"
// bootstrap
protected function _initActionHelpers()
{
Zend_Controller_Action_HelperBroker::addHelper(
new My_Controller_Action_Helper_Auth()
);
Zend_Controller_Action_HelperBroker::addHelper(
new My_Controller_Action_Helper_MyFlashMessenger()
);
}
Ejemplo Action Helper
class My_Controller_Action_Helper_Rand
extends Zend_Controller_Action_Helper_Abstract
{
public function getRand($max)
{
return rand(1, $max);
}
public function direct($max)
{
return $this->getRand($max);
}
}
Usando los Action Helpers
public function actionHelpersAction() {
if ($this->isAuth) {
$this->log->debug($this->auth);
}
$randHelper = $this->getHelper('Rand');
$this->view->rand1 = $randHelper->getRand(100);
$randHelper = $this->_helper->getHelper('Rand');
$this->view->rand2 = $randHelper->getRand(100);
$randHelper = $this->_helper->Rand;
$this->view->rand3 = $randHelper->getRand(100);
$this->view->rand4 = $this->_helper->Rand(100);
}
MANTENIBILIDAD
Agenda
Definiciones Comparaciones con otros Frameworks Anatomía de una Aplicación Zend Recomendaciones para lograr Mantenibilidad
Parametrización DRY
View Helpers Action Helpers
Coding Standards: PHP_CodeSniffer Object Calisthenics PHP
Manejo de Errores con Zend Uso de Logs
Grupo de discusión: php-standards Recomendaciones para lograr Alta Disponibilidad Recomendaciones de Seguridad PHP
Parametrización
• El objetivo es evitar futuros cambios de código en la aplicación
; ADECSYS
adecsys.wsdl = "http://dev.wsadecsys.info/AppService.asmx?wsdl"
; Parametros Globales reales DPCH
adecsys.proxy.enabled = 1 adecsys.proxy.param.proxy_host = '192.168.1.5'
adecsys.proxy.param.proxy_port = '8123'
adecsys.proxy.param.proxy_login = 'user'
adecsys.proxy.param.proxy_password = 'pass'
Parametrización
apis.facebook.appid = “jm97239j872398"
apis.facebook.appsecret = “0r09340980j95f834095jf3098d039486j403gj"
app.siteUrl = "http://devel.myzfapp.info"
app.adminUrl = "http://devel.myzfapp.info"
app.mediaUrl = "http://devel.myzfapp.info/static"
app.elementsUrlImg = "http://devel.myzfapp.info/elements/aptitus/cvs/"
app.elementsUrlCvs = "http://devel.myzfapp.info/elements/aptitus/cvs/"
app.elementsUrlLogos = "http://devel.myzfapp.info/elements/aptitus/logos/"
app.elementsUrlNotas = "http://devel.myzfapp.info/elements/aptitus/notas/
Parametrización [subjects]
nuevoUsuario = '{%subjectMessage%} a Aptitus.pe, {%nombre%}„
nuevoAdm = 'Bienvenido a Aptitus.pe'
nuevaEmpresa = '{%empresa%} registro de empresa en Aptitus.pe'
postularAviso = '{%nombre%}, postulaste al aviso de {%nombrePuesto%} en Aptitus.pe'
confirmarCompra = '{%nombre%}, compraste un aviso en Aptitus.pe'
confirmarVoucherPagoEfectivo = '{%nombre%}, registraste un aviso en Aptitus.pe„
avisoPublicado = 'Su aviso de {%nombrePuesto%} se publicó en Aptitus.pe'
avisoRegistrado = 'Su aviso de {%nombrePuesto%} está pendiente de Publicación'
recuperarContrasenaPostulante = '{%nombre%}, cambia tu contraseña en Aptitus'
recuperarContrasenaEmpresa = 'Cambio de contraseña en Aptitus'
recuperarContrasenaAdministrador = '{%nombre%}, cambia tu contraseña en Aptitus'
invitarPostular = '{%nombre%}, tienes una invitacion en Aptitus.pe'
mensajePostulante = '{%nombre%},tienes un mensaje de la empresa {%empresa%} en Apt.'
DRY
Don’t Repeat Yourself
Don’t Repeat Yourself
Aprovechar Helpers
Coding Standards
DEMO: PHP_CodeSniffer
Coding Standards
Link: http://www.slideshare.net/guilhermeblanco/object-calisthenics-applied-to-php
Motivación
• Código
– Legible
– Comprensible
– Testeable
– Mantenible
Reglas Simples
Regla:
Solo un nivel de Indentación por método
Solo un nivel de Indentación por método
Solo un nivel de Indentación por método
Solo un nivel de Indentación por método
Solo un nivel de Indentación por método
Solo un nivel de Indentación por método
Solo un nivel de Indentación por método
Solo un nivel de Indentación por método
Solo un nivel de Indentación por método
Solo un nivel de Indentación por método
Regla:
No usar else
No usar else
No usar else
No usar else
No usar else
Regla:
Solo una flecha por línea
Solo una flecha por línea
Zend_Auth::getInstance()->getStorage()->read()->write();
• Incrementa la dificultad de encontrar un error.
Solo una flecha por línea
• Usando Interfaz fluida
Solo una flecha por línea
• En varias lineas a no ser que sean setters o getters
$user->getLocationPoint()->getCountry()->getName();
Regla:
Mantener las clases pequeñas
• Max. 100 líneas por Clase • Max 15 Clases por Paquete
Regla:
Documenta tu código
Documenta tu código
Documenta tu código
Grupo de Discusión: php-standards
http://groups.google.com/group/php-standards Link
ALTA DISPONIBILIDAD
Agenda
Definiciones
Comparaciones con otros Frameworks
Anatomía de una Aplicación Zend
Recomendaciones para lograr Mantenibilidad
Recomendaciones para lograr Alta Disponibilidad
Performance
Base de datos
Indices
Desnormalizar
Correcto uso de Zend_Paginator
Cache
Adaptadores
Cache Metadata
Escalabilidad
Zend_Sesion_SaveHandler_ DbTable
No hardcodear links
Recomendaciones de Seguridad
PHP
• Performance • Base de Datos
• Indices
• Performance • Base de Datos
• Indices
SELECT * FROM empresa WHERE ruc=$ruc
• Performance • Base de Datos
• Desnormalizar
• Performance • Zend_Paginator
• Uso Incorrecto
• Performance • Zend_Paginator
• Uso Correcto
• Performance • Zend_Cache
• El dilema
• Alta Disponibilidad VS. Consistencia
• Performance • Zend_Cache
• Uso
• Performance • Zend_Cache
• Adaptadores
• Performance • Zend_Cache
• Cache Metadata
Metadata
• Performance • Zend_Cache
• Cache Metadata
resources.db.adapter = 'pdo_mysql'
resources.db.isDefaultAdapter = true
resources.db.params.host = '192.168.1.88'
resources.db.params.dbname = 'czpls_devel'
resources.db.params.username = 'czpls_devel'
resources.db.params.password = 'm83o823nkdnakh'
resources.db.params.charset = 'utf-8'
resources.db.params.profiler.enabled = true
resources.db.params.profiler.class = 'Zend_Db_Profiler_Firebug'
resources.db.params.defaultMetadataCache = 'file'
• Escalabilidad
Habilidad para poder incrementar la carga de trabajo sin que esto afecte la calidad del servicio.
• Escalabilidad
“Languages, libraries and frameworks don't scale. Architectures do”
• Escalabilidad
Si la aplicación va a ser desplegada en un ambiente distribuido, se deben de tomar algunas consideraciones
iNET LB
App1
App2
AppN
…
DB
Otros Serv.
• Escalabilidad • Carga distribuida
• Zend_Sesion_SaveHandler_DbTable
resources.session.saveHandler.class = "Zend_Session_SaveHandler_DbTable“
resources.session.saveHandler.options.name = "zend_session“
resources.session.saveHandler.options.primary = "id“
resources.session.saveHandler.options.modifiedColumn = "modified“
resources.session.saveHandler.options.dataColumn = "data“
resources.session.saveHandler.options.lifetimeColumn = "lifetime"
Almacenar las sesiones en un punto central
• Escalabilidad • Carga distribuida
• Evitar Links Duros
<a href="http://myapp.info/usuario/agregar">Agregar</a>
<img src="http://myapp.info/images/tile.png" />
<? $url=$this->url(array('controller'=>'usuario','action'=>'agregar'))?>
<a href="<?=$url?>">Agregar</a>
<img src="<?=MEDIA_URL?>/images/tile.png" />
SEGURIDAD
Agenda
Definiciones
Comparaciones con otros Frameworks
Anatomía de una Aplicación Zend
Recomendaciones para lograr Mantenibilidad
Recomendaciones para lograr Alta Disponibilidad
Recomendaciones de Seguridad
Top OWASP 2010
Sql Injection
Cross Site Scripting
Cross-site Request Forgery
DEMO
GRACIAS