Skip to content

Instantly share code, notes, and snippets.

@milo
Last active June 23, 2024 08:56
Show Gist options
  • Save milo/d4a15d67e6538bf82438babc39482b80 to your computer and use it in GitHub Desktop.
Save milo/d4a15d67e6538bf82438babc39482b80 to your computer and use it in GitHub Desktop.
PHP Oracle OCI8 extension on Linux Debian

Oracle Instant Client libraries installation

Download Oracle Instant Client libraries (URL may change, already happened few times). Be sure you download correct (x64 or x32) architecture. And correct version.

Last time I used Client 21.5.0.0.0 with Oracle 12c and PHP 8.1 and 8.3.

Before that Instant Client 21.3.0.0.0 with Oracle 12c and compiled with PHP 8.0, 7.4 and 7.3 fine.

Before that Instant Client 10.1.0.5.0 with Oracle 10g, 11g and 12c and PHP 5.6, 7.1, 7.2, 7.3 and 7.4.

Never hit any problem with such setups but my queries are quite simple. One should be fine with the newest version. It should be backward compatible (fingers crossed).

I had to download two files:

instantclient-basic-linux.x64-21.5.0.0.0dbru.zip
instantclient-sdk-linux.x64-21.5.0.0.0dbru.zip

and extacted them into single directory. I'm using /usr/local/lib/oracle. File tree follows:

/usr/local/lib/oracle/
    /instantclient_21_5/
        /network/
        /sdk/
        /libclntsh.so -> libclntsh.so.21.1
        /libclntsh.so.10.1 -> libclntsh.so.21.1
        /libclntsh.so.11.1 -> libclntsh.so.21.1
        /libclntsh.so.12.1 -> libclntsh.so.21.1
        /libclntsh.so.18.1 -> libclntsh.so.21.1
        /libclntsh.so.19.1 -> libclntsh.so.21.1
        /libclntsh.so.20.1 -> libclntsh.so.21.1
        /libclntsh.so.21.1
        /libnnz21.so
        /...

In older versions, I had to create a libclntsh.so symlink to libclntsh.so.10.1. Not needed now, symlinks already exists

Path to Instant Client libraries will be used for PHP extension compilation. So create symlink to drop version information from path.

cd /usr/local/lib/oracle
ln -s instantclient_21_5 instantclient

Ensure, that access to libraries is allowed for web server/PHP FPM user. Otherwise applications will fail with a strange NULL-message errors. I allow read for anyone:

cd /usr/local/lib/oracle
find instantclient_21_5 -type f -exec chmod 644 {} +
find instantclient_21_5 -type d -exec chmod 755 {} +

PHP OCI8 module compilation and installation

As a PHP packages repository I prefer Ondřej Surý's one (deb.sury.org).

# Install php-dev tools
apt-get install php8.3-dev

cd /tmp

# Download OCI8 extension sources (check for newest at https://pecl.php.net/package/oci8)
# 3.3.0 for PHP 8.2
# 3.2.1 for PHP 8.1, 8.2
# 3.0.1 for PHP 8.0
# 2.2.0 for PHP 7
# 2.0.12 for PHP 5.2 - 5.6
wget https://pecl.php.net/get/oci8-3.3.0.tgz
tar xzf oci8-3.3.0.tgz
cd oci8-3.3.0

# Compile extension
phpize8.3
./configure --with-oci8=instantclient,/usr/local/lib/oracle/instantclient --with-php-config=/usr/bin/php-config8.3
make

# Install extension
make install  # copy osi8.so into /usr/lib/php/20230831/
chmod 644 /usr/lib/php/20230831/oci8.so  # probably not needed, depends on your umask

# Configure PHP (just update php.ini in any way you perefer to load extension)
echo '; priority=10' > /etc/php/8.3/mods-available/oci8.ini
echo 'extension=oci8.so' >> /etc/php/8.3/mods-available/oci8.ini
chmod 644 /etc/php/8.3/mods-available/oci8.ini
phpenmod -v 8.3 oci8

DTrace support

If you want to compile OCI8 extension with DTrace support, you have to:

apt-get install systemtap-sdt-dev
export PHP_DTRACE=yes
# and ./configure ...

Hint system where to find libs

When you run php -v or php -m now, you probably get warning about missing libraries. If not, you are lucky one.

To hint system where to find Oracle libraries I prefer to update dynamic linker configuration. Create file /etc/ld.so.conf.d/zz_php_oci8.conf:

# Oracle libs for PHP OCI8 extension
/usr/local/lib/oracle/instantclient

ensure access rights by chmod 644 /etc/ld.so.conf.d/zz_php_oci8.conf and refresh configuration by executing ldconfig.

The other way is to set environment variable export LD_LIBRARY_PATH=/usr/local/lib/oracle/instantclient. But you probably had to set it in Apache/Nginx startup scripts, in your .bashrc files or whatever environment the PHP will run.

Missing libaio.so

Even I successfully compiled the PHP 8.1 extension on fresh Debian 11 installation, I got error:

PHP Warning:  PHP Startup: Unable to load dynamic library 'oci8'
(tried: /usr/lib/php/20200930/oci8 (/usr/lib/php/20200930/oci8: cannot
open shared object file: No such file or directory),
/usr/lib/php/20200930/oci8.so (libaio.so.1: cannot open shared object
file: No such file or directory)) in Unknown on line 0

Probably missing some dependency. Easy to fix:

apt-get install libaio1

Environmental variables

Besides LD_LIBRARY_PATH there are more variables you can adjust:

  • ORACLE_HOME - whole Oracle installation path, don't use with instant client libs
  • ORACLE_SID - don't use it, usable only with PHP and Oracle on the same machine, but you can always pass connection string to oci_connect()
  • NLS_LANG - National Language Support, can be set by putenv('NLS_LANG=CZECH.CZECH REPUBLIC.UTF8')
  • NLS_NUMERIC_CHARACTERS and NLS_DATE_FORMAT - NLS adjustments, ignored when NLS_LANG envvar not set, can be set by query
  • TNS_ADMIN - path to tnsnames.ora and sqlnet.ora config files if you use configuration names in oci_connect()

Handy queries

ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS'
ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH:MI:SS.FF'
ALTER SESSION SET NLS_NUMERIC_CHARACTERS = '. '
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment