PHP package to read metadata and extract covers from eBooks, comics and audiobooks.

Fund package maintenance!

2.2.01 2023-12-06 09:42 UTC


Banner with eReader picture in background and PHP eBook title

php version downloads license tests codecov

PHP package to read metadata and extract covers from eBooks, comics and audiobooks.

  • eBooks: .epub, .pdf, .azw, .azw3, .kf8, .kfx, .mobi, .prc, .fb2
  • Comics: .cbz, .cbr, .cb7, .cbt (metadata from
  • Audiobooks: .mp3, .m4a, .m4b, .flac, .ogg

To know more see Supported formats. Supports Linux, macOS and Windows.


This package favors eBooks in open formats such as .epub (from IDPF) or .cbz (from CBA) and which be parsed with native PHP, so for the best possible experience we recommend converting the eBooks you use. If you want to know more about eBook ecosystem, you can read documentation.


For DRM (Digital Rights Management) eBooks, in some cases you could read metadata but not contents (like HTML files for EPUB). To use all features, you have to use a software to remove DRM before using this package. For EPUB, you can use calibre with DeDRM plugin, this guide can help you.


This package was built for bookshelves-project/bookshelves, a web app to handle eBooks.


  • PHP version >=8.1
  • PHP extensions:
    • zip (native, optional) for .EPUB, .CBZ
    • phar (native, optional) for .CBT
    • rar (optional) for .CBR (p7zip binary can be used instead)
    • imagick (optional) for .PDF cover
    • intl (native, optional) for Transliterator for better slugify
    • fileinfo (native, optional) for better detection of file type
  • Binaries
    • p7zip (optional) binarys for .CB7 (can handle .CBR too)
  • To know more about requirements, see Supported formats.


You have to install requirements only if you want to read metadata for these formats, e.g. if you want to read metadata from .cbr files, you have to install rar PHP extension or p7zip binary. So all requirements for PHP extensions and binaries are optional.


Archives are handle with kiwilan/php-archive, for some formats (.cbr and .cb7) rar PHP extension or p7zip binary could be necessary. Some guides to install these requirements are available on kiwilan/php-archive.


  • Support multiple formats, see Supported formats
  • 🔎 Read metadata from eBooks, comics, and audiobooks
  • 🖼️ Extract covers from eBooks, comics, and audiobooks
  • 📚 Support metadata
  • 🔖 Chapters extraction (EPUB only)
  • 📦 EPUB and CBZ creation supported
  • Works perfectly with kiwilan/php-opds: PHP package to generate OPDS feeds (not included)


  • Better .epub creation support
  • Add .epub metadata update support
  • Add better handling of MOBI files: libmobi and ebook-convert from Calibre (fallback is available)
  • Add support of ebook-convert from Calibre
  • Add suport for DJVU: djvulibre
  • Support FB2 archive


You can install the package via composer:

composer require kiwilan/php-ebook


With eBook files or audiobook files (to know more about formats, see Supported formats).

use Kiwilan\Ebook\Ebook;

$ebook = Ebook::read('path/to/ebook.epub');

$ebook->getPath(); // string => path to ebook
$ebook->getFilename(); // string => filename of ebook
$ebook->getExtension(); // string => extension of ebook
$ebook->getTitle(); // string
$ebook->getAuthors(); // BookAuthor[] (`name`: string, `role`: string)
$ebook->getAuthorMain(); // ?BookAuthor => First BookAuthor (`name`: string, `role`: string)
$ebook->getDescription(); // ?string
$ebook->getDescriptionHtml(); // ?string
$ebook->getCopyright(); // ?string
$ebook->getPublisher(); // ?string
$ebook->getIdentifiers(); // BookIdentifier[] (`value`: string, `scheme`: string)
$ebook->getPublishDate(); // ?DateTime
$ebook->getLanguage(); // ?string
$ebook->getTags(); // string[] => `subject` in EPUB, `keywords` in PDF, `genres` in CBA
$ebook->getSeries(); // ?string => `calibre:series` in EPUB, `series` in CBA
$ebook->getVolume(); // ?int => `calibre:series_index` in EPUB, `number` in CBA

For pages count, you can use these methods:

$ebook->getPagesCount(); // ?int => estimated pages count (250 words by page) in `EPUB`, `pageCount` in PDF, `pageCount` in CBA
$ebook->getWordsCount(); // ?int => words count in `EPUB`


For performance reasons, with EPUB, pagesCount and wordsCount are only available on demand. If you use var_dump to check eBook, these properties will be null.

Some metadata can be stored into extras() method, without typing, directly from metadata.

$ebook->getExtras(); // array<string, mixed> => additional data for book
$ebook->getExtra(string $key); // mixed => safely extract data from `extras` array

To know if eBook is valid, you can use isValid() static method, before read().

use Kiwilan\Ebook\Ebook;

$isValid = Ebook::isValid('path/to/ebook.epub');

To get additional data, you can use these methods:

$ebook->getParser(); // ?EbookParser => Parser with modules
$ebook->getMetaTitle(); // ?MetaTitle, with slug and sort properties for `title` and `series`
$ebook->getFormat(); // ?EbookFormatEnum => `epub`, `pdf`, `cba`
$ebook->getCover(); // ?EbookCover => cover of book

To access to archive of eBook, you can use getArchive() method. You can find more informations about archive in kiwilan/php-archive.

$ebook->getArchive(); // ?BaseArchive => archive of book from `kiwilan/php-archive`

And to test if some data exists:

$ebook->isArchive(); // bool => `true` if `EPUB`, `CBA`
$ebook->isMobi(); // bool => `true` if Mobipocket derivatives
$ebook->isAudio(); // bool => `true` if `mp3`, `m4a`, `m4b`, `flac`, `ogg`
$ebook->hasMetadata(); // bool => `true` if metadata exists
$ebook->hasCover(); // bool => `true` if cover exists
$ebook->isBadFile(); // bool => `true` if file is not readable


Ebook::class contains many informations but if you want to access to raw metadata, metadata() method is available.

use Kiwilan\Ebook\Ebook;

$ebook = Ebook::read('path/to/ebook.epub');

$parser = $ebook->getParser();

$parser->getModule(); // Used into parsing can be any of `EbookModule::class`

$parser->getAudiobook(); // `AudiobookModule::class`
$parser->getCba(); // `CbaModule::class`
$parser->getEpub(); // `EpubModule::class`
$parser->getFb2(); // `Fb2Module::class`
$parser->getMobi(); // `MobiModule::class`
$parser->getPdf(); // `PdfModule::class`

$parser->isAudiobook(); // bool
$parser->isCba(); // bool
$parser->isEpub(); // bool
$parser->isFb2(); // bool
$parser->isMobi(); // bool
$parser->isPdf(); // bool


Can be set if book's title is not null.

use Kiwilan\Ebook\Ebook;

$ebook = Ebook::read('path/to/ebook.epub');
$metaTitle = $ebook->getMetaTitle(); // ?MetaTitle

$metaTitle->getSlug(); // string => slugify title, like `the-clan-of-the-cave-bear`
$metaTitle->getSlugSort(); // string => slugify title without determiners, like `clan-of-the-cave-bear`
$metaTitle->getSlugLang(); // string => slugify title with language and type, like `the-clan-of-the-cave-bear-epub-en`

$metaTitle->getSerieSlug(); // ?string => slugify series title, like `earths-children`
$metaTitle->getSerieSort(); // ?string => slugify series title without determiners, like `earths-children`
$metaTitle->getSerieLang(); // ?string => slugify series title with language and type, like `earths-children-epub-en`

$metaTitle->getSlugSortWithSerie(); // string => slugify title with series title and volume, like `earths-children-01_clan-of-the-cave-bear`
$metaTitle->getUniqueFilename(); // string => unique filename for storage, like `jean-m-auel-earths-children-01-clan-of-the-cave-bear-en-epub`


Cover can be extracted from ebook.

use Kiwilan\Ebook\Ebook;

$ebook = Ebook::read('path/to/ebook.epub');
$cover = $ebook->getCover(); // ?EbookCover

$cover->getPath(); // ?string => path to cover
$cover->getContents(bool $toBase64 = false); // ?string => content of cover, if `$toBase64` is true, return base64 encoded content


Formats specifications


With EPUB, metadata are extracted from OPF file, META-INF/container.xml files, you could access to these metatada but you can also get chapters from NCX file. And with chapters() method you can merge NCX and HTML chapters to get full book chapters with label, source and content.

use Kiwilan\Ebook\Ebook;

$ebook = Ebook::read('path/to/ebook.epub');

$epub = $ebook->getParser()?->getEpub();

$epub->getContainer(); // ?EpubContainer => {`opfPath`: ?string, `version`: ?string, `xml`: array}
$epub->getOpf(); // ?OpfItem => {`metadata`: array, `manifest`: array, `spine`: array, `guide`: array, `epubVersion`: ?int, `filename`: ?string, `dcTitle`: ?string, `dcCreators`: BookAuthor[], `dcContributors`: BookContributor[], `dcDescription`: ?string, `dcPublisher`: ?string, `dcIdentifiers`: BookIdentifier[], `dcDate`: ?DateTime, `dcSubject`: string[], `dcLanguage`: ?string, `dcRights`: array, `meta`: BookMeta[], `coverPath`: ?string, `contentFile`: string[]}
$epub->getNcx(); // ?NcxItem => {`head`: NcxItemHead[]|null, `docTitle`: ?string, `navPoints`: NcxItemNavPoint[]|null, `version`: ?string, `lang`: ?string}
$epub->getChapters(); // EpubChapter[] => {`label`: string, `source`: string, `content`: string}[]
$epub->getHtml(); // EpubHtml[] => {`filename`: string, `head`: ?string, `body`: ?string}[]
$epub->getFiles(); // string[] => all files in EPUB


For performance reasons, with ncx, html and chapters are only available on demand. If you use var_dump to check metadata, these properties will be null.


You can create an EPUB or CBZ file with create() static method.


Only EPUB and CBZ are supported for creation.

use Kiwilan\Ebook\Ebook;

$creator = Ebook::create('path/to/ebook.epub');

// Build manually
$creator->addFromString('mimetype', 'application/epub+zip')
    ->addFromString('META-INF/container.xml', '<?xml version="1.0" encoding="UTF-8" standalone="no" ?><container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container"><rootfiles><rootfile full-path="OEBPS/content.opf" media-type="application/oebps-package+xml"/></rootfiles></container>')

// Build from files
$creator->addFile('mimetype', 'path/to/mimetype')
    ->addFile('META-INF/container.xml', 'path/to/container.xml')

// Build from directory
$creator->addDirectory('./', 'path/to/directory')

Supported formats

There is a lot of different formats for eBooks and comics, if you want to know more about:

Name Extensions Supported Uses Support cover Support series
EPUB (IDPF) .epub Native zip
Kindle (Amazon) .azw, .azw3, .kf8, .kfx Native filesystem ✅ (See MOBI cover note)
Mobipocket .mobi, .prc Native filesystem ✅ (See MOBI cover note)
PDF .pdf smalot/pdfparser (included) Uses imagick
iBook (Apple) .ibooks N/A N/A
DjVu .djvu, .djv N/A N/A
Rich Text Format .rtf N/A N/A
FictionBook .fb2 Native filesystem
Broadband eBooks .lrf, .lrx N/A N/A
Palm Media .pdb N/A N/A
Comics CBZ .cbz Native zip
Comics CBR .cbr rar PHP extension or p7zip binary
Comics CB7 .cb7 p7zip binary
Comics CBT .cbt Native phar
Audio .mp3, .m4a, .m4b, .flac, .ogg See kiwilan/php-audio Depends of format

MOBI cover note

Mobipocket files and derivatives (.mobi, .prc, .azw, .azw3, .kf8, .kfx) can have a cover image embedded in the file. With native solution of php-ebook cover could be extracted but resolution is not good. Best solution is to convert file with calibre and use EPUB format.


composer test


Please see CHANGELOG for more information on what has changed recently.



The MIT License (MIT). Please see License File for more information.