COM arrays in PHP

We don’t claim to be experts in PHP, and an educated reader might find this article to be a redundant description of evident facts. Nevertheless, we hope that this article may be of some help to somebody.

We wanted to check whether our library (this one) works well with PHP. Below is the small script that we had created. All it was to do: create a plain PDF Document, and output it into the client’s stream:

<?
  $PDF = new COM("PDFCreatorPilot.PDFDocument4") or die("Unable to load instanciate.");
  $PDF->SetLicenseData("demo", "demo");
  $PDF->Compression = 1; // coFlate

  $fnt = $PDF->AddBuiltInFont(1, false, false);
  $PDF->UseFont($fnt, 14);
  $PDF->ShowTextAt(30, 30, "Hello from PHP!");

  $size = $PDF->GetBufferSize();
  $buffer = $PDF->GetBuffer();
  header("Content-type: application/pdf");
  header("Content-Disposition: attachment; filename=test.pdf");
  header("Content-Length: $size");
  echo $buffer;
  $PDF = null;
?>

The script did not work as expected.

The reason was: PHP does not work well with the VARIANT type representing VT_ARRAY. PHP easily converts all other COM types, and permits you to do with them whatever you wish. This is what the PHP script said about our $buffer:

echo var_dump($buffer)."\n";
echo variant_get_type($buffer)."\n";
// output:
// 8209
// object(variant)#2 (0){
// }

The variable that we received was impossible to convert into any COM type, since PHP reported an “unsupported type”.

We’ve found a solution. PHP seems to be unable to convert a VT_ARRAY into a native PHP array, but it permits us to access a COM array’s data. Both, “for” and “foreach” work fine.

Here is the working script:

<?
  $PDF = new COM("PDFCreatorPilot.PDFDocument4") or die("Unable to load instanciate.");
  $PDF->SetLicenseData("demo", "demo");
  $PDF->Compression = 1; // coFlate

  $fnt = $PDF->AddBuiltInFont(1, false, false);
  $PDF->UseFont($fnt, 14);
  $PDF->ShowTextAt(30, 30, "Hello from PHP!");

  $size = $PDF->GetBufferSize();
  $buffer = $PDF->GetBuffer();

  header("Content-type: application/pdf");
  header("Content-Disposition: attachment; filename=test.pdf");
  header("Content-Length: $size");

  // $PDF->GetBuffer() return a VARIANT array (VT_ARRAY) with elements of type VT_UI1, so we have to
  // transform them into char ourselves.
  foreach ($buffer as $byte)
  echo chr($byte);

  $PDF = null;
?>

It works. Good luck and take care when you have to use COM from PHP.

Filimonov Maxim

1 comment

  1. This blog aided me in narrowing down some issues with the latest release, Why do they often seem to leave out vital documentation when they release a new version? It may be trivial to them but not for us! I’m sure i’m not alone either.

Comments have been disabled.