PHP Conference Japan 2024

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

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

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

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

这与 PHP 无关。如果 HTML 文档请求 ActiveX 对象,则会在客户端加载它们。与 PHP 脚本之间没有关系,因此不可能进行直接的服务器端交互。

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

这可以通过 moniker 来实现。如果要获取对同一单词实例的多个引用,可以像这样创建该实例

<?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 对象,我们能否想象使用 MTS 来管理组件资源,并结合使用 PHP?

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

添加注释

用户贡献的注释 3 条注释

匿名
19 年前
关于:带有 MS Word 自动化的 Windows 英文 CHM 示例。

我看到在 $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。
junk.ghost@virgin dOtt net
20 年前
它可能对其他人来说很明显,但是…

如果您想在 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 匹配。
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