Search by

pd4ml / pd4ml-php

PD4ML

PD4ML for PHP: HTML to PDF, PDF/A, PDF/UA, DOCX, RTF and image conversion (the PD4ML Java API through a bridge)

v1.1.1 2026-11-11 01:54 UTC

This package is auto-updated.

Last update: 2026-11-11 02:04:41 UTC


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 (and openssl to download PD4ML)
  • Java 8 or later (JDK or JRE): JAVA_HOME, PD4ML_JAVA, or java on the PATH

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.