迁移到 php7 后的 oci8 (Oracle) 问题
oci8 (Oracle) Issues after migrating to php7
我想将我的网络服务器升级到最新的 Ubuntu 版本,因此也将 php5 升级到 php7。我完成了 VM 运行 lubuntu 16.04 的安装和配置以进行测试,查看是否需要更改代码并测试它是否正常工作。
在第一个应用程序中,我遇到了 oracle (oci8) 的一个奇怪问题。该应用程序使用服务器端分页,还显示 "Total Records" 和 "Total records (filtered)" 之类的内容。当然,这些 "metrics" 是基于简单的计数查询,它们可以工作并显示正确的结果。但是 select 语句获取实际数据 returns 0 命中。特别令人费解,因为它使用完全相同的查询:
$sQueryInner = "SELECT id, ROW_NUMBER() OVER ($sOrderByClause) R
FROM my_table " . $sWhereClause;
$sQueryFinal = "SELECT id FROM
(" . $sQueryInner . ")
WHERE R BETWEEN :startIndex and :endIndex";
// Total data set length after applying where
$sQueryFilteredCount = "SELECT COUNT(*) as \"totalRowsCount\" FROM (" . $sQueryInner . ")";
唯一的区别是 ROW_NUMBER()
子句,但我看不出这对没有返回结果的事情有何影响。我也没有收到任何错误消息或 php 警告。 oci_fetch_array
立即 returns false
意味着找不到更多行。
while ($row = oci_fetch_array($statementFinal, OCI_ASSOC + OCI_RETURN_NULLS)) {//...
我想找到一种调试 oci8 本身的方法。查看实际发送的SQL。但是 oci_internal_debug
自 php5.6 以来似乎已被禁用。
所以我很迷茫。任何想法可能导致此问题以及我如何进一步 debug/search 为什么会造成这种情况?
编辑:
Wit wireshark 我实际上可以看到 SQL 发送到数据库,它是正确的。问题是没有行被返回。唯一的结论是参数绑定无法正常工作,因此不会返回任何结果。但是我不明白,因为完全相同的事情在 ubuntu 14.04 上有效。唯一的区别是 php7。所有其他应用程序也可以工作,所以问题出在这个特定的查询上。它有一个 subselect 和 Row_number() 函数。
这是 php 的另一个 WTF。定义。考虑用其他语言重写...说真的 php 伙计们,抓紧时间...
他们 changed something fundamental 影响 oci_bind_by_name
但没有在任何地方提及。
可以通过重新排序您的代码来解决此问题。这意味着如果您在函数调用中绑定语句,则必须按此顺序执行:
- 创建报表
- 绑定语句 1
- 执行语句 1
- 绑定语句 2
- 执行语句 2
等等。如果您首先绑定所有语句然后执行它,则稍后对绑定的调用将覆盖以前的值,即使参数具有完全不同的名称和类型也是如此。什么鬼?
我想将我的网络服务器升级到最新的 Ubuntu 版本,因此也将 php5 升级到 php7。我完成了 VM 运行 lubuntu 16.04 的安装和配置以进行测试,查看是否需要更改代码并测试它是否正常工作。
在第一个应用程序中,我遇到了 oracle (oci8) 的一个奇怪问题。该应用程序使用服务器端分页,还显示 "Total Records" 和 "Total records (filtered)" 之类的内容。当然,这些 "metrics" 是基于简单的计数查询,它们可以工作并显示正确的结果。但是 select 语句获取实际数据 returns 0 命中。特别令人费解,因为它使用完全相同的查询:
$sQueryInner = "SELECT id, ROW_NUMBER() OVER ($sOrderByClause) R
FROM my_table " . $sWhereClause;
$sQueryFinal = "SELECT id FROM
(" . $sQueryInner . ")
WHERE R BETWEEN :startIndex and :endIndex";
// Total data set length after applying where
$sQueryFilteredCount = "SELECT COUNT(*) as \"totalRowsCount\" FROM (" . $sQueryInner . ")";
唯一的区别是 ROW_NUMBER()
子句,但我看不出这对没有返回结果的事情有何影响。我也没有收到任何错误消息或 php 警告。 oci_fetch_array
立即 returns false
意味着找不到更多行。
while ($row = oci_fetch_array($statementFinal, OCI_ASSOC + OCI_RETURN_NULLS)) {//...
我想找到一种调试 oci8 本身的方法。查看实际发送的SQL。但是 oci_internal_debug
自 php5.6 以来似乎已被禁用。
所以我很迷茫。任何想法可能导致此问题以及我如何进一步 debug/search 为什么会造成这种情况?
编辑:
Wit wireshark 我实际上可以看到 SQL 发送到数据库,它是正确的。问题是没有行被返回。唯一的结论是参数绑定无法正常工作,因此不会返回任何结果。但是我不明白,因为完全相同的事情在 ubuntu 14.04 上有效。唯一的区别是 php7。所有其他应用程序也可以工作,所以问题出在这个特定的查询上。它有一个 subselect 和 Row_number() 函数。
这是 php 的另一个 WTF。定义。考虑用其他语言重写...说真的 php 伙计们,抓紧时间...
他们 changed something fundamental 影响 oci_bind_by_name
但没有在任何地方提及。
可以通过重新排序您的代码来解决此问题。这意味着如果您在函数调用中绑定语句,则必须按此顺序执行:
- 创建报表
- 绑定语句 1
- 执行语句 1
- 绑定语句 2
- 执行语句 2
等等。如果您首先绑定所有语句然后执行它,则稍后对绑定的调用将覆盖以前的值,即使参数具有完全不同的名称和类型也是如此。什么鬼?