PHP oci8 won't install through pecl: "fatal error: oci8_dtrace_gen.h"

17,913

Solution 1

It seems that your PHP was built with DTrace support enabled. Due to some limitations with the PHP build & config files, the PECL OCI8 install needs a hint to also build with DTrace:

$ export PHP_DTRACE=yes
$ pecl install oci8

This is mentioned in http://php.net/manual/en/oci8.dtrace.php

Solution 2

Note: I got the same oci8_dtrace_gen.h but 'sudo yum install systemtap-sdt-devel && export PHP_DTRACE=yes && pecl install oci8' didnt help (added the systemtap-stp-devel step as comment below reminded me I did read in some article that I had to install it for DTRACE ).

I had to manually build which some articles recommended:

$ sudo yum install php-pear php-devel
$ pear download pecl/oci8 
$ tar xvzf oci8-2.1.8.tgz 
$ cd oci8-2.1.8/
$ phpize
# make sure of the instantclient path below... mine was version 18.3 so it was located in this folder... Also make note some tutorials ask for the ORACLE_HOME folder which theoretically is /usr/lib/oracle/18.3/client64 but if its instantclient then put the lib folder underneath it (worked for me at least:)
$ ./configure --with-oci8=instantclient,/usr/lib/oracle/18.3/client64/lib
$ make 
$ make install
#NOW an .so file built in: /usr/lib64/php/modules/oci8.so
#THIS STEP NOT NEEDED if SELinux disabled on your server/box, but if SELinux is enabled run: setsebool -P httpd_execmem 1
#NOW add:     extension=oci8.so     at the bottom of your php.ini file (probab in /etc/php.ini)
$ sudo service httpd restart
# note that you can also install PDO_OCI to connect to oracle but its very old and not as good as OCI8 lib (and maybe dependent on having OCI8 anyway)

Beforehand you may want to test and make sure the instantclient libs installed correctly by trying sqlplus:

$ sudo rpm -ivh oracle-instantclient18.3-basic-18.3.0.0.0-1.x86_64.rpm
$ sudo rpm -ivh oracle-instantclient18.3-sqlplus-18.3.0.0.0-1.x86_64.rpm
$ sudo rpm -ivh oracle-instantclient18.3-devel-18.3.0.0.0-1.x86_64.rpm
$ sudo rpm -ivh oracle-instantclient18.3-tools-18.3.0.0.0-1.x86_64.rpm
#add your TNSNAMES connection string info below to this file
$ sudo touch /usr/lib/oracle/18.3/client64/network/admin/tnsnames.ora 
$ vi ~/.bash_profile
#add below info to bash_profile to test sqlplus
ORACLE_HOME=/usr/lib/oracle/18.3/client64
export ORACLE_HOME
PATH=$PATH:$ORACLE_HOME/bin
export PATH
LD_LIBRARY_PATH=$ORACLE_HOME/lib
export LD_LIBRARY_PATH
TNS_ADMIN=$ORACLE_HOME/lib/network/admin
export TNS_ADMIN
# log out and log back in and test, sqlplus should have access to TNS_ADMIN now
$ sqlplus username/pass@TNSNAMES_SHORTCUT_OF_THE_DB_CONNECTION

and afterwards, you may want to check your phpinfo() output to make sure apache has access to ORACLE_HOME, TNS_ADMIN, LD_LIBRARY_PATH vars in its Environment section (i defined these in /etc/sysconfig/httpd).

Then you can test OCI with a simple script like this... I put various connection string formats which worked for me that you can uncomment and test (some dependent on EZCONNECT style or assuming you have TNS_ADMIN setup correctly. 1st uncommented $db one is the easiest):

<?php

//works
// ... as long as $TNS_NAMES is defined and passed to apache correctly (using /etc/sysconfig/httpd to add the var.... after defined ORACLE_HOME in there, DONT USE $ORACLE_HOME to define the rest of the vars like for TNS_ADMIN... aka dont do this: TNS_ADMIN=$ORACLE_HOME/lib/network/admin ... use full path: TNS_ADMIN=/usr/lib/oracle/18.3/client64/lib/network/admin )
$username = "myusername";
$password = "mypassword\$2"; //note: may need to escape some chars here like for me i had to escape $ with a backslash
$db = "TNSNAMES_SHORTCUT_OF_THE_DB_CONNECTION";

// works
/*
$db = <<<EOT
  (DESCRIPTION=
    (ADDRESS=
      (PROTOCOL=TCP)
      (HOST=mydbhost.example.com)
      (PORT=1521)
    )
    (CONNECT_DATA=
      (SERVER=dedicated)
      (SERVICE_NAME=name.of.the.service.here)
    )
 )
EOT;
*/

//works, double-check with your DBA as maybe you want to connect to a specific SID or different connection string format
//$db = "(DESCRIPTION=(ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = mydbhost.example.com)(PORT = 1521)))(CONNECT_DATA=(SERVER=dedicated)(SERVICE_NAME=name.of.the.service.here)))";

// works
// ezconnect format: username/password@[//]host[:port][/service_name] (username and pass are already in oci_connect function so removed from below)
//$db = '//mydbhost.example.com:1521/name.of.the.service.here';

$conn = oci_connect( $username, $password, $db);
if (!$conn) {
  $m = oci_error();
  trigger_error(htmlentities($m['message']), E_USER_ERROR);
}

$sql = "select SYSDATE from DUAL";
$stid = oci_parse($conn, $sql);
oci_execute($stid);
while ($row = oci_fetch_array ($stid)) {
  echo $row[0]."&lt;br&gt;";
}
oci_free_statement($stid);
oci_close($conn);

Solution 3

I couldn't get the RPM package installs to work on my Centos 6 server, so I tried manual install but was running into a number of problems, including the issue with the DTRACE option.

Here is what I did to upgrade OCI8 (after upgrade to PHP 7.3 broke the webapp).

Hopefully this might be of use to someone else.

Download the Instant Client Zip files from Oracle and extract on the server (I had top download them from a browser then SCP them to the server):

cd /u01/app/oracle/product/InstClient/
unzip instantclient-basic-linux.x64-11.2.0.4.0.zip

This creates instantclient_11_2 sub dir, unzip the SDK to the same location:

unzip instantclient-sdk-linux.x64-11.2.0.4.0.zip

Edit /etc/sysconfig/httpd and point LD_LIBABRY_PATH to new instantclient_11_2 home.

Sym links the library:

ln -s /u01/app/oracle/product/InstClient/instantclient_11_2/libclntsh.so.11.1  /u01/app/oracle/product/InstClient/instantcliet_11_2/libclntsh.so

Get the oci8 source package from php.net:

wget https://pecl.php.net/get/oci8-2.2.0.tgz
tar xf oci8-2.2.0.tgz
cd oci8-2.2.0
phpize

Needed to upgrade autoconf and install systemtap-sdt-devel

wget http://ftp.gnu.org/gnu/autoconf/autoconf-latest.tar.gz
gunzip autoconf-latest.tar.gz
tar xf autoconf-latest.tar
cd autoconf-2.69
./configure
make
make install
yum install systemtap-sdt-devel

Continue with OCI8:

cd ../oci8-2.2.0
phpize
phpize 7.3
export PHP_DTRACE=yes
./configure --with-oci8=instantclient,/u01/app/oracle/product/InstClient/instantclient_11_2 --with-php-config=/usr/bin/php-config
make
make test

The test reported lots of FAILs but reckon due to not having correct DB login creds so continued:

make install
ls -ltr /usr/lib64/php/modules/ # check oci8.so is updated

service httpd restart
php -v # No OCI8 error reported and web app working
Share:
17,913
Admin
Author by

Admin

Updated on August 04, 2022

Comments

  • Admin
    Admin almost 2 years

    I am trying to connect my fedora 25 webserver - php to Oracle db.

    To do this I need to pecl install oci8.

    However I get this error:

    /bin/sh /var/tmp/pear-build-roottqYEC6/oci8-2.1.4/libtool --mode=compile cc  -I. -I/var/tmp/oci8 -DPHP_ATOM_INC -I/var/tmp/pear-build-roottqYEC6/oci8-2.1.4/include -I/var/tmp/pear-build-roottqYEC6/oci8-2.1.4/main -I/var/tmp/oci8 -I/usr/include/php -I/usr/include/php/main -I/usr/include/php/TSRM -I/usr/include/php/Zend -I/usr/include/php/ext -I/usr/include/php/ext/date/lib -I/usr/include/oracle/12.1/client64  -DHAVE_CONFIG_H  -g -O2   -c /var/tmp/oci8/oci8.c -o oci8.lo
    libtool: compile:  cc -I. -I/var/tmp/oci8 -DPHP_ATOM_INC -I/var/tmp/pear-build-roottqYEC6/oci8-2.1.4/include -I/var/tmp/pear-build-roottqYEC6/oci8-2.1.4/main -I/var/tmp/oci8 -I/usr/include/php -I/usr/include/php/main -I/usr/include/php/TSRM -I/usr/include/php/Zend -I/usr/include/php/ext -I/usr/include/php/ext/date/lib -I/usr/include/oracle/12.1/client64 -DHAVE_CONFIG_H -g -O2 -c /var/tmp/oci8/oci8.c  -fPIC -DPIC -o .libs/oci8.o
    In file included from /var/tmp/oci8/oci8.c:49:0:
    /var/tmp/oci8/php_oci8_int.h:46:29: fatal error: oci8_dtrace_gen.h: No such file or directory
     #include "oci8_dtrace_gen.h"
                                 ^
    compilation terminated.
    Makefile:196: recipe for target 'oci8.lo' failed
    make: *** [oci8.lo] Error 1
    ERROR: `make' failed
    

    I do not know what to do. I've searched everywhere for a solution, and I can only find outdated articles.

    Any help much appreciated!