Crear un framework en PHP5 desde cero (1ª Parte)

Logo Gurú PHP FrameWork BySuenyos.Com

 

Introducción

En la actualidad muchos desarrolladores web necesitamos de un framework para poder realizar proyectos más rápidamente, pero existen muchos y con diversas características. Hay que saber elegir bien cuál es el framework que más nos interesa y se acerca a nuestros intereses. Básicamente un framework lo que hace es facilitar el desarrollo de portales, algunos están diseñados para proyectos muy grandes y pesados y otros para proyectos mucho más lights y livianos. Algunos de los frameworks más conocidos y con comunidades de usuarios amplia (este dato es importante para encontrar ayuda o soporte sobre el mismo) son los siguientes:

Zend Framework

zend framework logo

 

 

  • Es el más conocido en el mundo de los frameworks y de los primeros en ver la luz.
  • Es muy utilizado en entornos empresariales profesionales.
  • Su nivel de acoplamiento es muy bajo, de ahí que muchos usuarios lo clasifiquen de librería y no como un framework, puesto que se pueden utilizar sus módulos en conjunto con otros frameworks.
  • Su desarrollo corre de la mano de Zend, la empresa más importante y contribuyente en el código de PHP.
  • Su curva de aprendizaje es elevada, es decir, cuesta bastante acostumbrarse a trabajar con este Framework, aunque Zend ya se ha puesto manos a la obra para solventar esta piedra en el camino y creó RAD (Raid Aplication Development).
  • Está pensado para proyectos grandes.

Symfony

symfony logo

 

 

 

  • Uno de los frameworks que utiliza con frecuencia Yahoo!
  • Hoy en día es bastante famoso y cada día el framework de más gente.
  • Más complejo y elegante que CakePHP y CodeIgniter, pero menos que Zend.
  • Muy completo.
  • El “azúcar sintáctico” y la generación de código ayuda a recortar el tiempo de desarrollo.
  • Recomendado para cualquier tipo de proyecto, en ocasiones combinado con algún componente de Zend.

CakePHP

cakephp logo

 

 

 

 

 

 

 

 

  • Toma muchas de sus ideas de Ruby on Rails, por lo que gustará especialmente a los fans de la autoconfiguración y de lo “mágico”. Debido a esto, no es lo más adecuado para aquellos que quieran tener un mayor control.
  • Recomendado para proyectos no demasiado complejos, en ocasiones combinado con algún componente de Zend.

Code Igniter

code igniter logo

 

 

 

 

 

 

 

 

  • Probablemente, el menos popular de los cuatro.
  • Muy flexible y sencillo. A menudo demasiado, obligando al programador a desarrollar muchas funcionalidades que deberían incluirse por defecto.
  • Muy fácil de aprender, principalmente porque no hay mucho que aprender, al ser simple hasta el extremo.
  • También es el que menos recursos utiliza, al ser el más ligero.
  • Está escrito para mantener la compatibilidad con PHP 4, por lo que no aprovecha muchas de las características introducidas en PHP 5. Debido a esta y a otras razones muchos de sus desarrolladores se desvincularon del proyecto para crear un fork llamado Kohana.
  • Sólo recomendable como framework de iniciación, si el resto intimidan demasiado; o para aquellos a los que realmente no les gusten los frameworks.
Fuente: http://mundogeek.net/archivos/2010/10/30/frameworks-php/
 

Ahora que ya tenemos más idea sobre algunas de las decenas de frameworks que existen en el mercado, deberíamos tener más clara su utilidad. Pero ¿por qué no crear nuestro propio framework? Esta pregunta puede resultar inútil para los grandes gurús de los diferentes frameworks, pero si nos interesa la idea de poder crear nuestro propio framework para hacerlo simple, sencillo, a nuestro molde y que nos ayude en los proyectos que solemos realizar, pues nos creamos nuestro propio framework con el que agilizar nuestros proyectos. Todos sabemos que de normal los tiempos de desarrollo son para antes de ayer cuando nos lo pidieron hoy, así que qué mejor manera de tirar para adelante nuestros proyectos, poder ofrecer asesoramiento y además soporte sobre nuestro propio framework a nuestros clientes amoldando dicho marco de desarrollo a nuestras necesidades.

Pero ¿qué es un Framework? Y ¿cómo trabaja?

En primer lugar, como bien decíamos en la introducción, un framework tiene como finalidad el agilizar el desarrollo de aplicaciones e incluso ofrece ventajas a la hora de realizar cambios, actualizaciones o reparaciones debido a su estructura, planificada desde el inicio del desarrollo de un aplicativo. Imagina poder crear un blog desde cero, por ejemplo, en tan solo unos minutos, pudiendo incluso dividir el código fuente del diseño, entre otras ventajas y además sin perder la originalidad y sin el empleo de ningún CMS existente en el mercado. Gracias a lo cual podremos ofrecer mayor soporte y estabilidad, además de control sobre las aplicaciones creadas para nuestros clientes.

La forma de trabajar en la teoría es muy simple, vemos un esquema para entender un poco más la forma de trabajar de un framework mediante su arquitectura:

mvc esquema

  •  Controlador: Es el encargado de controlar el acceso a la aplicación o cualquier aspecto de la misma, es el corazón de nuestro framework. Recibe una petición, la analiza, recaba datos de nuestra BD busca la vista asociada y nos muestra los resultados.
  • Modelo: Es un vasallo del controlador encargado de las operaciones lógicas y de los datos. Es quién ataca directamente a la base de datos y nos recupera resultados.
  • Vista: El dibujante de la familia, se encarga de presentar utilizando plantillas de diseño los datos obtenidos, se entiende como GUI, la interfaz gráfica de nuestra aplicación.

Planificación y estructura de nuestro Framework

El objetivo es crear un pequeño framework que nos sirva para futuros proyectos que deseemos desarrollar con plazos de tiempo reducidos y sean sencillos. Por ello hemos pensado, ya que no somos gurús en ningún framework anteriormente mencionado ponerle el nombre a este sencillo framework de Gurú. Así al menos podemos decir que en Gurú somos unos gurús. Incluso nos hemos diseñado un logo. Todo esto si es que terminas desarrollando tu propio framework es necesario para moverlo y publicitarlo, claro que sí. Qué hay una crisis terrible y necesitamos que se escuche, además de poder colocar el típico Powered By Gurú.

Durante el transcurso de este tutorial aprenderemos a:

  1. La creación de un controlador, capa abstracta de base de datos y un administrador de plantillas
  2. La combinación de dichos objetos (Modelo Vista Controlador)
  3. Utilizar dicho framework para crear un site
  4. Crear un diseño atractivo para nuestro front end
  5. Diseñar el proceso de inicio de sesión
  6. Como nuestro framework puede crecer y extenderse (añadirle funciones y usos)

La arquitectura de nuestro framework, ha de ser robusta, flexible y que genere confianza. Es lo primero que se ha de tener en cuenta cuando nos ponemos a desarrollar una aplicación de este tipo o de cualquier otro. En particular en este tutorial vamos a ver y explicar los patrones Singleton y de Registro.

Paso 1: Archivos y Carpetas

Lo primero para empezar a crear nuestro framework, es crear una estructura de archivos adecuados, de tal manera que todo tenga su sitio en el servidor. Además de los archivos que alimentan nuestro framework (MVC), también tenemos que tener en cuenta a los archivos relacionados con el sitio web que vamos a crear con nuestro framework. La mayoría de sitios web y aplicaciones web tienen:

  •      Algunas funciones de uso común / objetos.
  •      La lógica de negocio.
  •      Un diseño

Con esto claro ya podemos iniciarnos en la creación de directorios, debemos de ser capaces de agrupar correctamente los elementos miembros de cada una de las categorías anteriormente citadas. Crearíamos una estructura similar a la que vemos a continuación. ¿Qué te parece? ¿Dudas? Pues obsérvala bien y continúa leyendo, damos las explicaciones al final.

archivos y carpetas

Archivos y carpetas, arquitectura básica de nuestro framework

Las funciones y objetos principales de nuestro framework, como el acceso a base de datos, autentificación, controlador de plantillas de diseño, envío de correo electrónico,… Irán guardados en el directorio objects que se encuentra dentro del directorio core. La carpeta controllers nos servirá para almacenar otras funciones propias del modelo de negocio, como por ejemplo galerías de imágenes, provisión y gestión de contenidos,… Que por el momento no veremos en este tutorial, pero aun así debemos contar con esta opción por lo que lo situamos también dentro de nuestro raíz.

Los gráficos y las plantillas propias del site los situamos en el directorio skins de modo que en la práctica se pueda cambiar de diseño sin que éste afecte a la programación. Esta quizás sea la mayor ventaja, el poder dividir de este modo el diseño y la programación. Después en tiempo de ejecución podremos cambiar el diseño del site sin apenas esfuerzo. Ya hemos creado la estructura básica para un skin de nuestro framework:

1. css: Contendrá las hojas de estilo

2. img: Contendrá las imágenes necesarias para el diseño

3. js: Contendrá las funciones javascript necesarias para el site

4. templates: Contendrá los diseños para cada vista

 

 

 

 

Paso 2: El Core

Como decíamos en el corazón de nuestro framework se encuentra el core o núcleo del mismo que es su motor principal. Será el encargado de almacenar y hacer uso de los diferentes objetos del framework funcionando de un modo muy similar a una agenda digital telefónica, almacenando y recuperando contactos, solo que en este caso trabaja con objetos. Será nuestro punto de contacto con los objetos, el dueño y señor de los mismos.

Debido a que vamos a almacenar esta información de forma centralizada debemos asegurarnos que no se puedan crear dos núcleos, por ello recurrimos al patrón de diseño Singleton, consiguiendo de este modo que nuestro framework solo pueda crear una instancia del núcleo y no genere duplicados o aun peor, núcleos independientes, pues podemos encontrar errores muy importantes si esto sucediera ya que no estaríamos haciendo uso correcto de los datos almacenados en la memoria del servidor por nuestra estancia del núcleo. Vemos el código que tal queda y así seguro que estos parámetros quedan más sentados:

<?php
/**
 * The GURURegistry object
 * Implements the Registry and Singleton design patterns
 *
 * @version 0.1
 * @author Alex Romero
 * @basedOnWorkOf Michael Peacock
 * @company Suenyos.Com
 */
class Guru {

	/**
	 * Colección de objetos
	 * @access private
	 */
	private static $objects = array();

	/**
	 * Colección de ajustes
	 * @access private
	 */
	private static $settings = array();

	/**
	 * El nombre de nuestro framework y versión
	 * @access private
	 */
	private static $frameworkName = 'Gurú Framework ver. 0.1';

	/**
	 * La instancia del registro
	 * @access private
	 */
	private static $instance;

	/**
	 * Constructor privado para evitar que se creen directamente
	 * @access private
	 */
	private function __construct()
	{

	}

	/**
	 * Utilizamos el método singleton para acceder a los objetos
	 * @access public
	 * @return
	 */
	public static function singleton()
	{
		if( !isset( self::$instance ) )
		{
			$obj = __CLASS__;
			self::$instance = new $obj;
		}

		return self::$instance;
	}

	/**
	 * Impedir la clonación de los objetos: issues an E_USER_ERROR if this is attempted
	 */
	public function __clone()
	{
		trigger_error( 'La clonación del registro no está permitida.', E_USER_ERROR );
	}

	/**
	 * Almacena un objeto en el registro
	 * @param String $object el nombre del objeto
	 * @param String $key el índice del array
	 * @return void
	 */
	public function storeObject( $object, $key )
	{
		require_once('objects/' . $object . '.class.php');
		self::$objects[ $key ] = new $object( self::$instance );
	}

	/**
	 * Obtiene un objeto del registro
	 * @param String $key el índice del array
	 * @return object
	 */
	public function getObject( $key )
	{
		if( is_object ( self::$objects[ $key ] ) )
		{
			return self::$objects[ $key ];
		}
	}

	/**
	 * Almacena los ajustes en el registro
	 * @param String $data
	 * @param String $key el índice del array
	 * @return void
	 */
	public function storeSetting( $data, $key )
	{
		self::$settings[ $key ] = $data;

	}

	/**
	 * Obtiene un ajuste del registro
	 * @param String $key el índice del array
	 * @return void
	 */
	public function getSetting( $key )
	{
		return self::$settings[ $key ];
	}

	/**
	 * Obtiene el nombre del framework
	 * @return String
	 */
	public function getFrameworkName()
	{
		return self::$frameworkName;
	}

}

?>

Los objetos se almacenan en un array. ¿Cómo? Pues muy sencillo, lo primero que hace es incluir la clase, después instancia el objeto y después almacena éste en un array. La manera de recuperarlos es simple y sencilla, llamaríamos al método getObject pasándole el índice perteneciente al objeto que deseamos recuperar. Por ejemplo si deseamos recuperar el objeto que se encuentra en la posición 3 del array de objetos haríamos getObject(3). Hasta aquí parece todo muy fácil, pero, ¿realmente evitamos que no se duplique el objeto de registro? Sí, lo evitamos utilizando un constructor de clase privado, para evitar que se cree desde fuera y de forma directa, además hemos añadido un disparador que saltará cuando el objeto se duplique. Además, contamos con el método Singleton, que nos permite recuperar la instancia de nuestro objeto registro desde cualquier lugar de nuestro framework aunque éste no esté disponible en dicho fichero.

 

Paso 3: index.php

Ahora vamos a ver como acceder a nuestro registro desde el único punto de acceso, desde nuestro index.php. Ahora bien ¿tenemos configurado nuestro servidor para administrar urls amigables? Esto es muy importante por muchas razones, una de las cuales nos permitirá realizar y completar una de las pautas para el SEO de un website, puesto que las url amigables se posicionan mejor en un buscador tipo google que las que no lo son. Además nuestro index.php será el encargado de procesar dichas urls y realizar en función de la misma una acción u otra. Pero ¿cómo configurar el servidor para que acepte urls amigables?

  1. Abrimos una consola en nuestro servidor (si no podemos porque el servidor es ajeno, deberemos de solicitar su activación a los administradores)
  2. Tipeamos la siguiente línea de comandos:
    sudo a2enmod rewrite
  3. Dicho comando realiza de forma automática la acción de habilitar el mod_rewrite de nuestro Apache2.
  4. Ahora tan solo queda reiniciar el servidor web para que el cambio surta efecto
    sudo /etc/init.d/apache2 restart
  5. Ahora lo que tenemos que hacer es indicar en qué host deseamos que aplique el rewrite. Para ello tipeamos el siguiente comando para editar el archivo en cuestión:
    sudo gedit /etc/apache2/sites-enabled/000-default
  6. Ahora buscamos AllowOverride None y lo cambiamos por AllowOverride All (Existen varias referencias, las cambiamos todas si se trata de un servidor local de pruebas, si no es así, andad con ojo y especificar en que host y con qué opciones deseáis que se aplique el rewrite
  7. Volvemos a resetear el servidor para que este último paso surta efecto:
    sudo /etc/init.d/apache2 force-reload
  8. ¡LISTO!

Ya tenemos el servidor habilitado para realizar la acción de intercambio de urls amigables. Ahora tenemos que configurar un archivo .htaccess válido para nuestro framework que deberemos alojar en el directorio raíz del mismo. Por el momento podemos dejarlo así:

## .htaccess de GURU
## Suenyos.Com 2011
## Alex Romero
###
## Habilitar Reescritura
RewriteEngine on

## Rewrite URLs
##     Entrada:
##     Salida:
#RewriteRule ^Escribir Regla/$

## Rewrites Genéricas
## Con 1 Variable
RewriteRule ^(*.)/(.*)/$ $1=$2

Ahora os dejo con el código del index.php que por ahora tan solo nos servirá de prueba y nos mostrará si realmente funciona o no:

<?php
/**
 * GURU Framework
 * Framework loader - acts as a single point of access to the Framework
 *
 * @version 0.1
 * @autor Alex Romero
 * @company Suenyos.Com
 * @basedOnWork Michael Peacock
 */

// Lo primero siempre es iniciar la sesión en el servidor
session_start();

// Configuración de algunas de las definiciones
// La raíz de nuestra aplicación, que nos servirá
// para utilizarla más adelante
define( "APP_PATH", dirname( __FILE__ ) ."/" );
// Usaremos esta definición para evitar que los scripts se llamen desde fuera del framework
define( "GURUFW", true );

/**
 * Función de autoload
 * Se utiliza para incluir el controlador apropiado, sólo cuando se necesita
 * @param String el nombre de la clase
 */
function __autoload( $class_name )
{
	require_once('controllers/' . $class_name . '/' . $class_name . '.php' );
}

// Incluimos el registro y lo instanciamos
require_once('core/registry.class.php');
$registry = GURU::singleton();

// Escribimos por pantalla el nombre de nuestro Framework
// para probar que todo ha ido correctamente
print $registry->getFrameworkName();

exit();

?>

¿Qué hace por ahora nuestro index.php?

  1. Iniciamos la sesión en el servidor, muy necesario y obligatorio para poder utilizar variables de sesión en un futuro a lo largo de nuestro framework.
  2. Definimos cual es la ruta absoluta de nuestra aplicación, de este modo podemos prevenir que se llamen a funciones de nuestro framework desde otra dependencia, entre otras opciones.
  3. Cargamos todas las clases que sean necesarias de forma automática.
  4. Creamos una instancia de nuestro registro. Muy importante que no se encuentre en la misma carpeta que los objetos.
  5. Por último mostramos el nombre del framework, para que veáis lo fácil que es utilizar un método de nuestro registro.

Deberíamos de poder acceder a nuestro servidor local y ver algo como esto:

guru/index.php

guru/index.php

Basado en: http://net.tutsplus.com/tutorials/php/create-a-php5-framework-part-1/

5 thoughts on “Crear un framework en PHP5 desde cero (1ª Parte)

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *