Tutorial A Z A - Programador PHP

13
zenphp :: un framework de aplicaciones en PHP para seres humanos 1 Tutorial Enero/Febrero ‘08 zenphp :: un framework de aplicaciones en PHP para seres humanos Creación de una aplicación web jbelon [arroba] correo [punto] ugr [punto] es Blog.zenphp.es

description

Gracias a http://programadorphp.org/Tutorial para construir una aplicación web sencilla con el framework zenphp.

Transcript of Tutorial A Z A - Programador PHP

Page 1: Tutorial A Z A - Programador PHP

zenphp :: un framework de aplicaciones en PHP para seres humanos

1

Tutorial

Enero/Febrero ‘08

zenphp :: un framework

de aplicaciones en PHP

para seres humanos Creación de una aplicación web

jbelon [arroba] correo [punto] ugr [punto] es

Blog.zenphp.es

Page 2: Tutorial A Z A - Programador PHP

2

blo

g.z

en

ph

p.e

s

Tutorial/Proyecto de creación de una aplicación con zenphp.es

Paso 1: Introducción y descarga

En la página web del proyecto encontrarás la última versión para descargar del framework,

descárgala ya que puedes utilizarla para coordinar con la línea general del tutorial, que se hizo con la

versión 0.1.1 [Enero-Febrero del 2008]

Puedes utilizar el editor Zend Studio o Eclipse para llevar un mejor control de la creación de tu

aplicación y de la depuración de la misma con información de variables, clases, objetos y otros

bloques de código que se implementan en este documento.

La página web completa y el código fuente lo puedes encontrar bajo licencia LGPL en el servidor de la

forja de rediris, aquí.

Cuando crees plantillas html, css, xml, también puedes editarlas dentro del editor.

Puedes cambiar fácilmente las plantillas para ajustarlas a otra aplicación al igual que el código de la

aplicación puedes reutilizarlo para cualquier otro proyecto. Puedes utilizar la galería de módulos de

zenphp para insertar funcionalidades a tu aplicación: manejadores de formularios, manipuladores de

imágenes, ajax, etc. Para ello consulta los documentos de diseño de zenphp en la forja de rediris del

proyecto: introducción, organigramas, diseño de clases, manuales, tutoriales, etc.

Para cambiar la plantilla general de tu aplicación, ve al directorio de /media/plantillas/es (o del

idioma que sea) y modifica la base_web.html. Las imágenes irán en /media/img donde podrás añadir

nuevos elementos para tu aplicación.

Una vez descargado zenphp, se descomprime en una carpeta dentro del servidor, si es el directorio

de apache /var/www/usuario/html/

Paso a explicar entonces la jerarquía de directorios tomando este directorio:

/zenphp/zen.php :: donde configuraremos un par de constantes para el sitio web

/zenphp/ :: contiene el núcleo de zenphp, no deberíamos de tocar el contenido de éste

directorio

/aplicaciones/ : contiene las clases de usuario,configuraciones de base de datos y:

modelos/ : donde guardaremos los modelos de datos de la aplicación

controladores/ : sirve para guardar ficheros que serán cargados para asociarlos a

modelos de datos como controladores de los mismos

vistas/ : aquí se guardan las vistas de nuestra aplicación

ayudantes/ : algunas clases que sirven como ayuda de nuestra aplicación y se asocian

a la clase principal

/media :: es el directorio donde guardaremos el contenido multimedia de la página web

plantillas/ :: aquí guardaremos todas las plantillas necesarias

es/ :: es ,en el idioma por defecto, de donde se toman las plantillas

Page 3: Tutorial A Z A - Programador PHP

3

blo

g.z

en

ph

p.e

s

idiomas/ :: directorio para almacenar subdirectorios de idiomas:

es/ :: ejemplo de idioma,español por defecto, ficheros con las definiciones de

constantes de idiomas, ejemplo: indice.php <?php

define('TXT_TITULO',"Mi titulo"); ?>

en/ idem …para el inglés, etc.

img/ :: aquí guardaremos las imágenes de la plantilla HTML

swf/ :: para almacenar los objetos flash

scripts/ :: contiene los ficheros javascript que utilizamos

etc/ :: resto de archivos: pdf, vídeos,lo que sea

Paso 2: Configuración y depuración

Configuración Opcional

Para mantenerlo todo muy ordenado, lo primero que tenemos que hacer después de copiar

los ficheros es tener a mano las plantillas,es decir, copiar los ficheros HTML,XML ,etc en el

directorio de idioma por defecto: /media/plantillas/es/ ; copiar las imágenes en

/media/img/, los objetos flash en /media/swf , los javascripts en /media/scripts/,etc.

Si queremos tener zenphp en otro directorio por motivos de seguridad o cualquier otro

directorio, podemos cambiarlo en el mismo fichero, con la constante ZF_CARPETA_ZEN,lo

mismo ocurre con los demás: plantillas,idiomas,etc.

Si estamos usando Zend Studio para crear la aplicación, iremos a ProyectoNuevo Proyecto y

aparecerá el “Asistente de Proyectos”, pondremos el nombre, aza_local, pulsamos en “Siguiente” y

ahora en “Añadir Directorio”, buscaremos ahora nuestro directorio del servidor y pulsaremos

“siguiente” hasta finalizar comprobando nuestra configuración del servidor de depuraciçon; en el

caso de que necesitemos usar un directorio de FTP tendríamos que haber añadido el servidor antes

de pulsar en “Nuevo Proyecto”.

Ahora estamos en condiciones de empezar con la configuración de la aplicación.

Para empezar abrimos el archivo /zen.php y configuramos las tres variables que

necesitamos: ZF_SITIO_WEB, ZF_NOMBRE_SITIO, ZF_CORREO_ADMIN con nuestros valores

del sistema.

Opcional: Con Zend Studio: para disponernos a comprobar el funcionamiento de zenphp,

desde el mismo fichero zen.php vamos a la línea que dice “zen___carga_clase('zen');” y

pulsamos F9, se habrá añadido un breakpoint o punto de ruptura, donde el depurador se

dentendrá en tiempo de ejecución,vamos a ello... Ahora pulsamos F5 para ejecutar el código

e iremos avanzando paso a paso comprobando qué es lo que va haciendo zenphp.

Si todo ha ido bien obtendremos una pantalla como la de la siguiente página:

Page 4: Tutorial A Z A - Programador PHP

4

blo

g.z

en

ph

p.e

s

En la parte inferior podemos tener acceso a las variables declaradas, comprobar el valor de una e

incluso dar una expresión en tiempo de ejecución, crear un “watch” o traza, para saber qué tiene una

variable en todo momento sin tener que buscarla en la lista asi como ver la pila de llamadas y qué

ficheros de scripts están llamando a qué scripts, también podemos conocer la posición de los puntos

de ruptura y qué tiene el búfer de salida.

Atendiendo a la parte izquierda del editor veremos una pestaña donde se colocan todos los ficheros

del proyecto y justo debajo, si seleccionamos el botón del “Proyecto” tenemos acceso a las clases

declaradas en él de forma que sabremos qué métodos y propiedades tiene cualquiera de nuestros

objetos.

La línea roja define el breakpoint y la azul donde se encuentra ejecutando el intérprete en ese

momento. A la derecha del editor se coloca la salida de cada script. Como éste no tenía ninguna ,no

se muestra mensaje alguno.

Page 5: Tutorial A Z A - Programador PHP

5

blo

g.z

en

ph

p.e

s

Paso 3: Creación de la aplicación

¿Qué es lo que hace zenphp por medio del generador de proyectos y aplicaciones que

utiliza la factoría de clases? (¡si no quieres saberlo salta a la página 7!)

1. Notificación: El subdominio aza.grandazen.com ha sido creado.

2. Crear directorio del proyecto y copiar zenphp al directorio.

3. Configurar zenphp/zen.php -> ZF_SITIO_WEB, ZF_NOMBRE_SITIO y ZF_CORREO_ADMIN.

Opcionales: ZF_MODO_DEPURACION y ZF_MODO_GUARDAR_LOG.

4. Crear la carpeta aplicaciones y los ficheros de aplicaciones:

aplicaciones/aza.php,aplicaciones/aza_admin.php, aplicaciones/aza.config.php

con todo su contenido...

Se lee el fichero XML de configuración

La aplicación por defecto usa el nombre del proyecto. Hereda de la clase

zen_aplicacion_cliente que hereda de la clase zen

La aplicación de administración del CMS usa el nombre del proyecto + "_" + nombre del

directorio de administración. Hereda de la clase zen_aplacion_admin que hereda de la clase

zen.

Las plantillas de aplicaciones están disponibles para ser modificadas.

5. Crear las plantillas HTML, el diseño ,etc. Una vez terminado organizarlo todo para meter

las imágenes y demás contenido en /media/img/, /media/css, /media/js, /media/swf, etc.

Para ello: crear el directorio /media/idiomas/es ,/media/idiomas/en , etc y

/media/plantillas/es , /media/plantillas/en, etc. El primero para las constantes de idiomas en

ficheros .php y el segundo

para guardar los ficheros de plantillas en HTML con sus #etiquetas# a substituir en el

programa.

Realizar todas las tareas de las plantillas:

* generar una plantilla base_web.html en /media/plantillas/es (idioma por defecto)

donde colocar las etiquetas de #titulo#,#scripts#,#contenido#,#pie#,etc. * recortar

todas las plantillas y mantener la estructura organizada: articulos/elementos.html,

articulos/mostrar.html, productos/elementos.html, etc.

7. Dar permisos de escritura al directorio media/img

8. Crear los modelos, vistas y controladores en las clases aplicaciones/aplicaciones/aza

9. Cuando zenphp intenta cargar la libreria comprimida zen_protoculous.js, si no existe en

ningún directorio devuelve error. En todo caso intenta cargar...( Prototype y Scriptaculous

combinados) comprueba si existe en /media/js ó /media/scripts ,si no existe intentará

copiarla allí y si no puede,usará zenphp/contenido/js/zen_protoculous.js

10.Crear /index.php con la instancia de la clase

<?php

require_once('zenphp/zen.php');

zen___carga_aplicacion('aza');

$ap = new MiProyecto();

$ap->enrutador->delegar();

Page 6: Tutorial A Z A - Programador PHP

6

blo

g.z

en

ph

p.e

s

?>

11. Crear /admin/ , /admin/index.php con el contenido como el del paso 10 pero para la

interfaz de administración del CMS:

<?php

require_once('../zenphp/zen.php');

zen___carga_aplicacion('MiProyecto_admin');

$ap_admin = new MiProyecto_admin();

$ap_admin -> enrutador-> delegar();

?>

12. Cargar el editor Zend Studio y crear el proyecto, añadir el directorio del proyecto.

13. Crear la base de datos

14. Crear el fichero aplicaciones/aza.config.php

con el contenido:

<?php

define('aza_usuario','usuario');

define('aza_servidor','localhost');

define('aza_contrasena','password');

define('aza_bd','nombre_bd');

?>

El Generador: (muy importante)! un proyecto necesita que exista el directorio

/media/plantillas/es donde "es" es el directorio de idioma por defecto

- Crear un proyecto::

-> Crear una aplicacion:

--> crear un modelo

--> crear una vista (html,xml)

--> crear asociación de caché

--> crear un controlador por defecto

-> Crear configuración: Fichero XML

<proyecto nombre="" sitio="">

<aplicacion><!--es la aplicación por defecto-->

<modelo></modelo>

<campos> <campo>id</campo><campo>nombre</campo></campos>

</aplicacion>

<aplicacion nombre="admin"><!--si no se define,no se genera el admin por defecto,dicho

nombre se usa para generar las clases con el nombre del proyecto+"admin"-->

</aplicacion>

</proyecto>

Opcional: Para crear una aplicación con el generador de aplicaciones es mucho más

fácil,de forma que genere además nuestras plantillas HTML de administración.

Page 7: Tutorial A Z A - Programador PHP

7

blo

g.z

en

ph

p.e

s

Continuamos aquí y nosotros mismos hacemos de generador empezando por crear la clase

principal en /directorio_web/aplicaciones/aza.php, ésta clase hace de central de contenido,

es por asi decirlo, el centro neurálgico de toda aplicación. Es por eso que en la parte cliente

hereda de zen_aplicacion y en la parte de administración hereda de zen_aplicacion_admin,

en ésta segunda, todas las clases terminan por _admin para facilitar su reconocimiento y

distinguirlas en el espacio de nombres del conjunto de aplicaciones en un mismo directorio.

El contenido de la clase aza es el siguiente:

Una clase zen_html en la variable $html , para mostrar el contenido con una plantilla,

que estará dentro de dicha clase HTML

Una clase zen_basedatos en la variable $bd que en nuestro caso será del tipo mysql y

estará configurada por el fichero /directorio_web/aplicaciones/aza.config.php

Una clase noticias que extiende de un modelo de datos y por lo tanto contiene un

visualizador. Término acuñado por el autor para montar en una misma clase, una

vista y un controlador que se asocian al modelo de datos para representar

información.

Una clase artículos que dispone de la misma filosofía que las noticias pero se añaden

otras opciones y campos a la tabla

Una clase galerias para mostrar una galería de imágenes en la web

Una clase enlaces para mostrar enlaces a otras webs ,administrables

El contenido de la clase aza_admin es el mismo que el de la clase aza pero las clases además

disponen en su interfaz del visualizador (recordar que es el controlador+vista en uno) los

formularios para altas/bajas/modificaciones de artículos,noticias,imágenes,etc.

Base de datos:

Para crear la base de datos usamos el comando

CREATE DATABASE aza

Sin olvidarnos de ejecutar también :

ALTER DATABASE `aza` DEFAULT CHARACTER SET utf8 COLLATE utf8_bin

ya que necesitamos que la codificación sea en UTF8.

Esto nos recuerda que el fichero /directorio_web/.htaccess ha de contener:

AddDefaultCharset UTF-8

Al igual que los HTML de las plantillas tienen que tener una metaetiqueta:

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

Aclarados estos puntos continuemos con la creación de tablas de usuarios, noticias, artículos

Ver adjuntos: consultas.sql

Page 8: Tutorial A Z A - Programador PHP

8

blo

g.z

en

ph

p.e

s

--

-- Estructura de tabla para la tabla `articulos`

--

CREATE TABLE `articulos` (

`ida` int(11) NOT NULL auto_increment,

`titulo` varchar(250) collate utf8_bin NOT NULL default '',

`HTML` text collate utf8_bin,

`fecha` date NOT NULL default '0000-00-00',

`imagen` varchar(250) collate utf8_bin default NULL,

`tipo` enum('local','municipal','casa','juventudes') collate utf8_bin NOT

NULL default 'local',

PRIMARY KEY (`ida`)

) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=13 ;

-- --------------------------------------------------------

--

-- Estructura de tabla para la tabla `enlaces`

--

CREATE TABLE `enlaces` (

`ide` int(11) NOT NULL auto_increment,

`titulo` varchar(250) collate utf8_bin NOT NULL default '',

`url` text collate utf8_bin NOT NULL,

PRIMARY KEY (`ide`)

) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=3 ;

-- --------------------------------------------------------

--

-- Estructura de tabla para la tabla `galerias`

--

CREATE TABLE `galerias` (

`idg` int(11) NOT NULL auto_increment,

`nombre` varchar(250) collate utf8_bin NOT NULL default '',

`listado` mediumtext collate utf8_bin,

PRIMARY KEY (`idg`)

) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=3 ;

-- --------------------------------------------------------

--

-- Estructura de tabla para la tabla `noticias`

--

CREATE TABLE `noticias` (

`idn` int(11) NOT NULL auto_increment,

`titulo` varchar(250) collate utf8_bin NOT NULL default '',

`HTML` text collate utf8_bin,

`fecha` date NOT NULL default '0000-00-00',

`imagen` varchar(250) collate utf8_bin default NULL,

`tipo` enum('noticia','opinion','evento') collate utf8_bin NOT NULL

default 'noticia',

PRIMARY KEY (`idn`)

) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=12 ;

-- --------------------------------------------------------

--

Page 9: Tutorial A Z A - Programador PHP

9

blo

g.z

en

ph

p.e

s

-- Estructura de tabla para la tabla `usuarios`

--

CREATE TABLE `usuarios` (

`idu` int(11) NOT NULL auto_increment,

`nombre` varchar(75) collate utf8_bin default NULL,

`usuario` varchar(16) collate utf8_bin NOT NULL default '',

`password` varchar(32) collate utf8_bin NOT NULL default '',

`correo` varchar(150) collate utf8_bin default NULL,

`nivel` tinyint(2) NOT NULL default '1',

PRIMARY KEY (`idu`)

) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=3 ;

El esquema es posible que cambie con el tiempo, no incluyo el Diagrama de

Entidad/Relación porque no es necesario nada complejo, simplemente porque no hay una

jerarquía bien definida, sólo existe un administrador que añadirá artículos,esto no es un

wordpress con varios usuarios ni nada por que se le parezca…

Tras ejecutar el fichero de consultas.sql del paquete aza adjunto tenemos que añadir un

usuario administrador, para ello insertamos una nueva tupla desde la línea de comandos de

mysql o bien usando PhpMyAdmin,…le daremos idu = 0 y nivel=3 ( automático ), y

rellenaremos el resto de campos, el password se encripta con MD5.

Ya estamos en condiciones de empezar a diseñar las plantillas y las clases.

Empezamos con la plantilla, necesitamos colocar base_web.html en

/directorio_web/media/plantillas/es/base_web.html para que los mecanismos automáticos

la tomen.

El contenido de una plantilla base_web es lo que se repite en todas las páginas que va a

tener la aplicación, esto es, la cabecera, el pie, etc. Y colocaremos unas marcas entre

símbolos de almohadilla “#” para distinguir los elementos que son intercambiables desde

PHP, ¡ojo!, no es un sistema de plantillas que use PHP dentro de HTML pues las vistas se

construyen desde el mismo controlador asociado al modelo, en cristiano, lo que queremos

reemplazar lo haremos a mano mediante una clase zen_plantilla.

En nuestro caso tenemos una plantilla básica con las etiquetas para #titulo#,

#scripts#,#contenido#,etc. Para la página principal cargamos indice.html y lo que hacemos es

reemplazar la etiqueta #contenido# con éste contenido en base_web.html.

Para probar que funciona todo correctamente necesitamos una base de datos funcionando,

se configura tan fácil como crear el fichero siguiente:

aplicaciones/aza.config.php:

<?php

define('aza_servidor',"localhost");

define('aza_usuario','usuario de base de datos');

define('aza_contrasena',"contraseña");

define('aza_bd',"nombre de base de datos");

define('aza_tipo','mysql');

?>

Page 10: Tutorial A Z A - Programador PHP

10

blo

g.z

en

ph

p.e

s

Una vez escrito base_web.html con su etiqueta del tipo

<div id="content">

#contenido#

</div>

Ya es hora de ir creando la aplicación principal del cliente:

aplicaciones/aza.php

Esta parte contiene la clase de la aplicación, se puede ver que además se hace una

instanciación a una clase zen_html pero que se llama html_aza, es lo que viene a

continuación.

Se puede separar en dos ficheros y hacer un require("clase_html_aza.php");

O bien como se muestra, colocar la clase a continuación ya que no dispone de muchas líneas

de código y se ve claramente quién es quién…(porque es importante conocerse a si mismo ;)

<?php

/**

* Aplicacion cliente de prueba...

*

*/

class aza extends zen_aplicacion {

/**

* Visualizador HTML para la clase

*

* @var html_aza

*/

var $html;

/**

* Clase para mostrar noticias

*

* @var noticias

*/

var $noticias;

/**

* Constructor

* @param str $inicializadores clases separadas por comas, a inicializar

* @return prueba

*/

function aza($inicializadores=""){

parent::zen_aplicacion($inicializadores);

$this->html =& new html_aza($this);

require_once('modelos/clase_noticias.php');

$this->noticias =& new noticias($this);

}

}

Page 11: Tutorial A Z A - Programador PHP

11

blo

g.z

en

ph

p.e

s

aplicaciones/aza.php (continuación)

Para que funcione este código necesitamos antes insertar las clases de las noticias, para ello

las colocamos asi

/**

* Para mostrar el HTML por pantalla con una plantilla

*

*/

class html_aza extends zen_html {

/**

* Clase plantilla para leer y mostrar HTML

*

* @var zen_plantilla

*/

var $plantilla;

/**

* Clase Aplicacion ppal

*

* @var aza

*/

var $padre;

/**

* Constructor

*

* @param aza $_padre

* @return html_prueba

*/

function html_aza(&$_padre){

parent::zen_html($_padre);

$c =& $this->padre->contenido;

$c['scripts'] = "";

}

function index(){

$c =& $this->padre->contenido;

$c['titulo'] = "Inicio";

$c['contenido'] = $this->plantilla->devolver_contenido("indice.html");

//$c['contenido'] = $this->padre->noticias->html->listado_indice();

parent::index();

}

}

?>

Page 12: Tutorial A Z A - Programador PHP

12

blo

g.z

en

ph

p.e

s

aplicaciones/modelos/clase_noticias.php

aplicaciones/vistas /clase_noticias_html.php

Sigue…

<?php

class noticias extends zen_modelo_datos {

/**

* Aplicacion

*

* @var aza

*/

var $padre;

/**

* Visualizador : vista + controlador en uno

*

* @var html_noticias

*/

var $html;

/**

* Constructor de noticias

*

* @param aza $padre

* @return noticias

*/

function noticias(&$padre){

parent::zen_modelo_datos($padre,"idn,titulo,HTML,fecha,imagen,tipo","noticias",

null,"");

require_once(ZF_DIR_APLICACIONES.'vistas/clase_html_noticias.php');

$this->html =& new html_noticias($this);

}

}

?>

<?php

class html_noticias extends zen_html_modelo_datos {

/**

* Clase de noticias asociada

*

* @var noticias

*/

var $padre;

/**

* Constructor del visualizador

*

* @param noticias $_padre

* @return html_noticias

*/

function html_noticias(&$_padre){

parent::zen_html_modelo_datos($_padre);

}

Page 13: Tutorial A Z A - Programador PHP

13

blo

g.z

en

ph

p.e

s

aplicaciones/vistas /clase_noticias_html.php (continuación)

Ya podemos crear index.php con la instanciación de la aplicación y la llamada al enrutador

que nos delegará a la vista por defecto ,de la clase aza, con $aza->html->index().

index.php ::

Ahora a probarlo, la dirección es http://aza.granadazen.com

El paquete con todo el código se está terminando.

/**

* Devuelve el listado de noticias con la plantilla para el indice

*

* @return str

*/

function listado_indice($tipo="noticia"){

$this->padre->condiciones_where = "where tipo='".$tipo."'";

$this->padre->campos = str_replace("HTML","SUBSTRING(HTML,1,100) as

intro",$this->padre->campos);

$this->padre->campos.= ",titulo as titulo_formateado";

$this->padre->filtros_postprocesamiento =

array("titulo_formateado"=>"zen_codifica_nombre_para_url");

$listado =

parent::listado('noticias/noticia_indice.html','noticias/indice.html','noticias

_indice');

if (count($this->padre->tuplas)==0) return "No hay noticias";

else return $listado;

}

/**

* Función que muestra el contenido por defecto de las noticias

*

*/

function index(){

$this->padre->padre->html->index();

}

function leer($datos=null){

$not = $this->padre->obtener_primero("titulo","","where

idn=".intval($datos[0]));

echo $not['titulo'];

}

}

?>

<?php

require_once('zenphp/zen.php');

zen___carga_aplicacion('aza');

$aza = new aza();

$aza->enrutador->establecer_direccion_base("/");

$aza->enrutador->delegar();

$aza->html->mostrar($aza->contenido);

?>