PHPackages                             x5qubits/fpdm - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [PDF &amp; Document Generation](/categories/documents)
4. /
5. x5qubits/fpdm

ActiveLibrary[PDF &amp; Document Generation](/categories/documents)

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.

v1.0.0(3mo ago)191↓22.2%MITPHPPHP &gt;=7.4.0

Since Apr 17Pushed 3mo agoCompare

[ Source](https://github.com/x5qubits/fpdm)[ Packagist](https://packagist.org/packages/x5qubits/fpdm)[ Docs](https://github.com/x5qubits/fpdm)[ RSS](/packages/x5qubits-fpdm/feed)WikiDiscussions master Synced 1w ago

READMEChangelogDependenciesVersions (3)Used By (0)

FPDM-FQB
========

[](#fpdm-fqb)

PHP PDF form filling library — actively maintained fork of [tmw/fpdm](https://github.com/codeshell/fpdm) (original script by Olivier Plathey, 2017).

Maintained by [Five Quantum Bits](https://fiveqb.com) — [github.com/x5qubits/fpdm](https://github.com/x5qubits/fpdm).

---

Why this fork?
--------------

[](#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** (`/Parent` hierarchies) 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
-------------------

[](#changes-vs-tmwfpdm)

### 1. Adobe Reader checkbox fix *(critical)*

[](#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)*

[](#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:

1. Captures `/Parent` object references during parsing
2. Stores nested widgets under temporary `__obj_X` keys
3. Post-processes to walk each `/Parent` chain and rebuild full dotted paths
4. 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)*

[](#3-php-80-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
------------

[](#installation)

```
composer require x5qubits/fpdm
```

Or standalone:

```
require_once '/path/to/src/fpdm.php';
```

---

Usage
-----

[](#usage)

### Basic — fill text fields

[](#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)

[](#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

[](#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

[](#template-compatibility)

If your PDF throws an error about object streams or incremental updates, run it through [ilovepdf.com/repair-pdf](https://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
------------

[](#output-modes)

ModeDescription`$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
------------

[](#requirements)

- PHP 7.4 or higher (PHP 8.0, 8.1, 8.2, 8.3 supported)
- No other dependencies

---

Credits
-------

[](#credits)

- **Olivier Plathey** — original FPDM script ([fpdf.org](http://www.fpdf.org/en/script/script93.php))
- **codeshell** — tmw/fpdm Composer package and PHP 7 compatibility
- **Five Quantum Bits** — this fork ([fiveqb.com](https://fiveqb.com))

###  Health Score

36

—

LowBetter than 79% of packages

Maintenance81

Actively maintained with recent releases

Popularity15

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity35

Early-stage or recently created project

 Bus Factor1

Top contributor holds 83.3% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

99d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/52882756?v=4)[FQB](/maintainers/x5qubits)[@x5qubits](https://github.com/x5qubits)

---

Top Contributors

[![codeshell](https://avatars.githubusercontent.com/u/23580812?v=4)](https://github.com/codeshell "codeshell (20 commits)")[![x5qubits](https://avatars.githubusercontent.com/u/52882756?v=4)](https://github.com/x5qubits "x5qubits (4 commits)")

---

Tags

pdffpdffieldsFormscheckboxfillpopulatefpdmAcroForm

### Embed Badge

![Health badge](/badges/x5qubits-fpdm/health.svg)

```
[![Health](https://phpackages.com/badges/x5qubits-fpdm/health.svg)](https://phpackages.com/packages/x5qubits-fpdm)
```

###  Alternatives

[tmw/fpdm

PDF form filling using FPDM Class written by FPDF author Olivier

129674.6k3](/packages/tmw-fpdm)[setasign/fpdi

FPDI is a collection of PHP classes facilitating developers to read pages from existing PDF documents and use them as templates in FPDF. Because it is also possible to use FPDI with TCPDF, there are no fixed dependencies defined. Please see suggestions for packages which evaluates the dependencies automatically.

1.2k155.8M297](/packages/setasign-fpdi)[setasign/fpdf

FPDF is a PHP class which allows to generate PDF files with pure PHP. F from FPDF stands for Free: you may use it for any kind of usage and modify it to suit your needs.

77870.8M282](/packages/setasign-fpdf)[setasign/tfpdf

This class is a modified version of FPDF that adds UTF-8 support. The latest version is based on FPDF 1.85.

437.5M44](/packages/setasign-tfpdf)[fpdf/fpdf

FPDF Composer Wrapper

573.0M29](/packages/fpdf-fpdf)[setasign/fpdi-protection

A FPDI compatible version of the FPDF\_Protection script.

324.4M2](/packages/setasign-fpdi-protection)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
