You are here

epub files with php

Posted at 20:47 on Wed, 2nd June 2010 in drupal, php.

A few tips and small hacks I came up with for dynamically creating compliant epub files in PHP.

Note: The purpose of this post is not to go into detail about the epub standard, but to share a few tips and small hacks I came up with for dynamically creating compliant epub files in PHP. If you've come here looking for details about the epub standard, look at the end of this post for some handy reference links.

The epub file format is an open e-book standard supported by a number of readers and tablet devices including Apple's new iBooks store and the IPad. With the previous imminent release of the IPad in Australia, I recently had the task at work of creating an epub builder for' the contents of a Drupal site.

The epub file format, is essentially a zip file renamed to an .epub. So the first thing you'll want to do is download an epub file from somewhere, rename it to <whatever>.zip, extract it and review the different files and their content in your favorite text editor. The contents of most of these files, follow a number of standards set out by the International Digital Publishing Forum. You don't have to know the in's and outs of these standards, as they're essentially just html and xml set out in a particular way. But if you use the example epub file you downloaded before, and reverse engineer things that way, you'll get there eventually without spending weeks of study (arguably a bad thing, but who's going to pay you to read 50 pages of a spec?).

There's probably dozens of php libraries out there that will do zipping features for you, but the easiest way I found was just using PHP's built in Zip Archive class. However, this class doesn't support adding files to an archive that are uncompressed - which is required for the mimetype file of the epub file (as set out in the standard). Below is a small hack to get around this along with the basics of using the Zip Archive class.

<?php
$filename 
'somefile.epub';
$mimetype 'model/mimetype'// this file essentially contains 'application/epub+zip' with no new line.

// note, the zip arguments tell zip to add this file to the archive as uncompressed. The epub standard requires the file be added at the start of the archive as uncompressed.
// you may need to do something different here if you're using a Windows server.
system('zip -q0Xj $filename $mimetype');

// For the rest of the epub file, lets use the easier ZipArchive php class.
$zip = new ZipArchive();

if (
$zip->open($filenameZIPARCHIVE::CREATE)!==TRUE) {
 
// error out here
}

// Example of creating folders in the archive.
$zip->addEmptyDir('META-INF');

// Example of adding a file via the contents of another file
$contents file_get_contents('model/article-template.html');
// perhaps do some preg replaces here to slap in your article contents from a database or other file.
$zip->addFromString('article_001.html'$contents);

// Example of adding a file to the archive directly from a file on the filesystem.
$zip->addFile('model/META-INF/container.xml''META-INF/container.xml');

// .. lots more to do here, as per the epub standard.
?>

When you've dynamically built your epub file in full, you'll want to test it out on your PC or Mac. Adobe Digital Editions (ADE) will do just that and its free. If your having trouble opening your epub files in ADE, turn on the logging opens in your preferences, and review the contents of your ADE log file - discussed here.

You'll also want to use the EPub validation tool to ensure the epub file is suitable for the other readers out there.

If you want to allow dynamic downloading of epub files, you can do this with the following headers in php:

<?php
header
('Content-type: application/epub+zip');
header('Content-disposition:attachment;filename='somefilename.epub'');
header('Content-Transfer-Encoding: binary');
readfile($filename);
?>

That's about it really. A few quick links:

Hopefully these notes can help someone else out there on the interwebs.