Sunday, 22 July 2012

Using V8 Javascript engine as a PHP extension (update: write PHP session)

"We Are Borg PHP. We Will Assimilate You. Resistance Is Futile!"
Just got to something described as: This extension embeds the V8 Javascript Engine into PHP.
It is called v8js and the documentation is already available on php.net, examples and the sources are here. V8 is known to work well in browsers and webservers like node.js, but does it work inside PHP? YES!

Here is the installation on Ubuntu 12.04:

sudo apt-get install php5-dev php-pear libv8-dev build-essential
sudo pecl install v8js
sudo echo extension=v8js.so >>/etc/php5/cli/php.ini
sudo echo extension=v8js.so >>/etc/php5/apache2/php.ini
php -m | grep v8

Let's run a small test script:

<?php
$start = microtime(true);
$array = array();
for ($i=0; $i<50000; $i++) $array[] = $i*2;

$array2 = array();
for ($i=20000; $i<21000; $i++) $array2[] = $i*2;

foreach ($array as $val) {
foreach ($array2 as $val2) if ($val == $val2) {}
}
echo (microtime(true)-$start)."\n"; // 8.60s


$start = microtime(true);
$v8 = new V8Js();
$JS = <<< EOT
var array = [];
for (i=0; i<50000; i++) array.push(i*2);

var array2 = [];
for (i=20000; i<21000; i++) array2.push(i*2);

for (key=0; key<array.length; key++) {
for (key2=0; key2<array2.length; key2++) if (array[key] == array2[key2]) {}
}
print('done.');
EOT;
$v8->executeString($JS, 'basic.js');
echo ' '.(microtime(true)-$start)."\n"; // 3.49s

Using Javascript – inside PHP – can make some operations at least 2 times faster.
Running the same Javascript code with node.js gives:

time node /tmp/test.js
real 0m0.729s
Since v8js is currently in beta status, we can expect even more performance coming with the next releases.

Here is an example using databases, sessions and request handling from PHP inside V8:

// v8js currently crashes with mysqli_result, so wrap it
class DB extends MySQLi {
public function query($sql) {
return parent::query($sql)->fetch_all(MYSQLI_ASSOC);
}
}

// v8js currently has no support for references or magic __set(), so wrap it
class Session {
public function set($key, $value) {
$_SESSION[$key] = $value;
}
public function __get($key) {
if (isset($_SESSION[$key])) return $_SESSION[$key];
return null;
}
public function toJSON() {
return $_SESSION;
}
}

session_start();
$js = new V8Js();
$js->db = new DB('localhost', 'root', '', 'mydb');
$js->session = new Session();
$js->request = $_REQUEST;

$js->executeString(<<<EOT
print( PHP.db.query('select * from some_table limit 1')[0].some_column );
print( PHP.request.hello );

print( JSON.stringify( PHP.session ) ); // calls toJSON
print( PHP.session.invalid ); // null
print( PHP.session.hello );
PHP.session.set('hello', 'world');
EOT
);

More coming soon: Javascript form validation on server side, Javascript template rendering on server side, APC-Cache

No comments:

Post a Comment