Bootstrap Class

Por zsamer en Mayo 22, 2008

Hoy veremos como centralizar toda la inicialización del bootstrap en una sola clase, permitiendo un index.php mucho más limpio y delegar todos los procesos en la clase Bootstrap que tendrá un método estático main() que es la puerta de entrada a nuestro sistema al puro estilo C#/JAVA, 100% Orientado a Objetos.

En nuestro ejemplo, nuestra clase Bootstrap la vamos a llamar Core, esta va ser final, no queremos que sea extendida.

Primero tenemos que crear un archivo settings que tendrá toda las configuraciones necesarias del ambiente, tales como el manejo de error, include path y un par de constantes del sistema.

Nuestro archivo settings.php lo vamos a dejar en el directorio /quickstart/application/.

Entonces, /quickstart/application/settings.php

PHP:
  1. <?php
  2. /** Configuración de manejo de error */
  3. error_reporting(E_ALL|E_STRICT);
  4. date_default_timezone_set("America/Santiago");
  5.  
  6. define('BI_PATH_BASE', rtrim(realpath(dirname(__FILE__) . '/../'), '/'));
  7. define('DS', DIRECTORY_SEPARATOR);
  8.  
  9. $paths[] = get_include_path();
  10. $paths[] = BI_PATH_BASE . DS . '/application/config';
  11. $paths[] = BI_PATH_BASE . DS . '/application/models';
  12. $paths[] = BI_PATH_BASE . DS . '/library';
  13. $paths[] = BI_PATH_BASE . DS . '/public';
  14.  
  15. set_include_path(implode(PATH_SEPARATOR, $paths));
  16.  
  17. require 'Core.php';
  18. Core::setBaseDir(BI_PATH_BASE);

Bueno y nuestra importante clase Core o Bootstrap la vamos a dejar en la raiz del directorio library.

Entonces, /quickstart/library/Core.php

PHP:
  1. <?php
  2. require 'Zend/Loader.php';
  3.  
  4. /**
  5. * Clase Bootstrap/Core
  6. * Contiene algunos metodos necesarios para operaciones de bajo nivel
  7. * para la aplicacion
  8. */
  9. final class Core
  10. {
  11.     /**
  12.      * Directorio del Web App, No es URL, directorio físico
  13.      * @var String
  14.      */
  15.     private static $basedir = null;
  16.  
  17.     /**
  18.      * Instancia de Zend_Controller_Request_Abstract
  19.      * @var Zend_Controller_Request_Abstract
  20.      */
  21.     private static $_request = null;
  22.  
  23.     /**
  24.      * Obtiene identificador de la Version Aplicacion
  25.      * @var String
  26.      */
  27.     public static function getVersion()
  28.     {
  29.         return '0.1.10000';
  30.     }
  31.  
  32.     /**
  33.      * Set request class/object
  34.      *
  35.      * Set the request object.  The request holds the request environment.
  36.      *
  37.      * @param Zend_Controller_Request_Abstract $request
  38.      * @throws Zend_Controller_Exception if invalid request class
  39.      */
  40.     public static function setRequest(Zend_Controller_Request_Abstract $request)
  41.     {
  42.         self::$_request = $request;
  43.     }
  44.  
  45.     /**
  46.      * Retorna el request object.
  47.      *
  48.      * @return null|Zend_Controller_Request_Abstract
  49.      */
  50.     public static function getRequest()
  51.     {
  52.         if(null === self::$_request){
  53.             self::$_request = self::getFrontController()->getRequest();
  54.         }
  55.         return self::$_request;
  56.     }
  57.  
  58.     /**
  59.      * Retorna el response object.
  60.      *
  61.      * @return null|Zend_Controller_Response_Abstract
  62.      */
  63.     public static function getResponse()
  64.     {
  65.         return self::getFrontController()->getResponse();
  66.     }
  67.  
  68.     /**
  69.      * Retorna el front controller object.
  70.      *
  71.      * @return null|Zend_Controller_Front
  72.      */
  73.     public static function getFrontController()
  74.     {
  75.         return Zend_Controller_Front::getInstance();
  76.     }
  77.  
  78.     /**
  79.      * Retorna la instancia unica del registry.
  80.      *
  81.      * @return Zend_Registry
  82.      */
  83.     public static function getRegistry()
  84.     {
  85.         Zend_Loader::loadClass('Zend_Registry');
  86.         return Zend_Registry::getInstance();
  87.     }
  88.  
  89.     public static function getLayout()
  90.     {
  91.         return Zend_Layout::getMvcInstance();
  92.     }
  93.    
  94.     /**
  95.      * Bootstrap, entrada a la aplicacion .
  96.      *
  97.      * @return void
  98.      */
  99.     public static function main()
  100.     {
  101.         //Setup class autoloading
  102.         Zend_Loader::registerAutoload();
  103.  
  104.         // initialize configuration information
  105.         $config = self::initConfig();
  106.        
  107.         // connect to the database
  108.         self::initConnection($config->database);
  109.         self::setupFrontController();
  110.     }
  111.    
  112.     /**
  113.      * setupFrontController, inicializacion del front controller.
  114.      *
  115.      * @return void
  116.      */
  117.     public static function setupFrontController()
  118.     {
  119.         self::initLayout();
  120.  
  121.         try
  122.         {
  123.             require_once 'Zend/Controller/Front.php';
  124.             $frontController = self::getFrontController();
  125.             $response = $frontController->addModuleDirectory(self::getRoot()  . '/modules')
  126.                                         ->returnResponse(true)
  127.                                         ->throwExceptions(true)
  128.                                         ->dispatch();
  129.                
  130.             self::sendResponse($response);
  131.            
  132.         } catch (Exception $e) {
  133.             print "Message: " . $e->getMessage() . "\n";
  134.         }
  135.     }
  136.  
  137.     /**
  138.      * sendResponse, envia la respuesta de la peticion (Response).
  139.      *
  140.      * @return void
  141.      */
  142.     public static function sendResponse(Zend_Controller_Response_Http $response)
  143.     {
  144.         $response->setHeader('Content-Type', 'text/html;', true);
  145.         $response->sendResponse();
  146.     }
  147.    
  148.     /**
  149.      * Inicializacion de la configuracion y retorna este como Zend_Config object
  150.      * object
  151.      *
  152.      * @returns Zend_Config
  153.      */
  154.     public static function initConfig()
  155.     {
  156.         Zend_Loader::loadClass('Zend_Config_Ini');
  157.         $config = new Zend_Config_Ini(self::getRoot() . '/config/quickstart.ini', 'default');
  158.         self::getRegistry()->set('configIni', $config);
  159.         return $config;
  160.     }
  161.  
  162.     /**
  163.      * Inicializacion de la base de datos information y retorna este como Zend_Db_Adapter_Abstract
  164.      * object
  165.      *
  166.      * @returns Zend_Db_Adapter_Abstract
  167.      */
  168.     public static function initConnection(Zend_Config $config)
  169.     {
  170.         Zend_Loader::loadClass('Zend_Db');
  171.         Zend_Loader::loadClass('Zend_Db_Table');
  172.  
  173.         try
  174.         {
  175.             $db = Zend_Db::factory($config);
  176.             $con = $db->getConnection();
  177.             Zend_Db_Table::setDefaultAdapter($db);
  178.         } catch (Zend_Db_Adapter_Exception $e) {
  179.             throw new Zend_Db_Adapter_Exception("Message: " . $e->getMessage() . "\n");
  180.         } catch (Zend_Exception $e) {
  181.             throw new Zend_Exception("Message: " . $e->getMessage() . "\n");
  182.         }
  183.         self::getRegistry()->set('db', $db);
  184.         return $db;
  185.     }
  186.    
  187.     /**
  188.      * Inicializacion de Zend Layout
  189.      * object
  190.      *
  191.      * @returns void
  192.      */
  193.     public static function initLayout()
  194.     {
  195.         Zend_Loader::loadClass('Zend_Layout');
  196.        
  197.         $options = array(
  198.             'layout'     => 'Main',
  199.             'layoutPath' => self::getRoot() . '/layouts/scripts/'
  200.         );
  201.        
  202.         Zend_Layout::startMvc($options);
  203.     }
  204.    
  205.     public static function setBaseDir($dir)
  206.     {
  207.         self::$basedir = $dir;
  208.     }
  209.  
  210.     public static function getBaseDir()
  211.     {
  212.         return self::$basedir;
  213.     }
  214.  
  215.     public static function getBaseUrl()
  216.     {
  217.         return self::getRequest()->getBaseUrl();
  218.     }
  219.  
  220.     public static function getRoot()
  221.     {
  222.         return self::getBaseDir() . DS. 'application';
  223.     }
  224. }

Hasta ahora todo bien, solo nos faltaría ver como queda nuestro limpio index.php
quickstart/public/index.php

PHP:
  1. <?php
  2. require '../application/settings.php';
  3.  
  4. try
  5. {
  6.     Core::main();
  7. } catch (Exception $e) {
  8.     echo "Message: " . $e->getMessage();
  9. }

Como se puede ver queda todo mucho más limpio, claro y ordenado.

Espero que les sirvan, en nuestro próximo post voy a explicar como podemos integrar el ORM Propel con Zend Framework, por supuesto que compartiendo la misma conexión PDO de acceso a la base de datos con el ORM de Zend Framwork (Zend_Db_Table). La idea de esto es tener la opción y facilidad de poder contar con dos ORM en nuestro proyecto, ocupando ambas ya que comparten la misma conexion de PDO.

Comentarios

8 Responses to “Bootstrap Class”

  1. Pablo Morales on Mayo 22nd, 2008 9:48 pm

    Impecable como siempre.

  2. zsamer on Mayo 23rd, 2008 1:59 pm

    gracias Pablo :-)

  3. _imc_ on Mayo 27th, 2008 3:55 pm

    Me ha gustado la entrada, a la espera de la nueva entrega…

    Has probado Doctrine (http://www.phpdoctrine.org/)? Dicen que esta bien, Symfony oficialmente soporta Propel como ORM por defecto y Doctrine a través de un plugin

    Un saludo

    Isidro

  4. zsamer on Mayo 27th, 2008 10:59 pm

    si, doctrine también es una buena librería para ORM, tiene casi las mismas funcionalidades de propel.

  5. Integrando Propel con Zend Framework: Primera Parte | Zend Framework: Estado del Arte on Junio 2nd, 2008 8:51 pm

    [...] mi ultimo articulo Bootstrap Class había quedado comprometido de escribir un post sobre cómo integrar ZF con el ORM Propel, así que [...]

  6. Integrando Propel con Zend Framework: Segunda Parte | Zend Framework: Estado del Arte on Junio 7th, 2008 1:27 am

    [...] Hoy en esta segunda y ultima entrega veremos la integración con Zend Framework, para ello será necesario extender la clase Zend_Db_Adapter_Pdo_Mysql (utilizando mysql) y agregaremos un par de métodos y funcionalidades en la clase Core/Bootstrap de nuestro sistema cubierto en el artículos anterior Bootstrap Class. [...]

  7. Load Model Action Helper | Zend Framework: Estado del Arte on Agosto 13th, 2008 4:38 pm

    [...] advertencia Core::getRoot() necesitan primero ver el Post Bootstrap Class, sino pueden remplazar a su [...]

  8. Top Posts 2008 | Zend Framework: Estado del Arte on Febrero 2nd, 2009 2:09 pm

    [...] Bootstrap Class [...]

Deja tu comentario




XHTML: puedes usar estas etiquetas: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>