Массив из COM в PHP

Мы, не специалисты в PHP, и вполне возможно, что эта статья покажется кому-то перечислением очевидных фактов. Но тем не менее, возможно, эта статья кому-то поможет.

Нам нужно было проверить нашу библиотеку (вот эту) на работоспособность из PHP.Написали вот такой скриптик, который должен был создать простой PDF документ и выдать его в поток клиента:

<?
  $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;
?>

Против ожиданий, скрипт выводил не то, что нужно.

Дело оказалось вот в чем. PHP как-то не очень дружит с типом VARIANT. Точнее отлично дружит с ним, если тип этого VARIANT’а не VT_ARRAY. Всякие другие COM типы PHP отлично превращает в “родные” и с ними можно делать все, что угодно. А о нашем $buffer PHP говорит вот что:

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

Причем полученную переменную не удавалось конвертировать ни в один другой  COM тип, ибо PHP говорил об ошибке, мол “не поддерживаемый тип”.

Выход был найдет. Хотя PHP и не может превратить такой массив в “родной”, он все же позволяет работать с ним как с массивом. Т.е. вполне применимы конструкции for и foreach.

Итого получаем скрипт:

<?
  $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() возвращает VARIANT массив (VT_ARRAY) с элементами
  // типа VT_UI1, поэтому мы их должны сами перевести в char.
  foreach ($buffer as $byte)
    echo chr($byte);

  $PDF = null;
?>

Вот теперь все заработало. В общем, будьте внимательны, когда работаете с COM в PHP.

Филимонов Максим
Разработчик PDF Creator

Leave a Reply

Your email address will not be published. Required fields are marked *