On Phar: PHP Archive Files


As part of an internal project at work, I built a command-line script that performed a series of useful actions. However, it was all contained within one big file to make it easy to move around to ~/bin folders and such. I found that this was difficult to maintain, and I wanted to be able to separate it into smaller components – but this would break the ability to move it around at will. I needed the best of both worlds.

Enter: Phar

PHP Archive (PHAR) files solve this problem. They allow you to bundle a bunch of associated source code files together into a single virtual filesystem. That’s exactly what I needed. Of course, most languages would call this a compiler … but most languages aren’t as fun as PHP. And Phar is not a real compiler, anyway – it’s more of a collector :)

To create the simplest of Phar projects, I made a basic script to practice Phar usage:

# ./src/hello.php

<?php
$input = readline( "What is your name? " );
echo "Hello, " . $input . "\n";
?>

Then, I began writing the build script:

# ./build.php

<?php
$p = new Phar( 'hello.phar', 0, 'hello.phar' );
$p->buildFromDirectory('src/','./\.php$/');

$stub = file_get_contents( 'stub.php' );

$p->setStub( $stub );
?>

The next step is to create a stub file. The stub is used to wrap the files inside the phar, and begin running the program.

# ./stub.php

<?php
Phar::mapPhar();
include 'phar://hello.phar/hello.php';
__HALT_COMPILER();
?>

At this point, I tried running my build script (php ./build.php), but I found out that I had made a few oversights:

  1. In order for a Phar file to be modified, you need to set “phar.readonly” to 0 in the php.ini on your development machine. This is a security feature to prevent Phar files from having the ability to behave like trojan horses and viruses; you might want to consider only enabling writable Phars in specific, controlled situations (i.e., during the build process only)
  2. It lacked the “hashbang” required to make it executable on Linux. Adding “#!/path/to/php” to the top of the stub file fixes this. Alternatively, you can use “php hello.phar” to avoid having to do this.
  3. It wasn’t marked as executable. Fixing the hashbang issue and running a simple “chmod 744 hello.phar” after running “php build.php” fixes this.

Once I sorted those issues out, I ended up with the desired hello.phar file.

Phar Trek: The Next Generation

My next avenue of Phar research is to find out the ideal way to make an application with multiple files come together as a single unit. This post is just a stepping-stone toward that goal. I’m going to have to look into the best way to achieve that functionality – with a particular eye to coding projects in a way where the ability to convert to a Phar is transparent (e.g., it can function both inside a Phar and outside of one – and includes a stable build process).

Additional Phar Resources

That’s all I know of so far. If I find any new resources, I’ll update this list.

, , , , ,

Comments are closed.