ODBC 连接通过命令行工作,而不是通过 apache


ODBC connection works through command line, not through apache

我正在尝试使用 PHP 连接到远程系统上的普遍 11 DB。DSN 在/etc/odbc.ini 中设置。psql(由 Pervasive 客户端安装程序创建)和 www-data 用户可以通过以下方式连接到远程系统

isql -v remote  

此外,www-data 用户被添加到 pvsw 组中,并且所需的环境变量PVSW_ROOT和LD_LIBRARY_PATH在/etc/apache2/envvars中设置,并使用 SetEnv 在虚拟主机中设置。

我的PHP脚本如下:

<?php  
$connect = odbc_connect("remote", "", "") or die("Could not connect");  
$query = "SELECT * FROM '"ITEMS'"";  
$prepared = odbc_prepare($connect, $query);  
$result = odbc_execute($prepared);  
odbc_result_all($prepared);  

脚本从命令行运行良好:

sudo -u www-data /usr/bin/php /var/www/odbc.php

并按预期输出。

但是,访问 http://example.org/odbc.php 会导致空白页,并且不会从Apache发送任何数据(使用wget和Chrome进行检查)。使用 tcpdump 显示了服务器和普遍远程数据库之间建立的连接,两者都是通过从 CLI 调用脚本和从 Apache 调用脚本。系统是 Debian 64 位 7.7。在虚拟主机配置中设置了"日志级调试",但不会记录任何错误。

为什么 Apache 不返回任何数据?

编辑:使用gdb并逐步完成处理请求的 Apache Web 服务器进程,我收到此错误:

Program received signal SIGSEGV, Segmentation fault.  
0x00007ff48c68ea2f in ErrStmtWithState () from /usr/local/psql/lib64/libodbcci.so  

看起来像一个错误,不是吗?

可能是一个错误:http://cs.pervasive.com/forums/p/14802/53328.aspx。

我遇到了同样的问题,但使用mod_wsgi和 python,并在谷歌上搜索了"ErrStmtWithState"来到达这里。我的(远非最佳)解决方案的灵感来自 https://serverfault.com/questions/451220/psql-64bit-driver-error。我创建了以下 shell 脚本:

#!/bin/bash
PVSW_ROOT=/usr/local/psql
PATH=$PATH:$PVSW_ROOT/bin:/bin:/usr/bin
LD_LIBRARY_PATH=$PVSW_ROOT/lib64:$PVSW_ROOT/bin:/usr/lib
MANPATH=$MANPATH:$PVSW_ROOT/man
export PVSW_ROOT
export LD_LIBRARY_PATH
python wrapper.py "$@"

其中"wrapper.py"针对作为参数传递的 dsn 运行查询并输出序列化结果集:

import pyodbc
import cPickle
import sys, getopt
def main(argv):
   dsn = ''
   query = ''
   hm = 'usage: wrapper.py -d <dsn> -q <query>'
   try:
       opts, args = getopt.getopt(argv,"hd:q:",["dsn=","query="])
   except getopt.GetoptError:
      print hm
      sys.exit(2)
   for opt, arg in opts:
      if opt == '-h':
         print hm
         sys.exit()
      elif opt in ("-d", "--dsn"):
         dsn = arg
      elif opt in ("-q", "--query"):
         query = arg
   cnxn = pyodbc.connect('DSN='+dsn)
   cursor = cnxn.cursor()
   cursor.execute(query)
   rows = cursor.fetchall()
   print(cPickle.dumps(rows))
if __name__ == "__main__":
   main(sys.argv[1:])

从普遍文档中复制的环境变量:http://docs.pervasive.com/products/database/psqlv10/wwhelp/wwhimpl/js/html/wwhelp.htm#href=getstart/unixappconf.15.3.html

当我运行您的代码时,我收到一条消息,指出odbc_result_all希望参数 1 是资源。
当我将其更改为以下内容时,它起作用了:

<?php  
$connect = odbc_connect("remote", "", "") or die("Could not connect.");  
$query = "SELECT * FROM '"ITEMS'"";  
$prepared = odbc_prepare($connect, $query);  
if (!odbc_execute($prepared)) {
    die(odbc_errormsg()); 
}
if (odbc_result_all($prepared) < 1) {
    die(odbc_errormsg());
}
?>

这是有道理的,因为odbc_excute声明为:

bool odbc_execute ( resource $result_id [, array $parameters_array ] )

odbc_result_all声明为:

int odbc_result_all ( resource $result_id [, string $format ] )

在 PHP 文档中。