1

I'm trying to connect to a Pervasive 11 DB on a remote system using PHP. The DSN is setup in /etc/odbc.ini. The psql (created by the Pervasive client installer) and www-data user can connect to the remote system using

isql -v remote  

Furthermore, the www-data user is added to the pvsw group and the needed environment variables PVSW_ROOT and LD_LIBRARY_PATH are set in /etc/apache2/envvars as well as in the vhost using SetEnv.

My PHP script is as follows:

<?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);  

The script runs fine from the command line:

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

and outputs as expected.

However, accessing http://example.org/odbc.php results in a blank page and no data is being sent from Apache (checked with wget and Chrome). Using tcpdump shows the connection being made between the server and the Pervasive remote DB, both by invoking the script from the CLI as from Apache. The system is Debian 64 bit 7.7. 'LogLevel debug' is set in the vhost config, but no errors are logged.

Why is Apache not returning any data?

EDIT: using gdb and stepping through the apache webserver process that is handling the request, I get this error:

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

Looks like a bug, no?

  • I am not the expert but I noticed that you use sudo for it to work from command line. Could it be permissions issue? Try to open your browser as super user and see if it works. – Makketronix Nov 19 '14 at 22:33
  • @Makketronix I use sudo -u www-data, which runs the command as the www-data user. It's not about opening my browser with SU privileges, it's Apache not sending data. Thanks! – HogeBlekker Nov 20 '14 at 19:33
  • How about reading the server logs and paste the messages in the question ? also if your logs are empty that means you're sending error logs to another files, try manually removing the script and error_log() a string and find out where it shows up. You shouldn't need sudo btw, I'm not sure what you're accomplishing by that ? – Mostafa Berg Nov 20 '14 at 19:42
  • @MostafaTorbjørnBerg. As said, there is nothing in the error logs about this, despite 'LogLevel debug'. Other errors (and using error_log('test')), do show up in the logs. – HogeBlekker Nov 20 '14 at 19:54
  • strange, did you try to set `error_reporting` to `E_ALL` and `display_errors` to `1` ? – Mostafa Berg Nov 20 '14 at 20:03
  • @MostafaTorbjørnBerg Yes, both are set in /etc/php5/apache2/php.ini, which is loaded according to phpinfo() – HogeBlekker Nov 20 '14 at 20:40
  • Used gdb to debug apache process. See EDIT above. – HogeBlekker Nov 20 '14 at 22:02
  • I haven't encountered similar issues like that before TBH, have you tried commenting out line by line and see if this issue goes away at a specific line, might at least show what's segfaulting either your code or if it's a bug ! – Mostafa Berg Nov 24 '14 at 08:36

2 Answers2

1

Probably a bug: http://cs.pervasive.com/forums/p/14802/53328.aspx.

I got the same issue but with mod_wsgi and python and googled "ErrStmtWithState" to get here. My (far from optimal) solution was inspired by https://serverfault.com/questions/451220/psql-64bit-driver-error. I created the following shell script:

#!/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 "$@"

Where "wrapper.py" runs a query against a dsn passed as an argument and outputs a serialized resultset:

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:])

Environment variables copied from pervasive documentation: http://docs.pervasive.com/products/database/psqlv10/wwhelp/wwhimpl/js/html/wwhelp.htm#href=getstart/unixappconf.15.3.html

Community
  • 1
  • 1
0

When I ran your code, I got a message saying that odbc_result_all expects parameter 1 to be a resource.
When I changed it to the following, it worked:

<?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());
}
?>

This makes sense because odbc_excute is declared as:

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

and odbc_result_all is declared as:

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

in the PHP docs.

mirtheil
  • 8,952
  • 1
  • 30
  • 29
  • Thanks for your comment. I apparently made an error copy/pasting my script here. The script is like you mentioned, with odbc_result_all($prepared). I edited the question to reflect your answer. Still, the problem remains: It runs from the command line (outputting HTML table) but not from Apache. – HogeBlekker Nov 20 '14 at 19:28
  • Are you getting a "No Rows Found" or is the page completely empty? See my edit for a "better" test script. – mirtheil Nov 20 '14 at 19:36
  • 1
    The page is completely empty. As stated, no response is sent by Apache (tried with wget/chrome). – HogeBlekker Nov 20 '14 at 19:38