Install php‑oci8 on Ubuntu: A Quick Fix for Oracle PHP Connectivity
If your PHP app keeps throwing “OCI initialization failed” or you’re hunting for the missing php_oci8.so after a fresh Ubuntu install, this guide will get you from zero to working in under ten minutes. I’ve wrestled with the same mess when migrating an old Laravel site to Ubuntu 20.04 and finally pinned down the culprit.
Why You Need php‑oci8
Oracle’s native PHP driver (php-oci8) is the only reliable way for PHP to talk directly to an Oracle database without going through ODBC or a middleware layer. It bundles the OCI libraries from the Oracle Instant Client, so you’ll need both the client and the PHP extension.
1. Grab the Right Oracle Instant Client
sudo apt-get update && sudo apt-get install wget unzip wget https://download.oracle.com/otn_software/linux/instantclient/211000/instantclient-basiclite-linux.x64-21.10.0.0.0.zip unzip instantclient-basiclite-linux.x64-21.10.0.0.0.zip
The basiclite zip contains the minimal set of binaries (libclntsh.so) that php‑oci8 will load. Skipping this step and pointing to a mismatched version often leads to “undefined symbol” errors.
2. Create a Wrapper Directory and Set Permissions
sudo mkdir /opt/oracle/instantclient_21_10 sudo mv instantclient/ /opt/oracle/instantclient_21_10/ sudo rm -rf instantclient* sudo chown -R $(whoami):$(whoami) /opt/oracle/instantclient_21_10
The wrapper directory keeps Oracle’s libraries out of the way of other applications. Without proper ownership, PHP’s worker processes (nginx or Apache) can’t read the files.
3. Tell the System Where to Find the Libraries
echo /opt/oracle/instantclient_21_10 >> ~/.bashrc source ~/.bashrc export LD_LIBRARY_PATH=/opt/oracle/instantclient_21_10:$LD_LIBRARY_PATH
This environment variable is required by php-oci8 to locate the OCI binaries at runtime. I’ve seen PHP crash with “libclntsh.so not found” if you skip this.
4. Install the php‑oci8 Extension Package
sudo apt-get install php-oci8
On Ubuntu 20.04 and later, the package pulls in the exact PHP version you have (e.g., php7.4-oci8 or php8.1-oci8). If you’re on a custom PHP build from source, you’ll need to compile oci8 manually instead.
5. Verify the Extension is Loaded
php -m | grep oci8
You should see oci8 in the list. If not, check /etc/php/*/mods-available/oci8.ini and ensure it’s enabled in your FPM pool or Apache config.
6. Test a Quick Connection Script
<?php
$tns = "(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=oracle.example.com)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=orcl)))";
$conn = oci_connect('myuser', 'mypassword', $tns);
if ($conn) {
echo "Connection succeeded!<br>";
oci_close($conn);
} else {
$e = oci_error();
echo "Failed: " . htmlentities($e['message']);
}
?>
Drop that into a file and hit it through your web server. If you get the “succeeded” message, congratulations—you’ve got a live PHP‑to‑Oracle link.
Common Pitfalls
- Wrong Oracle version – php‑oci8 will silently refuse to load if the Instant Client libraries are newer or older than what the extension was compiled against. Stick with the 21.x release unless you have a specific need.
- Missing LD_LIBRARY_PATH in web server user – Apache’s www-data doesn’t inherit your shell profile. Add export LD_LIBRARY_PATH=/opt/oracle/instantclient_21_10:$LD_LIBRARY_PATH to /etc/apache2/envvars or the equivalent for Nginx/FPM.
- SELinux/AppArmor blocking – On minimal installations, AppArmor may prevent PHP from reading /opt/oracle. You can relax it with sudo aa-complain /usr/sbin/php-fpm or create a custom profile.
I hit all of those when I first set up a migration service on a fresh Ubuntu 18.04 box. A single mis‑spelled path and my PHP app would spit out “OCI initialization failed” for hours until I dug through logs.
With the extension in place, your PHP code can now call oci_connect(), run queries with oci_parse()/oci_execute(), and handle OCI errors gracefully. No more mysterious “driver not found” messages or endless debugging sessions.
That’s all there is to it—grab the client, set the path, install the package, and test a quick connection script.