首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP於Windows平台操作COM組件完整指南:ADO資料庫實戰

     編輯:PHP 相關知識

前言:PHP與Windows COM技術的橋樑

PHP 4在Windows平台引入了對Microsoft COM(Component Object Model)技術的支援,使PHP腳本能直接調用Windows系統組件、Office應用程式、資料庫引擎等COM物件。官方文檔較為簡略,本文通過實戰範例詳細演示COM在PHP中的應用模式。

核心概念:ADO、OLEDB與ODBC關係圖譜

┌─────────────────────────────────────┐
│           應用層 (PHP/ASP/VB)        │
└──────────────┬──────────────────────┘
               ▼
┌─────────────────────────────────────┐
│           ADO (ActiveX Data Objects) │
│     統一的資料存取物件模型介面        │
└──────────────┬──────────────────────┘
               ▼
    ┌─────────────────┬─────────────────┐
    ▼                 ▼                 ▼
┌─────────┐      ┌─────────┐      ┌─────────┐
│  OLEDB  │      │  ODBC   │      │  其他   │
│  提供者  │      │  驅動程式│      │  提供者  │
└────┬────┘      └────┬────┘      └────┬────┘
     ▼               ▼               ▼
┌─────────────────────────────────────────┐
│          實體資料源 (SQL Server, Access, Oracle, MySQL...) │
└─────────────────────────────────────────┘
  • ADO:高層抽象介面,物件模型豐富(Connection, Recordset, Field, Command等)
  • OLEDB:COM基礎的低層資料存取介面,效能優於ODBC
  • ODBC:通用標準,支援最廣泛但有效能開銷

實戰一:PHP + ADO + Access (Northwind範例資料庫)

環境準備

  1. Windows Server / Windows 10/11 專業版
  2. 安裝Microsoft Access Database Engine (含Jet/ACE驅動)
  3. 確認php.ini啟用 extension=php_com_dotnet.dll
  4. 系統DSN配置:控制台 → 管理工具 → ODBC資料來源 → 系統DSN → 新增 → Microsoft Access Driver → 名稱 nwind 指向 Northwind.mdb

核心代碼

<?php
/**
 * PHP COM ADO 連線 Access 資料庫範例
 * 顯示 Products 表前三欄位資料
 */

try {
    // 1. 建立ADO連線物件
    $conn = new COM("ADODB.Connection") or die("無法建立ADODB.Connection物件");
    
    // 2. 設定提供者與連線字串
    $conn->Provider = "MSDASQL";  // 使用ODBC橋接器
    $conn->Open("nwind");         // 使用系統DSN名稱
    
    // 3. 執行SQL查詢,取得Recordset
    $sql = "SELECT ProductID, ProductName, UnitPrice FROM Products";
    $rs = $conn->Execute($sql);
    
    if ($rs === false) {
        throw new Exception("查詢執行失敗");
    }
    
    // 4. 取得欄位物件參考(效能優化:避免重複索引)
    $fldId = $rs->Fields(0);      // ProductID
    $fldName = $rs->Fields(1);    // ProductName
    $fldPrice = $rs->Fields(2);   // UnitPrice
    
    // 5. 迴圈輸出資料
    echo "<table border='1' cellpadding='5'>";
    echo "<tr><th>ID</th><th>產品名稱</th><th>單價</th></tr>";
    
    $count = 0;
    while (!$rs->EOF) {
        // MoveNext()會更新Fields集合的Value屬性
        echo "<tr>";
        echo "<td>" . htmlspecialchars($fldId->Value) . "</td>";
        echo "<td>" . htmlspecialchars($fldName->Value) . "</td>";
        echo "<td>" . number_format($fldPrice->Value, 2) . "</td>";
        echo "</tr>";
        
        $rs->MoveNext();
        $count++;
        
        // 安全限制:防止無限迴圈
        if ($count > 1000) break;
    }
    
    echo "</table>";
    echo "<p>共 {$count} 筆記錄</p>";
    
} catch (com_exception $e) {
    echo "COM錯誤: " . $e->getMessage() . " (Code: {$e->getCode()})";
} catch (Exception $e) {
    echo "執行錯誤: " . $e->getMessage();
} finally {
    // 6. 釋放資源(重要:COM物件需顯式釋放)
    if (isset($rs)) {
        $rs->Close();
        $rs = null;
    }
    if (isset($conn)) {
        $conn->Close();
        $conn = null;
    }
    // 強制垃圾回收
    gc_collect_cycles();
}
?>

實戰二:PHP + ADO + SQL Server (OLEDB直連,效能更佳)

<?php
$conn = new COM("ADODB.Connection");
$conn->Provider = "SQLOLEDB";  // SQL Server原生OLEDB提供者
$conn->Open(
    "Data Source=192.168.1.100;".
    "Initial Catalog=MyDatabase;".
    "User Id=sa;Password=your_password;"
);

// 參數化查詢防注入
$cmd = new COM("ADODB.Command");
$cmd->ActiveConnection = $conn;
$cmd->CommandText = "SELECT * FROM Users WHERE UserID = ? AND Status = ?";
$cmd->CommandType = 1; // adCmdText

// 建立參數
$param1 = $cmd->CreateParameter("@uid", 3, 1, 4, 1001); // adInteger=3, adParamInput=1
$param2 = $cmd->CreateParameter("@status", 200, 1, 10, "Active"); // adVarChar=200
$cmd->Parameters->Append($param1);
$cmd->Parameters->Append($param2);

$rs = $cmd->Execute();
// ... 處理結果集 ...

關鍵技術細節與避坑指南

1. COM物件生命週期管理

  • PHP請求結束時會自動釋放,但長時間運行腳本必須手動釋放
  • 使用$obj = null釋放引用,配合gc_collect_cycles()
  • Recordset/Connection需先呼叫Close()再釋放

2. 資料類型映射表

ADO類型常數值PHP對應類型說明
adInteger3int4位元組整數
adVarChar200string可變長度字串
adDouble5float雙精度浮點數
adDate7string/VARIANT日期時間,建議用Format轉字串
adBoolean11boolTrue/False (-1/0)
adLongVarBinary205string二進位資料(BLOB)

3. 常見錯誤碼對照

  • 0x800A0E7A:提供者不可用 → 驅動未安裝或Provider名稱錯誤
  • 0x80004005:未指定錯誤 → 連線字串錯誤、權限不足、資料庫不存在
  • 0x800A0BB9:引數型別錯誤 → CreateParameter類型/長度不匹配
  • 0x800A0BCD:物件或提供者無法執行操作 → Recordset已關閉或游標類型不支援

4. 效能優化技巧

  • 游標類型選擇:唯讀前向游標 adOpenForwardOnly (0) + adLockReadOnly (1) 效能最佳
  • 批次處理:大量寫入時使用adLockBatchOptimistic配合UpdateBatch()
  • 預編譯命令:重複執行同SQL結構時,重用Command物件與參數集合
  • GetRows()一次性取回:$data = $rs->GetRows() 返回二維陣列,避免逐行COM呼叫開銷

現代替代方案建議

雖然COM+ADO在Windows平台可行,但現代PHP開發建議:

  1. PDO + SQLSRV/ODBC驅動:原生PHP擴展,跨平台、效能更好、支援預處理語句
  2. Microsoft Drivers for PHP for SQL Server:官方維護,支援Always Encrypted、可用性群組等新特性
  3. 避免在Linux生產環境使用COM:COM僅限Windows,跨平台部署受限

總結

PHP透過COM操作ADO實現Windows平台資料庫存取,適用於維護舊系統、Office自動化、系統管理腳本等場景。掌握Connection/Recordset/Command/Field物件模型、參數化查詢、資源釋放規範,即可構建穩健的資料存取層。新專案優先考慮PDO等原生擴展。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved