2024 日本 PHP 研討會

PHP 與 COM

在 Win32 平台上,PHP 可用於存取 COM 和 DCOM 物件。

我建立了一個 DLL 來計算某些東西。有沒有辦法在 PHP 下執行這個 DLL?

如果這是一個簡單的 DLL,目前還沒有辦法從 PHP 執行它。如果 DLL 包含 COM 伺服器,而且它實作了 IDispatch 介面,則您或許可以存取它。

「不支援的變體類型:xxxx (0xxxxx)」是什麼意思?

VARIANT 類型及其組合有很多種。大多數都已支援,但仍有一些需要實作。陣列尚未完全支援。PHP 和 COM 之間只能傳遞單維度的索引陣列。如果您發現其他不支援的類型,請將其回報為錯誤(如果尚未回報),並提供盡可能多的資訊。

可以在 PHP 中操作視覺物件嗎?

一般來說是可以的,但由於 PHP 主要用作網頁腳本語言,它在網頁伺服器的環境中執行,因此視覺物件永遠不會出現在伺服器的桌面上。如果您將 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 無關。ActiveX 物件是由 HTML 文件請求時載入在用戶端。它與 PHP 腳本沒有關係,因此沒有直接的伺服器端互動。

可以取得元件的執行中實例嗎?

這可以藉助 moniker 來實現。如果您想取得同一個 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 物件,我們可以想像使用 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 失敗錯誤。範例的其餘部分運作正常,結果也符合預期。因此,我提出兩種情況
1. 文件有問題(更有可能)。
2. PHP504 本身有問題,因為這個問題在任何 COM Automation 呼叫中都會重現,而不僅僅是 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