Singleton para PHP 5.3, y parche para 5.2

singleton

Mediante esta clase abstracta de podremos crear nuestras clases simplemente extendiendo esta clase

  1. abstract class Singleton {
  2.  
  3.      protected function __construct() {
  4.      }
  5.      final public static function getInstance( $calledClassName = null ) {
  6.          static $aoInstance = array();
  7.   if ( $calledClassName == null ) {
  8.          $calledClassName = get_called_class();
  9.          
  10.          }
  11.          if (! isset ($aoInstance[$calledClassName])) {
  12.              $aoInstance[$calledClassName] = new $calledClassName();
  13.         }
  14.  
  15.          return $aoInstance[$calledClassName];
  16.      }
  17.      final private function __clone() {
  18.      }
  19.  }

Ejemplo:

  1.  
  2. class DataBase extends Singleton {
  3. []
  4. }
  5.  
  6. $db = DataBase::getInstance();

El problema que nos encontraremos en PHP 5.2.x es que no existe la función get_called_class por lo que deberemos tener esa función.

  1. if(!function_exists('get_called_class')) {
  2.     class class_tools {
  3.         static $i = 0;
  4.         static $fl = null;
  5.         static function get_called_class() {
  6.             $bt = debug_backtrace();
  7.             if(self::$fl == $bt[2]['file'].$bt[2]['line']) {
  8.                 self::$i++;
  9.             } else {
  10.                 self::$i = 0;
  11.                 self::$fl = $bt[2]['file'].$bt[2]['line'];
  12.             }
  13.  
  14.             $lines = file($bt[2]['file']);
  15.  
  16.             preg_match_all('
  17.                /([a-zA-Z0-9\_]+)::'.$bt[2]['function'].'/',
  18.                 $lines[$bt[2]['line']-1],
  19.                 $matches
  20.             );
  21.             $returnValue = $matches[1][self::$i];
  22.    // comprobamos si lo llamamos desde un call_user_func y similar
  23.             if ( empty( $returnValue ) && isset( $bt[3]['function'] ) && in_array($bt[3]['function'],array('call_user_func', 'call_user_func_array'))) {            
  24.               $returnValue = $bt[3]['args'][0][0];
  25.            
  26.             }
  27.             return $returnValue ;
  28.         }
  29.     }
  30.     function get_called_class() {
  31.         return class_tools::get_called_class();
  32.     }
  33. }

Como se puede ver utiliza la funcion debug_backtrace() para determinar a que clase estamos llamando. Con esta función ya no tendremos problemas a la hora de instanciar nuestros “Singleton” en php.

Ejemplos de uso que funcionan perfectamente en PHP 5.3, y ahora en PHP 5.2

  1. $objeto = DataBase::getInstance() ;
  2. []
  3. $miClase = 'DataBase';
  4. $objeto = call_user_func( array( $miClase, 'getInstance'));

PHP-FPM sobre Ubuntu 8.10

fastcgi-fpm

Tomada la decisión de sólo desarrollar, en el caso de , para la familia 5.3 o superior. En gran medidad por todas las mejoras y cambios que aporta. Para instalarlo y ser procesado desde un servidor web , este debe ser compilado como FastCGI.

La elección de frente a la usual de php5 como fastcgi y un wrapper, es simple: Además de eliminarl el wrapper, php-fpm nos aporta muchas ventajas

Partiendo de que para esta distribución, desde los páquetes, está con la familia 5.2, el pasar a la 5.3 significa que:

a) Debemos compilarla desde las fuentes

b) Debemos instalar un nuevo repositorio donde si exista la versión 5.3.x para .

Existe un repositorio con esta familia de php, repositorio que deberemos añadir a nuestro archivo /etc/apt/sources.list

deb http://php53.dotdeb.org stable all

Una vez esto sólo deberemos actualizar y (si no teníamos instalado anteriormente ) el php5 instalar los nuevos paquetes

  1. sudo apt-get update

En nuestro caso instalaremos el php5-fqm: Un binario de php que se ejecuta como un servicio de FastCGI, facilmente configurable y con procesos separados (si así lo queremos) por usuario, grupo, …

  1. sudo apt-get install php5-fqm

Problemas:

Si queremos compilar módulos de php con pecl, necesitaremos instalar el php5-dev. La instalación de este paquete nos dará error por el paquete libtool, por lo que tendremos que hacer una instalación “peculiar”

  1. #instalamos el libtool
  2. sudo apt-get install libtool
  3. #descargamos el paquete de php5-dev
  4. cd /tmp
  5. wget http://php53.dotdeb.org/dists/stable/php5/binary-i386/php5-dev_5.3.2-0.dotdeb.2_i386.deb
  6. sudo dpkg –install –ignore-depends=libtool   php5-dev_5.3.2-0.dotdeb.2_i386.deb

Con esto tenemos el PHP5-Dev (de la 5.3.x). Al tratar de instalar cualquier módulo nos dará problemas del tipo:

  1. root@miservidor:/tmp# pecl install mongo
  2. downloading mongo-1.0.7.tgz …
  3. Starting to download mongo-1.0.7.tgz (53,750 bytes)
  4. ………….done: 53,750 bytes
  5. 16 source files, building
  6. running: phpize
  7. Configuring for:
  8. PHP Api Version:         20090626
  9. Zend Module Api No:      20090626
  10. Zend Extension Api No:   220090626
  11. configure.in:150: warning: LTOPTIONS_VERSION is m4_require'd but not m4_defun'd
  12. aclocal.m4:2943: LT_INIT is expanded from…
  13. aclocal.m4:2978: AC_PROG_LIBTOOL is expanded from…
  14. configure.in:150: the top level
  15. configure.in:150: warning: LTSUGAR_VERSION is m4_require'd but not m4_defun'd
  16. configure.in:150: warning: LTVERSION_VERSION is m4_require'd but not m4_defun'd
  17. configure.in:150: warning: LTOBSOLETE_VERSION is m4_require'd but not m4_defun'd
  18. configure:4584: error: possibly undefined macro: m4_ifval
  19.       If this token and others are legitimate, please use m4_pattern_allow.
  20.       See the Autoconf documentation.
  21. configure:7363: error: possibly undefined macro: _LT_SET_OPTIONS
  22. configure:7363: error: possibly undefined macro: LT_INIT
  23. ERROR: `phpize' failed

Esto se debe a la conf del libtool instalado (rutas y contenido), por lo que deberemos corregirlo:

  1. sudo ln -s /usr/share/libtool/config/ltmain.sh  /usr/share/libtool/ltmain.sh
  2. sudo ln -s /usr/share/aclocal/libtool.m4 /usr/share/libtool/libtool.m4
  3. cd /usr/share/aclocal
  4. cp libtool.m4  libtool.m4.original
  5. cat > bsolete.m4 ltoptions.m4 ltsugar.m4 ltversion.m4 >> libtool.m4

A partir de este momento ya podemos instalar cualquier módulo con pecl:

  1. pecl install mongo
  2. downloading mongo-1.0.7.tgz …
  3. Starting to download mongo-1.0.7.tgz (53,750 bytes)
  4. ………….done: 53,750 bytes
  5. 16 source files, building
  6. running: phpize
  7. Configuring for:
  8. PHP Api Version:         20090626
  9. Zend Module Api No:      20090626
  10. Zend Extension Api No:   220090626
  11. []
  12. uild process completed successfully
  13. Installing '/usr/lib/php5/20090626+lfs/mongo.so'
  14. install ok: channel://pecl.php.net/mongo-1.0.7
  15. configuration option "php_ini" is not set to php.ini location
  16. You should add "extension=mongo.so" to php.ini

Twig, el sistema de plantillas definitivo

Twig

Siempre he sido muy receloso a la hora de utilizar un sistema de plantillas para , pero la llegada de Twig ha sido todo un acontecimiento.

Con un desarrollo límpio y optimizado  Fabien Potencier, el creador de Symfony ha creado un sistema en el que las plantillas están 100% libres de código (PHP) y siguen la fabulosa sintaxis de las plantillas de  Django. El resultado es un sistema potente y optimizado, ya que genera unas versiones en php de las plantillas con un código para quitarse el sombrero.

Aun estoy arañando la superficie de esta maravilla, pero con la creación de filtros, y añadiendo nuevas funcionalidades en breve tendremos una versión remozada (internamente) de SevillaPress.