Singleton para PHP 5.3, y parche para 5.2

Mediante esta clase abstracta de php 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

Tomada la decisión de sólo desarrollar, en el caso de PHP, 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 nginx, este debe ser compilado como FastCGI.

La elección de php-fpm 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 ubuntu.

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

Siempre he sido muy receloso a la hora de utilizar un sistema de plantillas para PHP, 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.

Nuevo diseño, nuevo planteamiento

Ya tocaba cambiar un poco mi web.

Poco a poco irá cogiendo forma, y en ella iré poniendo todos los proyectos en los que trabajo, mi portfolio, y mi colección de código que he ido creando o recopilando en los últimos años, que no son pocos.

Pontecesures.net

Web desarrollada sobre Wordpress.

Plantilla propia.

Url: http://www.pontecesures.net

Previous Older Entries