In the last years there is a trend in the PHP community to release tools, especially command line utilities, as PHAR files, so you can package an entire PHP application into a single file for convenience. But, how PHAR files work? In this post we will try to explain it.

PHAR files

PHAR files let you package PHP applications into a single file

What are PHAR files

PHAR files are equivalent to JAR files in the JAVA world, but for PHP. That is, a way to pack several PHP files, or any other resource, in a single file and be able to execute it.

Who is using PHAR files

Composer, PHPUnit or the Symfony installer are only three examples of projects using PHAR files. PHARs are especially useful for command line tools, so the user just have to download the file and execute it, as it already contains all the dependencies.

Creating the simplest PHAR file

So, let’s create the simplest PHAR file we can imagine, so we can investigate later what that file we are going to generate contains. First, let’s write a simple stub, which usually takes care of loading the autoload system and create a “map” to be able to find the files included in the PHAR file. The stub must always end with a call to the __halt_compiler() function, which tells the PHP interpreter to halt the execution and stop parsing the code.

#!/usr/bin/env php
<?php

Phar::mapPhar('test.phar');
echo 'hello world!';

__HALT_COMPILER();

After this, we can create a really simple (and quite useless) PHAR file. Its name will be “test.phar”, the file “1.txt” will be included and it will contain a signature with SHA1 so PHP can detect if the file has been tampered.

$phar = new Phar(__DIR__ . "/test.phar");
$phar->addFile(__DIR__ . '/1.txt', '1.txt');
$phar->setStub(file_get_contents(__DIR__ . '/stub.php'));
$phar->setSignatureAlgorithm(Phar::SHA1);

Pretty simple, right? But keep in mind that for complex PHAR files it’s recommended to use a tool like Box. Complex projects like Composer have their own compiler to generate PHAR files.

Format

Internally, PHAR files need a container to package all the files and some extra information. There are three different types of containers: zip files, tar files (compressed with gzip or bzip2) and PHAR “native” file. Regardless of the container, every PHAR file contain four sections:

Structure of the PHAR format

Structure of the PHAR format

If we see the file using an hexadecimal viewer, it’s easy to differentiate between the four sections:

Hexadecimal dump of a simple PHAR file

Hexadecimal dump of a simple PHAR file

More info

Photo: Cockpit Box, by Pascal