不要通过 PDO 连接 oracle 数据库和 PHP
Posted
技术标签:
【中文标题】不要通过 PDO 连接 oracle 数据库和 PHP【英文标题】:Do not connect oracle database with PHP through PDO 【发布时间】:2018-05-10 02:55:21 【问题描述】:我想默认通过 PDO 与 php 连接 oracle bd 中的 oracle Schema 数据库,但它抛出了这个错误:
致命错误:未捕获的 PDOException:SQLSTATE[42S02]: pdo_oci_handle_factory: ORA-12154: TNS: 无法解析连接 在中指定的标识符 (ext\pdo_oci\oci_driver.c:640) C:\xampp\htdocs\ORACLE\52conexion3.php:9 堆栈跟踪:#0 C:\xampp\htdocs\ORACLE\52conexion3.php(9): PDO->__construct('oci:host=localh...', 'hr', 'hr') #1 main 投入 C:\xampp\htdocs\ORACLE\52conexion3.php 第 9 行
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<?php
$base = new PDO('oci:host=localhost/XE; dbname= Schema - HR', 'hr','hr');
?>
</body>
</html>
在连接中的 sql developer 中,“shema”的 bd 在哪里,我右键单击查看属性并且我输入的数据是正确的,它显示连接名称:Schema - HR ,用户:hr,密码:hr,网络别名:XE。
其他尝试但仍然无效:
$base = new PDO('oci:host=localhost;dbname=Schema - HR', 'hr','hr');
$base = new PDO("oci:host=localhost;dbname=Schema - HR", "hr","hr");
$base = new PDO("oci:host=localhost/XE;dbname=Schema - HR", "hr","hr");
$base = new PDO("oci:host=XE;dbname=Schema - HR", "hr","hr");
$base = new PDO('oci:host=localhost;dbname="Schema - HR"', 'hr','hr');
我检查了 .ini 文件,它显然是正确的“extension = php_pdo_oci.dll”。
注意:我搜索了 php 手册,当我没有与 pdo 连接但通过程序我以这种方式(使用 oci_connect)进行连接时,它可以正常工作:
$connection = oci_connect('hr', 'hr', 'localhost/XE');
// oci_connect: 资源oci_connect(string$username,string$password[,string$connection_string[,string$character_set[,int$session_mode]])
【问题讨论】:
猜测 - 它不喜欢数据库名称中的空格。 我尝试使用其他数据库(名称不带空格“prueba”但也不起作用:/ 这个“localhost/XE”语法是什么?host
应该是主机名,应该是(DNS)可解析的名称;它不应包含斜杠。
我在一个论坛上看到他们是这样说的,但我尝试了很多方法(见帖子末尾)。
不确定 PDO Oracle 驱动程序是否专门处理/拆分主机名:github.com/php/php-src/blob/master/ext/pdo_oci/… - 但手册说它属于 dbname=
参数:php.net/manual/en/ref.pdo-oci.connection.php
【参考方案1】:
如 PHP manual page 和 mentioned in a comment by mario 中所述,OCI 的 PDO DSN 在其定义中使用 dbname
,而不是 schema
或 host
:
$conn = new PDO('oci:dbname=localhost/XE', $user, $pass);
您使用的localhost/XE
格式是“EZCONNECT”字符串。第一部分定义主机(localhost),第二部分定义服务(XE)。
您也可以使用“常规”连接字符串(通常在 tnsnames.ora
文件中定义):
$conn_string = '(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=XE)))';
$conn = new PDO('oci:dbname=' . $conn_string, $user, $pass);
【讨论】:
我以为 oracle 和 mysql 都是一样的,我在看一个 PDO 教程(但他们使用 mysql bd 和 phpmyadmin),他们放了 4 个字段(正如我在主题中写的) .显然它们是不同的,ORACLE 只需要 3 个字段:) 是否正确?现在它对我有用,但我想留下疑问。注意:我试着把 $ conn = new PDO ('oci: dbname = localhost', $ user, $ pass);没有 XE 并且它运行良好,为什么会这样?提前致谢 documentation 显示连接字符串的所有部分,host
除外,作为可选。 Quote: 如果用户指定了服务名称,那么侦听器会将用户连接到该特定数据库。否则,侦听器连接到listener.ora
文件中DEFAULT_SERVICE_listener_name
参数指定的数据库。【参考方案2】:
如果您使用 localhost 并设置 TNS,则可以只使用连接别名,在我的情况下为 orcl
:
$conn = new PDO('oci:dbname=orcl', $user, $pass);
在遥控器上,您可以:
$conn = new PDO('oci:dbname=hostname', $user, $pass);
【讨论】:
【参考方案3】:在您的 php 文件夹中有 php.ini 文件,在记事本中打开它并删除前面有 oci 的语句之前的扩展名,然后再次启动服务器,然后运行您的代码。
对于您需要添加的连接性:
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: Origin, Content-Type");
$rest_json = file_get_contents("php://input");
$_POST = json_decode($rest_json,true);
$opt = array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ,
PDO::ATTR_EMULATE_PREPARES => false,
);
// Create a PDO instance (connect to the database)
$pdo = new PDO('oci:dbname=127.0.0.1/xe;charset=CL8MSWIN1251', 'username', 'password');
【讨论】:
欢迎使用 ***:如果您发布代码、XML 或数据示例,请在文本编辑器中突出显示这些行,然后单击编辑器工具栏上的“代码示例”按钮 ( ) 或使用 Ctrl键盘上的 +K 可以很好地格式化和语法突出显示它!以上是关于不要通过 PDO 连接 oracle 数据库和 PHP的主要内容,如果未能解决你的问题,请参考以下文章
使用 SID 和 INSTANCE_NAME 将 oracle 与 pdo 连接