HHVM で FuelPHP が素直には動かなかった

Vagrant 1.7.4 で Ubuntu 14.04.3 (64-bit) に HHVM 3.10.1 を入れてある。 nginx 1.8.0 と FuelPHP 1.7 の組み合わせ。

Nginx の設定

default.conf の削除

/etc/nginx/conf.d/default.conf を削除して、余計な設定を消す。

sudo rm /etc/nginx/conf.d/default.conf

別に /etc/nginx/nginx.conf に書かれてる include /etc/nginx/conf.d/*.conf; から外れさえすれば何でもいいので、適当なリネームでも構わない。

hogefuga.conf の作成

/etc/nginx/conf.d/hogefuga.conf を以下の内容で作成する。

sudo vi /etc/nginx/conf.d/hogefuga.conf
server {
        listen 80;
        server_name _;
        root /home/vagrant/hogefuga/public;
        index index.php;
    
        include hhvm.conf;
}

これもファイル名は別に hogefuga じゃなくても何でもいい。

root には Fuel プロジェクトの public ディレクトリを指定すること。 ここでは vagrant 氏のホームディレクトリに hogefuga プロジェクトを clone してあるのでこうなった。

Nginx 再起動

sudo service nginx restart

HHVM 起動

sudo service hhvm restart

自動起動の設定

# update-rc.d hhvm defaults 
 Adding system startup for /etc/init.d/hhvm ...
   /etc/rc0.d/K20hhvm -> ../init.d/hhvm
   /etc/rc1.d/K20hhvm -> ../init.d/hhvm
   /etc/rc6.d/K20hhvm -> ../init.d/hhvm
   /etc/rc2.d/S20hhvm -> ../init.d/hhvm
   /etc/rc3.d/S20hhvm -> ../init.d/hhvm
   /etc/rc4.d/S20hhvm -> ../init.d/hhvm
   /etc/rc5.d/S20hhvm -> ../init.d/hhvm

Vagrant の設定

Vagrantfile で private network の設定

Vagrantfile 内の良き場所に次の一行を放り込む。

config.vm.network "private_network", ip: "192.168.33.10"

Vagrant に設定を反映させる。

vagrant reload

Fuel core の編集…

ここまでの作業で Mac のブラウザから 192.168.33.10 を開いて Fuel に繋がるようになったが、謎 Notice が表示された。しかもブラウザでリロードすると 2 回目以降は HHVM が落ちたのか Bad Gateway になる。

Notice!

Fuel\Core\PhpErrorException [ Notice ]:
Array to string conversion

COREPATH/classes/view.php @ line 230

やりたくないけど、とりあえず以下のように編集することで回避可能…。

vi /home/vagrant/hogefuga/fuel/core/classes/view.php
diff --git a/classes/view.php b/classes/view.php
index d5ed071..5f98ed3 100644
--- a/classes/view.php
+++ b/classes/view.php
@@ -227,7 +227,8 @@ class View
        {
                $clean_room = function($__file_name, array $__data)
                {
-                       extract($__data, EXTR_REFS);
+                       //extract($__data, EXTR_REFS);
+                       extract($__data);
 
                        // Capture the view output
                        ob_start();

何のエラーなんだ…

どうも extract($__data, EXTR_REFS) の部分で $__data に空配列が来ると hhvm では扱えないっぽい。試しにこんなコードを php で動かすと何ごともなく正常終了するけど、 hhvm で動かすと異常終了する。

<?php
extract([], EXTR_REFS);

EXTR_REFS をつけなければ動くしこのオプションがまずいらしい

EXTR_REFS 変数を参照として展開します。 これはインポート済みの変数が、 array パラメータの値に常に参照付けられることを意味します。 このフラグを単独で使用するか、 あるいはflagsと和算することにより、 他のフラグとそれを組み合わせることができます。 http://php.net/manual/ja/function.extract.php

とりあえずメモリ節約くらいの意味しかないのかなという気がしたので、よくわかっていないのにこのオプションを外して対応してしまった。

素の hhvm では何もわからないけど、 sudo apt-get install hhvm-dbg *1 してから実行すると empty-array.cpp:60 *2 で死んでるらしいことがわかる。

$ hhvm test.php 
hhvm: /tmp/tmp.37b2AKSInv/hphp/runtime/base/empty-array.cpp:60: static void HPHP::EmptyArray::NvGetKey(const HPHP::ArrayData*, HPHP::TypedValue*, ssize_t): Assertion `false' failed.
Core dumped: Aborted
Stack trace in /tmp/stacktrace.2318.log
Aborted (core dumped)
$ 
$ hhvm --version
HipHop VM 3.10.1 (dbg)
Compiler: tags/HHVM-3.10.1-0-g689b4969a141620ee5a282ce0dbf72278c84d44b
Repo schema: 6c99ee1f98340f6f3ef397a332583f0e843a627d

そこまで compatible にするつもりがあるかどうかわからないけど、プルリクチャンスかもしれない。

fork して回避版 core を用意し composer でそこを見る…

このやり方がいいのかわからないけど、 Fuel core を fork して、この回避版を用意し、 composer.json でそこを参照させることにした…。 https://github.com/yonexyonex/core/tree/1.7/master

vi composer.json
diff --git a/composer.json b/composer.json
index 3fa09b0..b33ca4e 100644
--- a/composer.json
+++ b/composer.json
@@ -6,7 +6,7 @@
     "license": "MIT",
     "repositories": [
         { "type": "vcs", "url": "https://github.com/fuel/docs" },
-        { "type": "vcs", "url": "https://github.com/fuel/core" },
+        { "type": "vcs", "url": "https://github.com/yonexyonex/core" },
         { "type": "vcs", "url": "https://github.com/fuel/auth" },
         { "type": "vcs", "url": "https://github.com/fuel/email" },
         { "type": "vcs", "url": "https://github.com/fuel/oil" },

既に composer install を実行してたので update した。それなりに時間かかる

./composer.phar update

そして、 hhvm が死んでたので再起動した

sudo service hhvm restart

おわり

以上。 Mac のブラウザで 192.168.33.10 を開けば Fuel の Welcome 画面を拝めた。

感想

Hack と FuelPHP の組み合わせは採用例もあるのにこんな最初でつまずいたのでおかしいな、という感想だった。

Hack言語に賭けたチームの話 http://www.slideshare.net/yujiotani16/hack-53487378

Hack+FuelPHPによるWebサービス開発 http://www.slideshare.net/yujiotani16/hikalab-hack

HHVM のフレームワークテスト結果一覧になぜか FuelPHP が(現時点では)載ってないのでそもそもまだ自信ないのかも。

HHVM http://hhvm.com/frameworks/