Ubuntu24系统PHP8.3安装oci8扩展(针对Oracle Database 23ai Free数据库)的方法

针对 Oracle Database 23ai Free(这是一个多租户架构的数据库,使用 Pluggable Database 或 PDB),PHP 最合适的 Oracle 扩展是 OCI8(Oracle Call Interface 8)。这是 Oracle 官方推荐的扩展,它提供高性能、全面的 Oracle 数据库交互功能,包括对 23ai 的完整支持(如 AI 向量搜索、JSON 等新特性)。

虽然 PDO_OCI(PDO 的 Oracle 驱动)也是一个选项,但它功能较 OCI8 有限(例如不支持 LOB 流式处理或某些高级绑定),且维护较少。OCI8 是首选,尤其在生产环境中。对于 PHP 8.3.6 和 Oracle 23ai Free,OCI8 3.4+ 版本完全兼容。

安装 OCI8 扩展的步骤

OCI8 依赖 Oracle Instant Client(客户端库)。对于 Oracle 23ai,推荐使用 Instant Client 23.x(最新版如 Version 23.26.1.0.0 (Requires glibc 2.28) 或更高,以确保最佳兼容性)。

以下是详细步骤(需要 root 权限,确保备份系统):

1 安装依赖包

sudo apt update
sudo apt install -y php8.3-dev php-pear libaio1 unzip build-essential

如果报错说“找不到libaio1”,解决方法参见Ubuntu24系统PHP8.3安装oci8扩展后启用报错:/usr/lib/php20230831/oci8.so (libaio.so.1 cannot open shared object file No such file or directory)的解决方法

2 下载 Oracle Instant Client

访问 Oracle 官网 Instant Client 下载页oracle.com/database/technologies/instant-client/downloads.html。

下载 Linux x86-64 的 Basic PackageSDK Package(如oracle-instantclient-basic-23.26.1.0.0-1.el10.x86_64.rpm和oracle-instantclient-devel-23.26.1.0.0-1.el10.x86_64.rpm)。如果 RPM 不便,用 ZIP 版(如instantclient-basic-linux.x64-23.26.1.0.0.zip 和 instantclient-sdk-linux.x64-23.26.1.0.0.zip)。

对于 ZIP 版,解压到如 /opt/oracle/instantclient_23_26/:

sudo mkdir -p /opt/oracle
cd /opt/oracle
sudo unzip /path/to/instantclient-basic-linux.x64-23.26.1.0.0.zip
sudo unzip /path/to/instantclient-sdk-linux.x64-23.26.1.0.0.zip

3 设置环境变量

编辑 /etc/profile.d/oracle.sh(新建如果不存在):

sudo nano /etc/profile.d/oracle.sh

添加:

export ORACLE_HOME=/opt/oracle/instantclient_23_26
export LD_LIBRARY_PATH=$ORACLE_HOME:$LD_LIBRARY_PATH
export PATH=$ORACLE_HOME:$PATH

使环境变量和Oracle Instant Client相关共享库立即生效、可用:

source /etc/profile.d/oracle.sh
sudo ldconfig

注意,如果有其他终端窗口开着,需要先登出系统再登录才能使上述使环境变量和Oracle Instant Client相关共享库生效、可用。

4 安装 OCI8 扩展

使用 pecl 安装(指定 Instant Client 版本):

sudo pecl install oci8

当提示 “instantclient,/path/to/client/lib” 时,输入instantclient,/opt/oracle/instantclient_23_26

如果提示 PHP 版本错误,确保 pecl 使用 PHP 8.3:sudo pear config-set php_bin /usr/bin/php8.3

5 配置 PHP

添加oci8扩展到 php.ini(CLI 和 FPM/Apache,根据你的 PHP 使用方式):

echo "extension=oci8.so" | sudo tee /etc/php/8.3/mods-available/oci8.ini
sudo phpenmod oci8

如果用 Apache,重启:

sudo systemctl restart apache2

如果用 PHP-FPM,重启:

sudo systemctl restart php8.3-fpm

验证oci8扩展是否启用成功:

php -m | grep oci8

在输出中应看到 oci8。

PHP 测试脚本(test_oracle_connection.php)

以下是一个简单脚本,使用 OCI8 扩展连接 Oracle 23ai Free数据库。保存为 .php 文件,在命令行运行 php test_oracle_connection.php 或通过 Web 服务器访问:

<?php
// 连接参数(调整为你的实际值)
$username = 'system';
$password = '密码';
$connection_string = '127.0.0.1:1521/FREEPDB1';  // EZCONNECT 格式:主机:端口/服务名

// 尝试连接
$conn = oci_connect($username, $password, $connection_string, 'AL32UTF8');  // 指定字符集,避免中文乱码

if (!$conn) {
    $error = oci_error();
    echo "连接失败: " . htmlentities($error['message'], ENT_QUOTES);
    exit;
}

// 连接成功,执行一个简单查询测试
$stmt = oci_parse($conn, 'SELECT name, open_mode FROM v$pdbs');
oci_execute($stmt);

echo "连接成功!PDB 状态:\n";
while ($row = oci_fetch_array($stmt, OCI_ASSOC + OCI_RETURN_NULLS)) {
    echo $row['NAME'] . " - " . $row['OPEN_MODE'] . "\n";
}

// 关闭连接
oci_free_statement($stmt);
oci_close($conn);

注意,脚本中用了 EZCONNECT 格式(无需 tnsnames.ora)。

如果脚本运行成功,会显示 “连接成功!PDB 状态:” 后跟 PDB 列表(如 FREEPDB1 – READ WRITE)。

兼容性说明

PHP 的 OCI8 扩展完全兼容 Oracle 11g(包括 11g Release 2,即 11.2.x 版本):

  • 很多遗留系统用 PHP 7/8 + OCI8 连接 Oracle 11g 运行多年。
  • Laravel + yajra/laravel-oci8 包也支持连接 11g。
  • 官方教程(如 Oracle 的 PHP + 11g 示例)直接使用 OCI8。

潜在小问题(极少见):

  • 如果你的 Oracle 11g 是非常早的 11.1(非 11.2),兼容性稍差,但 11.2 是主流版本,完全没问题。
  • 某些非常新的 OCI8 特性(如 oci_set_call_timeout,需要客户端 18c+)在 11g 上不可用,但基本 CRUD 操作、绑定、LOB、存储过程等全部正常。
  • 字符集:建议用 AL32UTF8,避免老的 WE8MSWIN1252 导致乱码。

测试兼容性的简单 PHP 脚本:

<?php
$conn = oci_connect('system', '你的密码', '127.0.0.1:1521/orcl');  // 替换为你的连接字符串,如 SID 或服务名

if (!$conn) {
    $e = oci_error();
    echo "连接失败: " . htmlentities($e['message'], ENT_QUOTES);
} else {
    echo "成功连接到 Oracle 11g!\n";
    
    $s = oci_parse($conn, 'SELECT * FROM v$version');
    oci_execute($s);
    
    while ($row = oci_fetch_array($s, OCI_ASSOC)) {
        print_r($row);
    }
    
    oci_close($conn);
}

运行后如果能看到数据库的版本信息(如 “Oracle Database 11g Release 2″),就证明兼容性没问题。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注