Installation
composer require iio/libmergepdf
Add the service provider in config/app.php (if not auto-discovered):
'providers' => [
// ...
Iio\LibMergePdf\LibMergePdfServiceProvider::class,
],
Basic Merge
use Iio\LibMergePdf\LibMergePdf;
$pdf = new LibMergePdf();
$pdf->merge('output.pdf', ['file1.pdf', 'file2.pdf']);
First Use Case Merge multiple PDFs from a user upload directory and send the result as an attachment:
$files = request()->file('pdfs')->all();
$tempFiles = [];
foreach ($files as $file) {
$tempFiles[] = $file->store('temp');
}
$pdf = new LibMergePdf();
$mergedPath = $pdf->merge('merged.pdf', $tempFiles);
return response()->download($mergedPath)->deleteFileAfterSend(true);
LibMergePdf class methods: merge(), setOptions(), getOptions().tests/.Dynamic File Merging Merge PDFs based on user input (e.g., a form selecting multiple files):
$selectedFiles = request('file_ids'); // Assume IDs from DB
$paths = File::whereIn('id', $selectedFiles)->pluck('path')->toArray();
$pdf->merge('merged.pdf', $paths);
Streaming Large Files Avoid memory issues by streaming output directly to a response:
$pdf = new LibMergePdf();
$pdf->setOutputFile('php://output');
$pdf->merge('', ['file1.pdf', 'file2.pdf']);
return response()->streamDownload(function () use ($pdf) {
echo $pdf->getOutput();
}, 'merged.pdf');
Conditional Merging Skip empty or invalid files before merging:
$validFiles = array_filter($allFiles, function ($file) {
return file_exists($file) && filesize($file) > 0;
});
$pdf->merge('output.pdf', array_values($validFiles));
Integration with Queues Offload merging to a queue job for long-running tasks:
// MergePdfJob.php
public function handle() {
$pdf = new LibMergePdf();
$pdf->merge(storage_path('app/merged.pdf'), $this->files);
}
Storage::disk('local')->path() for consistent path handling.mime_type()).try-catch to handle exceptions (e.g., corrupt files):
try {
$pdf->merge('output.pdf', $files);
} catch (\Exception $e) {
Log::error("Merge failed: " . $e->getMessage());
return back()->withError('Merge failed.');
}
Memory Limits
memory_limit. Use streaming or chunked processing.memory_limit in php.ini or use set_time_limit():
ini_set('memory_limit', '512M');
set_time_limit(300);
File Paths
storage_path('file.pdf')) to avoid issues.\r\n may cause errors. Normalize paths:
$paths = array_map('str_replace', ['\\', '/'], $paths);
Permission Errors
chmod -R 775 storage/app/public
storage_path('app') and verify permissions.Corrupt PDFs
function isValidPdf($path) {
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $path);
finfo_close($finfo);
return strpos($mime, 'pdf') === 0;
}
error_log():
$pdf->setOptions(['verbose' => true]);
temp_* files in /tmp).Custom Options Override default behavior (e.g., page rotation, compression):
$pdf->setOptions([
'page_rotation' => 90, // Rotate all pages
'compress' => true, // Reduce file size
]);
Pre/Post-Processing Hook into the merge process to modify pages (e.g., add watermarks):
// Use a wrapper class or extend LibMergePdf
class CustomMergePdf extends LibMergePdf {
protected function beforeMerge() {
// Add logic here (e.g., inject a header page)
}
}
Fallback for Missing Dependencies The library relies on Ghostscript or pdftk. If missing:
# Ubuntu/Debian
sudo apt-get install ghostscript
setasign/fpdf for simple cases.Laravel Artisan Command Create a command for CLI merging:
// app/Console/Commands/MergePdfs.php
public function handle() {
$pdf = new LibMergePdf();
$pdf->merge('merged.pdf', $this->argument('files'));
}
Run with:
php artisan merge-pdfs file1.pdf file2.pdf
How can I help you explore Laravel packages today?