PHP 和 COM

PHP 可用于访问 Win32 平台上的 COM 和 DCOM 对象。

我构建了一个 DLL 来计算一些东西。有没有办法在 PHP 下运行这个 DLL?

如果这是一个简单的 DLL,则目前还没有办法从 PHP 运行它。如果 DLL 包含 COM 服务器,则如果它实现了 IDispatch 接口,您可能可以访问它。

“不支持的变体类型:xxxx (0xxxxx)”是什么意思?

有几十种 VARIANT 类型及其组合。大多数已经得到支持,但仍有一些需要实现。数组没有完全支持。只能在 PHP 和 COM 之间传递一维索引数组。如果您发现其他不支持的类型,请报告为错误(如果尚未报告)并提供尽可能多的信息。

是否可以在 PHP 中操作可视对象?

一般来说可以,但由于 PHP 主要用作 Web 脚本语言,它在 Web 服务器的上下文中运行,因此可视对象永远不会出现在服务器的桌面上。如果您将 PHP 用于应用程序脚本编写,例如与 PHP-GTK 结合使用,则在通过 COM 访问和操作可视对象方面没有限制。

是否可以在会话中存储 COM 对象?

不,您不能。COM 实例被视为资源,因此它们仅在单个脚本的上下文中可用。

如何捕获 COM 错误?

COM 扩展抛出 com_exception 异常,您可以捕获这些异常,然后检查 code 成员以确定下一步该做什么。

我可以像在 Perl 中一样从 PHP 脚本生成 DLL 文件吗?

不,不幸的是没有这样的工具可用于 PHP。

“无法为 CLSID {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} 获取 IDispatch 接口”是什么意思?

此错误可能有多个原因

  • CLSID 错误
  • 请求的 DLL 丢失
  • 请求的组件没有实现 IDispatch 接口

如何从远程服务器运行 COM 对象?

与您运行本地对象的方式完全相同。您只需要将远程机器的 IP 作为第二个参数传递给 COM 构造函数。

请确保您已在 php.ini 中设置了 com.allow_dcom=true

我得到“DCOM 在 C:\path...\scriptname.php 的第 6 行被禁用”,我该怎么办?

编辑您的 php.ini 并设置 com.allow_dcom=true

是否可以在带有 PHP 的页面中加载/操作 ActiveX 对象?

这与 PHP 无关。如果 HTML 文档请求 ActiveX 对象,它们将在客户端加载。与 PHP 脚本无关,因此无法直接进行服务器端交互。

是否可以获取组件的运行实例?

这可以通过使用 moniker 来实现。如果您想获取对同一个 Word 实例的多个引用,您可以像下面这样创建该实例

<?php
$word
= new COM("C:\docs\word.doc");
?>

这将在没有运行实例可用时创建一个新实例,或者如果可用,它将返回一个指向运行实例的句柄。

是否有办法处理从 COM 对象发送的事件?

您可以定义一个事件接收器并使用 com_event_sink() 绑定它。您可以使用 com_print_typeinfo() 让 PHP 为事件接收器类生成一个框架。

我在尝试调用公开多个接口的 COM 对象的方法时遇到了问题。我该怎么办?

答案和令人不满意一样简单。我不知道确切的原因,但我认为您无能为力。如果有人对此有具体信息,请告诉我 :)

所以 PHP 可以与 COM 配合使用,那么 COM+ 呢?

COM+ 通过一个框架来扩展 COM,用于通过 MTS 和 MSMQ 来管理组件,但 PHP 在使用此类组件方面没有特殊需要支持的地方。

如果 PHP 可以操作 COM 对象,我们可以想象使用 MTS 来管理组件资源,并与 PHP 结合使用吗?

PHP 本身还不支持事务。因此,如果发生错误,不会启动回滚。如果您使用支持事务的组件,则必须自己实现事务管理。

添加说明

用户贡献的说明 3 条说明

10
匿名
19 年前
关于:Windows 英文 CHM 示例,使用 MS Word 自动化。

我看到在 $Word->Quit() 之后调用了 $Word->Release()。
这似乎是错误的。实际上,如果 COM 垃圾回收正常运行,则不必调用 $Word->Release()。Release() 是 C++ 构造,在 Visual Basic、VBScript 甚至 MS-JScript 中都不使用。不过为了确保,我通过 php.exe(Windows XP SP1 上的 5.04 CLI,带有 Office 2003)运行了该示例,并在包含 $Word->Release() 的行上得到了 RPC 失败错误。示例的其余部分运行良好,结果如预期。因此,我建议 2 种情况
1. 文档有问题(更有可能)。
2. PHP504 本身有问题,因为此问题在任何 COM 自动化调用中都会重现,而不仅仅是 Word。
9
junk.ghost@virgin dOtt net
19 年前
对于其他人来说可能很明显,但是...

如果您想在 MSVC++6 中编写自己的 COM DLL,并且想传递一个字符串,则需要在您的 .idl 文件中包含以下内容

HRESULT function_name([in] BSTR parameter_name,
[retval, out] BSTR * retval);

retval 是您函数的结果,作为要传递回的字符串。

BSTR 是一个 unsigned short *,因此如果您想将您的字符串与 STL string 等一起使用,您可能需要在 char * 之间进行转换。

我的信息的核心是,从 PHP

$comThing = new COM("comThing.comThing");
print $comThing->function_name("Jeremy");

Jeremy 将被编组为宽字符,与 BSTR 相匹配。
4
codeslinger at compsalot dot com
17 年前
针对上面的第 1 项:“如果这是一个简单的 DLL,则目前还没有办法从 PHP 运行它。”

回答:有几个不同的软件包/插件可以使 php 能够低级别地访问 windows api。其中最流行的软件包之一在 http://www.winbinder.org 上可用

Winbinder 确实具有加载 dll 并调用其函数的功能。Winbinder 还提供大量 windows api 用于创建窗口和控件。这对于创建独立的桌面应用程序很有用。它是 php-gtk 的一个可能的替代方案。

我对 Winbinder 的结果褒贬不一,有些事情运行得很好,有些事情则有错误;源代码可用。值得一看,仔细评估。
To Top