Archiving a Directory
Recursively tracing out a full directory and saving the files in an archive seemed like a fairly easy thing to do. After all, I knew how to glob() and was reasonably sure that the environment I was working in had the ZIP extension built into the PHP. But wait... Recursion? glob() does not handle recursion easily.
After digging around a little bit through some Stack Overflow articles I bumped into an alternate method to glob()… A handy set of SPL classes. After all, PHP 5 and cool new features and stuff. A bit of experimentation and I ended up with this little script that creates a friendly iterator-able recursive set of files that has a delightfully small memory footprint.
$directoryIterator = new RecursiveDirectoryIterator($directory_path);
$iteratorIterator = new RecursiveIteratorIterator($directoryIterator);
foreach ($iteratorIterator as $file)
{
// do something
}
RecursiveDirectoryIterator creates an interface to view the contents of a directory and RecursiveIteratorIterator (I love that name) can loop through iterators. It's nice, simple, and each $file in the foreach() is a full SplFileInfo object. Which opens up a lot of handy functionality.
Once I had this down it was a piece of cake to implement the ZipArchive logic. Once you create that class and open up a file, you can add files, one at a time, to the archive. Which was perfect, given that RecursiveIteratorIterator was looping through the files one at a time.
$directoryIterator = new RecursiveDirectoryIterator($directory_path);
$iteratorIterator = new RecursiveIteratorIterator($directoryIterator);
$archive = new ZipArchive();
$archive->open($archive_path, ZipArchive::OVERWRITE);
foreach ($iteratorIterator as $file)
{
$archive->addFile(
$file->getPathname(),
str_replace($directory_path, '', $file->getPathname())
);
}
$archive->close();
One area that got a little hairy was with the ZipArchive errors. If the archive is unable to open (file permissions, existing file, etc) ZipArchive::open() can return any one of a wide range of interger statuses to show the failure. Mapping out what problem showed up is a little messy. Also, ZipArchive::addFile() only returns a boolean if it worked with no hint as to the problem. Inconsistency in PHP is just par for course, though, even for some of the newer features.
A built out repository (archiver) of this script is available on my GitHub account, complete with some error checking and commented parameter areas. This was a fun venture into an area of PHP that I haven't had a ton of experience in (SPL) and I hope to find an excuse to jump in again soon!
Comments (0)