PHP 透過 oci8 擴充套件連接 Oracle,原生 API 程序式風格較強。本文提供一個 Oracle_db 類別,封裝連線、查詢、結果集獲取、錯誤處理、資源釋放等常用操作,方便在專案中複用。
class Oracle_db {
public $link;
public function __construct() {
$this->link = $this->connect();
if (!$this->link) { echo "連接失敗"; exit; }
}
public function connect() {
// oci_connect(使用者, 密碼, 連線字串, 字元集)
return oci_connect('demo', 'demo', 'localhost/xe', 'AL32UTF8');
}
public function execute($sql) {
$stid = oci_parse($this->link, $sql);
$result = $stid ? oci_execute($stid) : false;
return [$stid, $result];
}
public function fetch_assoc($stid) { return oci_fetch_assoc($stid); }
public function fetch_one($stid) {
$arr = $this->fetch_assoc($stid);
$this->free($stid);
return $arr;
}
public function fetch_all($stid) {
$arr = [];
while ($row = $this->fetch_assoc($stid)) $arr[] = $row;
$this->free($stid);
return $arr;
}
public function num_rows($stmt) { return oci_num_rows($stmt); }
public function error() { return oci_error($this->link); }
public function free($stid) { return oci_free_statement($stid); }
public function server_version() { return oci_server_version($this->link); }
public function client_version() { return oci_client_version(); }
public function __destruct() { return oci_close($this->link); }
}
$db = new Oracle_db();
// 單筆查詢
list($stid, $ok) = $db->execute("SELECT * FROM users WHERE id = 1001");
$user = $db->fetch_one($stid);
// 多筆查詢
list($stid, $ok) = $db->execute("SELECT * FROM orders WHERE status = 'NEW'");
$orders = $db->fetch_all($stid);
// 錯誤處理
if (!$ok) {
$e = $db->error();
log_error("Oracle Error: {$e['message']} (Code: {$e['code']})");
}
AL32UTF8 為 UTF-8,避免中文亂碼。若資料庫為 ZHS16GBK,需改用 ZHS16GBK。oci_bind_by_name() 綁定變數,防 SQL Injection。oci_pconnect() 或連線池(Oracle DRCP)。BLOB/CLOB 需用 oci_new_descriptor()、->write()/->read() 處理。fetch_all() 等方法中呼叫 free(),避免游標洩漏導致 ORA-01000。yajra/laravel-oci8 提供 Eloquent ORM、Migration、Schema Builder 完整支援。Oracle_db 類別展示了 OCI8 核心 API 的基本封裝模式。實務專案中,建議直接採用成熟的抽象層(PDO/DBAL/Eloquent),專注於業務邏輯而非底層資源管理,並嚴格落實預處理綁定與錯誤日誌記錄。