Form Filling

One of the most powerful and frequently used features of pdftk is its ability to interact with PDF AcroForms. php-pdftk simplifies this drastically by allowing you to pass standard PHP associative arrays directly to the PDF.

Filling with a Data Array

To fill a form, use the fillForm() method. The keys in your PHP array must match the exact field names defined in the PDF document.

use mikehaertl\pdftk\Pdf;

$pdf = new Pdf('/full/path/to/w9_form.pdf');

$data = [
    'Name' => 'John Doe',
    'BusinessName' => 'Doe Enterprises LLC',
    'Address' => '123 Tech Lane',
    'Checkbox1' => 'Yes', // Use the specific export value defined in the PDF
];

$result = $pdf->fillForm($data)
    ->needAppearances()
    ->saveAs('filled_w9.pdf');

if ($result === false) {
    echo "Error: " . $pdf->getError();
}

Handling Nested Fields (Dot Notation)

Some PDF forms use hierarchical field names (e.g., Address.Street, Address.City). php-pdftk gracefully handles dot-notation keys in your array, automatically converting them into the deeply nested XML structure required by the XFDF format.

$data = [
    'Client.FirstName' => 'Jane',
    'Client.LastName' => 'Smith',
    'Client.Contact.Email' => '[email protected]'
];
$pdf->fillForm($data)->needAppearances()->execute();

The UTF-8 Challenge & needAppearances()

Native pdftk notoriously struggles with non-ASCII (UTF-8) characters (like Ä, ö, ç, or Cyrillic alphabets). php-pdftk solves this by seamlessly converting your PHP array into a UTF-8 compliant XFDF temporary file under the hood.

However, injecting the text is only half the battle. The PDF reader (like Adobe Acrobat or Chrome's PDF viewer) must know how to draw those characters.

Best Practice: Always chain the ->needAppearances() method when filling forms.

This flag instructs the client's PDF reader to regenerate the visual appearance stream of the form fields using the correct embedded fonts upon opening the file.

$pdf->fillForm(['name' => 'ÄÜÖ äüö мирано čárka'])
    ->needAppearances()
    ->saveAs('international_form.pdf');

The flatten() Trade-off

The flatten() modifier merges interactive form fields directly into the static document layer, making them uneditable.

Warning: In standard pdftk, flattening a document strips the needAppearances requirement, causing the PDF generator to attempt to draw the text itself. If the text contains UTF-8 characters, pdftk will likely fail to render them correctly, resulting in blank fields or gibberish.

If you require flattened, UTF-8 compliant documents, you may need to look into alternative renderers or use the pdftk-java replacement font feature.

Replacement Fonts (pdftk-java >= 3.3.0)

If you are using the modern pdftk-java port and your PDF's embedded fonts do not support the characters you are trying to inject, you can force the use of a local TrueType font during rendering:

$pdf->fillForm($data)
    ->replacementFont('/usr/share/fonts/dejavu/DejaVuSans.ttf')
    ->saveAs('filled.pdf');

AcroForms vs. XFA Forms (dropXfa)

There are two types of PDF forms: older AcroForms and newer, XML-based XFA forms (created by Adobe LiveCycle). pdftk can only fill AcroForms.

If a document contains both, readers will prioritize the XFA form, making it appear as if your data wasn't injected. php-pdftk automatically calls dropXfa() by default when you use fillForm() to strip out the XFA layer, ensuring your AcroForm data is respected.

Generating FDF/XFDF Files Independently

Occasionally, you don't want to fill the PDF on the server. Instead, you want to generate an XFDF file and let the client's machine merge it. This library exposes its internal XFDF/FDF generators for public use.

use mikehaertl\pdftk\XfdfFile;
use mikehaertl\pdftk\FdfFile;

// Generate an XML-based XFDF file (Recommended for UTF-8)
$xfdf = new XfdfFile([
    'Employee' => 'Jürgen',
    'Department' => 'Engineering'
]);
$xfdf->saveAs('/path/to/data.xfdf');

// Generate a classic FDF file
$fdf = new FdfFile(['Employee' => 'Jürgen']);
$fdf->saveAs('/path/to/data.fdf');

You can also extract an FDF from an already filled PDF form:

$pdf = new Pdf('/path/filled_form.pdf');
$pdf->generateFdfFile('/path/extracted_data.fdf');