Over the past couple months, I have been Tweeting about PHP and Azure. Now that my projects are slowing down, I want to share one of the things I figured out in working with PHP and Azure.
My client had a WordPress plugin that communicated with an on-premises Oracle server. In the process of migrating their WordPress to another host, they realized that this plugin stopped working. Looking at the code, I pulled it into its own standalone application so that we could find a host to set up the communications with their server. We went with Azure, using virtual networks and VPN to make this happen.
The challenge I ran into working with the OCI8 extension and figuring out how to work with it in Azure is that it needs compiled with the Oracle drivers. Since the PHP application was a basic web application, I opted to use Azure App Service for hosting. Since the client’s code was in PHP 7.x, I did a lift-and-shift approach and provisioned a PHP 7.4 environment. However, looking at the expiration of community support for PHP 7.x, I have also started working on a PHP 8.0 environment.
These are my findings and how I got the OCI8 extension working with PHP 8.0 in Azure App Service.
Note: The /home
folder is persisted, so we will be working within the confines of that guidance.
Get the Instant Client Files
We are using the Oracle Instant Client files to connect to the Oracle server.
- Go to the Oracle Instant Client Linux downloads page.
- Copy the download URLs for the Basic Package (ZIP) and the SDK Package (ZIP) files.
- Navigate to your Azure App Service in the Azure portal.
- From the left navigation, under Development Tools, select SSH.
- Change the directory to the directory you want to work in. I decided to work in
/home/site
. - In the SSH client, use
wget
to download the zip files from the links gathered in Step 2. In my case, I was working with instantclient_21_5, so my commands were:
cd /home/site
wget https://download.oracle.com/otn_software/linux/instantclient/215000/instantclient-basic-linux.x64-21.5.0.0.0dbru.zip
wget https://download.oracle.com/otn_software/linux/instantclient/215000/instantclient-sdk-linux.x64-21.5.0.0.0dbru.zip
7. Unzip the zip files using unzip
. Since unzip isn’t installed by default, you will need to install unzip first.
apt install unzip
unzip instantclient-basic-linux.x64-21.5.0.0.0dbru.zip
unzip instantclient-sdk-linux.x64-21.5.0.0.0dbru.zip
Configure environment
Before we can compile the OCI8 extension, we need to set an environment variable. Set the LD_LIBRARY_PATH
environment variable to the path of the unzipped files. I also set ORACLE_HOME
to instantclient,<path of the unzipped files>
export LD_LIBRARY_PATH=/home/site/instantclient_21_5
export ORACLE_HOME=instantclient,/home/site/instantclient_21_5
Compile the OCI8 extension
Next, we need to get the OCI8 extension. I ran into issues with pecl install oci8-3.0.1
, so I ended up compiling the extension manually. These are the steps I took.
- Get the OCI8 package from PECL using
wget
. Note: Pay close attention to what version of PHP you are running versus which version of OCI8 you need to download. I ranphp -v
on the Azure App Service and found out it was running PHP v 8.0.13, so I needed to get theoci8-3.0.1
package. The Description for the package tells you which version of the OCI8 extension you need based on your PHP version.
wget https://pecl.php.net/get/oci8-3.0.1.tgz
2. Unpackage the file, then navigate to the extracted files.
tar xzf oci8-3.0.1.tgz
cd oci8-3.0.1
3. Run the compile manually. Pay close attention to the prompts. The ./configure
line includes the --with-oci8
parameter. Since we are using the Oracle instant client, we need to include instantclient
as well as the LD_LIBRARY_PATH. This process may prompt you again for this path, so pay close attention to the prompts.
phpize
./configure --with-oci8=instantclient,/home/site/instantclient_21_5
make
make install
Configure the App Service to use the custom extension
I prefer to keep my custom config files in a ini
folder, so I’ll create the ini
folder and echo the extension information to a new custom php.ini file.
mkdir /home/site/ini
echo "extension=/home/site/oci8-3.0.1/modules/oci8.so" >> /home/site/ini/php.ini
I also need the server to know about this new folder. So I will update my PHP_INI_SCAN_DIR
environment variable to include this.
export PHP_INI_SCAN_DIR=/usr/local/etc/php/conf.d:/home/site/ini
Confirm OCI8 is seen by PHP
Once the custom PHP file is in place and the INI scan folder is updated, then I want to confirm that PHP can see the custom extension successfully. Still in SSH, I run the following command:
php -i | grep oci8
The oci8
extension should appear in the output. You should see something like this:
oci8
OCI8 Support => enabled
OCI8 DTrace Support => disabled
OCI8 Version => 3.0.1
Oracle Run-time Client Library Version => 21.5.0.0.0
Oracle Compile-time Instant Client Version => 21.5
Directive => Local Value => Master Value
oci8.connection_class => no value => no value
oci8.default_prefetch => 100 => 100
oci8.events => Off => Off
oci8.max_persistent => -1 => -1
oci8.old_oci_close_semantics => Off => Off
oci8.persistent_timeout => -1 => -1
oci8.ping_interval => 60 => 60
oci8.privileged_connect => Off => Off
oci8.statement_cache_size => 20 => 20
Statistics =>
Active Persistent Connections => 0
Active Connections => 0
Thank you Sadukie, this helped me get it to work on a similar same setup.
I had to not export those ENV’s but i placed them in the Configuration > application settings of the azure app, because with a reboot, export env’s are wiped.
Also had to play around with LD_RUN_PATH and PHP_RPATHS as ENV var’s but unsure as to how neccecary they where.
but in the end, my phpinfo is showing a correctly working OCI8 and a connection test works ! Thanks! This took me 2 whole evenings to get sorted 🙂