おぎろぐはてブロ

なんだかんだエンジニアになって10年以上

FacebookのXHPを導入してみた

XHPとは、

Today, I'd like to take to this opportunity to share with you a project that's quickly becoming a cornerstone of front-end PHP development at Facebook. XHP is a PHP extension which augments the syntax of the language to both make your front-end code easier to understand and help you avoid cross-site scripting attacks.

XHP: A New Way to Write PHP | Facebook

ということで、フロントエンドのコードを書きやすく理解しやすいものにし、また、XSS攻撃を避けられるようなPHPの文法を増やすExtensionです。
具体的にどう変わるのかというと、これは普通のPHPのコード。

<?php
if ($_POST['name']) {
?>
    <span>Hello, <?=$_POST['name']?>.</span>
<?php 
} else {
?>
    <form method="post">
    What is your name?<br>
    <input type="text" name="name">
    <input type="submit">
    </form>
<?php
}

フロントエンドのコードは、HTMLとPHPが混在するため、このように <?php 〜 ?> のブロックが度々現れて、HTML自体のタグ文字も混ざり合って気持ち悪い感じです。と、入門書に思いっきり出てきそうな <?=$_POST['name']?> というXSS脆弱性のあるコードが含まれています。ここは、htmlspecialchars()の関数を通すべきでしょう。(それだと漏れがあるので、フレームワークやテンプレートエンジンの機能や、PHPインプットフィルタ機能で、デフォルトでタグ文字をきちんと処理するのがベター)

上のコードをXHPで書き直すとこうなります。

<?php
// note: includes omitted
if ($_POST['name']) {
  echo <span>Hello, {$_POST['name']}</span>;
} else {
  echo
    <form method="post">
      What is your name?<br />
      <input type="text" name="name" />
      <input type="submit" />
    </form>;
}

パっと見ても違いがわかりにくいですが、HTMLタグが、" とかで囲まれることなくechoされているのが分かるかと思います。普通に変数展開もされます。なんというか、E4Xっぽい。

  echo <span>Hello, {$_POST['name']}</span>;

要は、< から始まると、HTML文字列だと取り扱うような文法です。また、このコンテキストの中で、$_POSTを参照すると、自動でエスケープする仕様で、XSSも防ぐことができます。
詳しいことは記事参照

Macに導入してみる

とりあえず入れてみましょう。
動作環境は、

  • PHP 5.2.x or 5.3.x
  • gcc 4.0以上

です。
自分の環境では、加えてre2cが必要でした。Mac Portsで、port install re2cでおk。

ダウンロード、展開

ソースコードgithubで公開されているので、以下からアーカイブをダウンロードします。

解凍すると、こんなディレクトリ構成

INSTALL
LICENSE.PHP
LICENSE.ZEND
Makefile.frag
config.m4
ext.cpp
ext.hpp
php-lib/
tests/
xhp/
ビルド

ふつうに、phpize, ./configure, make

$ phpize
Configuring for:
PHP Api Version:         20090626
Zend Module Api No:      20090626
Zend Extension Api No:   220090626

./configure
...

make
----------------------------------------------------------------------
Libraries have been installed in:
   /Users/iogiwara/work/20100210xhp/facebook-xhp-db1e173/modules

If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the `-LLIBDIR'
flag during linking and do at least one of the following:
   - add LIBDIR to the `DYLD_LIBRARY_PATH' environment variable
     during execution

See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------

Build complete.
Don't forget to run 'make test'.

うまくmakeできたら

sudo make install

で、extension_dirにインストールされます。

動作確認

インストールマニュアルに書いてある

php -r 'echo "XHP!\n"; exit; <a />;'

で確認してみます。
普通に実行すると、

Parse error: syntax error, unexpected '<' in Command line code on line 1

とSyntax Errorが出ますが、php.iniに extension=xhp.so と書くか、起動オプションで -dextension=xhp.so を指定するかして、

php -dextension=xhp.so -r 'echo "XHP!\n"; exit; <a />;'
XHP!

と、成功すればOK。