kiwilan / php-ebook
PHP package to read metadata and extract covers from eBooks, comics and audiobooks.
Fund package maintenance!
kiwilan
Installs: 9 907
Dependents: 0
Suggesters: 0
Security: 0
Stars: 30
Watchers: 3
Forks: 9
Open Issues: 4
pkg:composer/kiwilan/php-ebook
Requires
- php: ^8.1
- kiwilan/php-archive: ^2.3.02
- kiwilan/php-xml-reader: ^1.1.0
Requires (Dev)
- illuminate/support: ^9.0 || ^10.0 || ^11.0 || ^12.0
- kiwilan/php-audio: ^4.0.01
- laravel/pint: ^1.7
- pestphp/pest: ^2.0
- phpstan/phpstan: ^1.10
- spatie/ray: ^1.28
- dev-main
- 3.0.09
- 3.0.08
- 3.0.07
- 3.0.06
- 3.0.05
- 3.0.04
- 3.0.03
- 3.0.02
- 3.0.01
- 2.6.9
- 2.6.8
- 2.6.7
- 2.6.6
- 2.6.5
- 2.6.4
- 2.6.3
- 2.6.1
- 2.6.0
- 2.5.13
- 2.5.12
- 2.5.11
- 2.5.10
- 2.5.0
- 2.4.9
- 2.4.8
- 2.3.8
- 2.3.7
- 2.3.6
- 2.3.5
- 2.3.4
- 2.3.3
- 2.3.2
- 2.3.1
- 2.3.0
- 2.2.01
- 2.2.0
- 2.1.02
- 2.1.01
- 2.1.0
- 2.0.20
- 2.0.12
- 2.0.11
- 2.0.1
- 2.0.0
- 1.3.54
- 1.3.53
- 1.3.52
- 1.3.51
- 1.3.41
- 1.3.35
- 1.3.34
- 1.3.33
- 1.3.32
- 1.3.31
- 1.3.30
- 1.3.20
- 1.3.10
- 1.3.4
- 1.3.0
- 1.2.0
- 1.1.0
- 1.0.12
- 1.0.11
- 1.0.10
- 1.0.01
- 1.0.0
- 0.34.0
- 0.33.0
- 0.32.0
- 0.31.0
- 0.3.40
- 0.3.32
- 0.3.31
- 0.3.30
- 0.3.20
- 0.3.10
- 0.3.0
- 0.2.10
- 0.2.0
- 0.1.01
- 0.1.0
- dev-dependabot/github_actions/stefanzweifel/git-auto-commit-action-7
- dev-develop
- dev-dependabot/github_actions/actions/checkout-5
This package is auto-updated.
Last update: 2025-10-13 13:02:24 UTC
README
PHP package to read metadata and extract covers from eBooks, comics and audiobooks.
Because metadata are the key against chaos.
- eBooks:
.epub,.pdf,.azw,.azw3,.kf8,.kfx,.mobi,.prc,.fb2 - Comics:
.cbz,.cbr,.cb7,.cbt(metadata from github.com/anansi-project) - Audiobooks:
.mp3,.m4a,.m4b,.flac,.oggwith external packagekiwilan/php-audio(MUST be installed separately)
To know more see Supported formats. Supports Linux, macOS and Windows.
Note
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.
Warning
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.
Requirements
- PHP version
>=8.1 - PHP extensions:
- Binaries
p7zip(optional) binarys for.CB7(can handle.CBRtoo)
- Audiobooks
kiwilan/php-audio(optional) for.mp3,.m4a,.m4b,.flac,.ogg(see Supported formats)
- To know more about requirements, see Supported formats
Note
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.
Warning
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.
Features
- Support multiple formats, see Supported formats
- π Read metadata from eBooks, comics, and audiobooks
- πΌοΈ Extract covers from eBooks, comics, and audiobooks
- π΅ Works with audiobooks if
kiwilan/php-audiois installed - π Support metadata
- eBooks:
EPUBv2 and v3 from IDPF withcalibre:seriesfrom Calibre |MOBIfrom Mobipocket (and derivatives) |FB2from FictionBook - Comics:
CBAM(Comic Book Archive Metadata) :ComicInfo.xmlformat from ComicRack and maintained byanansi-project PDFwithsmalot/pdfparser- Audiobooks:
ID3,vorbisandflactags withkiwilan/php-audio(not included), based on audiobookshelf specifications
- eBooks:
- π Chapters extraction (
EPUBonly) - π¦
EPUBandCBZcreation supported
- Works perfectly with
kiwilan/php-opds: PHP package to generate OPDS feeds (not included)
Roadmap
- Better
.epubcreation support - Add
.epubmetadata update support - Add better handling of MOBI files:
libmobiandebook-convertfrom Calibre (fallback is available) - Add support of
ebook-convertfrom Calibre - Add suport for DJVU:
djvulibre
Installation
You can install the package via composer:
composer require kiwilan/php-ebook
Usage
With eBook files or audiobook* files (to know more about formats, see Supported formats).
*: should be installed separately, see Requirements.
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->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 $ebook->getCreatedAt(); // ?DateTime => file modified date $ebook->getSize(); // int => file size in bytes $ebook->getSizeHumanReadable(); // string => file size in human readable format
For advanced description parsing, you can use getDescriptionAdvanced() method with BookDescription class.
use Kiwilan\Ebook\Ebook; $ebook = Ebook::read('path/to/ebook.epub'); $description = $ebook->getDescriptionAdvanced(); // BookDescription $description->getDescription(); // string => raw description $description->toHtml(?int $limit = null); // string => description formatted to HTML $description->toString(?int $limit = null); // string => description formatted to plain text $description->toStringMultiline(?int $limit = null); // string => description formatted to plain text with new lines
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`
Note
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
Note
For audiobooks, all metadata are stored into extras array, you will find duplicate with Ebook::class properties. See Formats specifications for more informations.
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 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->hasCover(); // bool => `true` if cover exists $ebook->hasMetadata(); // bool => `true` if metadata exists $ebook->hasSeries(); // bool => `true` if series exists $ebook->isBadFile(); // bool => `true` if file is not readable
Metadata
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
MetaTitle
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 => slug title, like `lord-of-the-rings-en-01-fellowship-of-the-ring-j-r-r-tolkien-1954-epub` $metaTitle->getSeriesSlug(); // ?string => slug series title, like `lord-of-the-rings-en`
You can customize slug with MetaTitle::class:
$meta->getSlug(removeDeterminers: true, addSeries: true, addVolume: true, addAuthor: true, addYear: true, addExtension: true, addLanguage: true); $meta->getSeriesSlug(removeDeterminers: true, addAuthor: false, addExtension: false, addLanguage: true);
Cover
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
Note
- For
PDF, cover can only be extracted ifimagickPHP extension. - For Audiobook, cover can be extracted with some formats.
Formats specifications
Audiobooks
For audiobooks, you have to install seperately kiwilan/php-audio.
Specifications are based on audiobookshelf and ID3 tags. Metadata on audio files will be mapped as follows (second tag after "/" is a fallback):
Properties of Audio::class are:
| ID3 Tag (case-insensitive) | eBook |
|---|---|
artist / album-artist |
Authors* |
album / title |
Title |
subtitle |
Extra property subtitle |
publisher |
Publisher |
year |
Publish Year |
composer |
Extra property narrators |
description |
Description |
genre |
Tags** |
series / mvnm |
Series |
series-part / mvin |
Volume |
language / lang |
Language |
isbn |
Identifiers isbn |
asin / audible_asin |
Identifiers asin |
| Overdrive MediaMarkers | Extra property chapters |
- * Authors naming as well as multiple authors separated by
,,;,&orand. - ** Tags can include multiple tags separated by
/,//, or;. e.g. "Science Fiction/Fiction/Fantasy"
You can find all metadata into getExtras() array of Ebook::class.
EPUB
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
Note
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.
Creation
You can create an EPUB or CBZ file with create() static method.
Note
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>') ->save(); // Build from files $creator->addFile('mimetype', 'path/to/mimetype') ->addFile('META-INF/container.xml', 'path/to/container.xml') ->save(); // Build from directory $creator->addDirectory('./', 'path/to/directory') ->save();
Supported formats
There is a lot of different formats for eBooks and comics, if you want to know more about:
- Comparison of e-book formats for eBooks
- Comic book archive for comics
- Amazing MobileRead wiki
| 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 |
β | 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 |
β | If kiwilan/php-audio is installed |
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.
Testing
composer test
Changelog
Please see CHANGELOG for more information on what has changed recently.
Credits
spatieforspatie/package-skeleton-phpkiwilanforkiwilan/php-archive,kiwilan/php-audio,kiwilan/php-xml-reader- Ewilan Rivière author of this package
- All Contributors
License
The MIT License (MIT). Please see License File for more information.
