13

phar ファイル内に phar ファイルを配置したいと思います。私はそれを最も簡単に試しました:

$p = new Phar('test.phar', null, 'self.phar');
$p->setStub('<?php Phar::mapPhar();
include \'phar://self.phar/index.php\'; __HALT_COMPILER(); ?>');
$p['index.php'] = '<?php
echo "hello world\n";';

$p = new Phar('test2.phar', null, 'self.phar');
$p->setStub('<?php Phar::mapPhar();
include \'phar://self.phar/index.php\'; __HALT_COMPILER(); ?>');
$p['index.php'] = '<?php
echo "hello phar world\n";';
$p['test.phar'] = file_get_contents('test.phar');

ただし、PHP はそれを開きたくないだけです。次のいずれも受け入れません。

// Warning: Phar::mapPhar(phar://path/to/test2.phar/test.phar): failed to open
// stream: Invalid argument in phar://path/to/test2.phar/test.phar
include('phar://test2.phar/test.phar');

// Warning: include(phar://test2.phar/test.phar/index.php): failed to open
// stream: phar error: "test.phar/index.php" is not a file in phar "test2.phar"
include('phar://test2.phar/test.phar/index.php');

// Warning: include(phar://test2.phar/phar://test.phar/index.php): failed to
// open stream: phar error: "phar:/test.phar/index.php" is not a file in phar
// "test2.phar"
include('phar://test2.phar/phar://test.phar/index.php');

この質問の建設性は限られていることを知っています.phar-in-pharでは機能しない可能性があるためです.

4

1 に答える 1

5

PHP で phar ファイルをロードするために使用する関数は、Phar ::loadPhar です。

Phar::loadPhar("test2.phar", "test2");

phar ファイル test2.phar がロードされ、エイリアス test2 を介してアクセスできるようになるため、次のようにしてそこからファイルを含めることができます。

include ('phar://test2/index.php');

ただし、そのファイルが phar 自体の中にある場合、これは機能しないようです。loadPhar の PHP コードは次のとおりです。

fp = php_stream_open_wrapper(fname, "rb", IGNORE_URL|STREAM_MUST_SEEK, &actual);

どうやらIGNORE_URLフラグにより​​、ファイルを開くことができなくなります。

回避策があります - 他の phar 内に含まれている phar ファイルを一時ファイルに抽出すると、問題なくロードできるようです。次のコードは、2 番目の phar ファイルに含まれる phar ファイル (phar1.phar) を抽出し、loadPhar を呼び出します。

function extractAndLoadPhar(){

    $tempFilename =  tempnam( sys_get_temp_dir() , "phar");

    $readHandle = fopen("phar://phar2/phar1.phar", "r");
    $writeHandle =  fopen($tempFilename, "w");

    while (!feof($readHandle)) {
        $result = fread($readHandle, 512);
        fwrite($writeHandle, $result);
    }

    fclose($readHandle);
    fclose($writeHandle);

    $result = Phar::loadPhar($tempFilename, "phar1");
}

extractAndLoadPhar(); //Extract and load the phar
include ('phar://phar1/src1.php'); //It can now be referenced by 'phar1'

このコードの作業コピーをhttps://github.com/Danack/pharpharに配置しました。これは、phar を作成し、それを 2 番目の phar に埋め込み、2 番目の phar 内の最初の phar から関数をロードして呼び出します。

注 - この手法が良いアイデアであるとは確信していません。各 phar ファイルのスタブ ファイルがどうなるかは、あいまいな点があるようです (つまり、私には理解できませんでした)。つまり、両方ともロードされますか、それともスタブがロードされて実行されるのは最も外側の phar ファイルだけですか。

于 2012-11-24T00:51:15.063 に答える