Merging PDF documents in PHP using FPDI and FPDF

Need to merge multiple PDFs into one file in your PHP application? In this DevTip, we'll explore how to combine PDF documents programmatically using PHP by leveraging the FPDI and FPDF libraries.
Prerequisites
Before we begin, ensure you have the following:
- PHP 7.1 or higher
- Composer installed
- Basic knowledge of PHP
Installing FPDI and FPDF libraries
First, install the required libraries using Composer. Open your terminal and run:
composer require setasign/fpdf:1.8.* setasign/fpdi:^2.5
This command installs FPDF and FPDI with their recommended versions for your project.
Basic usage of FPDF
FPDF is a PHP class that enables you to generate PDF files from scratch. Here’s an example of creating a simple PDF with FPDF:
<?php
declare(strict_types=1);
require 'vendor/autoload.php';
use FPDF;
$pdf = new FPDF();
$pdf->AddPage();
$pdf->SetFont('Arial', 'B', 16);
$pdf->Cell(40, 10, 'Hello World!');
$pdf->Output('F', 'hello_world.pdf');
This script generates a PDF file named hello_world.pdf
containing the text "Hello World!".
Importing existing PDFs with FPDI
FPDI extends FPDF by allowing you to import pages from existing PDF documents. The following example demonstrates how to import the first page of an existing PDF:
<?php
declare(strict_types=1);
require 'vendor/autoload.php';
use setasign\Fpdi\Fpdi;
use setasign\Fpdi\PdfParser\PdfParserException;
try {
$pdf = new Fpdi();
$pdf->AddPage();
$pdf->setSourceFile('existing.pdf');
$tplId = $pdf->importPage(1);
$pdf->useTemplate($tplId);
$pdf->Output('F', 'imported.pdf');
} catch (PdfParserException $e) {
error_log("PDF Parser Error: " . $e->getMessage());
}
This script imports the first page of existing.pdf
and generates a new PDF called imported.pdf
.
Merging two PDFs
Let’s combine our knowledge to merge two PDF documents. The following function imports all pages from two PDFs and merges them:
<?php
declare(strict_types=1);
require 'vendor/autoload.php';
use setasign\Fpdi\Fpdi;
use setasign\Fpdi\PdfParser\PdfParserException;
function mergePDFs(string $file1, string $file2, string $outputFile): bool {
try {
$pdf = new Fpdi();
// Import pages from the first PDF
$pageCount = $pdf->setSourceFile($file1);
for ($i = 1; $i <= $pageCount; $i++) {
$tplId = $pdf->importPage($i);
$pdf->AddPage();
$pdf->useTemplate($tplId);
}
// Import pages from the second PDF
$pageCount = $pdf->setSourceFile($file2);
for ($i = 1; $i <= $pageCount; $i++) {
$tplId = $pdf->importPage($i);
$pdf->AddPage();
$pdf->useTemplate($tplId);
}
$pdf->Output('F', $outputFile);
// Free memory
unset($pdf);
gc_collect_cycles();
return true;
} catch (PdfParserException $e) {
error_log("PDF Parser Error: " . $e->getMessage());
return false;
}
}
mergePDFs('document1.pdf', 'document2.pdf', 'merged.pdf');
This function takes two input files, imports all pages sequentially, and outputs a merged PDF.
Handling multiple PDFs dynamically
To merge an arbitrary number of PDFs, adjust the function to accept an array of file paths:
<?php
declare(strict_types=1);
require 'vendor/autoload.php';
use setasign\Fpdi\Fpdi;
use setasign\Fpdi\PdfParser\PdfParserException;
function mergePDFs(array $files, string $outputFile): bool {
try {
$pdf = new Fpdi();
foreach ($files as $file) {
if (!file_exists($file)) {
throw new \RuntimeException("File not found: $file");
}
$pageCount = $pdf->setSourceFile($file);
for ($i = 1; $i <= $pageCount; $i++) {
$tplId = $pdf->importPage($i);
$pdf->AddPage();
$pdf->useTemplate($tplId);
}
}
$pdf->Output('F', $outputFile);
// Free memory
unset($pdf);
gc_collect_cycles();
return true;
} catch (PdfParserException $e) {
error_log("PDF Parser Error: " . $e->getMessage());
return false;
} catch (\RuntimeException $e) {
error_log("Error: " . $e->getMessage());
return false;
}
}
$filesToMerge = ['document1.pdf', 'document2.pdf', 'document3.pdf'];
if (mergePDFs($filesToMerge, 'merged_multiple.pdf')) {
echo "PDFs merged successfully.";
} else {
echo "Failed to merge PDFs. Check error log for details.";
}
This version iterates over an array of PDFs, merging each document into a single output file.
PDF compatibility and limitations
When working with FPDI, keep these compatibility points in mind:
- FPDI supports PDF versions up to 1.7.
- Encrypted PDFs require additional handling and may not be supported out-of-the-box.
- Linearized PDFs (optimized for web viewing) are supported.
- Certain PDF features—such as forms, annotations, and interactive elements—might not be preserved.
- For large or complex PDFs, monitor memory usage and consider processing documents in smaller batches.
Alternative PDF libraries
If FPDI does not fully meet your requirements, consider exploring other PHP libraries for PDF manipulation:
- TCPDF offers comprehensive PDF generation and editing features, including support for advanced layout and formatting.
- tFPDF is a Unicode-enabled variant of FPDF, useful if you require extensive support for non-Latin characters.
Evaluate these alternatives based on your project’s complexity and specific needs.
Conclusion
Merging PDF documents in PHP with FPDI and FPDF provides a powerful solution for managing document workflows programmatically. This approach is flexible, allowing you to handle everything from simple PDF creation to complex, dynamic merging operations.
For more complex document processing needs or large-scale operations, consider using Transloadit's Document Processing service for a scalable, feature-rich solution.