If you need to combine multiple PDF files into a single PDF using PHP, FPDI makes it pretty straightforward.
I originally wrote this tutorial back in 2020 using a manual installation of FPDF and FPDI. The basic approach is still the same, but these days I recommend installing the libraries with Composer. It keeps the setup much cleaner and makes updating the libraries easier later.
In this example, we'll take multiple PDF files, loop through every page in each file, and create one merged PDF.
Install FPDF and FPDI
From your project directory, install FPDF and FPDI with Composer:
composer require setasign/fpdf setasign/fpdi
Once Composer finishes, you'll have a vendor directory containing the libraries and Composer's autoloader.
Your project can be as simple as:
project/
├── pdfs/
│ ├── page-1.pdf
│ ├── page-2.pdf
│ └── page-3.pdf
├── vendor/
├── composer.json
└── merge.php
For this example, the PDFs we're combining are stored inside the pdfs directory.
Merge Multiple PDF Files With PHP
Create a file called merge.php and add the following:
<?php
require_once __DIR__ . '/vendor/autoload.php';
use setasign\Fpdi\Fpdi;
$pdf = new Fpdi();
$files = [
__DIR__ . '/pdfs/page-1.pdf',
__DIR__ . '/pdfs/page-2.pdf',
__DIR__ . '/pdfs/page-3.pdf',
];
foreach ($files as $file) {
if (!file_exists($file)) {
throw new RuntimeException("PDF not found: {$file}");
}
$pageCount = $pdf->setSourceFile($file);
for ($pageNumber = 1; $pageNumber <= $pageCount; $pageNumber++) {
$templateId = $pdf->importPage($pageNumber);
$size = $pdf->getTemplateSize($templateId);
$pdf->AddPage(
$size['orientation'],
[$size['width'], $size['height']]
);
$pdf->useTemplate($templateId);
}
}
$pdf->Output('F', __DIR__ . '/merged.pdf');
Run the script and you should end up with:
merged.pdf
in your project directory.
That's really all there is to it.
How the Code Works
First, we load Composer's autoloader and create a new FPDI instance:
require_once __DIR__ . '/vendor/autoload.php';
use setasign\Fpdi\Fpdi;
$pdf = new Fpdi();
Next, we create an array containing the PDF files we want to merge:
$files = [
__DIR__ . '/pdfs/page-1.pdf',
__DIR__ . '/pdfs/page-2.pdf',
__DIR__ . '/pdfs/page-3.pdf',
];
You can add as many files to this array as you need.
We then loop through each PDF:
$pageCount = $pdf->setSourceFile($file);
setSourceFile() opens the PDF and returns the number of pages in it.
From there, we loop through every page:
for ($pageNumber = 1; $pageNumber <= $pageCount; $pageNumber++) {
Each page is imported with:
$templateId = $pdf->importPage($pageNumber);
We also grab the dimensions and orientation of the original page:
$size = $pdf->getTemplateSize($templateId);
That allows us to create the new page using the same dimensions:
$pdf->AddPage(
$size['orientation'],
[$size['width'], $size['height']]
);
Finally, the imported PDF page is placed onto the new page:
$pdf->useTemplate($templateId);
The process repeats until every page from every PDF has been added.
Save or Download the Merged PDF
In the example above, I'm saving the resulting PDF to a file:
$pdf->Output('F', __DIR__ . '/merged.pdf');
If you're building this into a web application and want the browser to download the resulting PDF instead, you can change it to:
$pdf->Output('D', 'merged.pdf');
So:
F = save the PDF to a file
D = send the PDF as a download
Which option you use depends on what you're building.
Using Dynamic PDF Files
The files don't have to be hardcoded like they are in the example.
For example, you might build the array from uploaded documents, files associated with an order, generated invoices, form submissions, or PDFs stored for a specific customer.
As long as you end up with valid file paths, the merging portion of the script stays basically the same:
$files = [
$firstPdf,
$secondPdf,
$thirdPdf,
];
FPDI will work through each file and append its pages to the resulting document in the same order they appear in the array.
A Note About PDF Page Sizes
One improvement over my original version of this tutorial is that the updated example keeps the dimensions and orientation of each imported page.
The original code simply called:
$pdf->addPage();
That works when your PDFs all use the same page format, but it can cause problems if you're combining PDFs with different dimensions or a mixture of portrait and landscape pages.
Getting the imported page size before calling AddPage() makes the script much more reliable.
That's It
Once the script is in place, all you really need to do is update the $files array with the PDFs you want to combine and choose a name for the output file.
FPDI handles importing the individual pages, and FPDF creates the final PDF.
The original version of this tutorial used XAMPP as the local PHP environment, and that's still perfectly fine for testing. You can also run the same code through whatever local or server-based PHP environment you're already using.
If you're working on a PHP or WordPress project that needs custom PDF generation, document processing, API integrations, or other custom functionality, I also offer custom PHP and WordPress development. Get in touch with a short description of what you're building and I'll let you know how I can help.