經過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或者評論一下。

相關文章
相關標籤/搜索