Enabling, Compiling and Installing PHP 5 on Mac OS X Leopard

September 19, 2009

Contents

Introduction

These installation instructions will compile PHP with a configuration that closely matches the PHP configuration shipped with OS X, but with the addition of enabling GD, PDO and MCRYPT support. These instructions will build either a 1-way 32-bit binary for the architecture you are compiling on or a 32/64-bit 4-way universal binary for both PowerPC and x86 architectures.

This document assumes that the OS X developer tools (XCode 3.13) are installed and you are using the BASH shell. It also assumes you are installing on the client version of OS X 10.5.8 Leopard with the latest security upgrades.

I have tried to make this document as concise and direct to the point as possible. It is helpful to have some knowledge of the basic UNIX commands and permissions, the GNU build system, and the infamous httpd configuration file (httpd.conf).

Enable PHP

If you just need to enable the preinstalled version of PHP, execute the following in terminal and then skip down to the Start HTTPD instructions. If you compile PHP, the build scripts will enable PHP for you.

Launch Terminal and execute the following commands.

# Change to the apache configuration directory
cd /etc/apache2

# Edit httpd.conf with your favorite editor
sudo nano httpd.conf

# Find the line .....
#LoadModule php5_module libexec/apache2/libphp5.so
# and uncomment it by removing the pound sign

# Save and exit the editor

# Create php.ini (For Development)
cd ..
sudo cp php.ini.default php.ini

Download the source code and unpack into source directory

Download the PHP source code

Download the Complete Source Code (tar.bz2) from http://www.php.net/downloads.php At the time of this writing PHP version 5.2.11 is the latest release. These instructions can also be used to compile PHP 5.3.

Create the source code directory and unpack

Launch Terminal and execute the following commands where <adminID> is your administrator ID. If you don't know your administrator id, just use the console command whoami to find out. That's assuming you are logged in as an administrator.

# Create a /usr/local/src directory if it doesn't already exist
cd /usr/local
sudo mkdir src
sudo chown <adminID> src
sudo chgrp admin src
chmod 750 src

# Change to the source directory and unpack
cd src
tar -xvjf ~/Downloads/php-5.2.11.tar.bz2

# If Safari has already attempted to open the archive after downloading it, you may have to do this instead
tar -xvf ~/Downloads/php-5.2.11.tar

# Consider changing the owner or group of the /usr/local directory to your admin id or the admin group. It will make administration easier as you won't have to do so many sudo's or run as root to install stuff in /usr/local.

# Some of the commands used in this document require the BASH shell. All versions of OS X from version 10.3 on up default to using BASH. However, if you upgraded OS X from an earlier version and imported your home directory, you may still be running TCSH. To find out what default login shell you are running and change it, go to the System Preferences Accounts pane. If the pane is locked, unlock it. Control Click on your account name and a contextual menu will appear. Click on Advanced Options. You will then be presented with a dialog where you can change the default login shell to whatever you want. You can also use the dscl utility to read and change the default login shell. Execute the following to read the directory service properties of your id:
dscl . read /Users/YourID.

# To find out what YourID is, execute the whoami command.
whoami

Install the JPEG, PNG, FREETYPE and MCRYPT Libraries

To enable GD support you must install the JPEG and PNG support libraries. Optionally, you may want to install the FREETYPE library. The easiest way to compile and install these libraries is to use MacPorts. If you don't need these libraries just skip these instructions and then modify the configure command in the build section of this document and delete the PHP options you don't need. If you don't already have MacPorts installed, you can obtain it from http://www.macports.org

Unless you manually configure macports to compile 64-bit universal binaries it will by default compile 1-way 32-bit binaries. Edit macports.conf to compile 4-way universal binaries. If you want to shorten compile times, you may want to leave out the architectures you don't need.

# Edit macports.conf
cd /opt/local/etc/macports
sudo nano macports.conf
# Change the line ....
universal_archs ppc i386
# to ...
universal_archs ppc ppc64 i386 x86_64

# Get the JPEG Library
sudo port install jpeg +universal

# Get the PNG Library
sudo port install libpng +universal

# Get the FREETYPE Library
sudo port install freetype +universal

# Get the MCRYPT Library
sudo port install mcrypt +universal

# If you are forced to use macports through an institutional http proxy,
# execute the following commands.

sudo bash
export http_proxy=proxyhostname:portnumber
   # (e.g. export http_proxy=wwwcache.uni.ac.uk:8080)
export HTTP_PROXY="$http_proxy"
   # (you might want to echo $HTTP_PROXY now to check this gives wwwcache...)
port install jpeg +universal
    # (etc.)

Install the ICONV Library

ICONV will have to be built manually as the macports version is not 64-bit ready. The library can be downloaded from http://www.gnu.org/software/libiconv

# Unpack
cd /usr/local/src/
tar -xvzf ~/Downloads/libiconv-1.13.1.tar.gz

# Configure
cd /usr/local/src/libiconv-1.13.1
CFLAGS='-arch i386 -arch ppc -arch ppc64 -arch x86_64' CCFLAGS='-arch i386 -arch ppc -arch ppc64 -arch x86_64' CXXFLAGS='-arch i386 -arch ppc -arch ppc64 -arch x86_64' ./configure

# Make
make

# Install
sudo make install

Backup the existing PHP installation

These directions will overwrite the PHP apache module included with Leopard, so you will first need to back up the existing module.

# Backup the main PHP Apache HTTPD module
cd /usr/libexec/apache2
sudo cp libphp5.so libphp5.2.11-apple.so

Run Apache HTTPD Server 32-Bit

Skip this section if compiling a 4-way 32/64 bit universal PHP binary. You can also skip this section if you are running on a 32-bit architecture. Use the arch command to find out what architecture you are running on.

The HTTPD server that ships with Leopard is compiled as a 4-way universal binary and will run 64-bit on 64-bit boxes (G5, Core 2 Duo, Xeon). If you run HTTPD 64-bit, it's modules must also be 64-bit. The trouble is that even though PHP can be compiled 64-bit, a number of external libraries have not been converted to 64-bit, especially on MacPorts. At best, you will have to download and manually compile each library you need. In a development environment, a 32-bit binary works fine, and even in a production environment it's debatable whether compiling in 64-bit support is worth the trouble. In many applications there is not going to be a significant difference in performance and running 32-bit might be a little faster.

# Create a /usr/local/sbin directory if it doesn't exist
sudo mkdir /usr/local/sbin

# List httpd's architecture types
cd /usr/sbin
file httpd

# Strip out the 64-bit support
sudo lipo httpd -thin ppc7400 -output httpd.ppc # PowerPC
sudo lipo httpd -thin i386 -output httpd.i386 # x86

# Stitch them together into a single 2-way 32-bit binary
sudo lipo httpd.ppc httpd.i386 -create -output /usr/local/sbin/httpd

# Edit org.apache.httpd startup plist
cd /System/Library/LaunchDaemons
sudo nano org.apache.httpd.plist

# Change the line:
<string>/usr/sbin/httpd</string>
to ..
<string>/usr/local/sbin/httpd</string>

Build and Install PHP

Use the ./configure --help command to get a complete list of build time options.

Your MySQL libraries or any other external libraries for that matter must be of the same architecture type as the architecture type you are building PHP for. For example, don't try to build a 32-bit PHP with 64-bit MySQL libraries. You may want to modify the configure command below to compile PHP for only the architectures you need.

These directions assume you have installed MySQL in the default MySQL directory /usr/local/mysql. They also assume that the mysql libraries are located at /usr/local/mysql/lib/mysql. If you have installed the packaged version of MySQL you will have to symlink the libraries. Also, make sure when building PHP that you have read/execute access to the mysql_config command located in /usr/local/mysql/bin

Execute the following commands in Terminal if using the packaged version of MySQL:

# Change to the mysql libraries directory
cd /usr/local/mysql/lib

# Create /usr/mysql/lib/mysql subdirectory
sudo mkdir mysql

# Symlink the libraries
sudo ln -s /usr/local/mysql/lib/lib* mysql

Execute the following commands in Terminal to build PHP:

The OS X developer tools must be installed.

# Change to the PHP source directory
cd /usr/local/src/php-5.2.11

# You may need to create or symlink gawk
# On my machine, gawk mysteriously disappeared and configure depends on it

sudo ln -s /usr/bin/awk gawk

# Issue this configure command to build the make file to produce a 32-bit one way binary for the architecture you are compiling on
./configure \
--prefix=/usr/local \
--with-apxs2=/usr/sbin/apxs \
--with-ldap=/usr \
--with-kerberos=/usr \
--enable-cli \
--with-zlib-dir=/usr \
--enable-exif \
--enable-ftp \
--enable-mbstring \
--enable-mbregex \
--enable-sockets \
--with-iodbc=/usr \
--with-curl=/usr \
--with-config-file-path=/etc \
--sysconfdir=/private/etc \
--with-mysql-sock=/var/mysql \
--with-mysqli=/usr/local/mysql/bin/mysql_config \
--with-mysql=/usr/local/mysql \
--with-openssl=/usr \
--with-xmlrpc \
--with-xsl=/usr \
--without-pear \
--with-libxml-dir=/usr \
--with-iconv=/usr/local \
--with-pdo-mysql=/usr/local/mysql/bin/mysql_config \
--with-gd \
--with-jpeg-dir=/opt/local \
--with-png-dir=/opt/local \
--with-freetype-dir=/opt/local \
--with-mcrypt=/opt/local

# Issue this configure command to build the make file to produce a 32/64-bit 4-way Universal binary
# The 4-Way Universal Binary build takes a long time.
# You may want edit this command and delete the architectures you don't need.
CFLAGS='-arch i386 -arch ppc -arch ppc64 -arch x86_64' CCFLAGS='-arch i386 -arch ppc -arch ppc64 -arch x86_64' CXXFLAGS='-arch i386 -arch ppc -arch ppc64 -arch x86_64' ./configure \
--prefix=/usr/local \
--with-apxs2=/usr/sbin/apxs \
--with-ldap=/usr \
--with-kerberos=/usr \
--enable-cli \
--with-zlib-dir=/usr \
--enable-exif \
--enable-ftp \
--enable-mbstring \
--enable-mbregex \
--enable-sockets \
--with-iodbc=/usr \
--with-curl=/usr \
--with-config-file-path=/etc \
--sysconfdir=/private/etc \
--with-mysql-sock=/var/mysql \
--with-mysqli=/usr/local/mysql/bin/mysql_config \
--with-mysql=/usr/local/mysql \
--with-openssl=/usr \
--with-xmlrpc \
--with-xsl=/usr \
--without-pear \
--with-libxml-dir=/usr \
--with-iconv=/usr/local \
--with-pdo-mysql=/usr/local/mysql/bin/mysql_config \
--with-gd \
--with-jpeg-dir=/opt/local \
--with-png-dir=/opt/local \
--with-freetype-dir=/opt/local \
--with-mcrypt=/opt/local

# Patch the make file per http://bugs.php.net/bug.php?id=48195
# Need to do this only on 64-bit builds
nano Makefile
# Change the line ....
$(CC) $(MH_BUNDLE_FLAGS) $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) $(LDFLAGS) $(EXTRA_LDFLAGS) $(PHP_GLOBAL_OBJS:.lo=.o) $(PHP_SAPI_OBJS:.lo=.o) $(PHP_FRAMEWORKS) $(EXTRA_LIBS) $(ZEND_EXTRA_LIBS) -o $@ && cp $@ libs/libphp$(PHP_MAJOR_VERSION).so
# to ...
$(CC) $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) $(LDFLAGS) $(EXTRA_LDFLAGS) $(PHP_GLOBAL_OBJS:.lo=.o) $(PHP_SAPI_OBJS:.lo=.o) $(PHP_FRAMEWORKS) $(EXTRA_LIBS) $(ZEND_EXTRA_LIBS) $(MH_BUNDLE_FLAGS) -o $@ && cp $@ libs/libphp$(PHP_MAJOR_VERSION).so

# Build the executables
make

If you receive the error:
Undefined symbols:
 "_EVP_CIPHER_CTX_block_size", referenced from:
    _zif_openssl_seal in openssl.o
ld: symbol(s) not found
after compiling and linking PHP, it indicates a conflict with other MacPorts libraries. When you link php with a MacPorts library, it starts searching for all libraries in MacPorts, some of which may conflict with other libraries on your system. You may have to isolate the MacPorts libraries that you need to compile php from any other MacPorts libraries or applications that you may have already installed with MacPorts. One way to do this is to move your old MacPorts directory (usually /opt) to a new directory, reinstall macports and rerun the port installs. Some have also found using --with-openssl=shared,/opt/local option in the configure command will also fix this problem. You will have to download and compile openssl with macports for this option to work.

# Copy the installation to the OS X PHP directories
sudo make install

# Copy the configuration file php.ini to /etc
sudo cp php.ini-dist /etc/php.ini # For a development environment
sudo cp php.ini-recommended /etc/php.ini # For a production environment

# Rename the module and edit httpd.conf
cd /usr/libexec/apache2
sudo mv libphp5.so libphp5.2.11-pdogd.so # Rename
cd /etc/apache2
sudo nano httpd.conf

# change the line:
LoadModule php5_module libexec/apache2/libphp5.so
# to ..
LoadModule php5_module libexec/apache2/libphp5.2.11.so

# The newly compiled php Command Line Interface (CLI), utilities, includes, as well as the man pages are installed in /usr/local.

# Add /usr/local/bin to your PATH in .profile.
nano ~/.profile

# Your PATH should look something like:
export PATH=/usr/local/bin:$PATH:/Developer/Tools:/usr/local/mysql/bin:
/opt/local/bin:/opt/local/sbin

# If you are searching for the original Apple installed PHP files, they are here:
# The command line interface and utilities are located in /usr/bin.
# The headers are located in /usr/include/php and the libraries are in /usr/lib/php.
# The man pages are located in /usr/share/man/man1.

Start HTTPD and Display the PHP Configuration

Use the System Preferences Sharing panel or the apachectl utility to stop and restart the HTTPD server

Execute the following commands in Terminal:

# Stop the HTTPD server if it's already running
sudo apachectl graceful-stop

# Start the HTTPD server
sudo apachectl start

# Create PHP Configuration Script
sudo echo "<?php phpinfo(); ?>" > /Library/WebServer/Documents/PHPInfo.php

Go to http://localhost/PHPInfo.php in your browser.

Troubleshooting

If things are not working as expected, first use the console utility to check the console messages and httpd error log at /var/log/apache2/error_log.

Also, check /etc/apache2/httpd.conf for any spelling errors. Look closely at the line that loads the php module. It should look something like this:
LoadModule php5_module libexec/apache2/libphp5.2.11-pdogd.so.
Make sure the PHP module is not being loaded twice, this can happen when installing a new version of PHP and the old version PHP has been renamed something different than the default.

Some have reported problems connecting with MySQL. Depending on whether you are running a packaged version of MySQL or have compiled it, mysql.sock can get created in either /var/mysql or /tmp. You may have to set mysql.default_socket = /var/mysql/mysql.sock in /etc/php.ini or set socket = /var/mysql/mysql.sock in /etc/my.cnf. Another way of handling this issue is create a symlink to the appropriate socket location.

Stop and then start the httpd server to force httpd to read httpd.conf. If you use the apachectl restart command, httpd.conf will not be read.

Useful Links

Feedback

Please let me know if you found this page useful or have any other comments.

Comments:

Your Email (Optional):
Include an email address if you would like a reply.