Documentation

EpubReader

FinalYes

Minimal in-tree EPUB reader.

Replaces kiwilan/php-ebook for LWT's single use case: pulling metadata and readable chapter text out of an EPUB. It deliberately implements only EPUB, where the dependency also covered MOBI, CBZ and PDF, none of which LWT imports.

Structure read, per the OCF and OPF specifications:

  1. META-INF/container.xml names the OPF package document.
  2. The OPF carries Dublin Core metadata, a manifest of every resource, and a spine giving reading order.
  3. The table of contents is either an EPUB 2 NCX (navMap/navPoint) or an EPUB 3 navigation document (<nav epub:type="toc">). Both are read; NCX wins when a book ships both, matching reader behaviour.

Every XPath query matches on local-name() because EPUBs in the wild are inconsistent about namespace prefixes and default namespaces.

Tags
since
3.4.0

Table of Contents

Constants

LIBXML_OPTIONS  : mixed = LIBXML_NONET | LIBXML_NOERROR | LIBXML_NOWARNING
libxml options: never fetch external resources, and keep entity substitution off, so a hostile EPUB cannot mount an XXE or billion-laughs attack through any of the XML documents we parse.

Methods

read()  : EpubBook
Read an EPUB from disk.
directoryOf()  : string
The directory part of an archive path, with a trailing slash, or '' at the root.
firstMetadataValue()  : string|null
The first Dublin Core value for an element name, or null when absent.
locatePackageDocument()  : string
Resolve the OPF package document path from `META-INF/container.xml`.
metadataValues()  : array<int, string>
Every non-empty Dublin Core value for an element name, in document order.
parseHtml()  : DOMDocument|null
Parse a navigation document, which may be XHTML or plain HTML.
parseXml()  : DOMDocument|null
Parse XML, returning null instead of raising on malformed input.
readArchive()  : EpubBook
Parse an already-open archive.
readManifest()  : array<string, array{href: string, mediaType: string, properties: string}>
Read the manifest into a map of item id => item details.
readNavEntries()  : array<int, array{0: string, 1: string}>
Read EPUB 3 navigation-document TOC links, in document order.
readNcxEntries()  : array<int, array{0: string, 1: string}>
Read EPUB 2 NCX navigation points, in document order.
readSpine()  : array<int, EpubDocument>
Read the spine into content documents, in reading order.
readTableOfContents()  : array<int, EpubChapter>
Build the chapter list from whichever table of contents the EPUB ships.
resolveHref()  : string
Resolve a TOC href, dropping any fragment, against its document's directory.

Constants

LIBXML_OPTIONS

libxml options: never fetch external resources, and keep entity substitution off, so a hostile EPUB cannot mount an XXE or billion-laughs attack through any of the XML documents we parse.

private mixed LIBXML_OPTIONS = LIBXML_NONET | LIBXML_NOERROR | LIBXML_NOWARNING

Methods

read()

Read an EPUB from disk.

public static read(string $filePath) : EpubBook
Parameters
$filePath : string

Absolute path to the EPUB

Tags
throws
RuntimeException

When the archive or its package document is unreadable

Return values
EpubBook

directoryOf()

The directory part of an archive path, with a trailing slash, or '' at the root.

private static directoryOf(string $path) : string
Parameters
$path : string
Return values
string

firstMetadataValue()

The first Dublin Core value for an element name, or null when absent.

private static firstMetadataValue(DOMXPath $xpath, string $name) : string|null
Parameters
$xpath : DOMXPath
$name : string
Return values
string|null

locatePackageDocument()

Resolve the OPF package document path from `META-INF/container.xml`.

private static locatePackageDocument(EpubArchive $archive) : string

Falls back to scanning for a lone .opf entry when the container is absent or malformed, which keeps slightly broken EPUBs importable.

Parameters
$archive : EpubArchive
Tags
throws
RuntimeException

When no package document can be located

Return values
string

metadataValues()

Every non-empty Dublin Core value for an element name, in document order.

private static metadataValues(DOMXPath $xpath, string $name) : array<int, string>
Parameters
$xpath : DOMXPath
$name : string
Return values
array<int, string>

parseHtml()

Parse a navigation document, which may be XHTML or plain HTML.

private static parseHtml(string $source) : DOMDocument|null
Parameters
$source : string
Return values
DOMDocument|null

parseXml()

Parse XML, returning null instead of raising on malformed input.

private static parseXml(string $source) : DOMDocument|null
Parameters
$source : string
Return values
DOMDocument|null

readArchive()

Parse an already-open archive.

private static readArchive(EpubArchive $archive) : EpubBook
Parameters
$archive : EpubArchive
Tags
throws
RuntimeException

When the package document is missing or unparseable

Return values
EpubBook

readManifest()

Read the manifest into a map of item id => item details.

private static readManifest(DOMXPath $xpath, string $baseDir, EpubArchive $archive) : array<string, array{href: string, mediaType: string, properties: string}>
Parameters
$xpath : DOMXPath
$baseDir : string
$archive : EpubArchive
Return values
array<string, array{href: string, mediaType: string, properties: string}>

readNavEntries()

Read EPUB 3 navigation-document TOC links, in document order.

private static readNavEntries(array<string, array{href: string, mediaType: string, properties: string}> $manifest, EpubArchive $archive) : array<int, array{0: string, 1: string}>
Parameters
$manifest : array<string, array{href: string, mediaType: string, properties: string}>
$archive : EpubArchive
Return values
array<int, array{0: string, 1: string}>

Label / resolved-href pairs

readNcxEntries()

Read EPUB 2 NCX navigation points, in document order.

private static readNcxEntries(array<string, array{href: string, mediaType: string, properties: string}> $manifest, EpubArchive $archive) : array<int, array{0: string, 1: string}>
Parameters
$manifest : array<string, array{href: string, mediaType: string, properties: string}>
$archive : EpubArchive
Return values
array<int, array{0: string, 1: string}>

Label / resolved-href pairs

readSpine()

Read the spine into content documents, in reading order.

private static readSpine(DOMXPath $xpath, array<string, array{href: string, mediaType: string, properties: string}> $manifest, EpubArchive $archive) : array<int, EpubDocument>
Parameters
$xpath : DOMXPath
$manifest : array<string, array{href: string, mediaType: string, properties: string}>
$archive : EpubArchive
Return values
array<int, EpubDocument>

readTableOfContents()

Build the chapter list from whichever table of contents the EPUB ships.

private static readTableOfContents(DOMXPath $xpath, array<string, array{href: string, mediaType: string, properties: string}> $manifest, EpubArchive $archive, array<int, EpubDocument$documents) : array<int, EpubChapter>
Parameters
$xpath : DOMXPath
$manifest : array<string, array{href: string, mediaType: string, properties: string}>
$archive : EpubArchive
$documents : array<int, EpubDocument>
Return values
array<int, EpubChapter>

resolveHref()

Resolve a TOC href, dropping any fragment, against its document's directory.

private static resolveHref(EpubArchive $archive, string $baseDir, string $href) : string
Parameters
$archive : EpubArchive
$baseDir : string
$href : string
Return values
string
On this page

Search results