The following is a HOWTO document for installing PHP with iODBC as an Apache module on MacOS X. Feel free to criticize, suggest modifications, or ask further questions. It is currently maintained by Tim Haynes of Openlink Software (iodbc@openlinksw.com)

Prerequisites include basic Unix familiarity, such as creating directories and users, using an editor, etc.

This HOWTO is intended to assist in connecting php/apache to back end databases via ODBC in a development environment and should not take the place of thorough testing before deployment on a production system.

ODBC Overview

ODBC (Open Database Connectivity) is an operating system- and database-independent communication API that allows a client application (productivity tool, other database, web page, custom application, etc.) to communicate via standards-based function calls to a back end database without relying on that vendor's proprietary communication protocols.

ODBC connections involve an application, driver manager, driver, and database. The driver manager under Microsoft Windows platforms is the ODBC Control Panel. The driver manager registers a set of ODBC driver connection parameters called a Data Source Name (DSN). An application looks to the driver manager for a DSN, and then passes the connection parameters specified in the DSN to the appropriate driver, which makes the connection. Under non-Windows platforms you may need to install a Driver Manager. iODBC is an Open Source Driver Manager maintained by OpenLink Software. It is released under a dual LGPL / BSD license.


You will also need an ODBC Driver and Database to complete the architecture.

If you need ODBC drivers to connect to a third-party database on the same or another machine, OpenLink ODBC Drivers are available, and may be downloaded from http://www.openlinksw.com

The Virtuoso database may also be downloaded from http://virtuoso.openlinksw.com/

Both Virtuoso and OpenLink's Multi-Tier ODBC drivers download with a free 30-day demo license.

Support for setting up the OpenLink Drivers may be obtained at http://support.openlinksw.com/

Overview & Requirements

First, download both php from http://www.php.net/ and the iODBC driver manager from http://www.iodbc.org/. Ensure you have any other dependencies for PHP installed (for example, mysql, postgresql, imap, libxml etc).

If you download a MacOS X binary package of iODBC from the iodbc.org or OpenLink websites, this will have been built as a framework. This is the recommended course of action, as it is compatible with other ODBC-using applications such as Excel, RealBasic, other packages of PHP for MacOS X, etc. The majority of the rest of this HOWTO assumes you're building from source, should you want to customize the process yourself.

Building iODBC from source

If you are compiling from source, on Macos X, there are two ways whereby a package might be compiled - as traditional shared libraries, or as a `Framework'. If you intend loading php from apache, then it must be compiled as a framework. It is also best if you compile iODBC as a framework as well.

Having downloaded the source tarball, unpack it, thus:

[oplusmacosx:~/tim] openlink% tar xvfz libiodbc-3.51.1.tar.gz 

In the libiodbc-3.51.1 directory, read the README.MACOSX file. You will find both a . configure script and a mac directory: you can choose the former to build a shared library of iodbc, or the latter to make a framework, thus:

Traditional Shared-Library approach

[oplusmacosx:~/libiodbc-3.51.1] openlink% ./configure   --enable-gui --prefix=$HOME/iodbc-3.51.1-shared

(enabling the GUI will require GTK to be installed) - then run `make' and `sudo make install', or

MacOS X Framework approach

[oplusmacosx:~/libiodbc-3.51.1-shared] openlink% cd mac
[oplusmacosx:~/libiodbc-3.51.1-shared/mac] openlink% make
sh framework-include.sh
cd iODBC; pbxbuild build -buildstyle Deployment

In the latter case, if you wish to install to a non-default location, you should amend Makefile in the mac/ subdirectory - search for the line beginning `install:', amend the DSTROOT directory and optionally remove the `sudo' if you're installing it into your user's home directory:

cd iODBC;     pbxbuild install -buildstyle Deployment DSTROOT=$(HOME)/iodbc
cd iODBCinst; pbxbuild install -buildstyle Deployment DSTROOT=$(HOME)/iodbc

then you can run `make install'.

Building PHP with iODBC

Obtain and unpack the sources for php, e.g. with:

[oplusmacosx:~/tim] openlink% bzcat < php-4.3.3.tar.bz2 | tar xvf -

If you built iODBC as a shared library earlier, building PHP against it is a simple matter of running configure with a point to the top directory where iODBC was installed:

[oplusmacosx:~/php-4.3.3] openlink% ./configure --with-iodbc=$HOME/iodbc-shared && nice make

However, if you built iODBC as a framework, it's a bit more complicated. PHP has no support for iODBC as a framework out of the box, so you need to configure it first and then edit the generated Makefile. A complete recommended set of configure options for PHP is:

./configure \
    --prefix=/Library/PHP4  \
    --with-openssl=/usr  \
    --with-zlib=/usr  \
    --enable-calendar  \
    --enable-exif \
    --enable-ftp  \
    --enable-mbstring  \
    --disable-mbregex  \
    --enable-session \
    --enable-sockets  \
    --enable-tokenizer  \
    --enable-wddx  \
    --with-xml  \
    --enable-yp \
    --enable-versioning  \
    --enable-trans-id  \
    --enable-track-vars  \
    --with-mysql \
    --with-ldap=/usr  \
    --with-iodbc=/usr  \
    --with-jpeg-dir=/Library/PHP4 \
    --with-png-dir=/Library/PHP4  \
    --enable-xslt  \
    --with-xslt-sablot=/Library/PHP4 \
    --with-pdflib=/Library/PHP4  \
    --with-tiff-dir=/Library/PHP4 \
    --with-pgsql=/Library/PHP4  \
    --with-iconv=/Library/PHP4 \
    --with-sybase=/Library/PHP4  \
    --with-mcrypt=/Library/PHP4 \
    --with-curl=/Library/PHP4  \
    --with-freetype-dir=/Library/PHP4 \
    --with-ttf=/Library/PHP4  \
    --with-xmlrpc  \
    --enable-mime-magic  \
    --without-pspell \
    --with-expat-dir=/Library/Apache2  \
    --with-t1lib=/Library/PHP4  \
    --enable-dbx \
    --without-pcre-regex  \
    --without-pgsql  \
    --enable-shared  \
    --enable-cli \
    #    --with-apxs2=/Library/Apache2/bin/apxs 

Note that if you enable the cli (as would make sense for testing) you should disable support for apxs, otherwise duplicate symbols may result - chose one or the other.

Now, edit the Makefile, and search for references to iodbc. You need to replace these lines:

ODBC_INCLUDE = -framework iODBC -F /Users/openlink/iodbc-mac/Library/Frameworks/
ODBC_LIBS =  -framework iODBC -F /Users/openlink/iodbc-mac/Library/Frameworks/
ODBC_LFLAGS = -framework iODBC -F /Users/openlink/iodbc-mac/Library/Frameworks/

Remove the first two words on the right side of this line:

EXTRA_LDFLAGS = -export-symbols \
/Users/openlink/php-4.3.3/sapi/apache2handler/php.sym \
-L/Library/PHP4/lib \
-L/Users/openlink/iodbc-mac//Library/Frameworks/iODBC.framework/lib \

(the `-export-symbols' and path to `php.sym')

Replace the EXTRA_LDFLAGS line accordingly:

EXTRA_LIBS = -lsablot -lexpat -lexpat -lexpat -lsybdb -lpdf -lz \
-ltiff -lpng -ljpeg -liodbc -lmcrypt -lltdl -lldap -llber -liconv -lcurl \
-lz -lssl -lcrypto -lm -ldl -lcurl -lz -lssl -lcrypto -lz -liodbc
EXTRA_LDFLAGS = -L/Library/PHP4/lib \
-L/Users/openlink/iodbc-mac//Library/Frameworks/iODBC.framework/lib \
EXTRA_LIBS = -lsablot -lexpat -lexpat -lexpat -lsybdb -lpdf -lz -ltiff \
-lpng -ljpeg -lmcrypt -lltdl -lldap -llber -liconv -lcurl -lz -lssl \
-lcrypto -lm -ldl -lcurl -lz -lssl -lcrypto -lz -framework iODBC

Finally, ensure there are no further references to `-liodbc' in the Makefile, before typing `make'.

Testing a PHP CLI works

It's advisable to build PHP as a CLI before going the whole way and testing with apache. To test that PHP is working with iODBC you can do something like:

[oplusmacosx:~/php-4.3.3] openlink% echo '<?php echo "foo
"; odbc_connect("foo","username","pwd");?>' | ./sapi/cgi/php
Content-type: text/html
X-Powered-By: PHP/4.3.3
<br />
<b>Warning</b>:  odbc_connect(): SQL error: [iODBC][Driver Manager]Data source name not found and no default driver specified. Driver could not be loaded, SQL state IM002 in SQLConnect in <b>/Users/openlink/php-4.3.3/-</b> on line <b>1</b><br />

The fact that the DSN `foo' is not found is immaterial; what matters here is that it's iODBC emitting a standard error message, showing PHP and iODBC are talking together. (If iODBC had not been included, you would have an error message about an attempt to call an undefined function `odbc_connect', instead).

You can double-check that the framework version of iODBC is in use by running the above command through `otool -l' and grep-ing the output for iodbc. If you see, for example, /usr/lib/libiodbc in there, you know it's using the shared-library version instead.

[oplusmacosx:~/php-4.3.3-shared-usr] openlink% echo \
'<?php echo "foo
"; odbc_connect("foo","username","pwd");?>' \
| otool -l ./sapi/cgi/php | grep -i iodbc
name /usr/lib/libiodbc.2.1.6.dylib (offset 24)

Integrating with Apache

If you've used the CLI mode as a test above, you will need to reconfigure and rebuild PHP using --disable-cli and --with-apxs2=/path/to/apxs.

Once PHP is built with all your required configure options against a framework iODBC, it should be sufficient to execute `make install' for it to invoke apxs, which will place suitable directives in apache's httpd.conf:

# PHP4 configuration
LoadModule php4_module modules/libphp4.so
AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps

You should restart the apache webserver when these directives are in place, and run a simple test-script to see how PHP is being loaded, and attempt a simple database connection:


<?php phpinfo(); ?>



#Set up environment variables
putenv("ODBCINI=/path/to/odbc.ini"); //odbc.ini contains your DSNs.


$sql="SELECT * FROM table";

// directly execute mode
if ($conn_id=odbc_connect("$dsn","","")) {
echo "connected to DSN: $dsn";
if($result=odbc_do($conn_id, $sql)) {
echo "executing '$sql'";
echo "Results: ";
echo "freeing result";
echo "can not execute '$sql' ";
echo "closing connection $conn_id";
echo "can not connect to DSN: $dsn ";