pscheit
pscheit

Reputation: 2981

Is it possible to put a phar into a phar?

first things first: my Phars do run. I'm playing around a little bit and I have the following scenario:

I'd like to put the lib-phar into the application-phar. and require only the application-phar. So that the bootstrap (stub) from the application-phar loads the bootstrap from the lib-phar.

This is the best introducing Resource I've come up with: http://www.slideboom.com/presentations/26182/PHP-5.3-Part-3---Introducing-PHAR

I have the following:

lib-phar

$innerPharFile = $this->newFile('lib.phar');
$innerPhar = new Phar((string) $innerPharFile);
$innerPhar->addFromString('index.php', '<?php echo "  inner index loaded"; ?>');
$innerPhar->setStub(file_get_contents('inner_stub.php'));

inner-stub

<?php
echo "  inner stub loaded\n\n";

// Here is the problem: how do i execute index.php from inner, here?
var_dump(Phar::running (TRUE));

echo "\n";
__HALT_COMPILER();
?>

application-phar

$pharFile = $this->newFile('application.phar');
$phar = new Phar((string) $pharFile);
$phar->addFile($innerPharFile,'lib.phar');
$phar->addFromString('index.php', '<?php echo "outer index loaded"; ?>');
$phar->setStub(file_get_contents('outer-stub.php'));

outer-stub

<?php
echo "outer stub loaded\n";

$inner_phar = 'phar://'.__FILE__.'/lib.phar';
require $inner_phar;

require 'phar://'.__FILE__.'/index.php';
__HALT_COMPILER();
?>

main

php -f 'application.phar'

outputs:

outer stub loaded

  inner stub loaded
  string(xx) "phar://full/path/to/application.phar"

outer index loaded

So long, so good, but... How Do I execute the inner index.php? I think the problem is, that i would like to dome something very confusing:

 require 'phar://phar://full/path/to/application.phar/lib.phar';

which is in readable form: :

 require 'phar://  
            phar://full/path/to/application.phar
          /lib.phar';

because my lib.phar is IN application.phar. So I think I would need a wrapper around the wrapper. So maybe the PHAR-Extension is not made for this. As we see the second stub is called, but the magic __FILE__ constant (as well as Phar::running(TRUE|FALSE) is set wrong here.

Do you have any ideas? Or made a similary setup?

Of course I know the alternatives:

I really like to think about this nesting setup. Maybe you got another great idea?

Best regards Philipp

Upvotes: 5

Views: 759

Answers (2)

Danack
Danack

Reputation: 25701

Short version, phar files cannot be opened from within other phar files. They must first be extracted to a temporary file outside of the phar:

function extractAndLoadPhar(){

$tempFilename =  tempnam( sys_get_temp_dir() , "phar");
//$tempFilename =  "/tmp/phar1.phar";

//echo "tempFilename is $tempFilename\r\n";

$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");
//echo "Load result is $result \r\n";

}

Also see: How to place a phar file inside a phar file?

Upvotes: 0

sujaisd
sujaisd

Reputation: 183

Your Idea of using phar looks great and nesting it too. while I see the same problem explained by you.

In Java world they use jar and war, the jar is for libraries, while war is for application, which contains all jars and extracts it on the web server before executing, ending up with lib folder having all the jars.

phar came up in PHP after the jar from Java, so definitely they should try to follow something similar.

The purpose of phar is to reuse that phar again in some other application, making it as part of other phar will make it not easily assesible for other applications. So I prefer to use phpmaven

Use phpmaven and build library project and publish to a maven server. Use phpmaven and build your application project with dependency to all your library projects

you get the build with all the library phars, you can even make a single phar out of it with onestub as explained by you using maven which is more easy to understand the project and its dependencies.

Upvotes: 1

Related Questions