x5qubits/fpdm
Composer 安装命令:
composer require x5qubits/fpdm
包简介
PHP PDF form filling library — actively maintained fork of tmw/fpdm (original by Olivier Plathey). Adds Adobe Reader checkbox compatibility, nested field support, and other fixes.
README 文档
README
PHP PDF form filling library — actively maintained fork of tmw/fpdm (original script by Olivier Plathey, 2017).
Maintained by Five Quantum Bits — github.com/x5qubits/fpdm.
Why this fork?
The upstream repository has been unmaintained since 2019. Several critical issues were discovered while using it in production with real-world PDF templates (Romanian government forms):
- Checkboxes were invisible in Adobe Acrobat / Adobe Reader (worked in browsers and Foxit, not Adobe)
- PDFs with nested form fields (
/Parenthierarchies) were only partially readable — 67 of 195 fields visible create_function()crashes on PHP 8.0+ (removed from the language)- Empty string input in
_bin2hex()caused fatal errors in PHP 8
Changes vs tmw/fpdm
1. Adobe Reader checkbox fix (critical)
Problem: The original set_field_checkbox() only wrote /AS /StateName (the appearance stream selector). Adobe Reader ignores /AS and reads /V (the field value) as authoritative. Result: checkboxes appeared checked in Chrome PDF viewer and Foxit but were always unchecked in Adobe.
Fix: After writing /AS, the library now also writes /V /StateName on the same widget object. If the template has no /V entry at all (common in ONRC templates), it is injected inline — without inserting new array elements which would corrupt xref offsets.
Before: /AS /Yes ← Adobe ignores this
After: /AS /Yes\n/V /Yes ← Adobe reads /V ✓
2. Nested field support via /Parent chain (major)
Problem: Complex PDF templates use AcroForm field hierarchies — a parent field contains children, children can have grandchildren, etc. Field names in such PDFs look like clasa_caen.0.3 or sectiune.row.col. The original parser only saw top-level objects and missed all nested widgets.
Fix: After the main parse loop, the library now:
- Captures
/Parentobject references during parsing - Stores nested widgets under temporary
__obj_Xkeys - Post-processes to walk each
/Parentchain and rebuild full dotted paths - Replaces temp keys with final paths like
clasa_caen.0.3
Result: a Romanian ONRC Declaratie Anexa 4 template went from 67 accessible fields to 195.
3. PHP 8.0+ compatibility (breaking in original)
create_function() removed in PHP 8.0
The _set_field_value() method used create_function() to build a callback dynamically. This was deprecated in PHP 7.2 and removed in PHP 8.0 — causing a fatal error on any PHP 8 server.
Fixed by replacing it with a proper closure using use ($self, $value).
_bin2hex() crash on empty string
The function used a do...while loop which unconditionally accessed $str[0] before checking length. On an empty string this triggers a warning in PHP 7 and a fatal error in PHP 8.
Fixed with an early return guard and a for loop.
Installation
composer require x5qubits/fpdm
Or standalone:
require_once '/path/to/src/fpdm.php';
Usage
Basic — fill text fields
$fields = [ 'name' => 'Ion Popescu', 'address' => 'Str. Victoriei nr. 10', 'date' => '17.04.2026', ]; $pdf = new FPDM('template.pdf'); $pdf->Load($fields, true); // true = UTF-8 $pdf->Merge(); $pdf->Output(); // stream to browser
Checkboxes (Adobe Reader compatible)
$pdf = new FPDM('template.pdf'); $pdf->useCheckboxParser = true; // required $pdf->Load([ 'agree_terms' => true, // checked 'newsletter' => false, // unchecked 'type_srl' => true, 'type_pfa' => false, ], true); $pdf->Merge(); $pdf->Output('F', 'output.pdf'); // F = save to file
You do not need to know the internal checkbox state name (Yes, On, 31.5, etc.) — it is read from the template automatically.
Nested / hierarchical fields
// Fields like "clasa_caen.0.3" work out of the box $fields = []; foreach (['6201', '6202', '6311'] as $i => $code) { $fields["clasa_caen.0.$i"] = $code; $fields["clasa_caen_desc.0.$i"] = 'Software development'; } $pdf = new FPDM('template_with_nested_fields.pdf'); $pdf->useCheckboxParser = true; $pdf->Load($fields, true); $pdf->Merge(); $pdf->Output('F', 'output.pdf');
Template compatibility
If your PDF throws an error about object streams or incremental updates, run it through ilovepdf.com/repair-pdf first. The repaired file is typically smaller and fully compatible.
Pattern for trying multiple candidates:
foreach (['template_repaired.pdf', 'template.pdf'] as $tpl) { try { $pdf = new FPDM($tpl); $pdf->useCheckboxParser = true; $pdf->Load($fields, true); $pdf->Merge(); $pdf->Output('F', 'output.pdf'); break; } catch (Exception $e) { $lastError = $e->getMessage(); } }
Output modes
| Mode | Description |
|---|---|
$pdf->Output() |
Stream to browser (default) |
$pdf->Output('F', 'path.pdf') |
Save to file |
$pdf->Output('S') |
Return as string |
$pdf->Output('D', 'name.pdf') |
Force download |
Requirements
- PHP 7.4 or higher (PHP 8.0, 8.1, 8.2, 8.3 supported)
- No other dependencies
Credits
- Olivier Plathey — original FPDM script (fpdf.org)
- codeshell — tmw/fpdm Composer package and PHP 7 compatibility
- Five Quantum Bits — this fork (fiveqb.com)
x5qubits/fpdm 适用场景与选型建议
x5qubits/fpdm 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 67 次下载、GitHub Stars 达 1, 最近一次更新时间为 2026 年 04 月 17 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「pdf」 「Forms」 「fpdf」 「fields」 「checkbox」 「populate」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 x5qubits/fpdm 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 x5qubits/fpdm 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 x5qubits/fpdm 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
ConfirmationField is a form field for Atk14 applications. It's like the BooleanField (checkbox) but the ConfirmationField must be ticked.
Field for number with restricted count of digits and decimal places
tfpdf
Extended FPDF
HTML and form generation
Build forms from schema
统计信息
- 总下载量: 67
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 1
- 点击次数: 40
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-04-17