13 nov 2012

Jquery Listar eventos de un objeto por consola


        var clickEvents = $('#selectores').data("events").click;

        jQuery.each(clickEvents, function(key, value) {
            console.log(value);
        });

29 oct 2012

Patrones de diseño en PHP: DAO Pattern

El Objeto de Acceso a Datos es un patrón ampliamente utilizado.

Un problema recurrente en el desarrollo de software es el acceso a recursos de datos. En el ámbito del desarrollo Web, las aplicaciones tienden a recoger datos de algún motor de persistencia, por ejemplo, una base de datos.

Esta tarea de recoger y almacenar datos, se sitúa intuitivamente en los controladores de nuestros objetos dentro del modelo de datos. Distribuyendo la información a cada objeto cuando este lo precise.
Tareas comunes a todos los objetos del modelo, y que ligan fuertemente la parte Web de la aplicación con el acceso a la base de datos.

La idea de diseñar una capa intermedia entre la capa frontal y la base de datos, que provea de una interfaz de acceso a la base de datos, solucionará el problema de acoplamiento entre las dos capas, y además permitirá reutilizar el código común, evitando duplicidades, mejorando su extensibilidad y mantenimiento.





Ref. DAO Pattern in PHP » World of Web

5 jul 2012

A dark corner of PHP: class casting » Jasny · web development

Sometimes you want things that simply look impossible in PHP. A few years ago I was using the DB library from PEAR. I wanted to add some functionality to the DB_Result class, however since the result object is created in the DB class and the class used for that isn’t configurable, I was kind of stuck there.
I solved this problem by writing a class extending the DB_Result class. The class had which used reflection to pull all the info out of the DB_Result class and created a new DB_Result_Ext object. In the end I decided that I didn’t like DB class at all (nor MDB2 for that mather), so I threw away this dirty code, however I always felt that there had to be a better way in solving these kind of issues.
The new solution for this problem I’m about to show, is really a dark corner of PHP and perhaps even dirtier than the other dirty solution. However the method can get you out of a jam when this situation arises.

PHP has a function serialize, which can create a hash from any type of variable, scalars, array, but objects as well. Using the unserialize function, PHP can recreate the variable from the serialized hashed. If we look at how an object is serialized, we see only the properties and the class name are stored. Serializing an object of the ‘mother’ class, with a protected variables ‘$myvar’, would give the following hash:
 
O:6:"mother":1:{s:8:"�*�myvar";i:5;}
 
We see an ‘O’ for object, the string length of the class name, the quoted class name and the properties. What would happen if we would change the class name and unserialize?

Let’s have a look at the following example:

/**
* Parent class
*/
class mother
{
protected $myvar;
function __construct($value)
{
$this->myvar = $value;
}
}
/**
* Child class
*/
class grandmother extends mother
{
protected $bval;
function __construct($value)
{
$this->bval = $value;
$this->myvar = $value / 10;
}
function __wakeup()
{
if (!isset($this->myvar)) throw new Exception("Illegal unserialize: The original object did not contain a myvar property.");
$this->bval = $this->myvar * 10;
}
function getVal() {
return $this->bval;
}
}
/**
* Cast an object to another class, keeping the properties, but changing the methods
*
* @param string $class Class name
* @param object $object
* @return object
*/
function casttoclass($class, $object)
{
return unserialize(preg_replace('/^O:\d+:"[^"]++"/', 'O:' . strlen($class) . ':"' . $class . '"', serialize($object)));
}
$a = new mother(5);
$z = casttoclass('grandmother', $a);
echo $z->getVal();


We have a class ‘mother’ and a class ‘grandmother’ extending ‘mother’. We create a ‘mother’ object and now we want to cast it to a ‘grandmother’. In the casttoclass() function, we serialize the object, use a preg_replace to change the class name and than unserialize the hash. This creates a ‘grandmother’ object, with a property ‘$myvar’ set to 5, however the ‘$bval’ property is not set. To solve this we can use the magic method __wakeup(). After the conversion, we can use $z normally as any other ‘grandmother’.

18 ene 2012

PHP y ORACLE

Ahora mismo estoy poniendo un producción un servidor en mi centro de trabajo, en el que además de tener que dar servicio para la base de datos PostgreSQL (explique hace poco cómo permitir conexiones entrantes a esta BBDD), debe hacer conexiones externas a una base de datos Oracle.
Estas conexiones las hará un script en PHP por lo que además, deberemos instalar OCI (Oracle Call Interface) para PHP. Suponemos que está ya instalado el servidor web Apache 2 y los componentes básicos de PHP.

Instalación de Oracle instantclient
Antes de instalar el instantclient como tal, debemos instalar la librería libaio, necesaria para gestionar entradas/salidas asíncronas al kernel. La instrucción será (utilizo “#” en el prompt para indicar como superusuario, “$” en caso contrario):
# yum install libaio1
O si usamos una distribución que use APT:
# apt-get install libaio1
Lo siguiente será acceder al portal de descargas de Oracle y descargar los componentes necesarios para el instantclient:
  • Basic
  • Devel
  • SQLPlus
Elegimos la última versión, nuestra arquitectura  y descargamos los paquetes RPM. La instalación será inmediata si tenemos una distribución basada en Red Hat:
# yum install paquete.rpm
En caso contrario, deberemos instalar alien previamente para que convierta los paquetes RPM en paquetes DEB:
# apt-get install alien
# alien paquete.rpm
# dpkg -i paquete.deb
Ahora ya nos tocar configurar el famoso fichero Tnsnames.ora. Este fichero variará de una configuración a otra por lo que sólo vamos a comentar dónde situarlo. Su ruta debe ser: /etc/oracle/tnsnames.ora, en caso de no existir, deberemos crearla.
Para terminar, deberemos crear unas variables de entorno. Para ello accedemos al fichero /root/.bashrc como superusuario e incluimos las siguientes líneas:
export TNS_ADMIN=/etc/oracleexport SQLPATH=/usr/lib/oracle/11.1.0.1/client/binexport LD_LIBRARY_PATH=/usr/lib/oracle/11.1.0.1/client/lib:$LD_LIBRARY_PATHexport PATH=$PATH:$SQLPATH
En algunas distribuciones, también podréis hacer ese cambio en otro fichero: /etc/environment.

Instalación de OCI en PHP
Ahora nos toca la parte de PHP, es decir, instalar los componentes necesarios para poder hacer llamadas a Oracle desde PHP usando el instantclient que acabamos de instalar (con lo fácil que es hacer esto mismo con MySQL o PostgreSQL…, las cosas del software cerrado).
Suponemos que tenemos instalado Apache2 y PHP, pero aún así instalaremos dos paquetes más:
# yum install php-pear php5-dev
# apt-get install php-pear php5-dev
PHP-PEAR es según definen sus siglas: PHP Extension and Application Repository, es decir, un repositorio de extensiones y aplicaciones para PHP que nos permite instalar sin problemas ciertos componentes de PHP que no podemos instalar a través de nuestro gestor de paquetes habitual (me recuerda a CPAN con Perl, pero esa es otra historia para otra entrada).

Ya estamos en disposición de ejecutarlo para instalar OCI:
pecl install oci8
En la terminal nos aparecerá algo así como:
1-1, ‘all’, ‘abort’, or Enter to continue:
Pulsamos “1″ luego ENTER y escribimos las siguientes opciones (debemos saber el PATH exacto de nuestras librerías Oracle, cambiará en función de la versión):
shared,instantclient,/usr/lib/oracle/mi_version/client/lib/
PHP-PEAR descargará, configurará, compilará e instalará el módulo. Finalmente, tenemos que añadir a nuestro fichero php.ini una línea para que cargue la librería dinámica de OCI y puedan hacerse llamadas desde los ficheros PHP.
La ruta del fichero será: /etc/php5/apache2/php.ini y la línea a agregar junto a las demás extensiones la siguiente:
extension=oci8.so
Reiniciamos el servidor web y listo:
services httpd restart
O:
/etc/init.d/apache2 reload