pd4ml / pd4ml-php
PD4ML for PHP: HTML to PDF, PDF/A, PDF/UA, DOCX, RTF and image conversion (the PD4ML Java API through a bridge)
Requires
- php: >=8.1
- ext-json: *
- ext-mbstring: *
- ext-simplexml: *
Requires (Dev)
None
Suggests
- ext-openssl: needed to download PD4ML over HTTPS (bin/pd4ml install)
Provides
None
Conflicts
None
Replaces
None
README
PD4ML for PHP: HTML and CSS to PDF, PDF/A, PDF/UA, DOCX, RTF and images, with the full public
PD4ML API (Java package com.pd4ml) available to PHP applications.
PD4ML runs in a small Java bridge process that PHP talks to; every public Java class, method, constant and enum can be used from PHP, and the module adds PHP I/O (paths, strings, streams) on top. New converters use the v42 layout engine by default.
require 'vendor/autoload.php'; // Composer's autoloader use Pd4ml\PD4ML; use Pd4ml\Java; $pd = new PD4ML(); // v42 layout engine $pd->setPageSize(Java::PageSize()->A4); $pd->setPageMargins(Java::PageMargins()->new(15, 15, 15, 15, Java::Units()->MM)); $pd->readHTML('invoice.html'); // a path, URL, Bytes or stream $pd->writePDF('invoice.pdf', Java::PdfSpec()->PDFA_3B); // a path or stream; no target: returned
Documentation: docs/guide.md — prerequisites, installation, use cases with code, tips and troubleshooting; docs/api.md — every class and method. The PD4ML manual itself is at https://pd4ml.com/docs/.
Requirements
- PHP 8.1+ with
json,mbstring,simplexml(andopensslto download PD4ML) - Java 8 or later (JDK or JRE):
JAVA_HOME,PD4ML_JAVA, orjavaon thePATH
Installation
The package is on Packagist, so Composer installs it:
composer require pd4ml/pd4ml-php
vendor/bin/pd4ml install # PD4ML 4.2 (Windows: vendor\bin\pd4ml install)
composer update pd4ml/pd4ml-php updates the module; vendor/bin/pd4ml install again updates
the PD4ML build it uses. Without Composer, clone https://github.com/zxfr/pd4ml-php, include
its src/autoload.php and run its tool as php bin/pd4ml.
pd4ml install downloads PD4ML from https://pd4ml.com/maven2 with the Bouncy Castle jars it
needs (from Maven Central), verifies them and stores them in the user's cache directory
(PD4ML_HOME to choose another); the module uses that build by itself. Options: --snapshots,
--version=X, --jakarta, --home=DIR, --force; vendor/bin/pd4ml list shows the versions.
By default it installs the newest PD4ML release from 4.2.0 on or, while there is none, the newest
4.2.x snapshot (4.2.0-SNAPSHOT today): this module's PD4ML 4.2 API (readEML/readMHT,
addAllowedResourceLocation, XMP addMetadata, the DOM API) needs PD4ML 4.2, which is not
released yet. Installs move to 4.2.0 by themselves once it is out. To stay on the current
release, pin it: vendor/bin/pd4ml install --version=4.1.2 (the 4.2 API is then unavailable).
Alternatively point the module at a build with PD4ML_CLASSPATH, PD4ML_CLASSPATH_FILE or
Bridge::configure(['classpath' => ...]).
Web servers
Under PHP-FPM or mod_php run one bridge server instead of a Java start per request:
vendor/bin/pd4ml serve --port=8723
and set PD4ML_BRIDGE=tcp://127.0.0.1:8723 for the web server.
Command line
vendor/bin/pd4ml convert page.html page.pdf [--spec=pdf/a-2b] [--engine=v40] # also .docx, .rtf, .png
vendor/bin/pd4ml version
Development
php tests/run.php |
the tests (PD4ML_NETWORK_TESTS=1: also the download; PD4ML_TEST_LICENSE: a license file for the DOM API tests) |
php tests/docs.php |
runs the guide's code snippets |
php tools/build-bridge.php |
rebuilds lib/pd4ml-bridge.jar from java/src (needs a JDK) |
php tools/gen-stubs.php [classpath-file] |
regenerates src/PD4MLApi.php and docs/api.md from the PD4ML classes |
The tests and generators use the PD4ML build from PD4ML_CLASSPATH/PD4ML_CLASSPATH_FILE,
./pd4ml.classpath (one classpath entry per line), or the installed one.
How it works
lib/pd4ml-bridge.jar (source in java/src, Java 8 bytecode) runs next to PD4ML and speaks a
line-based JSON protocol: PHP creates Java objects, calls methods (overloads resolved by
reflection) and reads fields by handle; bytes, streams, URLs and maps are converted at the
boundary; Java interfaces can be implemented by PHP callables (Java::proxy()), their calls
delivered to PHP while the conversion runs. The DOM API (getDocument(), layout()) comes as
PHP classes (Pd4ml\Dom) over the Java objects, with Java lists as PHP arrays.