问题描述
我想在一个phar文件中放置一个phar文件.我最直接地尝试过:
I'd like to place a phar file inside a phar file. I tried it most straight forward:
$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只是不想打开它.它不接受以下任何内容:
However PHP just does not want to open it. It does not accept any of the following includes:
// 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,但是我可能只是想念如何做到这一点,而我只是没有看到要解决的问题.树木.
I know the constructiveness of this question is limited, because it might just not work with phar-in-phar however probably I've just been missing a way how to do that and I'm just not seeing the wood for the trees.
推荐答案
用于在PHP中加载phar文件的函数为 Phar :: loadPhar 例如
The function that you should use to load a phar file in PHP is Phar::loadPhar e.g.
Phar::loadPhar("test2.phar", "test2");
将使phar文件test2.phar可以通过别名test2加载并访问,因此您可以通过执行以下操作来包含文件:
Would make the phar file test2.phar be loaded and accessible via the alias test2, so you could include files from it by doing:
include ('phar://test2/index.php');
但是,如果该文件位于phar本身中,则似乎无法正常工作. loadPhar的PHP代码是:
However it appears that this does not work if that file is inside a phar itself. The PHP code for loadPhar is:
fp = php_stream_open_wrapper(fname, "rb", IGNORE_URL|STREAM_MUST_SEEK, &actual);
显然,IGNORE_URL标志使该文件无法打开.
and apparently the IGNORE_URL flag makes it impossible for the file to be opened.
有一种解决方法-将另一个phar内包含的phar文件提取到一个临时文件中,然后显然可以加载该文件而没有任何问题.以下代码将提取第二个phar文件中包含的phar文件(phar1.phar),然后调用loadPhar.
There is a workaround - extract the phar file that is contained inside the other phar to a temporary file, and then it apparently can be loaded without any issue. The following code will extract a phar file (phar1.phar) that is contained in a 2nd phar file, and then call 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,将其嵌入到第二个phar中,然后从第二个phar中的第一个phar加载并调用函数.
I have placed a working copy of this code here https://github.com/Danack/pharphar which creates a phar, embeds it in a 2nd phar, and then loads and calls a function from the 1st phar inside the 2nd phar.
请注意-我不相信这种技术是个好主意.每个phar文件的存根文件似乎发生了一些歧义(又是我不明白).即它们是否都已加载,还是只是最外层的phar文件已存根并运行.
To note - I'm not convinced that this technique is a good idea. There seems to be some ambiguity (aka I didn't understand) what happens to the stub files for each of the phar files. i.e. do they both get loaded, or is it just the outermost phar file that has it's stub loaded and run.
这篇关于如何在Phar文件中放置Phar文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!