How to Generate PDFs with PHP
Choose a PHP PDF library based on whether you build pages in code or already have HTML and CSS. Compare the main approaches and create a PDF with tc-lib-pdf.
To generate PDFs with PHP, choose between a document-authoring API that builds page elements in code and an HTML-to-PDF library that renders HTML and CSS. If starting a new project in the TCPDF family, consider tc-lib-pdf: its project describes it as the current generation, installable with Composer, requiring PHP 8.2 or later. The legacy TCPDF codebase is deprecated. If your application already produces HTML, evaluate mPDF or Dompdf against your real templates. None of these choices should be assumed to behave like a full modern browser.
This guide shows a complete small document-authoring example, explains the HTML-to-PDF alternatives, and gives a checklist for layout, fonts, remote assets, operations, and licensing.
1. Choose the PDF workflow that matches your input
| Workflow | Good fit when | Check before choosing |
|---|---|---|
| Document-authoring API | Your PHP code assembles text, shapes, images, and page structure directly. | Page layout, font embedding and multilingual text, image handling, required PDF features, and the learning curve of the API. |
| HTML/CSS conversion | Your application already creates HTML documents and the library supports the CSS and typography your templates need. | Supported CSS, tables, page breaks, headers and footers, font behavior, remote-resource settings, and output from representative documents. |
For direct construction, FPDF is described by its project as a PHP class for creating PDFs without PDFlib; the project says it may be used and modified for any kind of usage. The tc-lib-pdf project describes a broader pure-PHP authoring API and documents features across layout, fonts, multilingual text, graphics, images, barcodes, interactive documents, standards, encryption, signatures, and PDF reuse. Verify specific capabilities in the current documentation and with a sample matching your document.
For HTML input, mPDF describes itself as a library for generating PDFs from UTF-8 encoded HTML. Dompdf describes itself as a CSS 2.1 layout engine. Treat those descriptions as starting points, not promises that every browser layout or CSS feature will render identically.
2. Generate a PDF with tc-lib-pdf
Prerequisites and installation
- Check that the deployment runtime is PHP 8.2 or later, as required by the tc-lib-pdf project.
- Install Composer if your project does not already use it.
- From the project directory, install the package:
composer require tecnickcom/tc-lib-pdf
Consult the tc-lib-pdf project documentation for the current API and package guidance. The project identifies tc-lib-pdf as the current generation of TCPDF and says new development happens in tc-lib-pdf and companion packages; legacy TCPDF is deprecated.
Build a minimal document
The following is a complete PHP entry point that loads Composer’s autoloader and checks the runtime and installed package. It deliberately stops before constructing the PDF: use the current project documentation’s API example for the installed package version rather than relying on an unverified method sequence.
<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
if (PHP_VERSION_ID < 80200) {
throw new RuntimeException('tc-lib-pdf requires PHP 8.2 or later.');
}
// Create the document, add a page, place text and graphics, and write the
// output using the API documented for the installed tc-lib-pdf version.
// See https://tcpdf.org/docs/ for current examples and feature guidance.
A useful first implementation should create one page with a heading, a paragraph, and a short table or image if your real documents need them. Then test page boundaries, font rendering, and output delivery before adding more features. The project documentation’s feature index covers many advanced areas; confirm the exact API and requirements for any feature you depend on.
3. Convert HTML and CSS to PDF
If your app already renders the document as HTML, compare mPDF and Dompdf using a representative template. Use the package documentation for the current installation commands and API because versions and runtime requirements can change.
mPDF
mPDF is intended to generate PDFs from UTF-8 encoded HTML. It can suit an application whose content is already HTML, but check the exact CSS, page-break, and font requirements of your templates in the project’s documentation and with actual output. The project states that it is licensed under GPL v2; review how that license applies to your distribution before adopting it.
Dompdf
Dompdf is a PHP CSS 2.1 layout engine. Its project repository says that fetching remote stylesheets and images requires cURL or allow_url_fopen. Configure remote resource access carefully for the HTML your application accepts, and avoid treating user-provided markup as safe merely because it will be converted to a PDF.
The Dompdf repository also advises against using one Dompdf instance to render multiple HTML documents, because parsing and rendering artifacts may remain and affect later renders. Create a fresh instance per document unless the current project guidance says otherwise.
4. Make a representative test document before committing
- List the real requirements. Include page size, margins, page numbering, headers and footers, tables, images, links, and any interactive or archival PDF requirements.
- Include difficult content. Test long paragraphs, content near page boundaries, wide tables, missing or long words, accented characters, and every required writing system.
- Check typography. Confirm font formats, embedding, Unicode coverage, bidirectional text, and shaping for the languages you use. Do not assume a library’s general multilingual claims guarantee correct output for every font and script.
- Check layout fidelity. For HTML conversion, exercise the CSS actually used in production. Verify breaks, repeated table headings, positioning, and headers and footers by inspecting the resulting PDF.
- Check assets and links. Test images, local assets, and any remote assets with the deployment environment’s network and permissions.
- Check runtime and operations. Measure memory and render time with realistic document sizes, and account for temporary files and cleanup if your workflow uses them.
- Review maintenance and licensing. Recheck package status, supported PHP releases, exact dependency licenses, and upgrade compatibility before release.
5. Options and document behavior to verify
The right options depend on the chosen library and document. Confirm each in that library’s current documentation rather than assuming identical names or behavior across packages.
- Page geometry: paper size, orientation, margins, and custom page dimensions.
- Pagination: page breaks, repeated table headings, page numbers, headers, and footers.
- Typography: font registration, embedding, fallback behavior, Unicode coverage, and shaping.
- HTML and CSS: supported selectors and properties, table layout, positioning, and print-specific styles.
- Images and assets: accepted formats, relative paths, local file access, remote fetching, and missing-resource behavior.
- Output handling: return bytes to an HTTP response, save to a controlled path, or stream to a caller; set the response content type and filename appropriately in your application.
- Advanced PDF needs: encryption, signatures, forms, PDF/A or other standards, barcodes, and importing or reusing existing PDFs.
6. Common problems and fixes
| Symptom | Likely cause | What to do |
|---|---|---|
| Composer reports an unsupported PHP version | The installed runtime is below the package requirement. | For tc-lib-pdf, use PHP 8.2 or later, or choose a package compatible with the runtime you must support. |
| HTML looks different in the PDF than in a browser | The renderer supports a subset of CSS and has its own layout behavior. | Reduce the template to a failing case, check the library’s supported CSS, and adjust the markup or choose a renderer that meets the required layout. |
| Remote images or stylesheets are missing in Dompdf | Remote fetching is unavailable or not configured; cURL or allow_url_fopen may be needed. |
Check the PHP environment and the Dompdf remote-resource configuration. Prefer controlled, trusted resources and verify access from the actual deployment environment. |
| Characters appear as boxes or incorrectly shaped | The selected font may lack glyphs or the renderer may not handle the required script as expected. | Test a font with the needed coverage, verify embedding and shaping support, and generate a sample containing the actual languages in use. |
| Later documents contain stale content or render inconsistently with Dompdf | A reused instance can retain parsing or rendering artifacts. | Use a fresh Dompdf instance for each HTML document, as the project repository advises. |
| Output is empty or truncated | Rendering may have failed, output may have been sent before PDF bytes, or the response path may be incorrect. | Check application and PHP error logs, ensure no debug output precedes the PDF, and validate the returned or saved file with a PDF reader. |
| Memory or execution limits are hit on large documents | Large images, long tables, many pages, or repeated rendering can raise resource use. | Reproduce with realistic input, reduce image dimensions where appropriate, split work if the document can be divided, and tune runtime limits only after measuring. |
7. Performance, reliability, and cost considerations
The reviewed project documentation does not establish comparable performance benchmarks, so select by measured output and behavior on your own representative documents. Rendering cost in your application includes CPU time, memory, storage or temporary-file handling, and any external resources or rendering service your chosen approach needs. Track failures and render duration in production, and decide how the application will handle a failed render, retry safely, or report a useful error to the caller.
For reliability, keep templates and assets controlled, test dependency upgrades against saved representative documents, and validate that generated output can be opened. If remote resources are required, account for network failures and slow or unavailable hosts. Review exact package licenses and project maintenance at adoption time; package versions, PHP support, and licensing metadata can change.
8. Or skip the browser setup
If by “PDF” you mean a PDF capture of an existing web page, use ScreenshotNeo’s website screenshot API instead of building and maintaining a browser capture setup. It returns a PDF from one GET request. See the ScreenshotNeo API documentation; the product also provides an MCP server and screenshot API.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o page.pdf
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com", "format": "pdf"},
timeout=90,
)
r.raise_for_status()
open("page.pdf", "wb").write(r.content)
const q = new URLSearchParams({
access_key: 'YOUR_API_KEY',
url: 'https://stripe.com',
format: 'pdf'
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`ScreenshotNeo request failed: ${res.status}`);
const bytes = new Uint8Array(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('page.pdf', bytes));
ScreenshotNeo accepts cookie or consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be turned off. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and responses identify the page verdict and billing status in headers. Its MCP server includes tools for AI agents to take screenshots, get page information, and capture PDFs. The free plan includes 1,000 screenshots each month with no card; paid plans start at $5 for 3,000 shots. This is for capturing a website as a PDF, not composing a custom PDF document from PHP data.
Sign up for 1,000 free screenshots a month with no card.
9. Frequently asked questions
Is legacy TCPDF still the best starting point for a new project?
The TCPDF project marks the legacy codebase as deprecated and points new development to tc-lib-pdf and companion packages. Check the current requirements and migration guidance before choosing.
Can an HTML-to-PDF library render any page that works in Chrome?
No. mPDF and Dompdf have their own supported features and layout behavior. Verify your actual templates rather than assuming browser equivalence.
Which library is best for multilingual documents?
There is no universal answer from the project descriptions alone. Test the fonts, glyph coverage, bidirectional behavior, and shaping needed by your languages with representative content.
Can I use ScreenshotNeo to create an invoice PDF from PHP values?
ScreenshotNeo captures a web page as a PDF. For a custom invoice composed from PHP data, use a PDF authoring library or render a controlled HTML invoice with an HTML-to-PDF library.


