A feature of PHP 5.3 is PHAR. The ability to run whole php applications from one archive. In this article (you could call it workshop) I will show how they are created and how to develop a small blog application inside one of those archives.
Configuration of PHAR is easy, as it is linked to PHP 5.3 statically you don't have to activate it. Only thing you might want to do is map the file extension ".phar" to php. To do this just add the following line, depending on the webserver in use, to your configuration.
Note: This is not necessarily required as php runs the phar archive as long as ".phar" is part of the file extension. So "someArchive.phar.php" works!
Now that everything works and Phar is available, we create our first archive. Create a directory called 'listing1' and put a file (let's take index.php) with the following content in there:
This simple program will be enough to create our first archive. Create another file in your directory:
Make sure the current directory is writable by the script and run it. The script above creates a new php archive named
listing1.phar by passing the name to the constructor of the Phar class. We use
addFile( $file, $local) here to add a single file to the archive. You can now call
listing1.phar in your browser (if the extension .phar is not associated with php you would have to rename it to 'listing1.phar.php'. '.phar' must be a part of the extension!). When calling the phar, you will get automatically redirected to "index.php" which is the default directory index.
Similar to manifest files in Java we define a file which is used as bootstrap stub by calling the methods
string createDefaultStub( void ) - to create a default stub (can be more than one) - and
void setStub(string $stub) to set the created stub. The difference between a manifest and a stub is that a manifest usually only defines a main class while a stub can contain PHP code to execute everytime the stub is parsed.
After this I was asking myself if it's possible to include media files like images into PHP archives as well. I created a directory named listing2 by copying the first one, added an image and inserted the required html tag to show the image. I created an archive and.. indeed, it works! See listing2 for details.
Of course you will have to put an image named "logo.png" into the directory "images" if you just copy and paste the source.
As you can see, there is no big difference to the first one. Only one new directive to add the image file. Create the archive and execute it.
Developing a blog module
We can use PHP archives to store whole applications, including images, templates and source. So instead of distributing a bunch of files seperately, we pack them together in an archive. Let's take a small blog application as an example.
A blog needs a configuration file, which the user should be able to modify. We cannot expect the user to modify the archive manually, so the file needs to be saved externally. The Phar class provides a way of mounting external files into an archive at runtime, which we will make use of to ease getting the configuration.
Step 1: Mounting the configuration
Before mounting a configuration we will have to create one. I chose an XML-based configuration with the following format:
I saved the file to a subdirectory named "data". As this file is only for testing purposes you will have to remove it later, to let the installation generate the configuration.
This time we only check if the stub does the expected work and mounts the configuration file into our archive. Since I choosed XML for our config we have to send the correct header, so that the data also gets interpreted as XML as well.
Step 2: Provide installation
When installing new applications there are always things that need to be configured. In our case we want to specify author, description and title of the blog and generate the xml configuration. We also have to check if the directory where configuration and database will be stored is writeable.
There is only one new function introduced here:
string running( bool ). This functions either return a phar URL or the full path to the running phar archive. Since the installation script is too long to be posted here I shortened it a bit.
Step 3: The SQLite database
Every entry of our blog will be stored in a small SQLite3 database. We will use only one table to store the data.
Now we will use this piece of SQL in our installation:
We also have to check if a configuration has already been created and being mounted when starting the phar. If that is the case installation has already finished and we have to avoid re-execution of the installation.
Step 4: The blog class
A blog class has to implement several functions. We want to be able to add, edit and remove entries from the databse, so the class skeleton would look something like the following:
Of course there has to be some sort of authentication method so that standard users are not able to remove or edit your entries. I don't discuss the implementation of this authentication mechanism here, just take a look at the source code.
Now that every line of code has been written we just need to pack all our stuff together and create the archive.
To use the blog application you will have to keep in mind that there has to be a directory named "data" where configuration and database will be stored after installation. As we save the hashed password in this directory, it might be a good idea to limit access to this directory:
PHP archives offer a lot more functionality than what has been described in this article. Have a look at the PHP manual to get an idea of what is possible.
Depending on your build options the phar extension has compiled against bzip2 or gzip. We can use
array Phar::getSupportedCompression() to check which compression methods are available. To compress an archive, we add the following lines:
You could also use
Phar::getSupportedCompression() to determine which compression method to use.