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!
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
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]."<br>";
}
oci_free_statement($stid);
oci_close($conn);