<?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 => 'zh',
  ),
  'this' => 
  array (
    0 => 'faq.com.php',
    1 => 'PHP 和 COM',
    2 => 'PHP 和 COM',
  ),
  'up' => 
  array (
    0 => 'faq.php',
    1 => 'FAQ',
  ),
  'prev' => 
  array (
    0 => 'faq.html.php',
    1 => 'PHP 和 HTML',
  ),
  'next' => 
  array (
    0 => 'faq.misc.php',
    1 => '其他问题',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'zh',
    '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">
    PHP 可以在 Win32 平台中访问 COM 和 DCOM 对象。
   </p>

  <div class="qandaset"><ol class="qandaset_questions"><li><a href="#faq.com.q1">
        我建立了一个 DLL 来做某种计算。有办法在 PHP 中运行这个 DLL 吗？
      </a></li><li><a href="#faq.com.q2">
        &ldquo;Unsupported variant type: xxxx (0xxxxx)&rdquo;是什么意思？
      </a></li><li><a href="#faq.com.q3">
        在 PHP 中有可能操纵可视对象吗？
      </a></li><li><a href="#faq.com.q4">
        可以将一个 COM 对象保存在 session 中吗？
      </a></li><li><a href="#faq.com.q5">
     
      怎样可以捕获 COM 的错误？
     
    </a></li><li><a href="#faq.com.q6">
        我能像在 Perl 中一样从 PHP 脚本生成 DLL 文件吗？
      </a></li><li><a href="#faq.com.q7">
        &ldquo;Unable to obtain IDispatch interface for CLSID {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}&rdquo;是什么意思？
      </a></li><li><a href="#faq.com.q8">
        怎样从远端服务器运行 COM 对象？
      </a></li><li><a href="#faq.com.q9">
        我得到一个&ldquo;DCOM is disabled in C:\path...\scriptname.php on line 6&rdquo;信息，应该怎么办？
      </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 对象，那么可以设想结合 PHP 用 MTS 来管理组件资源吗？
      </a></li></ol></div>
    <dl class="qandaentry" id="faq.com.q1">
      <dt><strong>
        我建立了一个 DLL 来做某种计算。有办法在 PHP 中运行这个 DLL 吗？
      </strong></dt>
      <dd class="answer">
        <p class="para">如果这是个简单的 DLL 那么还没有办法在 PHP 中运行它。如果这个 DLL 中包含有一个 COM 服务器并且它实现了 IDispatch 接口，那有可能访问它。</p>
      </dd>
    </dl>
    <dl class="qandaentry" id="faq.com.q2">
      <dt><strong>
        “Unsupported variant type: xxxx (0xxxxx)”是什么意思？
      </strong></dt>
      <dd class="answer">
        <p class="para">有几十种 VARIANT 类型以及它们的组合。大多数已经被支持了但还有几种尚未实现。数组没有完全被支持。只有一维的仅用作索引的数组可以在 PHP 和 COM 之间传递。如果你发现其它未支持的类型，请当作一个 bug 报告（如果尚未被报告的话）并提供尽可能多的信息。</p>
      </dd>
    </dl>
    <dl class="qandaentry" id="faq.com.q3">
      <dt><strong>
        在 PHP 中有可能操纵可视对象吗？
      </strong></dt>
      <dd class="answer">
        <p class="para">一般来说是可以的，但是 PHP 大都用来作为 web 脚本语言并运行在 web 服务器的上下文环境中，因此可视对象决不会在服务器的桌面上显示。如果你把 PHP 用作应用程序脚本例如结合 PHP-GTK 来使用，那么访问和通过 COM 来操纵可视对象方面没有限制。</p>
      </dd>
    </dl>
    <dl class="qandaentry" id="faq.com.q4">
      <dt><strong>
        可以将一个 COM 对象保存在 session 中吗？
      </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>
        我能像在 Perl 中一样从 PHP 脚本生成 DLL 文件吗？
      </strong></dt>
      <dd class="answer">
        <p class="para">不行，PHP 没有这样的工具。</p>
      </dd>
    </dl>
    <dl class="qandaentry" id="faq.com.q7">
      <dt><strong>
        “Unable to obtain IDispatch interface for CLSID {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}”是什么意思？
      </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">确认在 <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.q9">
      <dt><strong>
        我得到一个“DCOM is disabled in C:\path...\scriptname.php on line 6”信息，应该怎么办？
      </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 的事。如果在 HTML 文档中请求的话，ActiveX 对象被加载在客户端。这和 PHP 脚本没有关系，因此也不可能和服务器端发生直接的交互作用。</p>
      </dd>
    </dl>
    <dl class="qandaentry" id="faq.com.q11">
      <dt><strong>
        有可能得到一个组件在运行中的实例吗？
      </strong></dt>
      <dd class="answer">
        <p class="para">在绰号的帮助下这有可能。如果你想得到同一个 word 实例的多个引用你可以这样建立此实例：</p>
        <div class="example-contents">
          <div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<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 /></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>函数绑定之。可以用 
        <span class="function"><a href="function.com-print-typeinfo.php" class="function">com_print_typeinfo()</a></span>来让 PHP 产生事件收报方类的框架。</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+ 通过使用 MTS 和 MSMQ 来管理组件的框架扩展了 COM，但并没有什么特殊之处使 PHP 非要支持这样的组件。</p>
      </dd>
    </dl>
    <dl class="qandaentry" id="faq.com.q15">
      <dt><strong>
        如果 PHP 可以操纵 COM 对象，那么可以设想结合 PHP 用 MTS 来管理组件资源吗？
      </strong></dt>
      <dd class="answer">
        <p class="para">PHP 本身还并不处理事务。因而如果出错也不会发动撤回机制。如果你使用了支持事务处理的组件那你不得不自己实现事务管理。</p>
      </dd>
   </dl>
 
  
 </div>
<?php manual_footer($setup); ?>