前置條件
- Windows 平台(32 位元 PHP)
- PHP 開啟
com_dotnet 擴充模組(extension=php_com_dotnet.dll)
- 目標機器安裝對應 COM 元件(MDAC for ADO、Microsoft Word)
- Apache/IIS 執行身分具備 COM 元件存取權限(DCOM 設定)
案例一:ADO 連接 Access 資料庫
<?php
// 建立 ADO 連線物件
$conn = new COM("ADODB.Connection") or die("無法建立 ADODB.Connection");
$conn->Provider = "MSDASQL"; // 使用 ODBC 提供者
$conn->Open("nwind"); // 系統 DSN 名稱 "nwind" (Northwind 範例資料庫)
// 執行查詢
$rs = $conn->Execute("SELECT * FROM Products");
$i = 0;
while (!$rs->EOF) {
$i++;
$f0 = $rs->Fields(0); // ProductID
$f1 = $rs->Fields(1); // ProductName
$f2 = $rs->Fields(2); // SupplierID
echo "$f0->value $f1->value $f2->value<br>";
$rs->MoveNext();
}
$rs->Close();
$conn->Close();
?>
關鍵點解析
ADODB.Connection、ADODB.Recordset、ADODB.Field 為 ADO 核心物件
- Provider 可為
MSDASQL (ODBC)、Microsoft.Jet.OLEDB.4.0 (Access 直連)、SQLOLEDB (SQL Server)
Open() 參數:DSN 名稱、或完整連線字串 "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\path\db.mdb;"
- 記錄集導航:
MoveNext()、MovePrevious()、MoveFirst()、MoveLast()、EOF/BOF 判斷邊界
- 欄位存取:
Fields(index) 或 Fields("name"),取值用 ->value
案例二:自動化 Microsoft Word
<?php
$word = new COM("Word.Application") or die("無法啟動 Word");
echo "Word 版本: {$word->Version}<br>";
$word->Visible = 1; // 顯示 Word 視窗(除錯用,生產設 0)
$word->Documents->Add(); // 新增文件
$word->Selection->TypeText("This is a test from PHP via COM"); // 寫入文字
// 另存為
$word->ActiveDocument->SaveAs("C:\\temp\\php_test.doc");
$word->Quit(); // 關閉 Word
unset($word); // 釋放 COM 參考
?>
Word 自動化常用操作
| 操作 | 代碼範例 |
| 開啟現有文件 | $word->Documents->Open("C:\\path\\file.doc") |
| 尋找替換 | $word->Selection->Find->Execute("old", false, false, false, false, false, true, 1, false, "new", 2) |
| 轉換 PDF | $word->ActiveDocument->SaveAs("file.pdf", 17) // wdFormatPDF = 17 |
| 列印 | $word->ActiveDocument->PrintOut() |
| 郵件合併 | $word->ActiveDocument->MailMerge->OpenDataSource(...)->Execute() |
常見問題與解決
| 問題 | 原因 | 解決 |
| Class 'COM' not found | 未啟用 com_dotnet 擴充模組 | php.ini 加入 extension=php_com_dotnet.dll、重啟 Web Server |
| 無法建立 COM 物件 / 80080005 | DCOM 權限不足 / 身分無權存取 | dcomcnfg → 元件服務 → 電腦 → 我的電腦 → DCOM 設定 → Word Application/ADODB → 安全性 → 啟動與啟用權限/存取權限 → 加入 IIS_IUSRS/網路服務 |
| Word 進程殘留不退出 | 未呼叫 Quit() / 未 unset() / 例外中斷 | try-finally 確保釋資源、定期殺殘留進程 taskkill /im winword.exe |
| 中文亂碼 | 字符集轉換問題 | PHP 檔案 UTF-8、COM 內部 Unicode、必要時 iconv/mb_convert_encoding |
| 效能極差 | COM 跨程序邊界調用開銷大 | 批次操作、避免迴圈中頻繁建立/釋放物件、考慮改用 PHP 原生庫 |
現代替代方案建議
- Access/Excel:
PDO_ODBC、PhpSpreadsheet、php-excel-reader 純 PHP 解析,跨平台、無 COM 依賴
- Word/PDF 生成:
PhpOffice\PhpWord、dompdf、tcpdf、wkhtmltopdf 純 PHP/命令列工具
- SQL Server:
PDO_SQLSRV、sqlsrv 官方驅動,效能遠優於 ADO/ODBC
總結
PHP COM 橋接 Windows 生態系統(ADO、Office、WMI、Shell 等)功能強大但部署複雜、平台鎖定、效能敏感、維護困難。教學價值在於理解「跨語言元件互操作」原理。現代專案強烈建議改用純 PHP 庫或跨平台工具鏈,僅在必須操作既有 COM 資產(如複雜 Word 模板郵件合併)且無遷移預算時,才在隔離的 Windows 服務器上謹慎使用。
- 上一篇文章: PHP 輸出控制函數 ob_* 系列深度解析:緩衝區管理、Header 重定向、靜態快取生成
- 下一篇文章: PHP 爬取網頁所有連結:fopen + 正則解析 href 實作
Copyright ©
程式碼之家 All Rights Reserved