Apache 2.4 + PHP 5.4 + PDO_OCI on Ubuntu 12.04 HOWTO

This simple HOWTO will guide you about how to setup Apache2.4 + PHP5.4 + PDO_OCI from sketch. Compile all package from tarball can give you the maximum flexibility of functionality, e.g. you can enable both mysql/mysqli/pgsql/oci8/pdo_mysql/pdo_pgsql/pdo_oci within single installation.

Before start, I will assume you have Ubuntu 12.04 and Oracle 11gR2 installed correctly, which will not detail within this document. If you really need some help for that, please refer to my other article for more indeed guideline.

Install required packages

Debian apt-get can give us a great hand when prepare system for building custom packages from sketch. Just simply run this command:

aptitude update && \
aptitude -y full-upgrade && \
aptitude -y install git vim libmcrypt-dev && \
apt-get -y build-dep apache2 php5

Install Apache2.4

Get Apache2.4 source from GIT, compile, and install it:

cd /usr/local/src
git clone --branch 2.4.x https://github.com/apache/httpd.git httpd-2.4.x
cd httpd-2.4.x
git clone https://github.com/apache/apr.git srclib/apr
./buildconf
./configure -enable-modules=all --with-included-apr --enable-mpm=worker --enable-suexec --enable-rewrite
make
make install

You should retouch the Apache configuration. Edit /usr/local/apache2/conf/httpd.conf and take the similar change as below:

User www-data
Group www-data
ServerAdmin root@localhost.localdomain
DocumentRoot "/var/www"
<Directory "/var/www">
    Options Indexes FollowSymLinks
    AllowOverride all
    Require all granted
</Directory>

Also need to ensure Apache have correct privilege to access its document root:

chown -Rf www-data:www-data /var/www

Symbolic link all Apache execute binaries to /usr/local/bin:

ln -s /usr/local/apache2/bin/* /usr/local/bin/

Remove the /etc/init.d/apache2 and replace it as a symbolic link to /usr/local/bin/apachectl:

rm -rf /etc/init.d/apache2
ln -s /usr/local/bin/apachectl /etc/init.d/apache2

Ensure your Apache will start automatically during system boot:

update-rc.d -f apache2 remove
update-rc.d -f apache2 defaults 91 09

Restart Apache and so let all changes take effect:

/etc/init.d/apache2 stop
/etc/init.d/apache2 start

Try to access http://localhost.localdomain/index.html and check if message appear.

Install PHP5.4

First of all, unpack the PHP tarball:

cd /usr/local/src/
git clone --branch PHP-5.4 https://github.com/php/php-src.git php-5.4.x
cd /usr/local/src/php-5.4.x/ext/
wget http://pecl.php.net/get/APC-3.1.13.tgz
gzip -d < APC-3.1.13.tgz | tar -xvf -
mv APC-3.1.13 apc
cd /usr/local/src/php-5.4.x/
rm -rf configure
./buildconf --force

NOTE (2012-06-23): Up to now pdo_oci facing at least 2 critical bug with BLOB related issues (#52958 and #57702) so let's patch it before next step:

cd /usr/local/src/php-5.4.x
wget https://raw.github.com/hswong3i/pdo_oci/7.x-1.x/patches/php-5.4.x.patch -O /tmp/php-5.4.x.patch
patch -p0 < /tmp/php-5.4.x.patch

You should check all available parameter with:

./configure --help
Before start the configuration, I would like to give you some suggested combination of parameters. E.g.:
  --enable-bcmath \
  --enable-calendar \
  --enable-dba \
  --enable-exif \
  --enable-ftp \
  --enable-mbstring \
  --enable-shmop \
  --enable-sigchild \
  --enable-soap \
  --enable-sockets \
  --enable-sqlite-utf8 \
  --enable-sysvmsg \
  --enable-wddx \
  --enable-zip \
  --with-apxs2=/usr/local/apache2/bin/apxs \
  --with-bz2 \
  --with-config-file-path=/usr/local/apache2/conf \
  --with-curl \
  --with-gd \
  --with-gettext \
  --with-mcrypt \
  --with-mysql \
  --with-mysqli \
  --with-openssl \
  --with-pdo-mysql \
  --with-pdo-pgsql \
  --with-pgsql \
  --with-xmlrpc \
  --with-zlib \
Moreover, OCI8 and PDO_OCI should configuration as (assume you have install Oracle 11gR1 to /u01/app/oracle/product/11.2.0/dbhome_1):
  --with-oci8=/u01/app/oracle/product/11.2.0/dbhome_1 \
  --with-pdo-oci=/u01/app/oracle/product/11.2.0/dbhome_1 \

So the complete PHP5.4 configuration command with PDO_OCI should be:

./configure \
  --enable-apc \
  --enable-bcmath \
  --enable-calendar \
  --enable-dba \
  --enable-exif \
  --enable-ftp \
  --enable-mbstring \
  --enable-shmop \
  --enable-sigchild \
  --enable-soap \
  --enable-sockets \
  --enable-sysvmsg \
  --enable-wddx \
  --enable-zip \
  --with-apxs2=/usr/local/apache2/bin/apxs \
  --with-bz2 \
  --with-config-file-path=/usr/local/apache2/conf \
  --with-curl \
  --with-gd \
  --with-gettext \
  --with-mcrypt \
  --with-mysql-sock=/run/mysqld/mysqld.sock \
  --with-mysqli \
  --with-openssl \
  --with-pdo-mysql \
  --with-pdo-oci=/u01/app/oracle/product/11.2.0/dbhome_1 \
  --with-pdo-pgsql \
  --with-xmlrpc \
  --with-zlib

Next, build and install the PHP5:

make && \
make test && \
make install

Copy PHP's supplied initialization file:

cp /usr/local/src/php-5.4.x/php.ini-development /usr/local/apache2/conf/php.ini
sed -i 's/^;\(date\.timezone\) =\s*$/\1 = "Asia\/Hong_kong"/g' /usr/local/apache2/conf/php.ini
sed -i 's/^\(memory_limit\) = .*$/\1 = 256M/g' /usr/local/apache2/conf/php.ini
sed -i 's/^\(post_max_size\) = .*$/\1 = 32M/g' /usr/local/apache2/conf/php.ini
sed -i 's/^\(upload_max_filesize\) = .*$/\1 = 32M/g' /usr/local/apache2/conf/php.ini
sed -i 's/^\(max_execution_time\) = .*$/\1 = 3600/g' /usr/local/apache2/conf/php.ini
sed -i 's/^\(max_input_time\) = .*$/\1 = 7200/g' /usr/local/apache2/conf/php.ini

Create a PHP configuration file for Apache as /usr/local/apache2/conf/extra/httpd-php5.conf and add the following lines:

#
# This next section will call PHP for .php, .phtml, and .phps files
#
AddType application/x-httpd-php .php
AddType application/x-httpd-php .phtml
AddType application/x-httpd-php-source .phps

#
# This is the directory containing php.ini
#
PHPIniDir "/usr/local/apache2/conf"

Retouch /usr/local/apache2/conf/httpd.conf and add this line to the end of file:

Include conf/extra/httpd-php5.conf

If a LoadModule line was not already inserted by the PHP install, add it too:

LoadModule php5_module modules/libphp5.so

Also update the DirectoryIndex:

#
# DirectoryIndex: sets the file that Apache will serve if a directory
# is requested.
#
<IfModule dir_module>
    DirectoryIndex index.html index.cgi index.pl index.php index.xhtml
</IfModule>

Create a testing file as /var/www/phpinfo.php with below content:

<?php phpinfo(); ?>

Restart your Apache and test your PHP setup with http://localhost.localdomain/phpinfo.php

Oracle specific fine tune

By default, Apache's user account and user group don't have privilege to access Oracle's resources, so we will need some hack:

adduser www-data oinstall

Next, Apache don't have the idea about where is the Oracle instance client, so we need to specify for it. Edit /usr/local/apache2/bin/envvars and add the following lines at the end of file:

umask 022
export ORACLE_HOSTNAME=localhost.localdomain
export ORACLE_BASE=/u01/app/oracle
export ORACLE_HOME=$ORACLE_BASE/product/11.2.0/dbhome_1
export ORACLE_SID=AL32UTF8
export NLS_LANG=.AL32UTF8
export ORACLE_UNQNAME=AL32UTF8
unset TNS_ADMIN
if [ -d "$ORACLE_HOME/bin" ]; then
    PATH="$ORACLE_HOME/bin:$PATH"
fi

Assume you have already activate your Oracle's HR user account from database AL32UTF8. Create /var/www/pdo_oci.php with following content, access http://localhost.localdomain/pdo_oci.php, test if your PDO_OCI driver install correctly:

<?php
$db_conn = new PDO('oci:dbname=//localhost.localdomain/AL32UTF8.localdomain', 'HR', 'CHANGE');
$cmdstr = 'SELECT "LAST_NAME", "SALARY" FROM "HR"."EMPLOYEES"';
$stmt = $db_conn->query($cmdstr);
$results = $stmt->fetchAll();
$stmt = $db_conn->query("SELECT COUNT(*) AS nrows FROM ($cmdstr)");
$nrows = $stmt->fetch(PDO::FETCH_OBJ)->NROWS;
echo "<html><head><title>Oracle PHP Test</title></head><body>";
echo "<center><h2>Oracle PHP Test</h2><br>";
echo "<table border=1 cellspacing='0' width='50%'>\n<tr>\n";
echo "<td><b>Name</b></td>\n<td><b>Salary</b></td>\n</tr>\n";
for ($i = 0; $i < $nrows; $i++ ) {
        echo "<tr>\n";
        echo "<td>" . $results[$i]["LAST_NAME"] . "</td>";
        echo "<td>$ " . number_format($results[$i]["SALARY"], 2). "</td>";
        echo "</tr>\n";
}
echo "<tr><td colspan='2'> Number of Rows: $nrows</td></tr></table><br>";
echo "<em>If you see data, then it works!</em><br>";
echo "</center></body></html>\n";
?>

Sample output:

Comments

root's picture

Hi, thank's for ur tutorial - works great!

But could you make another one how to compile php with suhosin patch, zend optimizer?

thank you.

root's picture

Thanks mate! I've been looking round for a tutorial to get the latest PHP 5.4.x, Apache 2.4.x and MySQL 5.5.x working for the past 3 weeks to no avail. Tried like 10 different guides (including reinstalls of Ubuntu) and none worked except yours.

I ended up installing MySQL using apt-get install mysql-server which got my 5.5.24 when you use the dotdeb repositories http://www.dotdeb.org. To get MySQL going with PHP PDO I had to edit php.ini pdo_mysql.default_socket = /var/run/mysqld/mysqld.sock. Also the mod_rewrite module wasn't turned on in the httpd.conf so I enabled it with LoadModule rewrite_module modules/mod_rewrite.so.

Works very well after that! I think I'll pull down the stable .tar.gz files of Apache and PHP from the website rather than the development versions from git as I want to use it in Production.

Do you know why we are enabling --enable-suexec with Apache? When I visited manual http://httpd.apache.org/docs/2.0/suexec.html they have a big warning at the top saying: "Used properly, this feature can reduce considerably the security risks involved with allowing users to develop and run private CGI or SSI programs. However, if suEXEC is improperly configured, it can cause any number of problems and possibly create new holes in your computer's security. If you aren't familiar with managing setuid root programs and the security issues they present, we highly recommend that you not consider using suEXEC." So if we enable it, is it good in its default state? Or does it need more configuration to be actually secure.

root's picture

Thanks for the walkthrough, I'd recommend the following additional compiler options if you want to be able to support multiple PHP installations:

--prefix=/usr/local/php-5.4.4 --with-config-file-path=/usr/local/php-5.4.4/apache2 \
--with-config-file-scan-dir=/usr/local/php-5.4.4/apache2/conf.d

Works wonders for our internal development environment here :)

root's picture

Thank u!

root's picture

Thanks for your work!

Mark T's picture

Great instructions! However this gets the latest 'dev' version of Apache/PHP. Is there a git branch to get the latest stable version of Apache 2.4/PHP 5.4?

Add new comment