OCI8 為 PHP 存取 Oracle 8/8i/9i/10g/11g/12c/19c 的原生擴展,支援:
:name)。ROWID 支援。oci_pconnect)、Statement Cache。# Linux/Unix .bash_profile 或 Apache envvars
export ORACLE_HOME=/u01/app/oracle/product/19.0.0/dbhome_1
export ORACLE_SID=ORCL
export LD_LIBRARY_PATH=$ORACLE_HOME/lib:$LD_LIBRARY_PATH
export NLS_LANG=AMERICAN_AMERICA.AL32UTF8 # 字元集關鍵
export ORA_NLS33=$ORACLE_HOME/ocommon/nls/admin/data
# Web 伺服器使用者 (www-data, apache) 需加入 oinstall/dba 群組
| 分類 | 代表函數 |
|---|---|
| 連線 | oci_connect, oci_pconnect, oci_close |
| 解析/執行 | oci_parse, oci_execute, oci_fetch_array, oci_fetch_assoc |
| 綁定變數 | oci_bind_by_name, oci_bind_array_by_name |
| LOB 操作 | oci_new_descriptor, OCILob->read, OCILob->write, OCILob->save, OCILob->load |
| 交易控制 | oci_commit, oci_rollback, oci_set_prefetch |
| 錯誤處理 | oci_error |
save("大量文字內容..."); // 寫入 LOB
oci_commit($conn); // 提交交易
// 讀取
$stmt2 = oci_parse($conn, "SELECT content FROM docs WHERE id = :id");
oci_bind_by_name($stmt2, ':id', $id);
oci_execute($stmt2);
$row = oci_fetch_assoc($stmt2);
if (is_object($row['CONTENT'])) $content = $row['CONTENT']->load();
echo $content;
?>
| 問題 | 原因 | 解決 |
|---|---|---|
| ORA-12154: TNS could not resolve | tnsnames.ora 未設定、ORACLE_HOME 錯誤 | 檢查 $ORACLE_HOME/network/admin/tnsnames.ora、EZCONNECT 字串 |
| ORA-12705: Invalid NLS parameter | NLS_LANG 未設定或不支援 | 設定 NLS_LANG=AMERICAN_AMERICA.AL32UTF8 |
| LOB 讀取回傳 Object 而非字串 | 需呼叫 ->load() 或 ->read() | if (is_object($lob)) $data = $lob->load(); |
| 預存程序 OUT 參數無值 | 綁定長度不足、模式錯誤 | 確認 oci_bind_by_name($sth, ':out', $var, 32) 長度足夠 |
| 中文亂碼 | 資料庫/連接字元集不一致 | 統一 AL32UTF8,NLS_LANG 設定正確 |
$pdo = new PDO('oci:dbname=ORCL', 'scott', 'tiger');
$stmt = $pdo->prepare("SELECT * FROM emp WHERE deptno = :dno");
$stmt->execute([':dno' => 10]);
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { /* ... */ }
PDO_OCI 提供統一介面,但部分進階功能 (LOB 串流、陣列綁定) 仍需原生 OCI8。