Oracle y PHP5 (y van tres)
Recientemente me ha tocado reinstalar un servidor donde tenía que montar una aplicación que usa el cambalache que monté anteriormente con el módulo pdo_oci.
He podido descubrir que esta no es la manera más sencillo ni correcta de hacerlo. Resulta que desde Oracle nos dicen que nos olvidemos de pdo_oci y que usemos oci8. Recomiento la lectura de: Underground PHP and Oracle Manual
Pues bien, a ello me he lanzado y ha sido sorprendente la facilidad con la que se puede instalar el soporte de oracle si lo haces con el módulo oci8. Los pasos a seguir son los siguientes:
- Descargar las librerías “Basic” y “SDK” del Instant Client de Oracle. Esta vez podremos usar el último que hayan sacado. Yo lo he hecho con la versión 11.1 y funciona de maravilla. Podéis descargarlo todo aquí: http://www.oracle.com/technology/software/tech/oci/instantclient/index.html
- Crea el directorio /opt/oracle/instantclient, mueve los zips allí y descomprímelos. Creará un directorio /opt/oracle/instantclient/instantclient_11_1
- Instala, si no lo has hecho ya, los paquetes php-pear, php5-dev y build-essential
- Ejecuta “pecl install oci8” con privilegios de root (sudo o lo que más te apetezca)
- Te preguntará por la ruta a las librerías. Debes configurar la ruta para que apunte al directorio recién creado y pasarle algún parámetro más, por lo que deberías escribir “shared,instanclient,/opt/oracle/instantclient/instantclient_11_1” (sin las comillas, claro)
- Después de hacer sus cosillas, el instalador te habrá dejado en /usr/lib/php5/20060613+lfs un fichero llamado oci8.so. Ahora tienes que decirle a PHP5 que lo tenga en cuenta escribiendo al final de los ficheros “php.ini” que tengas la línea “extension=oci8.so“. Los ficheros “php.ini” están en /etc/php5/cli y /etc/php5/apache
Solo tienes que tener una cosa más en cuenta: Asegúrate de que el usuario www-data puede acceder a la ruta /opt/oracle… porque si no, verás un mensaje de error como este:
PHP Warning: PHP Startup: Unable to load dynamic library ‘/usr/lib/php5/20060613+lfs/oci8.so’ – libaio.so.1: cannot open shared object file: No such file or directory in Unknown on line 0
Además, si vas a ejecutar scripts con tu usuario de sistema, tu también tendrás que tener acceso al directorio.
Nada más :)
En el próximo post pondré como configurar Symfony para que utilice las funciones de oci8 en vez de las de pdo_oci.
Atención spoilerazo de Lost muy gordo sobre la temporada 6!!
Estáis avisados.
Antes de nada los antecedentes:
Promo de la Season 6 – Atención segundo 0:11
Resumen del S01E01 (Piloto de Lost) – Atención segundo 0:07
Ahora un detalle del ojo extraido de ambos vídeos:
Promo Season 6:

Primer capítulo, Season 1

He corregido la escala del ojo y los he puesto juntos usando Photoshop. Este es el resultado:
Conclusión:
Cada pestaña en su sitio, la textura de la piel idéntica, lagrimal exactamente igual, la imagen reflejada en el ojo es la misma. No solo se trata de Jack, sino que me aventuro a afirmar que se trata de una imagen extraida de la misma sesión de rodaje, si no la misma de la primera escena del primer capítulo de la serie, solo que con mayor iluminación y ligeramente distinto encuadre.
Generar PDF dinámicos
En la empresa en la que trabajo tenemos un catálogo de más de 1000 productos vendibles que tienen su descripción, fotos, especificaciones, etc. Toda esta información está almacenada en bases de datos, hojas de cálculo y demás soportes y hasta ahora el proceso de generación de las fichas comerciales de los productos era realizada a mano por una persona del departamento de diseño.
Pues bien, ya que la información está disponible desde varias fuentes a las que se puede acceder por medio de un script PHP, me han encargado la tarea de automatizar el proceso.
Librerías de generación de PDFs en PHP
En la búsqueda de librerías de generación de PDFs dinámicos he encontrado las siguientes opciones:
Se trata de una librería de pago con bindeos para muchos lenguajes de programación que permite componer los PDFs objeto a objeto. Está perfectamente integrada en PHP y ofrece dos versiones, dependiendo de si trabajamos con PHP4 o PHP5 orientado a objetos.
También tiene una versión PDFLib Lite que es gratuita y tiene casi todo lo necesario.
Esta es una versión libre, más limitada y lenta que la anterior. En este caso no podremos utilizar las funciones incorporadas en PHP sino que usaremos métodos de una clase desarrollada “a pelo” para generar nuestros PDFs. Sin embargo, la filosofía detrás de esta librería es la misma que en PDFLib.
Igual que la anterior, pero parece aun más limitada.
Esta librería es un wrapper que utilizará como backend de generación PDFLib, R&OS CPDF o GD para contruir los PDFs. Es un misterio para mi cómo hacen para generar PDFs con GD, pero sospecho que generan una “foto” de cada página y se lo enchufan a un fichero con formato PDF de alguna manera.
Conclusión
Si no me quedara más remedio que construir a mano los PDFs en PHP seguramente usaría DOMPDF o PDFLib Lite. Sin embargo, creo que la mejor opción es la que voy a describir a continuación:
SVG: La alternativa que gusta a pequeños y mayores
SVG: Scalable Vector Graphics. Se trata de un lenguage de marcado creado por la W3C para contener dibujos vectoriales. Se supone que será uno de los standards para ficheros de dibujo vectorial más usados en los próximos años.
La estructura de un SVG es la de un XML. Cada etiqueta define propiedades del documento y objetos como bloques de texto, párrafos, imágenes, formas, etc.
Este formato gustará a todos y todas porque las personas responsables del diseño podrán utilizar magnificas aplicaciones de diseño vectorial como Inkscape en las que podrán dar rienda suelta a su creatividad y nosotros, los encargados de rellenar de contenido sus diseños, podremos utilizar sencillas funciones de reemplazo de texto para tratar el contenido XML del fichero SVG y “producir” un documento final. El programador más habilidoso podrá incluso utilizar sus funciones preferidas de modificación del árbol DOM de XML para trabajar con el documento e incluso crear objetos on-the-fly.
Una vez creado un SVG final, podemos usar una infinidad de aplicaciones para convertir el SVG en PDF (o en el formato que nos dé literalmente la gana). El propio Inkscape permite ser ejecutado en línea de comandos y de la siguiente manera conseguiremos un radiante PDF:
$ inkscape -A documento.pdf documento.svg
Para más info hacer un ‘man inkscape’. El programa permite definir parámetros de exportación de las imágenes del documento para definir sus DPIs, por ejemplo.
Propel 1.3 ya puede inspeccionar Oracle
Gracias a unos cambios en Propel 1.3 en los que he estado currando por necesidad, he podido contribuir al magnífico proyecto Propel y me han hecho comitter en su SVN para temas de Oracle, a pesar de que soy un novato en el área.
A partir de ahora, si necesitáis trabajar contra Oracle con Propel, podréis realizar tareas de ingeniería inversa para generar el modelo a partir de una base de datos viva con los cambios del changeset 1107 de la versión 1.3 de Propel (http://propel.phpdb.org/trac/changeset/1107).
Huelga decir que supone un gran honor para mi el poder realizar esta aportación y que estoy muy contento por ello.
Si encontráis cualquier problema avisad!
Symfony 1.2 + Propel 1.3 + Oracle (Parte 2)
Ahora que ya tenemos el módulo PDO_OCI funcionando, podemos intentar hacer una prueba en Symfony 1.2 con Propel 1.3. Después de dar muchas vueltas, he llegado a la conclusión de que el formato para databases.yml es el siguiente:
all:propel:
class: sfPropelDatabase
param:
classname: PropelPDO
phptype: oracle
dsn: oci:dbname=//%IP_DEL_SERVIDOR%:%PUERTO_DEL_SERVIDOR%/%BASE_DE_DATOS%
username: %USUARIO%
password: %CONTRASEÑA%
encoding: utf8
persistent: true
pooling: true
(No consigo que el maldito WordPress indente correctamente el código anterior así que recuerda que la jerarquía es: all >> propel >> param >> resto)
El formato de propel.ini sería el siguiente:
propel.database = oraclepropel.database.driver = oracle
propel.database.url = oci:
dbname=//%IP_DEL_SERVIDOR%:%PUERTO_DEL_SERVIDOR%/%BASE_DE_DATOS%
propel.database.creole.url = ${propel.database.url}propel.database.user =
%USUARIO%
propel.database.password =%CONTRASEÑA%
propel.database.encoding = utf8
Lo último que necesitas para que la ingeniería inversa funcione es un parseador de estructura de base de datos para bases de datos de Oracle. Propel 1.3 no trae uno, así que puedes usar el que un servidor ha preparado convenientemente: Oracle Schema Parser (PHP5 script) (Bórrale la extensión “doc” y déjalo en un directorio “lib/plugins/sfPropelPlugin/lib/vendor/propel-generator/classes/propel/engine/database/reverse/oracle” nuevo que tienes que crear en la instalación de Symfony).
Con esto y un bizcocho, ya deberías ser capaz de ejecutar la tarea “propel:build-schema” :)
Symfony 1.2 + Propel 1.3 + Oracle
Después de intentar poner el marcha la extensión de PHP5 de PDO_OCI durante dos días, hoy al fin lo he conseguido.
No hay apenas documentación y para más inri, la poca que hay mezcla versiones incompatibles entre si. Ha sido una auténtica aventura ponerlo en marcha.
La configuración del servidor es la siguiente:
- Ubuntu Server 8.10 x86 sobre VMWare
- PHP5 (la versión del repositorio de Ubuntu)
Parte 1: Instalar el driver OCI (oracle) de PDO
Antes de nada debes saber que vas a tener que instalar la extensión PDO y PDO_OCI a mano. Por un lado, la de PDO_OCI no tiene candidatos y si la compilas a mano, resulta que es incompatible con el API de PDO que te instala el repositorio de ubuntu, por lo que al final, la mejor solución es compilar a mano ambas, a partir del repositorio de fuentes de PEAR.
Para instalar PDO solo hay que hacer un “sudo pecl install pdo”. Asegúrate de tener instalado el paquete php-pear y el php5-dev porque si no no podrás hacer esto.
Despues de hacerlo, habrás reemplazado la extensión PDO que te viene al hacer un “apt-get install php5″ por el de PEAR.
Ahora viene la parte divertida: instalar en el sistema la extensión PDO_OCI. Para ello debes instalar dos cositas de nuestro gran amigo Oracle (http://www.oracle.com/technology/software/tech/oci/instantclient/index.html):
- Oracle Instant Client (library)
- Oracle Instant Client (SDK)
Lamentablemente, solo podrás utilizar las versiones inferiores a la 11 (de la 10.2.0.4 para abajo).
Luego descomprime la librería en /usr/lib/oracle/10.2.0.4/client/lib y el sdk en /usr/include/oracle/10.2.0.4/client
Luego dile al sistema que añada estas rutas con el comando ldconfig y corriges un par de nombres de ficheros:
sudo ldconfig /usr/lib/oracle/10.2.0.4/client/lib
sudo ldconfig /usr/include/oracle/10.2.0.4/client
sudo ln -s /usr/lib/oracle/10.2.0.4/client/lib/libclntsh.so.10.1 /usr/lib/oracle/10.2.0.4/client/lib/libclntsh.so
sudo ln -s /usr/lib/oracle/10.2.0.4/client/lib/libocci.so.10.1 /usr/lib/oracle/10.2.0.4/client/lib/libocci.so
Ahora vamos a descargar las fuentes de PDO_OCI, compilarlas e instalarlas en el sistema:
sudo mkdir /usr/src/pdo_oci
cd /usr/src/pdo_oci
sudo pecl download pdo_oci
sudo tar -zxvf PDO_OCI-1.0.tgz
cd PDO_OCI-1.0
sudo phpize5
sudo ./configure –prefix=/usr –with-pdo-oci=/usr/lib/oracle/10.2.0.4/client
* editar Makefile *
sudo make
sudo make install
Al editar Makefile debéis añadir la ruta a /usr/include/oracle/10.2.0.4/client/include en la directiva “INCLUDES”
Después de esto ya tendréis la extensión instalada en vuestro sistema. Sólo hay que editar /etc/php5/conf.d/pdo.ini y añadir:
extension=pdo_oci.so
Ale, a disfrutar! En el siguiente post explicaré como hacer que todo esto funcione con Propel 1.3 y Symfony, pero antes tengo que averiguar cómo coño se hace T_T.