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

Like it? Share it!
  • email
  • Twitter
  • Facebook
  • Digg
  • StumbleUpon
  • del.icio.us
  • LinkedIn
  • Reddit
  • Technorati
  • DZone

Most Commented Posts

0 Responses

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