一個重要的提示:如果您使用的是未編譯 PDO_OCI 的預建 PHP 套件,您應該下載與您的伺服器使用的 PHP 版本相對應的原始 PHP 原始碼。
這些原始碼在 ext/pdo_oci 目錄中包含 PDO_OCI 原始碼。
切換到該目錄,使用以下指令建置模組
phpize
./configure
make
然後將新建置的模組安裝到您的 PHP 擴充套件目錄,並將其新增到您的設定中。
對我來說,這在使用 sury.org 模組的 Debian 伺服器上有效 (PHP 8.2)。
如果 Oracle 資料庫與 PHP 位於同一台機器上,則資料庫軟體已包含必要的程式庫。當 PHP 位於不同的機器上時,請使用免費的 » Oracle Instant Client 程式庫。詳細資訊請參閱 OCI8 需求 章節。
此擴充功能已移至 » PECL 儲存庫,並且從 PHP 8.4.0 開始不再與 PHP 捆綁在一起。
有關安裝此 PECL 擴充功能的資訊,請參閱標題為 安裝 PECL 擴充功能 的手冊章節。其他資訊,例如新版本、下載、原始碼檔案、維護者資訊和 CHANGELOG,可在此處找到: » https://pecl.php.net/package/PDO_OCI。
使用 --with-pdo-oci[=DIR] 來安裝 PDO Oracle OCI 擴充套件,其中可選的 [=DIR]
是 Oracle Home 目錄。 [=DIR]
預設為 $ORACLE_HOME 環境變數。
使用 --with-pdo-oci=instantclient,prefix,version 安裝 Oracle Instant Client SDK,其中 prefix 和 version 需要設定。
// Using $ORACLE_HOME $ ./configure --with-pdo-oci // Using OIC for Linux with 10.2.0.3 RPMs with a /usr prefix $ ./configure --with-pdo-oci=instantclient,/usr,10.2.0.3
以下常數由這個驅動程式定義,並且只有在擴充套件已編譯到 PHP 中或在執行時動態載入時才可用。此外,這些驅動程式特定的常數應該只在使用此驅動程式時使用。將驅動程式特定的屬性與其他驅動程式一起使用可能會導致非預期的行為。可以使用 PDO::getAttribute() 來取得 PDO::ATTR_DRIVER_NAME
屬性以檢查驅動程式,如果您的程式碼可以在多個驅動程式上執行。
PDO::OCI_ATTR_ACTION
(整數)提供一種指定資料庫工作階段動作的方法。
此功能自 PHP 7.2.16 和 7.3.3 版本開始提供
PDO::OCI_ATTR_CLIENT_INFO
(整數)提供一種指定資料庫工作階段用戶端資訊的方法。
此功能自 PHP 7.2.16 和 7.3.3 版本開始提供
PDO::OCI_ATTR_CLIENT_IDENTIFIER
(整數)提供一種指定資料庫工作階段用戶端識別碼的方法。
此功能自 PHP 7.2.16 和 7.3.3 版本開始提供
PDO::OCI_ATTR_MODULE
(整數)提供一種指定資料庫工作階段模組的方法。
此功能自 PHP 7.2.16 和 7.3.3 版本開始提供
一個重要的提示:如果您使用的是未編譯 PDO_OCI 的預建 PHP 套件,您應該下載與您的伺服器使用的 PHP 版本相對應的原始 PHP 原始碼。
這些原始碼在 ext/pdo_oci 目錄中包含 PDO_OCI 原始碼。
切換到該目錄,使用以下指令建置模組
phpize
./configure
make
然後將新建置的模組安裝到您的 PHP 擴充套件目錄,並將其新增到您的設定中。
對我來說,這在使用 sury.org 模組的 Debian 伺服器上有效 (PHP 8.2)。
如果已安裝 Oracle 和 Oracle Instant Client,
且資料庫不在同一主機上
對於 UNIX/LINUX,設定 $LD_LIBRARY_PATH
將您的 Instant Client 路徑和 client/lib 路徑附加到其中,
Windows 系統設定 PATH 環境變數:
設定 PATH 後,設定 TNS_ADMIN 環境變數,指向
`tnsnames.ora` 檔案所在的目錄。
接著,您就可以使用服務名稱連線到您的資料庫。
測試程式碼:
<?php
$param = $_POST;
$db_username = "您的使用者名稱";
$db_password = "您的密碼";
$db = "oci:dbname=您的SID";
$conn = new PDO($db,$db_username,$db_password);
$name = $param['module'];
$file = $param['file'];
$stmt = $conn->exec("INSERT INTO AL_MODULE (AL_MODULENAME, AL_MODULEFILE) VALUES ('$name', '$file')");
?>
如果您遇到「找不到 oci.h」的錯誤,請嘗試建立多種路徑。一種方法是只使用 OIC 版本的主要和次要版本號(例如,11.2 代表 11.2.0.2),另一種方法是使用 client64 以及 client。
例如這樣 (以 11.2.0.2 為例):
`ln -s /usr/include/oracle/11.2.0.2/ /usr/include/oracle/11.2`
`ln -s /usr/include/oracle/11.2/client /usr/include/oracle/11.2/client64`
`ln -s /usr/lib/oracle/11.2.0.2/ /usr/lib/oracle/11.2`
`ln -s /usr/lib/oracle/11.2/client /usr/lib/oracle/11.2/client64`
這應該涵蓋 64 位元系統以及修補過 PHP 以僅使用 major.minor 版本號的情況。另請參閱 PHP bug #44989。
要在 PHP 上啟用 Oracle Instant Client 11.1.x 的 PDO 支援,您應該按照 Andrew 指出的編譯指令中的語法,如同 http://bugs.php.net/bug.php?id=39312, 所述,預設情況下,您已將 OIC 安裝在 `/usr/lib/oracle`(instant client 和 sdk 位於子資料夾中)
`./configure --with-oci8=shared,instantclient,/usr/lib/oracle`
`--with-pdo-oci=instantclient,/usr/lib/oracle,11.1`
只需指定您的 Oracle OIC 版本即可。
這樣就可以順利編譯。
此致。
請注意頂部的說明,這確實是一個實驗性擴充功能。我嘗試從 Oracle 讀取資料時遇到問題,導致 PHP 出現一些奇怪的行為。例如,`foreach` 迴圈沒有結束,也沒有錯誤訊息。我也設法將 Oracle 的資料讀入 PHP 的陣列中,但無法從函式返回該陣列。
經過一天的苦思維修,原來是 Oracle 中的 CLOB 欄位導致 PHP 出現奇怪的行為。我認為此擴充功能並不完全支援它們。
我改用 SQL 將其轉換為 VARCHAR2,這似乎解決了問題。
`SELECT CAST(columnx AS VARCHAR2(4000)) AS columnx ...`
這可能對遇到類似問題的人有所幫助。
警告聲明
PDO::oci 不支援 REF CURSOR。
在此頁面上(直到現在!)都沒有提到這一點。
現在您知道了!
如果您需要使用 ref cursor,請暫時避免使用 PDO。
我的參考資料:
`http://www.oracle.com/technology/pub/articles/`
php_experts/otn_pdo_oracle5.html
很棒的文章,真的非常出色。我不太清楚
這份文件有多久的歷史了,但它肯定已經蒙塵了,
因為它提到了「PHP5.1...」,這有點過時了」
... 截至 2006 年 6 月 1 日,PHP5.1 已經推出好一段時間了。
注意此頁面開頭的紅色區塊... pdo_oci 仍處於高度實驗階段。
儘管它從 2004 年就開始開發,但它至今仍缺乏對一些重要功能的支援
- 綁定一個 3500 個字元的 varchar2
- 取得選取的詮釋資料(meta)
- 使用 blob/clob 進行左聯結
- 等等。
就我的經驗而言,因為我們的軟體使用 pdo_pgsql,我認為使用 pdo_oci 來運行 Oracle 應該是可行的。經過一番努力,我終於得出以下結論:
1) 如果請求的驅動程式有非實驗性的 pdo 版本可用,請使用它。
2) 否則(至少對於 pdo_oci 來說),請使用您自己的抽象層。
3) 完成。
我做的更詳細的說明...
為了與 "$obj instanceof PDO" 等相容,我建立了兩個「主要」類別
- class PhpDb extends PDO
- class PhpDbStatement extends PDOStatement
兩個定義 PDO 實際功能的「抽象」類別
- abstract class PhpDbAbstract
- abstract class PhpDbAbstractStatement
最後,針對每個驅動程式,建立兩個執行抽象化的類別
- class PhpDbDriverOracle extends PhpDbAbstract
- class PhpDbDriverOracleStatement extends PhpDbAbstractStatement
您的腳本會存取「主要」類別,只需將「new PDO」替換為「new PhpDb」。
「抽象」類別主要用於文件說明 :p
「驅動程式」類別在背景執行工作,它們是由主要類別實例化的。
我的 PhpDb 遲早會成為一個開源專案,搜尋 Google 或寄信給我!