planet-ibuildings

Lessons in Phar

by planet-ibuildings | Comments Off | July 21, 2009

Dear Reader,

In preparation of an episode of boxlunchtraining.com I have been doing a lot of research into creating and using PHP’s new phar archives. While I’ve not answered all my questions yet, I’ve been able to do most of what I wanted. One of the tasks I wanted to complete was to create a phar archive for Zend Framework. Here is a very quick intro into how I did it. Most of this is just a reminder for me but if you find it useful then I’m glad.

Zend Framework

First, we need a copy of Zend Framework. Luckily, I keep a recent version checked out on my laptop at all times. This zf.phar was built from svn checkout #16836.

Phar

You have to have PHP 5.3 installed for this to work. While it should be possible to use it using PHP 5.2.x and the ext/phar, I’ve not tested that. Also, I do a lot of work from the cli. I’ve tested this phar from the cli but not from a web app yet. Theoretically, it should work just fine. I’m just warning you if it doesn’t.

package.php

I’ve now built 2 phar files and learned a lot about what works and what doesn’t. The one thing I learned, that is not explicitly stated in the manual, is that each project you are going to archive in a phar, will need a program to package it up. I call mine, package.php. Each one is a little different. I still think I can use phing to standardize them. However, for now, I’m building them by hand.

< ?php
/** * package.php * Create a Zend Framework par * * @author Cal Evans <cal@calevans.com> */
 
/* * change these to match your setup. */
$zfLocation = "c:\zf-full\library\Zend";
$zfBasePointer = strpos($zfLocation,'Zend');
 
/* * Let the user know what is going on */
echo "Creating phar for Zend Framework located at ".$zfLocation."\n";
/* * Clean up from previous */
if (file_exists('zf.phar')) { Phar::unlinkArchive('zf.phar');
}

If you’ve run this before, make sure and delete the archive before starting again.

 
/* * Setup the phar */
$p = new Phar('zf.phar', 0, 'zf.phar');
$p->compressFiles(Phar::GZ);
$p->setSignatureAlgorithm (Phar::SHA1);

Now setup the phar object. In this case, I want to use gzip compression and the SHA1 hash signature.

/* * Now build the array of files to be in the phar. * The first file is the stub file. The rest of the files are built from the directory. */
$files = array();
$files['stub.php']='stub.php';
 
$rd = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($zfLocation));
foreach($rd as $file) { if (strpos($file->getPath(),'.svn')===false && $file->getFilename() != '..' && $file->getFilename() != '.') { $files[substr($file->getPath().DIRECTORY_SEPARATOR.$file->getFilename(),$zfBasePointer)]=$file->getPath().DIRECTORY_SEPARATOR.$file->getFilename(); }
}

There are several ways to add files to an archive. After experimenting with all of the ones I could find, i decided that the fastest way to do it was build the list of files I want to add to the archive in an array and then add the array to the archive. If you don’t need to do any pre-processing or want to accept everything in a directory, you can use buildFromDirecotry(). In this case however, I needed to strip out all of the subversion files.

/* * Now build the archive. */
$p->startBuffering();
$p->buildFromIterator(new ArrayIterator($files));
$p->stopBuffering();

Once I had my array built, it was a simple matter of calling buildFromIterator() and passing in an instance of ArrayIterator() with the files array. The manual recommended turning on buffering using startBuffering and stopBuffering() for large archive, however, I didn’t notice a sizable difference in speed.

/* * finish up. */
$p->setStub($p->createDefaultStub('stub.php'));
$p = null;

Finally, we finish processing.

Stub.php

You probably noticed that the phar has a stub. To get the autoloaded running automatically, I put the autoload code in a file called stub.php and included it in the phar.

< ?php
require_once dirname(__FILE__).'/Zend/Loader/Autoloader.php';
Zend_Loader_Autoloader::getInstance();
Zend_Loader_Autoloader::getInstance()->setFallbackAutoloader(true);
__HALT_COMPILER();

Stubs have to end with __HALT_COMPILER();.

Conclusion

Once you’ve built your zf.phar, using is as simple as:

include 'phar://zf.phar';

Now you have the complete Zend Framework in a handy archive. Like I said, this was a quickie. I just needed to get my thoughts down before I forget them. If you have additions to this or if I got something wonr, ge make sure and leave me a comment.

Until next time,
(l)(k)(bunny)
=C=

  Tags: phar, PHP, zend framework

Related posts

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)

Most Commented Posts

0 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.