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

PHP 操作 Oracle 資料庫實戰(六):使用 OCI8 擴充查詢資料完整範例

     編輯:PHP 綜合知識

前言

OCI8 是 PHP 官方支援的 Oracle 資料庫擴充,提供高效能、功能完整的介面。本文示範使用 OCI8 函式風格 (Procedural) 連線 Oracle、執行查詢、逐行取得結果並輸出 HTML 表格的完整流程。程式碼已加入嚴格錯誤處理與資源釋放。

環境需求

  • Oracle Instant Client (Basic + SDK) 或完整 Oracle Client 安裝。
  • PHP 編譯時加入 --with-oci8=instantclient,/path/to/instantclient (Linux) 或啟用 extension=oci8 (Windows)。
  • 環境變數 ORACLE_SID、NLS_LANG (如 AMERICAN_AMERICA.AL32UTF8) 正確設定。

完整查詢範例:列出 email_info 表所有資料

<?php
declare(strict_types=1);

// 1. 設定 Oracle 環境 (需在連線前)
putenv('ORACLE_SID=ORASID');
putenv('NLS_LANG=AMERICAN_AMERICA.AL32UTF8'); // 關鍵:避免中文亂碼

// 2. 建立連線
$conn = oci_connect('username', 'password', '//host:1521/service_name');
if (!$conn) {
    $e = oci_error();
    die("連線失敗: {$e['message']}");
}

// 3. 解析 SQL 語句
$sql = 'SELECT full_name, email_address FROM email_info ORDER BY full_name';
$stid = oci_parse($conn, $sql);
if (!$stid) {
    $e = oci_error($conn);
    oci_close($conn);
    die("SQL 解析失敗: {$e['message']}");
}

// 4. 執行查詢
$r = oci_execute($stid);
if (!$r) {
    $e = oci_error($stid);
    oci_free_statement($stid);
    oci_close($conn);
    die("查詢執行失敗: {$e['message']}");
}

// 5. 輸出 HTML 表格頭
echo '<table border="1" cellpadding="5" cellspacing="0">';
echo '<thead><tr><th>姓名</th><th>Email 地址</th></tr></thead>';
echo '<tbody>';

// 6. 逐行取得資料 (oci_fetch_array 預設回傳數字+關聯雙索引)
while (($row = oci_fetch_array($stid, OCI_ASSOC + OCI_RETURN_NULLS)) !== false) {
    // htmlspecialchars 防 XSS,處理 NULL 顯示
    $name  = htmlspecialchars($row['FULL_NAME'] ?? '', ENT_QUOTES, 'UTF-8');
    $email = htmlspecialchars($row['EMAIL_ADDRESS'] ?? '', ENT_QUOTES, 'UTF-8');
    echo "<tr><td>{$name}</td><td>{$email}</td></tr>";
}

echo '</tbody></table>';

// 7. 釋放資源 (重要!避免連線洩漏)
oci_free_statement($stid);
oci_close($conn);
?>

關鍵 API 對照表

舊版 ORA_* 函式 (已移除)現代 OCI8 函式說明
Ora_Logon()oci_connect() / oci_pconnect()建立連線,支援 Easy Connect 字串
Ora_Open()不需要,oci_parse() 直接回傳 statement
Ora_Parse()oci_parse()預處理 SQL
Ora_Exec()oci_execute()執行 statement
Ora_Fetch_Into()oci_fetch_array() / oci_fetch_assoc() / oci_fetch_object()取得下一行,支援多種模式
Ora_Close()oci_free_statement()釋放 statement 資源
Ora_Logoff()oci_close()關閉連線
Ora_Error()oci_error()取得錯誤資訊陣列
Ora_Commit()oci_commit()提交交易
Ora_Rollback()oci_rollback()回滾交易

進階技巧:繫結變數與效能優化

// 參數化查詢 (防注入、提升解析重用)
$sql = 'SELECT * FROM email_info WHERE department = :dept AND created_at > :date';
$stid = oci_parse($conn, $sql);

// 繫結 PHP 變數到 Oracle 佔位符
oci_bind_by_name($stid, ':dept', $deptVar);
oci_bind_by_name($stid, ':date', $dateVar, 20); // 長度建議指定

// 執行
oci_execute($stid);

// 重複執行不同參數時,無需重新 parse,直接改變 $deptVar/$dateVar 再 execute
// 這就是「軟解析」重用的威力

物件導向封裝建議 (PDO 風格)

原生 OCI8 函式較冗長,建議封裝或使用社區庫:

  • yajra/laravel-oci8:Laravel 專用 Eloquent 驅動。
  • spatie/oci8:輕量 PDO 風格封裝。
  • 自建 OracleDB 類別封裝 connect, query, fetchAll, execute, beginTransaction, commit, rollback 等方法。

常見坑點與解決方案

  • 中文亂碼: 必須設定 NLS_LANG=.AL32UTF8 (或資料庫字符集對應值),並在 PHP 檔案存為 UTF-8 無 BOM。
  • 欄位名大小寫: Oracle 預設回傳大寫欄位名 (如 FULL_NAME),使用 OCI_ASSOC 時鍵值為大寫。
  • NULL 值處理: oci_fetch_array(..., OCI_RETURN_NULLS) 才會在陣列中包含 NULL 鍵,否則會略過。
  • LOB (CLOB/BLOB) 讀取: 需用 oci_fetch_array 取得 LOB 描述子,再呼叫 ->load() 或 ->read()。
  • 長時間腳本連線中斷: 使用 oci_pconnect 長連線,或 CLI 模式下定期 oci_ping($conn) 心跳。

小結

OCI8 是 PHP 連接 Oracle 的標準方式,提供完整的預處理、繫結變數、LOB 處理、交易控制等企業級功能。本文示範了從連線、查詢、取值、輸出到資源釋放的標準流程,並對照了已移除的舊版 ORA_* 函式。掌握 oci_parse → oci_bind_by_name → oci_execute → oci_fetch_array 這條主線,即能應對絕大多數 Oracle 開發場景。

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