わぁいPhar、あかりPhar作るの大好き!
2012年はpharの年!嘘です!
みなさん、プログラムソースが1ファイルになってるの好きですか!
好きですよね!
http://www.google.co.jp/search?ie=UTF-8&q=phpspot+1%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB
ファイルの総行数が1万行超えても?
、、、ということで、PHPのためのアーカイブ形式pharについてです。
http://php.net/phar
ここ最近はpharとして提供されるものがいくつか出てきましたね!
- pyrus.phar
- imagine.phar
- goutte.phar
- guzzle.phar
また、Zend Framework 2 (http://packages.zendframework.com/) では
$pyrus download Zend_**
で、pharファイルとしてダウンロードできます。
PHP界隈での大きな流れとしてPHPUnitが3.6で下位互換性の問題が浮上したこともあり、
phpunit.phar作成についてSebastian Bergmanも前向きな姿勢がみえます。まさにpharのビッグウェーブ!といった所ですが、shimookaさんのphar紹介記事 意外と身近なphar - PHp ARchive から4年以上経ってます。そう、この記事は人類には早すぎたんだ!
(【※2016年7月追記】 上記Unohラボの過去記事は https://unoh.github.io/2007/12/24/phar_php_archive.html にて確認ください )
基本的なpharアーカイブの作成方法はマニュアルにある通りです。・・・って書こうと思ってたらこうだよ!
そのうちにきちんと書きます。
http://www.php.net/manual/ja/phar.creating.intro.php
めちゃんこ端的なサンプルとしての作成コードは
<?php $phar = new Phar('hello.phar', 0, 'hello.phar'); $phar->addFromString('hello.php', '<?php echo "hello";'); $phar->setStub("<?php Phar::mapPhar(); __HALT_COMPILER();");
( マニュアルの"buildFromIterator"や"TwigをPhar化"のbuildFromDirectoryの記事も参照してみてください)
とにかく
- stub(cli用とweb用)
- 署名 (シグネチャ) http://php.net/manual/ja/phar.setsignaturealgorithm.php
- 圧縮形式
などをアーカイブ作成する際に考慮しておきたい基本事項です。
んで、2、3のファイルなら明示的に追加対象にすればいいのですが、
などちょっとややこしいですね!
GoutteやBehatは独自にCompilerクラスを作ってpharコンパイルを行っています。
そのソースを見たところだと定型処理としてツールができそうだし、ありそうですね!
pharアーカイブ作成・展開を対象としたツールはいくつかあります。
Imagineはphar-utilをguzzleはphingのタスクを使ってるようです。
このうちempireについてはPEARの開発者@hことHelgi Þormar ÞorbjörnssonのPHP Beneluxスライドで知りました。
pyrusでのpharの作成はこのような形で実現できます。
$pyrus generate-pear2 Foo __uri $pyrus make $pyrus package -p
上記のコマンドのうちpackage -p
はphar作成オプションでのパッケージングコマンドで、phpの設定でphar.readonly=0でなくてはだめなので、一般には
$php -d phar.readonly=0 pyrus package -p
です。
(補足として、phar作成の記事やライブラリのエラーメッセージでphp.ini変えろとか言ってきますが、上記のようにディレクティブ設定してればいいでないのん?)
あなたが単にPSR-0に沿ったライブラリ用ソースを持っていれば、上記generate-pear2で作ったひな形フォルダのsrcにファイルをぶち込めばphar作成可能です。
デフォルトのstubの方でspl_autoload_registerが作成されているので、作成されたphar形式のライブラリの使用は、
<?php require_once 'Foo-0.1.0.phar';
となります。
また、この pyrus package -p で作成したpharファイルは、PEARだと、*.tgzでおなじみだったPEARパッケージアーカイブ形式でもあるようで、
pyrus install Foo.phar
でそのままインストールも可能です。
作成するpharが依存するファイルやPEARパッケージの中身加えるにはどうすればいいの?
作成対象のpharが何かしらの依存ファイルがある場合、extrasetup.phpに個別のファイルやpearパッケージを指定することで、依存ファイルをひっくるめたpharパッケージを作成可能です。
<?php // レジストリ内にあるパッケージを参照する場合 $config = \Pyrus\Config::singleton(__DIR__ . '/vendor'); $extrafiles = array( $config->registry->toPackage('PEAR2_HTTP_Request', 'pear2.php.net'), ); // 直接チェックアウト先のpackage.xmlを参照する場合 $extrafiles = array( new \PEAR2\Pyrus\Package(__DIR__ . '/../../HTTP_Request/trunk/package.xml'), ); // 個別に特定のファイルを指定する場合 $extrafiles = array( 'php/PEAR2/HTTP/Request.php' => __DIR__ . '/Request.php',
http://pear.php.net/manual/ja/pyrus.commands.package.php
extrasetup.phpに記述した依存情報はpackage.xmlにはwriteされません。
ただし、今のところの不具合としてgenerate-pear2で対象としてるひな形でのフォルダ"scripts"、"tests"、"data"が存在した場合、makeで不整合のあるpackage.xmlが作成されるようで、インストールに失敗します。んがんぐ。
pyrus/Pyrus_Developer#14
pyrus/Pyrus#26
*1:リポジトリのホームURLが http://blog.kotowicz.net/2010/08/hardening-php-how-to-securely-include.html になってる通りphar作成のセキュリティ目的が主なようですが、--nsオプションで証明書なしで作成できます