jamesthomsen / mightypdf
A from-scratch PDF library for PHP: raw PDF assembly plus a content layer for text, drawing, images, SVG, and AcroForm fields -- and a reader that can open an existing PDF and edit it in place.
Requires
- php: ^8.3
- ext-dom: *
- ext-iconv: *
- ext-libxml: *
- ext-openssl: *
- ext-simplexml: *
- ext-zlib: *
Requires (Dev)
- phpstan/phpstan: ^2.2
- phpunit/phpunit: ^11.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
A from-scratch PDF library for PHP: raw PDF assembly plus a content layer for text, drawing, images, SVG, barcodes and AcroForm fields, a layout layer with cells and tables on top of it — and a reader that can open an existing PDF and edit it in place.
Requires PHP 8.3+, ext-iconv, ext-openssl, and ext-zlib.
Installation
composer require jamesthomsen/mightypdf
Quick start
require 'vendor/autoload.php'; use MightyPDF\Assembler\Document; use MightyPDF\Content\Font\StandardFont; use MightyPDF\Content\PageBuilder; $document = new Document(); $page = $document->newPage(); $content = new PageBuilder($document, $page); $content->drawText(StandardFont::HelveticaBold, 24.0, 72, 720, 'Hello, MightyPDF!'); $document->saveToFile('hello.pdf');
Runnable, more elaborate versions of every example below live in
examples/ — run any of them with php examples/0X-name.php;
output is written to examples/output/.
| File | Demonstrates |
|---|---|
| 01-blank-document.php | Minimal document, custom page size |
| 02-text-and-fonts.php | All 14 standard fonts, measuring text |
| 03-lines-and-shapes.php | Lines, filled/stroked rectangles, method chaining |
| 04-images.php | JPEG, PNG, GIF |
| 05-svg.php | SVG vector graphics |
| 06-form-fields.php | Text fields and checkboxes |
| 07-combined-document.php | Everything together, across multiple pages |
| 08-editing-existing-pdf.php | Opening a PDF with PdfEditor and editing an object (page rotation) |
| 09-encrypting-a-document.php | AES-256 encryption with Document::encrypt() and Permissions |
| 10-filling-an-existing-form.php | Filling an existing PDF's form fields with FormFiller |
| 11-stamping-an-existing-page.php | Stamping a page with PageOverlay, plus adding a field to an existing form |
| 12-document-metadata.php | Setting Title/Author/Subject/Keywords/Creator/Producer/CreationDate |
| 13-merging-documents.php | Combining pages from multiple PDFs into one with PdfMerger |
| 14-embedding-a-font.php | Embedding a TrueType or OpenType font, and pointing a form field at one |
| 15-links-and-bookmarks.php | Links out of and inside a document, and a bookmark tree |
| 16-a-report-with-the-layout-layer.php | A business report through Flow: cells, a table, a chart, a footer on every page |
| 17-shapes-transforms-and-transparency.php | Paths, ellipses, polygons, dashes, and scoped transforms, clips and alpha |
| 18-a-table-that-breaks-across-pages.php | Table: wrapping cells, a repeating header, colspans, striping |
| 19-barcodes-and-qr-codes.php | Code 39, Code 128, EAN-13, UPC-A, and QR at all four levels |
| 20-print-colours.php | CMYK, a spot colour at five tints, and a dieline separation |
| 21-attachments-and-viewer-preferences.php | An invoice carrying its own XML, viewer preferences, a rotated page |
| 24-a-print-ready-flyer-with-bleed.php | Bleed and trim boxes, artwork off the edge, margins from the cut |
| 25-form-data-in-and-out.php | Exporting a filled form as XFDF and JSON, and importing both back |
| 26-flattening-a-form-and-dropping-the-history.php | Inspecting a form's fields and where they sit, then flattening it and saving one revision |
Core concepts
Document is the top-level object. It owns every page and every
indirect object in the file, and is responsible for producing final PDF
bytes.
new Document()— start a new, empty document.$document->newPage(PageSize|PdfRectangle|null $mediaBox = null): Page— append a page and return it. Defaults to US Letter (612×792pt); pass aPageSize(PageSize::A4) or aPdfRectanglefor anything else.$document->pages(): array— all pages added so far.$document->save(): string— serialize the whole document to a PDF byte string.$document->saveToFile(string $path): void— serialize and write to disk in one step.$document->writeTo($handle): void— serialize straight to an open stream. See large documents.
PageBuilder is where you actually draw. Each page gets its own
builder:
$page = $document->newPage(); $content = new PageBuilder($document, $page);
Every draw call appends to that page's single content stream and returns
$this, so calls can be chained:
$content ->fillRectangle(72, 440, 40, 40, 1.0, 0.0, 0.0) ->fillRectangle(122, 440, 40, 40, 0.0, 1.0, 0.0) ->fillRectangle(172, 440, 40, 40, 0.0, 0.0, 1.0);
Coordinates and units. Everything is in PDF points (1/72 inch),
measured from the page's bottom-left corner, X increasing right and
Y increasing up — standard PDF convention, not screen/CSS convention.
Colors are RGB with each channel in the 0.0–1.0 range; Color
converts from hex and 0–255.
If you would rather work in millimetres from the top-left, with a cursor, cells and automatic page breaks, see the layout layer — it is built on everything below and replaces none of it.
Documentation
The reference used to live in this file. It outgrew it, so it is now
next door in docs/ — one page per thing you might be trying
to do.
Putting marks on a page
- Text and fonts — the standard 14, embedding TrueType and OpenType, wrapping, alignment, Unicode
- Drawing — lines, shapes, paths, transforms, clipping, transparency, and colour in RGB, CMYK or a named ink
- Images — JPEG, PNG, GIF and TIFF
- SVG — paths, gradients, patterns, text, CSS
- Barcodes — Code 128, EAN-13, QR, Data Matrix
Laying a document out
- The layout layer — millimetres from the top-left, cells, tables, columns, automatic page breaks, headers and footers
- Forms — creating AcroForm fields, filling them in, reading the data back, flattening
- Document features — links, bookmarks, metadata, attachments, how the file asks to be opened
- Print production — bleed, trim and the other page boxes
- Accessibility and tagging — a structure tree, reading order, alternate text
Producing and reworking files
- Producing the file — compression, documents larger than memory, encryption, and what this library throws when it fails
- Editing existing PDFs — opening, stamping, merging, splitting, extracting text, signing, saving as one revision
Before you file a bug
- Known limitations — what this does not do, and which of those are deliberate
- Upgrading — what changed between versions
Development
composer install vendor/bin/phpunit
Tests live in tests/, mirroring the src/ structure.