Instalar Runkit en Debian

Tengo que escribir este post mas que nada para acordarme que carajo hice para instalar Runkit. Runkit es una extensión de PHP que permite modificar los simbolos del interprete en tiempo de ejecución, que significa esto, basicamente que puedo modificar el valor de las constante, redefinir variables globales, modificar el comportamiento de las funciones, metodos objetos y otras cosas del entorno en tiempo de ejecución. La pregunta del millon de dolares es para que carjo quiero hacer algo tan descabellado, la respuesta es sencilla, estoy viendo como poder hacer mocks de funciones y para ello necesito poder, en tiempo de ejecución, modificar las funciones previamente definidas para injectar el mock de la misma. Moraleja, esta extensión es bastante prohibida y no debería utiliarse nunca, no se les ocurran andar instalandola para hacer sistemas de producción.

Bueno, estuve peleando toda la tarde con la Mac roñosa que me dan en el laburo para poder compilar esta extensión, logre compilarla pero la extensión quedo pinchada, tira segmentation fault por todos lados, voy a escribir otro post para cuando la tenga funcionando posta. Pensé que en mi Linux iba a funcionar de una pero me encontré con que tampoco se podía compilar tan fácilimente, aparentemente el build de PECL esta pinchado y no funciona bien con PHP 5.3 en Debian y derivados, pero hay un santo que se tomo el trabajo de hacer una versión que funciona.

Los pasos de instalación son sencillos.

#wget https://github.com/zenovich/runkit/zipball/master

#unzip tcz-phpunit-mockfunction-{hashcambia}.zip

#cd tcz-phpunit-mockfunction-{hascambia}

#phpize

#./configure

#make

#make install

Si todo salio sin errores el último paso es habilitar la extensión, en el caso normal consta con añadir la regla extension=runkit.so al php.ini; como en los debians se mantiene una conf separada para  el interprete de la linea de comandos (cli) y el apache la mejor opcion es añadir un archivo runkit.conf en el directorio /etc/php5/conf.d con la linea para incluir la extension.

# echo ‘extension=runkit.so’> /etc/php5/conf.d/runkit.conf

Para testear si esta funcionando

echo ‘extension=runkit.so

% php –info|grep runkit

/etc/php5/cli/conf.d/runkit.ini,

runkit

runkit support => enabled

runkit.internal_override => Off => Off

runkit.superglobal => no value => no value

Si aparecer support enabled esta funcionado. Voy a seguir trabajando sobre esto y voy a ir posteando mas cosas al respecto de este viaje que estoy haciendo sobre esta extensión.
Links de interes
Share

Expresiones como valores de Arrays en PHP

Recién estaba programando un poco para disfrutar del sol de un día feriado y me topo con un problema, había definido un array de la siguiente manera.

La cuestión fue que cuando quería utilizar el elemento message este no aparecía definido en el Array, PHP no estaba arrojando ningun tipo de error y el elemento
simplemente no estaba ahí. Cuando me pongo a mirarlo en detalle encuentro un error de tipeo en el segundo elemento, en vez de poner => puse simplemente >, al
cambiarlo mi programa funcionó como lo esperado.

Me puse a pensar un poco lo que paso por que me pareció muy extraño que PHP no arroje errores, me pongo a mirar el caso puntual en detalle y me encuentro con esto.

Como pueden ver el segundo elemento posee el mismo error que había cometido, al ver el contenido del array con var_dump podemos ver que el segundo elemento tomo la clave 0 (dado que no había un elemento con clave numérica previo) y su valor es falso, ahí es cuando digo por que falso?, y es falso por haber evaluado la expresión ‘bar’ > ‘floflo’. la cual da como resultado falso. Me puse a buscar un poco de documentación al respecto pero no encontré nada donde diga que PHP evalua las expresiones dentro de los valores de un array y no recuerdo haberlo usado antes. Me puse a hacer algunas otras pruebas y llegue a estos resultados.

Probablemente muchos conocían esta característica, yo acabo de asimilarla.

Share

Evitando Switchear

Entre las estructuras de control disponibles en PHP tenemos el famoso y conocido Switch. Famoso por que
esta entre las estructuras de control de los lenguajes de programación mas conocidos desde hace mucho tiempo.

Esta es una estructura, a mí gusto, es bastante incomoda para utilizar dado que no tiene una sintaxis
muy amigable y generalmente introduce un monton de código rigido y aveces innecesario.

Hoy estaba viendo algunas alternativas utilizando funciones anonimas para evitar el uso del switch. Una opción
que me pareció interesante es definir las funciones anonimas para tratar cada caso y
después componerlas en un array donde la clave de cada entrada sea la opcion del case.

Por último podemos invocar directamente a la función que maneje el caso correspondiente.

Si no les gusta definir las funciones por separado, puede hacerlo directamente sobre el array.

Obviamente no es un reemplazo para todos los casos del Switch, pero puede ser muy práctico para varios escenarios.

Share

PD que ?, PDO !

En los principios de PHP solo teníamos librerías nativas para interactuar con bases de datos. La más conocida son las nativas de mysql (mysql_connect, mysql_query, mysql_*).  Dichas librerías son muy efectivas y funcionan perfectamente, pero podemos encontrarnos con dos cuestiones que pueden molestarnos.

– No son orientadas a objetos

– Son especificas y acoplan al RDBMS con nuestro código

Para solventar estos problemas deberíamos agregar bastante código a nuestra aplicación a fin de darle soporte a múltiples bases de datos y armar una abstracción orientada a objetos.

Recuerdo la primera vez que vi ADO.NET y JDBC, ambas librerías, en sus lenguajes respectivos, subsanaban los problemas aquí comentados; nosotros en PHP3 no teníamos nada parecido. Con el pasar del tiempo aparecieron algunas abstracciones como MDB (http://pear.php.net/package/MDB/redirected) y ADOdb las cuales pretendían solventar este problema.

Con la salida de PHP5 y el nuevo modelo de Objetos incorporado al lenguage se incorporó una librería llamada PDO (PHP Data Objects) la cual es un librería abstracta, orientada a objetos para interactuar con bases de datos.

PDO Definie básicamente es un conjunto de interfaces para interactuar con bases de datos, los proveedores de drivers simplemente deben implementar dichas interfaces para proveer soporte PDO a su RDBMS.

PDO proporciona una capa de abstracción acceso a datos, que significa que, independientemente de la base de datos que está utilizando, se utiliza las mismas funciones para realizar consultas y obtener datos. PDO no proporciona una abstracción base de datos; reescribe SQL o emular características faltantes. Debe usar una capa de abstracción en toda regla, si necesita esto, para esto pueden ver Doctrine o Propel.

Lo interesante es que si programamos todo medianamente estándar, y en los casos particulares añadimos la compatibilidad necesaría para las bases de datos a soportar, podemos cambiar de RDBMS muy fácilmente.

Ademas de todo esto, PDO incorporá ventajas de optimización, seguridad, transacciones, pooling de conexiones y varias cosas mas.

Aquí el manual de PDO.

http://www.php.net/manual/es/intro.pdo.php

Instalación

Esta librería viene nativamente dentro de PHP5 o superior (salvo que su versión de PHP no este compilado con el flag de pdo); lo que no viene por defecto son los drivers concretos de cada RDBMs, estos deben instalarse por separado y habilitarlos en el php.ini como una extensión dado que estos componentes son binarios (.so en Unixes y .dll en windows). Si tienen la suerte de trabajar sobre debían podrán ver los paquetes que tenemos en los repositorios mediante apt-cache search

php5-mysql – MySQL module for php5
php5-odbc – ODBC module for php5
php5-pgsql – PostgreSQL module for php5
php5-sqlite – SQLite module for php5
php5-sybase – Sybase / MS SQL Server module for php5
php5-oracle – Oracle module for php5

Solo basta con hacer un apt-get install y reiniciar el servidor web para tener disponible el driver. Si su base de datos poseen un driver que no esta en los gestores de paquetes simplemente deben descargar el binario y añadir la extensión en el php.ini (extension=/path/al/binario.so).
Para verificar su correcta instalación y los drivers disponibles phpinfo() al rescate, aparece en el listado de features.
php5-mysql – MySQL module for php5
php5-odbc – ODBC module for php5
php5-pgsql – PostgreSQL module for php5
php5-sqlite – SQLite module for php5
php5-sybase – Sybase / MS SQL Server module for php5
php5-oracle – Oracle module for php5solo

Los Objetos de PDO

PDO cuenta con dos objetos principales, PDO y PDOStatement, el primero es el encargado de manejar las cuestiones de conexión, el segundo el encargado de manejar las consultas. Para realizar la conexión a la base de datos, PDO requiere un DSN (Data Source Name) que es un string que contiene los parámetros de conexión. Para conectarnos a la base necesitamos crear una nueva instancia de la clase PDO, pasando como argumentos al constructor el DSN, usuario y contraseña; en otras palabras, el DSN es tipo una url pero para especificar a donde conectarnos.

El DSN de PDO sigue la siguiente forma.

DRIVER:hots=IP;dbname=NOMDB

Donde

DRIVER: depende de la base a conectarse, (mysql, pgsql, oci (oracle),ibm(db2))

IP: es la dirección ip del servidor a conectarnos o su nombre de dominio

NOMDB: es el nombre de la base a conectarse.

Un ejemplo de conexión sería

$dbh = new PDO(‘mysql:host=localhost;dbname=test’, $user, $pass);

Deben tener en cuenta que mediante el objeto podremos realizar las operaciones con la base. Para desconectarse solo deben asignar null al objeto de conexión.

$dbh = null;

Consultas a la base

Las consultas se realizan a trabes del objeto de conexión y utilizando el método query. Este nos devuelve un arreglo con los resultado, lo que nos hace olvidar del fecth.

Veamos un ejemplo.

$res = $dbh->query(‘SELECT * from FOO’);
foreach($res as $row) {
print_r($row);
}

En el caso querer obtener el arreglo por separado para tratarlo de otra manera se puede utilizar el método fetchAll para asignar toda la consulta en un arreglo. Por ejemplo.

$res = $dbh->query(“SELECT * FROM persona”);
$res_arr = $res->fetchAll();

Si queremos ir obteniando de a uno los registros como arreglos podemos usar fetch, esto avanza el puntero interno de los resultados y al llegar al final devuelve falso.

Prepared Statement

La ventaja mas potente de PDO es la de poder crear Consultas Preparadas, o Prepared Statement. Esta fija el formato de la Consulta a una determinada manera y luego recibe los parámetros tal como nosotros especificamos. Esta separación del formato de la consulta y los parámetros evita el problema de la Injección SQL dado que es imposible realizarla en una consulta Preparada. Por otro lado este tipo de consultas otorgan al RDBMs mucha mejor facilidad de tratamiento de las consultas dado que pueden tener preparado el plan de ejecución de las mismas optimizando un poco el rendimiento general de la aplicación.

Para crear una consulta preparada se utiliza el Prepare de PDO, esa operación devolverá un Statement al cual mediante el método bindParam asociaremos los parámetros y mediante execute tendremos los resultados de la consulta. Si execute devuelve falso podremos saber si se produjo un error. Una vez realizado el método execute podremos tratar los resultados en el Statement.

Veamos un ejemplo.

Transacciones

Una transacción es un conjunto de operaciones que deben ser realizadas todas juntas o no debe realizarse ninguna. Para trabajar con transacciones debemos enviar señalizadores al RDBMS de como es el proceso, donde empieza (begin), cuando termina ok (commit) y si fallo (rollback) para que vuelva atrás los cambios realizados. En PDO contamos con dichos metodos para señalizar la operación de transacción.

Métodos provistos por PDO

PDO::beginTransaction – Inicia la Transacción.
PDO::commit – Confirma los Cambios y finaliza la transacción.
PDO::rollback – Deshace los cambios realizados y finaliza la transacción.

Ejemplo

Conclusión

PDO es muy ordenado y limpio para trabajar como pueden ver, es muy util para el trabajo cotidiano. Varios de los proveedores de drivers últimamente solo estan soportando drivers para esta interfaz. Su aprendizaje puede tomar una o dos tardes, es muy sencillo de utilizar y la ganancia es grande.

Mi romendación, comiencen a utilizar esta librería lo antes posible y olvidensé de mysql_connect (al menos por un rato).

Share

PHP odbc_connect sobre Windows 2003 en 64bits

Ayer me cruce con un problema super interesante, me consultaron por un desarrollo que estaban realizando bajo windows, con PHP, IIS, SQLServer y para realizar la conneción utilizaban las librerías nativas de PHP para odbc (odbc_*).

postgres-odbcImagen del ODBC connection manager

El problema era que cuando estaban en entorno de desarrollo funcionaba todo fantástico, cuando pasaban a producción la conección odbc no funcionaba, la cuestión concreta,  no podía encontrar el DSN. Después de chequear varias veces en el odbc connection manager de windows, el DSN estaba registrado y funcionaba perfecto.

Dimos varias vueltas hasta encontrar el problema, dado que en desarrollo utilizaban windows para 32bits y en producción utilizaban windows para 64bits, en las versiones de 64bits windows posee dos versiones del odbc connection manager las cuales no comparten los mismos datos.  Como el interprete de PHP era para 32 bits utilizaba los datos registrados mediante el odbc connection manager de 32bits, por el panel de control solo se puede acceder a la versión de 64bits, por ende nuestras configuraciones solo funcionaban para 64bits.

Solución, bueno, muy sencilla, abrir el odbc connection manager para 32bits (C:\Windows\SysWOW64\odbcad32.exe), [OJO!, el de 64 también dice 32 pero esta en otro directorio, tienen que abrir este] y configurar la conexiones nuevamente. Después de eso funcionara todo perfecto.

Nuevamente, lo único que puedo decir, gracias M$ por los servicios ofrecidos 😛

Share