Я пытаюсь подключить свой веб-сервер fedora 25 — php к Oracle db.
Для этого мне нужно pecl установить oci8.
Однако я получаю эту ошибку:
/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
Я не знаю, что делать. Я всюду искал решение, и я могу найти только устаревшие статьи.
Любая помощь высоко ценится!
Похоже, что ваш PHP был построен с поддержкой DTrace. Из-за некоторых ограничений в сборке PHP & Конфигурационные файлы, для установки PECL OCI8 также требуется подсказка для сборки с DTrace:
$ export PHP_DTRACE=yes
$ pecl install oci8
Это упоминается в http://php.net/manual/en/oci8.dtrace.php
Примечание: я получил тот же oci8_dtrace_gen.h, но ‘sudo yum install systemtap-sdt-devel && экспорт PHP_DTRACE = да && pecl install oci8 ‘не помогло (добавлен шаг systemtap-stp-devel, поскольку приведенный ниже комментарий напомнил мне, что я читал в какой-то статье, что мне нужно было установить его для DTRACE).
Я должен был вручную построить, что некоторые статьи рекомендовали:
$ 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
и после этого вы можете проверить вывод phpinfo (), чтобы убедиться, что apache имеет доступ к переменным ORACLE_HOME, TNS_ADMIN, LD_LIBRARY_PATH в его разделе Environment (я определил их в / etc / sysconfig / httpd).
Затем вы можете протестировать OCI с помощью простого скрипта, подобного следующему … Я поместил различные форматы строки подключения, которые сработали для меня, которые вы можете раскомментировать и протестировать (некоторые зависят от стиля EZCONNECT или если вы правильно установили TNS_ADMIN. Первый uncommented $ db, один — самый легкий):
<?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);