经过WebAssembly在浏览器运行PHP

clipboard.png

演示地址:PIB: PHP in Browser,你能够在上面运行PHP代码,而后经过复制地址栏分享代码。php

项目地址:oraoto/pibhtml

某天晚上,在看Emscripten的文档,发现Emscripten有emconfigureemmake,能够直接用Emscripten替换编译器实现项目移植,灵光一现就有了这个项目。前端

性能测试

首先娱乐测试一下,改自eechen的测试,10万的数组填充和字符串拼接:git

<?php

$start = microtime(true);

$arr = [];

for ($i = 0; $i < 100000; $i++) {
    $time = microtime(true);
    $arr[$i . '_' . $time] = $time;
}

echo (microtime(true) - $start) . PHP_EOL;

点我直接跑一下github

个人电脑CPU是i5-6400,Chrome 66耗时0.35秒,Firefox耗时0.25秒,而原生PHP 7.2只需0.048秒,也就是说性能大约是原生PHP 7.2的1/7左右。json

跑PHP源代码自带的Zend/bench.php数组

simple             0.288
simplecall         0.088
simpleucall        0.226
simpleudcall       0.241
mandel             1.138
mandel2            1.251
ackermann(7)       0.221
ary(50000)         0.037
ary2(50000)        0.033
ary3(2000)         0.626
fibo(30)           0.855
hash1(50000)       0.067
hash2(500)         0.084
heapsort(20000)    0.264
matrix(20)         0.285
nestedloop(12)     0.444
sieve(30)          0.178
strcat(200000)     0.043
------------------------
Total              6.369

而原生PHP 7.2只要0.591秒,差了近11倍。浏览器

功能测试

由于是直接编译PHP解析器,因此语言层面的大部分功能都是支持的,目前已知不支持的只有Generator(已支持)服务器

下面是一些PHP7的新特性:函数

库函数方面支持比较少,默认只编译了datepcrebcmathctypejsonReflectionSPLtokenizerstandardCore这些扩展。

实现原理

原理并不复杂,就是用Emscripten把PHP解释器编译到WebAssembly,而后经过JavaScript调用Zend的API。

为了能让PHP解释器编译成功,须要对代码作少许修改,主要是文件系统相关的两处代码,我只直接注释掉或者return跳过代码。

对比现有方案

3v4l这种在服务端执行代码而后返回结果到前端的方案已经很成熟,在运行和分享PHP代码方面,PIB的优点就是省去了我部署服务器的钱(文件都在Github pages)。

也有其余的在浏览器直接运行PHP的方案:

  • php2wasm直接把PHP代码编译成wasm,如今还不成熟
  • pyhp.js用Pyton实现PHP解释器(PyHP,据做者说性能比PHP7好),而后再把这个解释器编译到JS,支持的特性有限,做者已经弃坑

而PIB已经支持了大部分PHP语言特性,不过性能和稳定性仍需提升。

将来

一开始设想是用PHP进行前端开发的,可是实现不容易,因此先作成这个样子了。

若是要让PHP代码操做浏览器的DOM,必须写PHP扩展,使用Emscripten的API去调用JavaScript,这仍是能够作的。

而JavaScript不少接口都是须要回调的,Emscripten也是能够作到,可是只是回调到C/C++,若是要回调到PHP,就要本身实现协程方案,这我还作不了。

目前能够完善和尝试的:

  1. 语法检查
  2. 错误信息显示
  3. 减小代码体积
  4. 处理内存泄漏

若是你有什么有趣的想法,也不妨提个issue或者评论一下。

相关文章
相关标签/搜索