picture of Uwe Steinmann

Motivation

Interaction on the WWW often means filling out forms, hitting the submit button and getting a certain result. HTML and HTTP provide a mechanism to perform this quite easily through forms. PHP has support for this mechanism in a very convenient way. The values of each input field are stored in PHP variables, with the same name as the input field.
A mechanism quite similar has been developed by Adobe, but for PDF documents. They simply call it Acrobat Forms. From the users point of view, the only difference in HTML forms and Acrobat forms is their appearance. The first one uses HTML documents, while the second one uses PDF documents to present the form.
For developers of web interfaces, Acrobat Forms can be handled like HTML forms, if the form provides its input data as HTML forms. However, Adobe has introduced a new format for form data called FDF (Form Data Format). PHP already includes support for this format.
The possibility to populate a PDF document with data, e.g. to customize it, is an additional feature of Acrobat Forms. . Using PDF documents as forms and populating PDF documents with data using PHP will be described in this article. Two examples demonstrate how easy it is.
Before you start trying the online examples in this article you should install the Acrobat Reader Plug-in or use Acrobat 4. If you want to test the PHP scripts on your own web server you will also need to install the FDF Toolkit and enable FDF support in PHP. Finally, if you want to develop your own PDF forms you will need Acrobat Exchange 3.x or Acrobat 4.

How it works

Adobe has developed the portable document format (PDF) and extended it over the last years. One of these extensions are Acrobat Forms which allow a user to input data and send it to the server where it is evaluated, just as HTML forms. Such a PDF document is very similar to a static PDF document, but when you look at it with the Acrobat Reader, you will find areas which can be edited.
There are many input fields available just like in HTML, e.g. a submit and reset button, text input fields, check boxes etc.. Creating such a PDF form requires Acrobat Exchange 3.x or the new Acrobat 4 software, which unfortunately only runs on Windows and MacOS. Both provide a mode to place the different input fields into an existing PDF document. The submit button carries an attribute which specifies the URL to call when it is pressed. This is very similar to HTML, but can differ in the format when the entered data is transfered to the server. Data from HTML forms is transfered using a certain syntax which can be observed in the URL after hitting the submit button. Acrobat Forms support this format, but also FDF (Form Data Format).
FDF is a new format which requires the FDF Toolkit (current version is 4.0) to parse. If PHP has FDF support compiled, it can parse FDF data and access any field by its name. FDF data is currently stored by PHP in the variable HTTP_RAW_POST_DATA (just as HTML data is stored in HTTP_POST_DATA). The actual evaluation of the data has to be done in the PHP script, as opposed to the HTML post data which is evaluated by the PHP engine.
To get an impression of what the FDF data looks like, here is an example:
%FDF-1.2 %âãÏÓ 1 0 obj << /FDF << /Fields [ << /V (This is just some text for testing)/T (comment)>> ....
It is just the first portion of a complete record, but one should be able to clearly identify the input field comment and its value. Here is text for testing.
In order to make this clearer, a simple example is provided. First, assume we have a PDF form containing the fields volume, publisher, preparer, date, comment show_publisher, show_preparer. The first five fields are text input fields; the last two are check boxes. Our PHP script shall always display the values of the fields volume, date, comment, but display the value of the fields publisher and preparer only if the corresponding check boxes are checked. If the boxes are checked, their value is "On" since it was preset when the form was created. And of course the form also has a submit button, in our case it even has a reset button. Hitting the submit button runs the following script. This script evaluates the field data as described above.

<?php

   $fdffp 
fopen("test.fdf""w");
   
fwrite($fdffp$HTTP_RAW_POST_DATAstrlen($HTTP_RAW_POST_DATA));
   
fclose($fdffp);

   
$fdf fdf_open("test.fdf");
   
$volume fdf_get_value($fdf"volume");
   echo 
"The volume field has the value '<B>$volume</B>'<BR>";

   
$date fdf_get_value($fdf"date");
   echo 
"The date field has the value '<B>$date</B>'<BR>";

   
$comment fdf_get_value($fdf"comment");
   echo 
"The comment field has the value '<B>$comment</B>'<BR>";

   if(
fdf_get_value($fdf"show_publisher") == "On") {
     
$publisher fdf_get_value($fdf"publisher");
     echo 
"The publisher field has the value '<B>$publisher</B>'<BR>";
   } else
     echo 
"Publisher shall not be shown.<BR>";

   if(
fdf_get_value($fdf"show_preparer") == "On") {
     
$preparer fdf_get_value($fdf"preparer");
     echo 
"The preparer field has the value '<B>$preparer</B>'<BR>";
   } else
     echo 
"Preparer shall not be shown.<BR>";
   
fdf_close($fdf);

?>
You can try this example at http://gehtnix.fernuni-hagen.de:8000/testfdf/example1.pdf
Beside the fact that PDF forms have a nicer appearance than HTML forms, there seems to be no real advantage of this technology. However, there is another usage of FDF. You can turn the above process around and populate a PDF document with data. This is quite useful if you need to customize only certain parts in a PDF document, e.g. a address, date etc.. One could also create the complete PDF document, with PHP's PDF creation functions, but this is a lot of work for complex documents. In general, it is also desirable to use prepared documents created by a designer, for example. Creating PDF forms with the PDF functions in PHP is not possible.
Populating a PDF document with data is quite simple with FDF. You will have to create a PDF document and add input fields to it, e.g. with Acrobat 4. Put in on your web server. Then, you need to create the FDF document with PHP, which contains each field, its value and a reference to the document where the data is to be inserted. (The PDF document you have just created). This will be done on the fly with PHP. The reference is a URL pointing to the PDF document.
Taking the first example as a basis, the following script shows how easy this is with PHP. The second part of the script has been added.

<?php

   $fdffp 
fopen("test.fdf""w");
   
fwrite($fdffp$HTTP_RAW_POST_DATAstrlen($HTTP_RAW_POST_DATA));
   
fclose($fdffp);

   
$fdf fdf_open("test.fdf");
   
$volume fdf_get_value($fdf"volume");
   
$date fdf_get_value($fdf"date");
   
$comment fdf_get_value($fdf"comment");

   if(
fdf_get_value($fdf"show_publisher") == "On") {
     
$publisher fdf_get_value($fdf"publisher");
   } else
     
$publisher "";

   if(
fdf_get_value($fdf"show_preparer") == "On") {
     
$preparer fdf_get_value($fdf"preparer");
   } else
     
$preparer "";

   
fdf_close($fdf);

   
$outfdf fdf_create();
   
fdf_set_value($outfdf"f_volume"$volume0);
   
fdf_set_value($outfdf"b_volume"$volume0);

   
fdf_set_value($outfdf"f_comment"$comment0);
   
fdf_set_value($outfdf"b_comment"$comment0);

   
fdf_set_value($outfdf"f_date"$date0);
   
fdf_set_value($outfdf"b_date"$date0);

   
fdf_set_value($outfdf"f_preparer"$preparer0);
   
fdf_set_value($outfdf"b_preparer"$preparer0);

   
fdf_set_value($outfdf"f_publisher"$publisher0);
   
fdf_set_value($outfdf"b_publisher"$publisher0);

   
fdf_set_file($outfdf"http:/testfdf/resultlabel.pdf");
   
fdf_save($outfdf"outtest.fdf");
   
fdf_close($outfdf);
   
Header("Content-type: application/vnd.fdf");
   
$fp fopen("outtest.fdf""r");
   
fpassthru($fp);
   
unlink("outtest.fdf");

?>
You can try this example at http://gehtnix.fernuni-hagen.de:8000/testfdf/example2.pdf
In this example several steps are performed:
  1. The user fills out the PDF form example2.pdf
  2. After hitting the submit button, the URL associated with the submit button is called. In this case, it has to be the PHP script.
  3. The PHP script retrieves the data from the FDF data stream and creates a new FDF document, which contains the data for the resulting PDF document.
  4. The FDF document is sent back with the MimeType application/vnd.fdf.
  5. The Acrobat Plug-In reads the data and displays the refereed PDF document. In this case resultlabel.pdf.
This is still not everything FDF has to offer, but there is too much left to be discussed in this tutorial. You should check out the documentation at Adobe's web site.
-- Uwe