PHP 和 COM
PHP 可以在 Win32 平台中访问 COM 和 DCOM 对象。
- 我建立了一个 DLL 来做某种计算。有办法在 PHP 中运行这个 DLL 吗?
- “Unsupported variant type: xxxx (0xxxxx)”是什么意思?
- 在 PHP 中有可能操纵可视对象吗?
- 可以将一个 COM 对象保存在 session 中吗?
- 怎样可以捕获 COM 的错误?
- 我能像在 Perl 中一样从 PHP 脚本生成 DLL 文件吗?
- “Unable to obtain IDispatch interface for CLSID {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}”是什么意思?
- 怎样从远端服务器运行 COM 对象?
- 我得到一个“DCOM is disabled in C:\path...\scriptname.php on line 6”信息,应该怎么办?
- 有可能在 PHP 页面中加载/操纵 ActiveX 对象吗?
- 有可能得到一个组件在运行中的实例吗?
- 有办法处理 COM 对象中发送的事件吗?
- 我在尝试调用一个打开了多于一个接口的 COM 对象中的方法时碰到问题,应该怎么办?
- 这么说 PHP 可以和 COM 一起工作,那么 COM+ 呢?
- 如果 PHP 可以操纵 COM 对象,那么可以设想结合 PHP 用 MTS 来管理组件资源吗?
- 我建立了一个 DLL 来做某种计算。有办法在 PHP 中运行这个 DLL 吗?
-
如果这是个简单的 DLL 那么还没有办法在 PHP 中运行它。如果这个 DLL 中包含有一个 COM 服务器并且它实现了 IDispatch 接口,那有可能访问它。
- “Unsupported variant type: xxxx (0xxxxx)”是什么意思?
-
有几十种 VARIANT 类型以及它们的组合。大多数已经被支持了但还有几种尚未实现。数组没有完全被支持。只有一维的仅用作索引的数组可以在 PHP 和 COM 之间传递。如果你发现其它未支持的类型,请当作一个 bug 报告(如果尚未被报告的话)并提供尽可能多的信息。
- 在 PHP 中有可能操纵可视对象吗?
-
一般来说是可以的,但是 PHP 大都用来作为 web 脚本语言并运行在 web 服务器的上下文环境中,因此可视对象决不会在服务器的桌面上显示。如果你把 PHP 用作应用程序脚本例如结合 PHP-GTK 来使用,那么访问和通过 COM 来操纵可视对象方面没有限制。
- 可以将一个 COM 对象保存在 session 中吗?
-
不行。COM 的实例被看作是资源,因此只在一个脚本的上下文中有效。
- 怎样可以捕获 COM 的错误?
-
在 PHP 5 中,COM 扩展会发出
com_exception
异常信息,可以捕获并检查code
成员来决定下一步的行为。在 PHP 4 中除了用 PHP 自己提供的办法之外(@,track_errors,..)不可能捕获 COM 的错误。
- 我能像在 Perl 中一样从 PHP 脚本生成 DLL 文件吗?
-
不行,PHP 没有这样的工具。
- “Unable to obtain IDispatch interface for CLSID {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}”是什么意思?
-
此错误可以有多种原因:
- 错误的 CLSID
- 找不到所请求的 DLL
- 所请求的组件没有实现 IDispatch 接口
- 有可能在 PHP 页面中加载/操纵 ActiveX 对象吗?
-
这不关 PHP 的事。如果在 HTML 文档中请求的话,ActiveX 对象被加载在客户端。这和 PHP 脚本没有关系,因此也不可能和服务器端发生直接的交互作用。
- 有可能得到一个组件在运行中的实例吗?
-
在绰号的帮助下这有可能。如果你想得到同一个 word 实例的多个引用你可以这样建立此实例:
<?php
$word = new COM("C:\docs\word.doc");
?>如果没有运行中的实例这将建立一个新的实例,否则将会返回正在运行中的实例的句柄,如果可用的话。
- 有办法处理 COM 对象中发送的事件吗?
-
可以自定义事件收报方并且用 com_event_sink()函数绑定之。可以用 com_print_typeinfo()来让 PHP 产生事件收报方类的框架。
- 我在尝试调用一个打开了多于一个接口的 COM 对象中的方法时碰到问题,应该怎么办?
-
我也不知道怎么办,我想这没办法。如果什么人有对此问题的明确信息请 » 告诉我。:)
- 这么说 PHP 可以和 COM 一起工作,那么 COM+ 呢?
-
COM+ 通过使用 MTS 和 MSMQ 来管理组件的框架扩展了 COM,但并没有什么特殊之处使 PHP 非要支持这样的组件。
- 如果 PHP 可以操纵 COM 对象,那么可以设想结合 PHP 用 MTS 来管理组件资源吗?
-
PHP 本身还并不处理事务。因而如果出错也不会发动撤回机制。如果你使用了支持事务处理的组件那你不得不自己实现事务管理。

User Contributed Notes 3 notes
Re: The Windows English CHM Sample with MS Word Automation.
I see that $Word->Release() is called after $Word->Quit().
This seems to be erroneous. Actually, $Word->Release() should not have to be called if proper COM garbage collection is taking place. Release() is a C++ construction not used in either Visual Basic or VBScript or even MS-JScript. Just to be sure, however, I ran the sample through php.exe (5.04 CLI on Windows XP SP1 with Office 2003) and got a RPC failed error on the line containing $Word->Release(). The rest of the sample works fine, and the results are as expected. So, I propose 2 scenarios:
1.There is a problem with the documentation (more likely).
2.There is a problem with PHP504 itself, as this problem is reproduced with any COM Automation call, not just Word.
It may be obvious to everyone else but...
If you want to write your own COM DLL in MSVC++6 and you want to pass it a string, you need the following in your .idl file:
HRESULT function_name([in] BSTR parameter_name,
[retval, out] BSTR * retval);
retval is the result of your function as a string to be passed back.
BSTR is an unsigned short *, so if you want to use your string with STL string etc. you may need to convert parameters to and from char *.
The burden of my message is that from PHP
$comThing = new COM("comThing.comThing");
print $comThing->function_name("Jeremy");
Jeremy will be marshalled as wide chars, which match BSTR.
in response to item #1 above: "If this is a simple DLL there is no way yet to run it from PHP."
Answer: There are several different packages/add-ons to php that enable low level access to the windows api. One of the most popular of these packages is available at http://www.winbinder.org
Winbinder does have the ability to load a dll and call it's functions. Winbinder also provides a large set of windows apis for creating windows and controls. This is useful for creating stand-alone desktop apps. It is a possible alternative to php-gtk.
I've had mixed results with Winbinder, some things work very well, others are buggy; source code is available. It's worth a look, Evaluate carefully.