PHP 連接 Oracle 需要 OCI8 擴展與 Oracle Instant Client 庫。CentOS 上安裝涉及 RPM 套件、PECL 編譯、環境變數、SELinux 等多環節。本文提供針對 CentOS 7/8、PHP 7.4/8.x 的標準化流程,並整理常見錯誤與解法。
yum install php-devel php-pear gcc libaio# 下載對應版本 (從 Oracle 官網需登入,或使用內部鏡像)
# 基本、SDK、SQL*Plus 三包必裝
# 範例:19.3 版 64-bit
wget https://yum.oracle.com/repo/OracleLinux/OL7/oracle/instantclient/x86_64/getPackage/oracle-instantclient19.3-basic-19.3.0.0.0-1.x86_64.rpm
wget https://yum.oracle.com/repo/OracleLinux/OL7/oracle/instantclient/x86_64/getPackage/oracle-instantclient19.3-devel-19.3.0.0.0-1.x86_64.rpm
wget https://yum.oracle.com/repo/OracleLinux/OL7/oracle/instantclient/x86_64/getPackage/oracle-instantclient19.3-sqlplus-19.3.0.0.0-1.x86_64.rpm
# 安裝
rpm -ivh oracle-instantclient19.3-*.rpm
# 設置庫路徑 (關鍵!)
echo /usr/lib/oracle/19.3/client64/lib > /etc/ld.so.conf.d/oracle-instantclient.conf
ldconfig
# 設置環境變數 (編譯與執行階段皆需)
export ORACLE_HOME=/usr/lib/oracle/19.3/client64
export LD_LIBRARY_PATH=$ORACLE_HOME/lib:$LD_LIBRARY_PATH
# 永久生效請寫入 /etc/profile.d/oracle.sh
# 方式一:PECL 自動編譯 (推薦)
pecl install oci8-3.2.1 # PHP 8.0+ 用 3.x,PHP 7.x 用 2.x
# 提示輸入 ORACLE_HOME 時按 Enter (已設環境變數) 或輸入 instantclient,/usr/lib/oracle/19.3/client64/lib
# 方式二:手動編譯 (需指定 php-config)
cd /tmp
wget https://pecl.php.net/get/oci8-3.2.1.tgz
tar xzf oci8-3.2.1.tgz
cd oci8-3.2.1
/usr/bin/phpize
./configure --with-php-config=/usr/bin/php-config --with-oci8=shared,instantclient,/usr/lib/oracle/19.3/client64/lib
make && make install
# 找到 php.ini
php --ini
# 新增擴展行
echo "extension=oci8.so" > /etc/php.d/20-oci8.ini
# 或直接編輯 php.ini
# 重啟 PHP-FPM / Apache
systemctl restart php-fpm
# 或
systemctl restart httpd
# CLI 驗證
php -m | grep oci8
php -r 'echo oci8_version();' # 輸出版本字串
# 連線測試
php -r '
$conn = oci_connect("user", "pass", "//host:1521/service_name");
if ($conn) {
echo "Connected successfully\n";
oci_close($conn);
} else {
$e = oci_error();
echo "Connection failed: " . $e["message"] . "\n";
}
'
| 錯誤訊息 | 原因 | 解法 |
|---|---|---|
libclntsh.so: cannot open shared object file | 動態連結器找不到 Instant Client 庫 | 確認 ldconfig 已執行,LD_LIBRARY_PATH 包含 lib 目錄,PHP-FPM 啟動腳本已 source 環境變數 |
OCIEnvNlsCreate() failed | 字元集不支援、NLS 設定錯誤 | 設定 NLS_LANG=AMERICAN_AMERICA.AL32UTF8 (或對應字元集) |
ORA-12705: Cannot access NLS data files | ORACLE_HOME 未正確指向 Instant Client 根目錄 | export ORACLE_HOME=/usr/lib/oracle/19.3/client64 |
phpize: command not found | 缺 php-devel | yum install php-devel |
configure: error: Oracle lib not found | Instant Client SDK (devel) 未安裝或路徑錯誤 | 安裝 devel RPM,確認 --with-oci8=shared,instantclient,/path/to/lib 路徑正確 |
| SELinux 阻擋 httpd 讀取 Oracle 庫 | 安全上下文錯誤 | chcon -t textrel_shlib_t /usr/lib/oracle/19.3/client64/lib/*.so 或 setsebool -P httpd_execmem 1 |
# PECL 安裝
pecl install pdo_oci-1.0 # 較舊,可能需手動編譯
# 連線字串不同
$pdo = new PDO("oci:dbname=//host:1521/service_name", 'user', 'pass');
# OCI8
$conn = oci_connect('user', 'pass', '//host:1521/service_name');
# Dockerfile 片段
FROM php:8.2-fpm
# 安裝系統依賴
RUN yum install -y libaio gcc make
# 複製 Instant Client RPM (預先下載到本地)
COPY oracle-instantclient19.3-*.rpm /tmp/
RUN rpm -ivh /tmp/oracle-instantclient19.3-*.rpm \
&& echo /usr/lib/oracle/19.3/client64/lib > /etc/ld.so.conf.d/oracle.conf \
&& ldconfig
ENV ORACLE_HOME=/usr/lib/oracle/19.3/client64
ENV LD_LIBRARY_PATH=$ORACLE_HOME/lib
# 編譯 OCI8
RUN pecl install oci8-3.2.1 \
&& docker-php-ext-enable oci8
OCI8 安裝核心在於「Instant Client 庫路徑正確暴露給連結器與 PHP 執行階段」。採用 RPM + ldconfig + 環境變數 + PECL 標準流程,並以 Docker 固化環境,能最大程度避免「在我機器上能跑」的部署困境。