<?php
include_once $_SERVER['DOCUMENT_ROOT'] . '/include/shared-manual.inc';
$TOC = array();
$TOC_DEPRECATED = array();
$PARENTS = array();
include_once dirname(__FILE__) ."/toc/faq.inc";
$setup = array (
  'home' => 
  array (
    0 => 'index.php',
    1 => 'PHP Manual',
  ),
  'head' => 
  array (
    0 => 'UTF-8',
    1 => 'ru',
  ),
  'this' => 
  array (
    0 => 'faq.com.php',
    1 => 'PHP и COM',
    2 => 'PHP и COM',
  ),
  'up' => 
  array (
    0 => 'faq.php',
    1 => 'ЧАВО',
  ),
  'prev' => 
  array (
    0 => 'faq.html.php',
    1 => 'PHP и HTML',
  ),
  'next' => 
  array (
    0 => 'faq.misc.php',
    1 => 'Разные вопросы',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'ru',
    'path' => 'faq/com.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="faq.com" class="chapter">
  <h1 class="title">PHP и COM</h1>

  

   <p class="para">
    На платформах Win32 языком PHP пользуются для доступа к COM- и DCOM-объектам.
   </p>

  <div class="qandaset"><ol class="qandaset_questions"><li><a href="#faq.com.q1">
     
      Я собрал DLL-библиотеку для вычислений. Каким способом запустить DLL-файл под PHP?
     
    </a></li><li><a href="#faq.com.q2">
     
      Что значит &#039;Unsupported variant type: xxxx (0xxxxx)&#039;?
     
    </a></li><li><a href="#faq.com.q3">
     
      Возможно ли манипулирование визуальными объектами в PHP?
     
    </a></li><li><a href="#faq.com.q4">
     
      Можно ли сохранять COM-объект в сессии?
     
    </a></li><li><a href="#faq.com.q5">
     
      Как отлавливать ошибки COM?
     
    </a></li><li><a href="#faq.com.q6">
     
      Можно ли генерировать DLL-файлы из PHP-скриптов так, как это делают в языке Perl?
     
    </a></li><li><a href="#faq.com.q7">
     
      Что значит
      &#039;Unable to obtain IDispatch interface for CLSID {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}&#039;?
     
    </a></li><li><a href="#faq.com.q8">
     
      Как COM-объекты запускают с удалённого сервера?
     
    </a></li><li><a href="#faq.com.q9">
     
      Я получаю &#039;DCOM is disabled in C:\path...\scriptname.php on line 6&#039;,
      что делать?
     
    </a></li><li><a href="#faq.com.q10">
     
      Умеет ли PHP загружать и манипулировать объектом ActiveX на странице?
     
    </a></li><li><a href="#faq.com.q11">
     
      Можно ли получить экземпляр компонента, который выполняется?
     
    </a></li><li><a href="#faq.com.q12">
     
      Как обработать событие, которое отправил COM-объект?
     
    </a></li><li><a href="#faq.com.q13">
     
      При попытке вызвать метод COM-объекта возникли проблемы,
      который даёт больше одного интерфейса. Что делать?
     
    </a></li><li><a href="#faq.com.q14">
     
      Итак, PHP работает с моделью COM, а что насчёт технологии COM+?
     
    </a></li><li><a href="#faq.com.q15">
     
      Раз PHP умеет манипулировать COM-объектами, можно ли представить,
      что служба MTS управляет ресурсами компонентов в сочетании PHP?
     
    </a></li></ol></div>
   <dl class="qandaentry" id="faq.com.q1">
    <dt><strong>
     
      Я собрал DLL-библиотеку для вычислений. Каким способом запустить DLL-файл под PHP?
     
    </strong></dt>
    <dd class="answer">
     <p class="para">
      PHP пока не умеет запускать просто DLL-библиотеки,
      но если DLL-файл содержит COM-сервер и библиотека реализует
      интерфейс IDispatch, для PHP откроется доступ к такому серверу.
     </p>
    </dd>
   </dl>

   <dl class="qandaentry" id="faq.com.q2">
    <dt><strong>
     
      Что значит &#039;Unsupported variant type: xxxx (0xxxxx)&#039;?
     
    </strong></dt>
    <dd class="answer">
     <p class="para">
      В конкретных языках программирования определяют десятки типов данных VARIANT и их комбинаций.
      Бо́льшую часть вариантов PHP уже поддерживает, но отдельные варианты в языке по-прежнему не реализовали.
      Массивы поддерживаются не на 100 %. Между PHP и COM разрешается передавать
      только одномерные индексные массивы. Пожалуйста, сообщите о других типах как об ошибке,
      если не сделали это раньше, если обнаружите типы, которые PHP не поддерживает,
      и дайте как можно больше информации.
     </p>
    </dd>
   </dl>

   <dl class="qandaentry" id="faq.com.q3">
    <dt><strong>
     
      Возможно ли манипулирование визуальными объектами в PHP?
     
    </strong></dt>
    <dd class="answer">
     <p class="para">
      Да, PHP умеет манипулировать визуальными объектами, но поскольку PHP чаще работает
      как язык веб-скриптов и запускается в контексте веб-сервера, визуальные объекты
      не появятся на рабочем столе сервера. Доступ и манипулирование визуальными объектами
      через COM не ограничиваются, когда на PHP пишут приложения,
      например, в связке с модулем PHP-GTK.
     </p>
    </dd>
   </dl>

   <dl class="qandaentry" id="faq.com.q4">
    <dt><strong>
     
      Можно ли сохранять COM-объект в сессии?
     
    </strong></dt>
    <dd class="answer">
     <p class="para">
      Нет, нельзя, поскольку экземпляры COM рассматриваются
      как ресурсы, они доступны только в контексте одного скрипта.
     </p>
    </dd>
   </dl>

   <dl class="qandaentry" id="faq.com.q5">
    <dt><strong>
     
      Как отлавливать ошибки COM?
     
    </strong></dt>
    <dd class="answer">
     <p class="para">
      Модуль COM выбрасывает исключение <code class="literal">com_exception</code>,
      которое перехватывают, а затем проверяют в исключении свойство <code class="literal">code</code>,
      чтобы понять, что делать дальше.
     </p>
    </dd>
   </dl>

   <dl class="qandaentry" id="faq.com.q6">
    <dt><strong>
     
      Можно ли генерировать DLL-файлы из PHP-скриптов так, как это делают в языке Perl?
     
    </strong></dt>
    <dd class="answer">
     <p class="para">
      Нет, для PHP такого инструмента нет.
     </p>
    </dd>
   </dl>

   <dl class="qandaentry" id="faq.com.q7">
    <dt><strong>
     
      Что значит
      &#039;Unable to obtain IDispatch interface for CLSID {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}&#039;?
     
    </strong></dt>
    <dd class="answer">
     <p class="para">
      Эта ошибка возникает по разным причинам:
      <ul class="itemizedlist">
       <li class="listitem">
         <span class="simpara">
         неправильный ключ CLSID
         </span>
        </li>
       <li class="listitem">
         <span class="simpara">
         DLL-библиотека, которую запросили, отсутствует
         </span>
        </li>
       <li class="listitem">
         <span class="simpara">
         компонент, который запросили, не реализует интерфейс IDispatch
         </span>
        </li>
       </ul>
     </p>
    </dd>
   </dl>

   <dl class="qandaentry" id="faq.com.q8">
    <dt><strong>
     
      Как COM-объекты запускают с удалённого сервера?
     
    </strong></dt>
    <dd class="answer">
     <p class="para">
      Точно так же, как запускают локальные объекты. Потребуется только передать
      IP-адрес удалённой машины как второй параметр конструктора COM.
     </p>
     <p class="para">
      Убедитесь, что включили директиву
      <a href="com.configuration.php#ini.com.allow-dcom" class="link">com.allow_dcom</a><code class="literal">=</code><strong><code><a href="reserved.constants.php#constant.true">true</a></code></strong> в файле <var class="filename">php.ini</var>
     </p>
    </dd>
   </dl>

   <dl class="qandaentry" id="faq.com.q9">
    <dt><strong>
     
      Я получаю &#039;DCOM is disabled in C:\path...\scriptname.php on line 6&#039;,
      что делать?
     
    </strong></dt>
    <dd class="answer">
     <p class="para">
      Отредактируйте файл <var class="filename">php.ini</var> и включите директиву
      <a href="com.configuration.php#ini.com.allow-dcom" class="link">com.allow_dcom</a><code class="literal">=</code><strong><code><a href="reserved.constants.php#constant.true">true</a></code></strong>.
     </p>
    </dd>
   </dl>

   <dl class="qandaentry" id="faq.com.q10">
    <dt><strong>
     
      Умеет ли PHP загружать и манипулировать объектом ActiveX на странице?
     
    </strong></dt>
    <dd class="answer">
     <p class="para">
      Это не имеет отношения к PHP. Объекты ActiveX загружаются на стороне клиента,
      если их запросил HTML-документ. Связи с PHP-скриптом здесь нет,
      поэтому прямое взаимодействие со стороны сервера невозможно.
     </p>
    </dd>
   </dl>
   <dl class="qandaentry" id="faq.com.q11">
    <dt><strong>
     
      Можно ли получить экземпляр компонента, который выполняется?
     
    </strong></dt>
    <dd class="answer">
     <p class="para">
      Экземпляр получают через моникеры (англ. monikers). Экземпляр создают вот так,
      когда требуется получить больше одной ссылки на один и тот же экземпляр Word:
     </p>
     <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br />$word </span><span style="color: #007700">= new </span><span style="color: #0000BB">COM</span><span style="color: #007700">(</span><span style="color: #DD0000">"C:\docs\word.doc"</span><span style="color: #007700">);<br /><br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
     </div>

     <p class="para">
      Код создаст новый экземпляр, если нет доступного запущенного экземпляра,
      или вернёт дескриптор запущенного экземпляра, если экземпляр доступен.
     </p>
    </dd>
   </dl>
   <dl class="qandaentry" id="faq.com.q12">
    <dt><strong>
     
      Как обработать событие, которое отправил COM-объект?
     
    </strong></dt>
    <dd class="answer">
     <p class="para">
      Приёмник события определяют и привязывают функцией <span class="function"><a href="function.com-event-sink.php" class="function">com_event_sink()</a></span>.
      Скелет класса приёмника событий функция в PHP генерирует
      функция <span class="function"><a href="function.com-print-typeinfo.php" class="function">com_print_typeinfo()</a></span>.
     </p>
    </dd>
   </dl>

   <dl class="qandaentry" id="faq.com.q13">
    <dt><strong>
     
      При попытке вызвать метод COM-объекта возникли проблемы,
      который даёт больше одного интерфейса. Что делать?
     
    </strong></dt>
    <dd class="answer">
     <p class="para">
      Ответ настолько же простой, насколько и неудовлетворительный.
      Точно не известно, но, скорее всего, ничего сделать невозможно.
     </p>
    </dd>
   </dl>

   <dl class="qandaentry" id="faq.com.q14">
    <dt><strong>
     
      Итак, PHP работает с моделью COM, а что насчёт технологии COM+?
     
    </strong></dt>
    <dd class="answer">
     <p class="para">
      Технология COM+ расширяет модель COM
      за счёт платформы управления компонентами через службу MTS и MSMQ-очередь,
      но PHP не поддерживает ничего отдельно, чтобы работать с такими компонентами.
     </p>
    </dd>
   </dl>

   <dl class="qandaentry" id="faq.com.q15">
    <dt><strong>
     
      Раз PHP умеет манипулировать COM-объектами, можно ли представить,
      что служба MTS управляет ресурсами компонентов в сочетании PHP?
     
    </strong></dt>
    <dd class="answer">
     <p class="para">
      Сам PHP пока не обрабатывает транзакции. Поэтому, если возникает
      ошибка, откат не инициируется. При работе с компонентами,
      которые поддерживают транзакции придётся реализовать управление
      транзакциями самому.
     </p>
    </dd>
   </dl>

  
 </div>
<?php manual_footer($setup); ?>