3

PHAR アーカイブを PHP としてマークして(これの正しい用語はわかりません)、一部なしで cli から使用できるようにしようとしていphpます。そのため、呼び出す代わりに、php /path/to/my/archive.phar ARGUMENTS_HERE移動してどこからでも/usr/local/bin呼び出すことができarchiveます。(PHPUnit や Composer と同じように)。

私が正しければ、それを行うに#!/usr/bin/env phpは、PHAR アーカイブ ファイルの上に追加するだけでよいのでしょうか?

それ、どうやったら出来るの?ビルドスクリプトでcomposer コンパイラを模倣しようとしましたが、 PHP_CLI (セグメンテーション違反)がクラッシュするだけです。

$archiveName = 'phpbenchmark.phar';

$phar = new Phar($archiveName);

$phar->buildFromDirectory(__DIR__, '/\/lib\/|\/vendor\//');

$phar->setStub(createStub());

function createStub()
{
    $stub = <<<EOD
#!/usr/bin/env php
<?php
Phar::mapPhar('phpbenchmark.phar');
require 'phar://phpbenchmark.phar/lib/app.php';
__HALT_COMPILER();
EOD;
    return $stub;
}

ご覧のとおり、/lib/app.phpファイルを実行するために必要なのはスタブだけで、それだけです。

コンパイルされた PHAR の先頭に追加

もちろん、私が最初に試したのは手動でアーカイブに追加することでしたが、それは破損しているようです:

PHP Fatal error:  Uncaught exception 'PharException' with message 'manifest cannot be larger than 100 MB in phar "/home/igor/Dropbox/www/Github/PIFlexPHPBenchmark/phpbenchmark.phar"' in /home/igor/Dropbox/www/Github/PIFlexPHPBenchmark/phpbenchmark.phar:9
Stack trace:
#0 /home/igor/Dropbox/www/Github/PIFlexPHPBenchmark/phpbenchmark.phar(9): Phar::webPhar(NULL, 'index.php')
#1 {main}
  thrown in /home/igor/Dropbox/www/Github/PIFlexPHPBenchmark/phpbenchmark.phar on line 9

Fatal error: Uncaught exception 'PharException' with message 'manifest cannot be larger than 100 MB in phar "/home/igor/Dropbox/www/Github/PIFlexPHPBenchmark/phpbenchmark.phar"' in /home/igor/Dropbox/www/Github/PIFlexPHPBenchmark/phpbenchmark.phar on line 9

PharException: manifest cannot be larger than 100 MB in phar "/home/igor/Dropbox/www/Github/PIFlexPHPBenchmark/phpbenchmark.phar" in /home/igor/Dropbox/www/Github/PIFlexPHPBenchmark/phpbenchmark.phar on line 9

Call Stack:
    0.0010     306272   1. {main}() /home/igor/Dropbox/www/Github/PIFlexPHPBenchmark/phpbenchmark.phar:0
    0.0011     307840   2. Phar::webPhar() /home/igor/Dropbox/www/Github/PIFlexPHPBenchmark/phpbenchmark.phar:9

手動で変更する前に、まったく同じアーカイブが機能することに注意してください。(ただしphp /path/to/arch、もちろん必要です)

4

2 に答える 2

0

それを機能させるために必要だったのは、次の行を更新することだけです。

$phar->setStub($phar->createDefaultStub("main.php"));

に :

$phar->setStub("#!/usr/bin/env php\n\n" . $phar->createDefaultStub("main.php"));

これは、phar が作成するデフォルトのスタブを取得し、requires #! を追加します。それに一直線。次に、結果の phar ファイルを chmod 700 するだけで、準備完了です。

于 2015-10-14T16:37:45.113 に答える
0

ああ、数時間頭を悩ませた後、(ちょっと)解決しました。理由はまだわかりませんが、このビルド スクリプトは機能しているようです。

$archiveName = 'phpbenchmark.phar';

$phar = new Phar($archiveName);

$phar->buildFromDirectory(__DIR__, '/\/lib\/|\/vendor\//');

$phar->setStub(createStub());

function createStub()
{
    $stub = <<<ENDSTUB
#!/usr/bin/env php
<?php
Phar::mapPhar('phpbenchmark.phar');
require 'phar://phpbenchmark.phar/lib/app.php';
__HALT_COMPILER();
ENDSTUB;

    return $stub;
}

例外.....質問に投稿された元のスクリプトとの違いは本当にわかりませんか? なぜ元のものは PHP Cli をクラッシュさせ、これは動作するのでしょうか?

于 2013-03-06T01:45:16.633 に答える