Thursday, July 23, 2009

Php 5.3 without screwing up apt-get

Php 5.3 is stable and if you want to experience improved performance and lessened memory usage, and also play with nice tools like Doctrine 2 that are built for this version, you have to install on your box. But a .deb is better than 'make install': it does not sends binaries and configuration files all over your system, without a mean to trace where they end up.

Php 5.3 is a new minor version of Php, so it does not break the strict compatibility of your application. Though, it deprecates some old features and practices and it could cause problems, so you shoud cautious about using it in a production environment. That's what staging exists for.
However, if you choose to install it, your better choice is to use a .deb package that could be easily removed when the distributors catch up and provide a php5 package: 'make install' command issued after compiling will spread files all over the filesystem, without let know you what is being overwritten and created. A .deb will also help upgrading with its simple removal procedure.
This example is based on Ubuntu Jaunty (9.04), but probably will work on other versions and Debian-derivated distros.

Step 0: downloading the source
To build a package, the C source code is needed. A tarball for the release is provided from the php team:
tar xvjf php-5.3.0.tar.bz2
cd php-5.3.0
Now we have source files at hand.

Step 1: compiling
Compiling is the fragile and longest part, as the compile time can be very long, especially if you use many bundled extensions and your machine is performing other tasks at the same time.
First, the build configuration has to be created.
./configure --disable-short-tags --with-zlib --enable-bcmath --enable-exif --enable-ftp --with-gd --with-jpeg-dir --with-png-dir --enable-mbstring --with-pdo-mysql --with-sqlite --enable-sqlite-utf8 --enable-zip --with-pear
"with" and "enable" commands are listed using --configure --help and will tell you what bundled extensions are available in this release. The more extension you pull in the compilation, the more time it will take, but you do not want not be surprised with undefined function: mysql_connect. With this configuration, it is not included because PDO is used instead.
The ./configure command will fail often, and it probably means that you lack some source files or libraries needed for the extension to compile and to be linked to. They are normally not installed in the average system, so is something is needed you will probably run commands such as:
sudo apt-get install libjpeg
sudo apt-get install libbz2
depending on the extension choosed. To find the name of the library, see the Requirements section on for the extension in question.
When ./configure does not fail anymore, we can start the compilation:
This will take time, so you should consider running when you're not at the pc.

Step 2: building a package
When the compiling is finished, a .deb has to be built from the produced binaries. checkinstall is the command line tool that will do the job for us. Of course if you do not have it, sudo apt-get install checkinstall.
sudo checkinstall -D --install=no --fstrans=no --reset-uids=yes --nodoc --pkgname=php5 --pkgversion=5.3 --pkgrelease=200907011400 --arch=x86
We are telling checkinstall to create a Debian package (-D), to not install it for now, do not use a fake filesystem since this is not necessary, to not include the documentation since we aren't going to distribute this package but only to use it at home.
To be useful, checkinstall must be run as root, so we use sudo.
After this command, checkinstall asks you to confirm the options and by pressing Enter your (probably if you're still reading this simple guide) first deb is created.

Note: use php with apache
If you included the directive --with-apxs, to build a mod_php instance, checkinstall (but also make install) will tell you that almost one LoadModule directive has to exist. This happens because the installation process reads /etc/apache2/httpd.conf, that is not used in Ubuntu, so let's fake it. Add the following line:
LoadModule php5_module /usr/lib/apache2/modules/
to /etc/apache2/httpd.conf; create it if it not exists. You will need sudo to write such a file.
After generating the package, you could clean this file and leave it empty as Ubuntu uses the /etc/apache2/mods-enabled/ folder to maintain the LoadModule directives.

Step 3: avoid conflicts
The compilation process has not touched your system yet, but probably there is an old installation of php hanging around that will get in the way. Let's remove all package and extensions: if you need a particular extension you should have included it in Step 1; if you need a PECL or PEAR package you will grab it later, in the new installation.
This will remove any package whose name contains php:
sudo apt-get remove --purge `dpkg -l | grep php | awk '{print $2}';`
You could also delete /usr/share/php, the PEAR folder. A new pear will be installed if you enable it in Step 1 and old files will point the old php binary and it will be a mess. Take them out:
sudo rm /usr/bin/php
sudo rm /usr/bin/pear
sudo rm /usr/share/php
If you have any PEAR packages, the folder was not removed by apt because it was not empty.

Step 4: install your brand new, fine-tuned package
Assuming that your package is named php5_5.3.0-200907181600_i386.deb, install it:
sudo dpkg -i php5_5.3.0-200907181600_i386.deb
You will find it in the source folder.
If you're using php from the command line you have finished. You have the possibility to run pear on php 5.3 and install what you want.
If you use php with apache, you need to set up the loading of mod_php. Put in /etc/apache2/mods-available two files named php5.conf

AddType application/x-httpd-php .php .phtml .php3
AddType application/x-httpd-php-source .phps
and php5.load:
LoadModule php5_module /usr/lib/apache2/modules/
The content could slightly differ, and the files may already be present (from your previous installation).
Then Apache could use php compiled by you:
sudo a2enmod php5
sudo /etc/init.d/apache2 restart
Enabled the module, and restarted the webserver. Have fun with your shiny new php!


Unknown said...

This was very helpful, however, the command line is not working. The rest (except for phpMyAdmin, which I had to modify to make it work) is fine. Any idea on why cli is failing?

Giorgio said...

AFAIK --enable-cli in the ./configure command should be active by default, so there's no need to add it. Maybe the binay was not copied in the path, you should do a `dpkg -L php5` to see which files are contained in the package.

Unknown said...

I had to add "--with-readline" =) Now everything works at perfection.

I'm in love with namespaces and lambdas hahaha. :D