一个重要的提示:如果您使用的是预编译的 PHP 包,其中没有编译 PDO_OCI,则应下载服务器正在使用的 PHP 版本的原始 PHP 源代码。
这些源代码在 ext/pdo_oci 目录中包含 PDO_OCI 源代码。
更改到该目录,使用以下命令构建模块
phpize
./configure
make
然后将新构建的模块安装到您的 PHP 扩展目录,并将其添加到您的配置中。
这对我在 Debian 服务器上使用 sury.org 模块(PHP 8.2)有效。
如果 Oracle 数据库与 PHP 在同一台机器上,数据库软件已经包含了必要的库。如果 PHP 在不同的机器上,请使用免费的 » Oracle Instant Client 库。有关详细信息,请参阅 OCI8 需求 部分。
使用 --with-pdo-oci[=DIR] 安装 PDO Oracle OCI 扩展,其中可选的 [=DIR]
是 Oracle Home 目录。 [=DIR]
默认设置为 $ORACLE_HOME 环境变量。
对于 Oracle Instant Client SDK,使用 --with-pdo-oci=instantclient,prefix,version,其中 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
(int)提供一种方法来指定对数据库会话的操作。
从 PHP 7.2.16 和 7.3.3 开始存在。
PDO::OCI_ATTR_CLIENT_INFO
(int)提供一种方法来指定对数据库会话的客户端信息。
从 PHP 7.2.16 和 7.3.3 开始存在。
PDO::OCI_ATTR_CLIENT_IDENTIFIER
(int)提供一种方法来指定对数据库会话的客户端标识符。
从 PHP 7.2.16 和 7.3.3 开始存在。
PDO::OCI_ATTR_MODULE
(int)提供一种方法来指定对数据库会话的模块。
从 PHP 7.2.16 和 7.3.3 开始存在。
一个重要的提示:如果您使用的是预编译的 PHP 包,其中没有编译 PDO_OCI,则应下载服务器正在使用的 PHP 版本的原始 PHP 源代码。
这些源代码在 ext/pdo_oci 目录中包含 PDO_OCI 源代码。
更改到该目录,使用以下命令构建模块
phpize
./configure
make
然后将新构建的模块安装到您的 PHP 扩展目录,并将其添加到您的配置中。
这对我在 Debian 服务器上使用 sury.org 模块(PHP 8.2)有效。
如果已安装 oracle 和 oracle instant client,
但数据库不在同一主机上
对于 UNIX/LINUX,设置 $LD_LIBRARY_PATH
将您的 instant client 路径和 client/lib 路径追加到其中,
对于 Windows,设置 PATH 如下
设置路径后,设置 TNS_ADMIN 环境,指向
tnsnames.ora 所在的位置。
然后,您可以使用服务名称连接到您的数据库
测试代码
<?php
$param = $_POST;
$db_username = "youusername";
$db_password = "yourpassword";
$db = "oci:dbname=yoursid";
$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。另请参见 PHP 错误 #44989。
要为 Oracle Instant Client 11.1.x 在 PHP 上启用 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 ...
这可能对遇到类似问题的其他人有所帮助。
如果已安装 instant client 但完整的 oracle client
尚未安装,您可以使用 pdo 连接到 oracle 数据库
例如以下代码
<?php
$tns = "
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = yourip)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = orcl)
)
)
";
$db_username = "youname";
$db_password = "yourpassword";
try{
$conn = new PDO("oci:dbname=".$tns,$db_username,$db_password);
}catch(PDOException $e){
echo ($e->getMessage());
}
?>
警告声明
PDO::oci 不支持 REF CURSORS。
此页面上没有提到这一点(直到现在!)。
现在您知道了!
如果你想使用游标,现在请避免使用 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
- 获取选定的元数据
- 使用 blob/clob 进行左连接
- 等等。
故事是这样的,因为我们的软件使用 pdo_pgsql,所以我认为使用 pdo_oci 在 Oracle 上运行是可行的。经过一番漫长的战斗,我终于成功了
1) 如果请求的驱动程序有可用的非实验性 pdo 版本,请使用它。
2) 否则(至少对于 pdo_oci 而言),使用您自己的抽象层。
3) 就完成了。
我更详细的做法...
2 个“主要”类,用于与“$obj instanceof PDO”等兼容
- class PhpDb extends PDO
- class PhpDbStatement extends PDOStatement
2 个“抽象”类,定义 PDO 的实际功能
- abstract class PhpDbAbstract
- abstract class PhpDbAbstractStatement
最后,对于每个驱动程序,2 个用于抽象的类
- class PhpDbDriverOracle extends PhpDbAbstract
- class PhpDbDriverOracleStatement extends PhpDbAbstractStatement
“主要”类可从您的脚本访问,只需将“new PDO”替换为“new PhpDb”。
“抽象”类主要用于文档目的:p
“驱动程序”类在后台执行工作,它们是由主要类实例化的。
我的 PhpDb 将很快出现在开源项目中,请搜索 Google 或给我发邮件!
哇,游标。为了使用轻量级客户端,你打了不少字。
试试这个
$db = '//hostname/servicename'; //例如 '//192.168.1.1/orcl'
$user = 'username';
$pass = 'password';
$conn = new PDO($db,$user,$pass);
来自 PHP 5.3 UPGRADING 文件
- PDO_OCI php_pdo_oci8.dll 库(用于 Oracle 8 客户端
库)不再构建[在 PHP 5.3 中]。改为使用 php_pdo_oci.dll(注意没有
'8')与 Oracle 10 或 11 客户端库一起使用。连接到其他数据库
版本仍然受支持。
当我尝试连接时,服务器返回错误:“SQLSTATE[HY000]: pdo_oci_handle_factory: ORA-12560: TNS:protocol adapter error (ext\pdo_oci\oci_driver.c:579)”
为了解决它,我使用了这个
$conn = new PDO("oci:dbname=DBNAME;host=NN.NN.NN.NNN",'USER','PASSWORD');
例如
$conn = new PDO("oci:dbname=DB_FOO;host=10.10.48.245",'FOO','Foo%&5b');
为了在我的 CentOS 5.4 x86_64 机器上编译它,我不得不进行一些额外的设置,这些设置可能对其他人有用
从 Oracle 安装 oracle-instantclient11.2-basic 和 oracle-instantclient11.2-devel RPM 包
创建一些符号链接,因为 configure 包含一些有关路径名称的过时假设,并且不关心 64 位系统
ln -s /usr/lib/oracle/11.2/client64 /usr/lib/oracle/11.2/client
ln -s /usr/include/oracle/11.2/client64 /usr/lib/oracle/11.2/client/include
在您的 configure 命令中添加以下内容
--with-pdo-oci=shared,instantclient,/usr,11.2
对于 Red Hat 6,64 位,客户端 11.2,
在调整 config.m4 并调整 libs 符号链接后..
我遇到了编译错误“pdo_oci.c:34: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘pdo_oci_functions’”。
要解决这个问题,只需在 pdo_oci.c 文件中将 function_entry 更改为 zend_function_entry。
:)
PHP 到 Oracle 的速度比 PHP 到 MySQL 慢很多吗?我已经历经千辛万苦,将 Php4/MySQL 转换为 Php5/Oracle(在 Clobs 和 php5-variable-initialization 上跌跌撞撞)。一切正常,但是...
在 MySQL 中需要 8 秒的查询现在使用 Oracle 需要 3 分钟。是的,我在 Oracle 表中建立了索引。Oracle 连接比 MySQL 连接昂贵得多吗?我确实使用了 oci_pconnect。