Phar建立與使用

這幾天為了Pointless而嘗試使用Phar去包裝整套系統,但除了官方文件之外,中文的資源相當的少,所以我在這邊筆記一下使用方法與問題

Phar

Phar(PHP Archive)它是PHP的extension,就像是Java的jar一樣可以用來打包程式碼,可讓專案易於散佈並安裝使用

包裝PHP Source

<?php
$phar = new Phar('bin/pointless.phar');

指定Phar的路徑以及名稱,需要注意的是結尾一定要用.phar

$phar->setAlias('poi.phar');

Alias用來設定Phar檔的別名

$phar->setStub("<?php Phar::mapPhar('poi.phar'); define('ROOT', 'phar://poi.phar/'); require ROOT. 'Boot.php'; __HALT_COMPILER(); ?>");

Stub的用途是,如果你不是在PHP檔案中引用Phar檔案,而是直接用Phar作為執行檔,它就會以Stub作為預設的呼叫對象

而在Stub中用到的mapPhar的作用是指定並註冊為你所設定的Phar檔,Phar會使用執行檔的名稱作為註冊的依據

$phar->buildFromDirectory(dirname(__FILE__) . '/pointless');

buildFromDirectory則是指定要打包成Phar檔的資料夾

$phar->compressFiles(Phar::GZ);

compressFiles設定Phar的打包格式,除了Phar::GZ還有Phar::BZ2

$phar->stopBuffering();

stopBuffering用來將打包好的Phar檔寫入磁碟

使用方式

<?php
Phar::mapPhar('poi.phar');
require 'phar://poi.phar/Boot.php';

$boot = new Boot();
$boot->run();

假設在原本打包的資料夾的根目錄下有個叫做Boot.php的檔案,可以這樣呼叫並使用

php ./pointless.phar

如果是直接當成可執行檔,可以這樣使用,如果要直接執行那麼就要在Stub中的第一行加入#!/usr/bin/env php

Example

<?php
$stub = <<<EOF
#!/usr/bin/env php
<?php
    Phar::mapPhar('poi.phar');
    require 'phar://poi.phar/Boot.php';
    __HALT_COMPILER();
?>
EOF;

$phar = new Phar('pointless.phar');
$phar->setAlias('poi.phar');
$phar->setStub($stub);
$phar->buildFromDirectory(dirname(__FILE__) . '/pointless');
$phar->compressFiles(Phar::GZ);
$phar->stopBuffering();

注意

PHP Fatal error:  Uncaught exception 'UnexpectedValueException' with message 'creating archive "poi.phar" disabled by the php.ini setting phar.readonly' in /path/to/build.php:20
Stack trace:
#0 /path/to/build.php(20): Phar->__construct('poi.phar')
#1 {main}
  thrown in /path/to/build.php on line 20

如果在打包Phar時發生以上錯誤,那麼就去把php.ini中的Phar設定改為以下內容

[Phar]
; http://php.net/phar.readonly
phar.readonly = Off

; http://php.net/phar.require-hash
;phar.require_hash = On

;phar.cache_list =

Reference

About
ScarWu

刀疤

記錄學習過程、生活以及一些想說的話。