V8: Extendiendo PHP

Hace prácticamente un año escribí un artículo denominado Spidermonkey: extendiendo PHP, donde comentaba como emplear Spidermonkey para poder emplearlo como lenguaje de extensión a un núcleo sencillo hecho en PHP.

Incluso lo emplee como elemento principal en el desarrollo de PHAS-JS, realizando un servidor de aplicaciones en PHP, con la potencia que brindan muchas de sus librerías, pero escribiendo código de forma segura en JavaScript (o ECMAScript).

Hoy voy a tratar otra máquina que permite ejecutar código JavaScript dentro de PHP, de la misma forma que cuando vimos Spidermonkey, pero variando la forma en la que interactúa con PHP. En esta ocasión tenemos entre nosotros la máquina: el V8 de Google. Va a estar un poco inspirado en lo que he ido comentando con Sergio, que he visto que ha escrito también al respecto en su blog: PHP y JavaScript se entienden.

Instalando

Lo primero, es que si tenemos como paquete el libv8-dev, todo será más fácil ya que se resume en estos sencillos pasos (esto es válido para Debian y Ubuntu):

apt-get install libv8-dev
pecl install v8js

Esta es una de las implementaciones de V8 que hay para PHP, también está disponible V8 (a secas) que es un módulo que intenta imitar la implementación de Spidermonkey, con lo que, si tienes un código que emplee el sistema de spidermonkey, pasar a v8 debe de ser cambiar muy poquitas cosas. No obstante este código está marcado como experimental y hay cosas que no funcionan del todo. La instanación sería:

apt-get install libv8-dev
git clone https://github.com/metagoto/v8.git
cd v8 && phpize && ./configure && make && make install

La configuración es compatible si instalamos los dos, ya que es:

extension=v8js.so
extension=v8.so

Actualización: escribí un email a metagoto sobre el mantenimiento y mejora del módulo v8 para PHP. La respuesta fue que esa implementación la realizó para poder jugar y ver cómo se comportaba el sistema v8, y que no le pudo dedicar mucho tiempo, es más, abandonó el desarrollo y no tiene pensado retomarlo. Sobre el problema que observé del paso de objetos y que no pasaba sus métodos, parece que el problema no es trivial, por lo que, desecho la idea de tomarlo como una solución práctica y la dejo únicamente para pruebas y ensayos.

Probando…

En principio, podemos repetir la misma prueba que hicimos en el artículo de spidermonkey, a modo de poder enseñarlo de ambas formas. El código, por tanto sería así:

<?php
 
// crea la máquina para JavaScript
$js = new V8Js();
 
// define valores para el entorno JS
$js->a = 10;
$js->b = 2;
 
// define el código a ejecutar
$script = <<<END
  c = PHP.a + PHP.b;
END;
 
// evalua el script y muestra el resultado
echo "La suma de $a y $b es: " . $js->executeScript($script);

La pega que tiene este, en comparación con spidermonkey, es que las funciones solo se pueden pasar si son anónimas (como variables) y que la ejecución restringe o separa lo que se pasa desde PHP en un objeto específico, por lo que queda un poco engorroso (desde mi punto de vista).

Con el tema de los objetos pasa igual, se pueden pasar objetos, pero no clases, con lo que no se pueden realizar instancias nuevas, a menos que se emplee una función anónima que haga las veces de factory o singleton.

El código de v8, que intenta emular a spidermonkey facilita esto agregando registro de funciones, clases y variables en la parte global. No obstante, este código no es completamente funcional, ya que, en las pruebas realizadas, por ejemplo, no se tiene acceso a los métodos de las clases registradas cuando se crea un nuevo objeto dentro de V8.

Conclusiones

La máquina V8 ha demostrado ser un gran intérprete de JavaScript, ya que es la que emplea Google en el navegador Chorme, no obstante, su integración con PHP falta que madure un poco y se ajuste en usabilidad a algo similar a lo que se puede conseguir con Spidermonkey.