facebook製PHP拡張XHPが面白い

XHP面白い。単なるcross-site scripting対策以上のものを感じるんだけどうまく魅力を説明できるかどうか。

XHPはfacebookが作ったPHPのextensionで、PHPコンパイラにフックすることによりソースコード内にXMLを書くことを可能にします。

XMLタグリテラルは、"xhp_{タグ名}"というクラスのインスタンスになります。このクラスはデフォルトで定義されているわけじゃないので、上記URLみたいな標準的な使い方をする場合は、ソースツリーのphp-lib/以下にあるphpファイルをrequireします。

<?php
//require 'php-lib/init.php';   これが必要
$a = <a href="http://d.hatena.ne.jp">はてな</a>;
echo $a . "\n";

実行:
Fatal error: Class 'xhp_a' not found in /path/to/TEST/xhp/t1.php on line 3

逆にいえば、このクラスを自分で定義したり、新たなタグを定義したりもできます。

<?php
require 'php-lib/init.php';
class :my:hello extends :x:element {
    function render() { return <b>Hello</b>; }
}
echo <a href="http://d.hatena.ne.jp"><my:hello /></a> . "\n";

実行:
<a href="http://d.hatena.ne.jp"><b>Hello</b></a>

Domっぽいアクセスとか

$a = <a href="http://d.hatena.ne.jp">はてな</a>;
var_dump($a->getAttribute("href"));

実行:
string(21) "http://d.hatena.ne.jp"

XMLリテラル内の{}には任意のPHPの式を書くことができます。エスケープやクオートは自動的に行なわれます。

for ($i = 0; $i < 5; $i++) {
    echo <span class={$i % 2 === 0 ? "even" : "odd"}>{$i}</span> . "\n";
}

実行:
<span class="even">0</span>
<span class="odd">1</span>
<span class="even">2</span>
<span class="odd">3</span>
<span class="even">4</span>

式展開はネストしてもいいみたい。

for ($i = 0; $i < 5; $i++) {
    echo <span>{
        $i % 2 === 0 ? $i : <b>{$i}</b>
    }</span> . "\n";
}

実行:
<span>0</span>
<span><b>1</b></span>
<span>2</span>
<span><b>3</b></span>
<span>4</span>

あとおまけで、php.iniでxhp.idx_expr = 1としておくと、foo()[1]みたいなのが書けるようになるので不意にPHPを改造したくなったときも安心です。compiler_hook祭りとかおこんないかな。

function foo() { return array(1, 10, 100); }
echo foo()[1] . "\n";