章 56. PHP 和 COM

PHP 可以在 Win32 平台中訪問 COM 和 DCOM 對象。

1. 我建立了一個 DLL 來做某種計算。有辦法在 PHP 中運行這個 DLL 嗎?
2. 「Unsupported variant type: xxxx (0xxxxx)」是什麼意思?
3. 在 PHP 中有可能操縱可視對象嗎?
4. 可以將一個 COM 物件儲存在 session 中嗎?
5. 怎樣可以捕捉 COM 的錯誤?
6. 我能像在 Perl 中一樣從 PHP 腳本建立 DLL 檔案嗎?
7. 「Unable to obtain IDispatch interface for CLSID {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}」是什麼意思?
8. 怎樣從遠端伺服器運行 COM 物件?
9. 我得到一個「DCOM is disabled in C:\path...\scriptname.php on line 6」訊息,應該怎麼辦?
10. 有可能在 PHP 頁面中加載/操縱 ActiveX 對象嗎?
11. 有可能得到一個元件在運行中的案例嗎?
12. 有辦法處理 COM 物件中傳送的事件嗎?
13. 我在嘗試呼叫一個開啟了多於一個介面的 COM 物件中的方法時碰到問題,應該怎麼辦?
14. 這麼說 PHP 可以和 COM 一起工作,那麼 COM+ 呢?
15. 若果 PHP 可以操縱 COM 對象,那麼可以設想結合 PHP 用 MTS 來管理元件資源嗎?

1. 我建立了一個 DLL 來做某種計算。有辦法在 PHP 中運行這個 DLL 嗎?

若果這是個簡單的 DLL 那麼還沒有辦法在 PHP 中運行它。若果這個 DLL 中包括有一個 COM 伺服器並且它實現了 IDispatch 介面,那有可能訪問它。

2. 「Unsupported variant type: xxxx (0xxxxx)」是什麼意思?

有幾十種 VARIANT 類型以及它們的組合。大多數已經被支援了但還有幾種尚未實現。陣列沒有完全被支援。只有一維的僅用作索引的陣列可以在 PHP 和 COM 之間傳遞。若果你發現其它未支援的類型,請當作一個 bug 報告(若果尚未被報告的話)並提供盡可能多的訊息。

3. 在 PHP 中有可能操縱可視對象嗎?

一般來說是可以的,但是 PHP 大都用來作為 web 腳本語系並運行在 web 伺服器的上下文環境中,因此可視物件決不會在伺服器的桌面上顯示。若果你把 PHP 用作套用程式腳本例如結合 PHP-GTK 來使用,那麼訪問和通過 COM 來操縱可視物件方面沒有限制。

4. 可以將一個 COM 物件儲存在 session 中嗎?

不行。COM 的案例被看作是資源,因此只在一個腳本的上下文中有效。

5. 怎樣可以捕捉 COM 的錯誤?

在 PHP 5 中,COM 增加會發出 com_exception 異常訊息,可以捕捉並檢查 code 成員來決定下一步的行為。

在 PHP 4 中除了用 PHP 自己提供的辦法之外(@,track_errors,..)不可能捕捉 COM 的錯誤。

6. 我能像在 Perl 中一樣從 PHP 腳本建立 DLL 檔案嗎?

不行,PHP 沒有這樣的工具。

7. 「Unable to obtain IDispatch interface for CLSID {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}」是什麼意思?

此錯誤可以有多種原因:

  • 錯誤的 CLSID

  • 找不到所請求的 DLL

  • 所請求的元件沒有實現 IDispatch 介面

8. 怎樣從遠端伺服器運行 COM 物件?

完全和運行本地物件一樣。只須將遠端伺服器的 IP 作為第二個變量傳遞給 COM 的構造函數即可。

確認在 php.ini 中設定了 com.allow_dcom =TRUE

9. 我得到一個「DCOM is disabled in C:\path...\scriptname.php on line 6」訊息,應該怎麼辦?

編輯 php.ini 並設定 com.allow_dcom =TRUE

10. 有可能在 PHP 頁面中加載/操縱 ActiveX 對象嗎?

這不關 PHP 的事。若果在 HTML 文件中請求的話,ActiveX 物件被加載在用戶端。這和 PHP 腳本沒有關係,因此也不可能和伺服器端發生直接的互動作用。

11. 有可能得到一個元件在運行中的案例嗎?

在綽號的說明下這有可能。若果你想得到同一個 word 案例的多個引用你可以這樣建立此案例:

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

若果沒有運行中的案例這將建立一個新的案例,否則將會返回正在運行中的案例的識別碼,若果可用的話。

12. 有辦法處理 COM 物件中傳送的事件嗎?

可以自訂事件收報方並且用 com_event_sink() 函數綁定之。可以用 com_print_typeinfo() 來讓 PHP 產生事件收報方類的框架。

13. 我在嘗試呼叫一個開啟了多於一個介面的 COM 物件中的方法時碰到問題,應該怎麼辦?

我也不知道怎麼辦,我想這沒辦法。若果什麼人有對此問題的明確訊息請告訴我。:)

14. 這麼說 PHP 可以和 COM 一起工作,那麼 COM+ 呢?

COM+ 通過使用 MTS 和 MSMQ 來管理元件的框架增加了 COM,但並沒有什麼特殊之處使 PHP 非要支援這樣的元件。

15. 若果 PHP 可以操縱 COM 對象,那麼可以設想結合 PHP 用 MTS 來管理元件資源嗎?

PHP 本身還並不處理事務。因而若果出錯也不會發動撤回機制。若果你使用了支援事務處理的元件那你不得不自己實現事務管理。