HipHopを実行するには(和訳)
こちらはHipHopの利用法のドキュメントの和訳です。
- PHPをC++に変換して高速化する「HipHop for PHP」をFacebookが公開
- HipHopのビルドとインストール方法(和訳)
- HipHopを実行するには(和訳)
原文
http://wiki.github.com/facebook/hiphop-php/running-hiphop
HipHopを実行するには
注:これらのコード例では、HipHopコンパイラが完全に組み込まれていると仮定します。
環境設定
まず最初に、2つの環境変数の設定が必要です。
cd .. # into the root of the hphp checkout
export HPHP_HOME=`pwd`
export HPHP_LIB=`pwd`/bin
HipHopを実行するモードの選択
HipHopは5つの異なるモードで実行することができます。これらはHello Worldの例をそれぞれ示しています。すべてのコマンドはこれらの例では、src /ディレクトリから実行されます。
まず、test.phpをと呼ばれるファイルを作成します。テキストを下記のように流し込むなら、"echo Hello World!> test.php"のような感じです。次に、以下のようにモードを選択します:
モード1:HipHopでコンパイルし、直接実行する。
hphp/hphp test.php
モード2:HipHopで一時ディレクトリにコンパイルし、コマンドラインからコンパイルしたプログラムを実行する。
hphp/hphp test.php --keep-tempdir=1 --log=3
/tmp/hphp_p6vSsP/program (use your own temporary directory name from output)
--keep-tempdir=1
も-k 1
で指定することができます。ハイフン一つとkのあとにスペースが空いている事に注意してください。これは、boostのコマンドラインオプションでの作業を監視するものです。
--log=3
いくつかの冗長な情報の出力。どの一時ディレクトリが作成されたかを見つけることができる。--output-dir=mypath
または-o mypath
で独自の出力ディレクトリを指定することができます。
モード3:HipHopで一時ディレクトリにコンパイルし、Webサーバーとしてコンパイルしたプログラムを実行する。
hphp/hphp test.php --keep-tempdir=1 --log=3
sudo /tmp/hphp_p6vSsP/program -m server
その後、別のウィンドウから実行:
curl localhost/test.php
sudoを使用しない場合は、ポート8080上でHipHopを実行することができます。
hphp/hphp test.php --keep-tempdir=1 --log=3
/tmp/hphp_p6vSsP/program -m server -p 8080
GET http://localhost:8080/test.php
あなたのサーバーを管理するにはこのコマンドを実行:
GET http://localhost:8088
また、デーモンとしてサーバを実行することができます:
sudo /tmp/hphp_p6vSsP/program -m daemon
モード4:HipHopインタプリタで直接実行する。
hphpi/hphpi -f test.php (note the "-f" flag)
モード5:HipHopインタプリタを逐次変換Webサーバかデーモンとして起動する。
sudo hphpi/hphpi -m server (or daemon)
curl localhost/test.php
curl localhost:8088
大きなコードベースのコンパイル
まずコンパイラの様々なスイッチを理解しましょう:
hphp/hphp --help
いくつかのフラグを指定する方法が3つあります。 (1)HDF形式の設定ファイル。hdf形式の詳細については doc/hdf をお読みください。次に、--config
で、使用する設定ファイルを指定します。(2)HDFファイル内のほぼすべてのオプションは、直接ドット表記形式で列挙することができます。たとえば-v "node.subnode=value"
のように。(3)我々は、最も頻繁に使用されるものをいくつかのショートカットを作成しました。このようになります--force
。
最も重要なフラグはインクルードまたは除外するファイルやディレクトリを指定するものです。これらはきれいに設計されていないので、今後改善する必要があると感じています。疑問がある場合は、単にファイル名のリストを別のファイルに準備して--input-list
のスイッチを使用します。
オンデマンド解析モード使用する(オプション)
コマンドラインから指定されていないファイルは、コンパイラがそれらを見つける事が出来る場合のみ 、インクルードされます。あなたの書いたinclude文下記のように扱われる事になります:
- 単純なリテラルの結合、コンパイラはコンパイル時にそれを計算することができます。
"include_once $MY_ROOT.'/path/file.php';"
のような単純な形式で記述
注:ここでいう、$ MY_ROOTはこのような内容の設定ファイルを作成する事でコンパイラに指示することができます:
IncludeRoots {
* {
root = $MY_ROOT
path = lib/my_code
}
* {
root = $ANOTHER_ROOT
path = anotherlib
}
}
この設定ファイルを含むように--config
を使用する 。コンパイラは、上記のinclude文を"lib / my_code/path/file.php"として解決します。
注:オンデマンドモードを設定することが困難な場合、すべてのコンパイルしたいPHPファイル含めるように--input-list
を使用してください。
distccの使用
大規模なコンパイルについては、我々はdistccのセットアップをお勧めします。
例:PHPUnitのコンパイル
1. PHPUnitの PHPファイルをチェックアウトする:
git clone git://github.com/sebastianbergmann/phpunit.git
cd phpunit
git checkout -b 3.4 origin/3.4
2.確実かつ安全な方法として入力ファイルを指定します。
find . -name "*.php" > files.list
これはコンパイルしたいすべてPHPファイルのリストです。
3.プロジェクトをコンパイルする準備が整いました。
$HPHP_HOME/src/hphp/hphp --input-list=files.list -k 1 --log=3 \
--include-path="." --force=1 --cluster-count=50 \
-v "AllDynamic=true" -v "AllVolatile=true"
-k 1
または--keep-tempdir=1
で、新しい一時的なディレクトリが毎回作成されます。この方法はコンパイルを試している時に便利です。
PHPUnitはPHPUnitのルートディレクトリから相対的にインクルードを行っているので、--include-path
が必要です。このオプションを指定しない場合、すべてのこのような形式 "include 'somepath/file.php';" はそれを含むファイルからの相対パスとして扱われます。
HipHopがコードに発見した警告やエラーを無視するには--force=1
が必要です。このオプションがなければ、コンパイラはエラーがあれば画面上にダンプして停止します。--force=1
を使った場合、これらのエラーのほとんどは実行時エラーでしょう。この場合もあなたはまだ出力ディレクトリの下に生成された CodeError.js でそれらを確認できます。
--cluster-count=50
distcc無しでのコンパイルに役立ちます。このフラグがなければ、それぞれのPHPファイルに対してcppファイルが1つ生成されます。PHPファイルの数が多い場合、cppファイルのコンパイルがToo Manyで終わる可能性があります。clusteringを使えばPHPファイルの数は重要ではありません。HipHopは指定された数の.cppファイルを生成し、より簡単にdistccに少ない回数でこれを渡す事ができます。クラスタの数はdistccのワーカー数より少し少ないくらいにすべきです。例えば20台のマシンで8つずつのdistccワーカーを動かしている場合はクラスタ数は100がよいでしょう。しかし、ある種の最適値を見つけるにはコンパイル時間を比較しながらにクラスタ数を上げたり下げたりしてください。
-v "AllDynamic=true"
このオプションにより 、動的な関数や、動的メソッド呼び出しを問題なくサポートすることができます。コーディング中に動的関数呼び出しや動的メソッド呼び出しをしている場合はオンを推奨します。少しパフォーマンスが犠牲になりますが、それが安全です。
-v "AllVolatile=true"
このオプションにより、関数やクラスの動的な宣言を問題なくサポートすることができます。function_exists()
やclass_exits()
を宣言の前後で実行したり、その順序に意味があるような異常なテストを実行しない限りはオンにすることを推奨します。PHPUnitは、いくつかのクラスファイルをロードした後、新しいクラスを見つけるためその戻り値を比較する為にget_declared_classes()
を呼び出すことがあります。したがって、PHPUnitにはこのスイッチを追加する必要があります。ほとんどの場合は、オンにする必要はありません。これは、パフォーマンスが場合によって犠牲になります。
4.これでコンパイルされたPHPUnitのバイナリができたはずです。もしここまで到達することはできない場合は、私たちに報告してください。バイナリを実行するには、
php phpunit.php (in PHP)
/tmp/hphp_po33pK/program -f phpunit.php (in HipHop, note the -f flag)php phpunit.php PHPUnit/Tests/Framework/SuiteTest.php
/tmp/hphp_po33pK/program -v "Server.SourceRoot=`pwd`" \
-f phpunit.php PHPUnit/Tests/Framework/SuiteTest.php
コンパイルされたバイナリの"プログラム"は、通常phpunit.php
と同じディレクトリから実行するよう注意してください。PHPUnitは、ローカルディスクから.phpファイルを探す際にfile_exists()
を使っているからです。より高度な設定をし静的ファイルキャッシュを構築することで、ディスク上の場所の依存関係を削除する事もできます。
注意-v "Server.
SourceRoot=`pwd`"
は、通常は必要ありません。しかし、PHPUnitのかなりの数のファイル操作はいくつかのファイルの場所に基づく、ローカルディスク上にへのrealpath()
を呼び出しています。だから我々はテストを実行する場合にこれを追加する必要がありました。
5.いくつかの役に立つヒント:
(1)--keep-tempdir=1
でバイナリを作ったが、その名前を忘れてしまった場合は、単純なコマンドは、通常それを見つけることができます。
ls -altrd /tmp/hphp_* | tail -1
(2)多くの一時的なディレクトリがディスク容量を使い切る事があります。全てのHipHopの一時ファイルはこのよう削除できます。
rm -fR /tmp/hphp_*
例:HPHPiの下でPHPUnitの実行
$HPHP_HOME/src/hphpi/hphpi -f phpunit.php
$HPHP_HOME/src/hphpi/hphpi -f phpunit.php PHPUnit/Tests/Framework/SuiteTest.php
海平:私たちは、すべてのSuiteTest.php渡すことができますが、我々は、我々はまだ完全に、PHPUnitのいくつかのローカルディスク上の推定といくつかのマイナーなバグをのために、PHPUnit/Tests/Frameworkの下で完全にパスすることはできていません。全ての問題を修正する為に今もデバッグ中です。
例:WordPressのコンパイル
1.WordPressのコピーを取得します。注意、私たちはHipHopでWordPressをコンパイルする前に修正する必要がある2つ、3つの問題を見つけました。これらは、WordpressのSVNのトランクにも反映されていますがバックポートはされていません。
wget http://wordpress.org/latest.tar.gz
tar zxvf wordpress-2.9.1.tar.gz
cd wordpress
[patch to fix some PHP coding problems that will cause compilation errors]
2.config.sample.phpをコピーするなどしてconfig.phpを作成し、データベース情報を設定します。このファイルは、 コンパイル前に準備しなければならないので、最終的なバイナリにされます。このファイルの変更がある場合はパッケージ全体の再コンパイルが必要です。
3.すべてのコンパイルしたいPHPファイルのリストを作成:
find . -name "*.php" > files.list
4.プロジェクトをコンパイルする準備が整いました。
$HPHP_HOME/src/hphp/hphp --input-list=files.list -k 1 --log=3 \
--force=1 --cluster-count=50
WordPressはPHPUnitほど動的なコーディングを持っていないためPHPUnitよりも簡単です。
5.コンパイル済みのバイナリが出来たはずです。それを実行するには
sudo /tmp/hphp_xpl7hT/program -m server -v "Server.SourceRoot=`pwd`" \
-v "Server.DefaultDocument=index.php" -c $HPHP_HOME/bin/mime.hdf
sudo
WordPressがそのポートのみで動作するのでポート80にListenする為に必要です。
-m server
サーバーモードでプログラムを実行します-m daemon
としても大丈夫です。
-v "Server.SourceRoot=`pwd`"
画像やcssファイルを見つけるには、依然として必要です。
-v "Server.DefaultDocument=index.php"
http://server/ として動作する為に必要。
-c $HPHP_HOME/bin/mime.hdf
静的なコンテンツのファイル拡張子に応じて異なる MIMEヘッダを提供する必要とするサーバーではロードする必要がある。
冗長なログを参照するには、
-v "Log.Level=Verbose"
これはエラー、警告、情報よりも多く出力します。-v "Log.NoSilencer=on"
は、WordPressのコードで多く使用される@演算子でエラーを出力します 。-v "Log.Header=on"
ログの各行のヘッダに出力されます 。ほとんどのヘッダは16進数による長い文字列です。これは16進エンコードされたスタックトレースです。これを読めるように変換するには以下のコマンドを実行します。
/tmp/hphp_xpl7hT/program -m translate the-long-hex-string-without-brackets
--訳ここまで