<docbook><section><title>IODBCPHPHOWTO</title><title> iODBC-PHP-Apache HOWTO for Linux/UNIX Systems</title> iODBC-PHP-Apache HOWTO for Linux/UNIX Systems
<para> </para>
<bridgehead class="http://www.w3.org/1999/xhtml:h2">Disclaimer</bridgehead>
<para>The following is a HOWTO document for installing PHP with iODBC as an Apache module on Linux or Unix.
 Feel free to criticize, suggest modifications, or ask further questions.
 It is currently maintained by Tim Haynes of Openlink Software (iodbc@openlinksw.com).</para>
<para>Prerequisites include basic Unix familiarity, such as creating directories and users, using an editor, etc.</para>
<para>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.</para>
<para> </para>
<bridgehead class="http://www.w3.org/1999/xhtml:h2"> ODBC Overview</bridgehead>
<para>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 backend database without relying on that vendor&#39;s proprietary communication protocols.</para>
<para>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.</para>
<para> iODBC is an Open Source Driver Manager maintained by OpenLink Software.
 It is released under a dual LGPL / BSD license.</para>
<para> </para>
<bridgehead class="http://www.w3.org/1999/xhtml:h2"> Preface</bridgehead>
<para>You will also need an ODBC Driver and Database to complete the architecture.</para>
<para>If you need ODBC drivers to connect to a third-party database on the same or another machine, <ulink url="http://uda.openlinksw.com/odbc/">OpenLink ODBC Drivers</ulink> are available, and may be <ulink url="https://shop.openlinksw.com/license_generator/uda/">downloaded for free trial</ulink>.</para>
<para>The <ulink url="http://virtuoso.openlinksw.com/">Virtuoso database</ulink> may also be <ulink url="https://shop.openlinksw.com/license_generator/virtuoso/">downloaded for free trial</ulink>.</para>
<para>Support with downloading, installing, configuring, and testing these OpenLink products may be obtained through the <ulink url="http://community.openlinksw.com/">OpenLink Community Space</ulink>.</para>
<bridgehead class="http://www.w3.org/1999/xhtml:h2"> Compiling PHP with linked iODBC Driver Manager as an Apache shared module</bridgehead>
<para>The process is fairly straightforward.
 You will need to be a user who has sufficient privileges to perform all of these steps as well.
 Root privileges can be obtained by typing su root and entering your root password, but be forewarned that you can easily destroy your system as root.
 If you use root privileges, please do so on a test machine.</para>
<para>Set up a build location, and get the latest builds of <ulink url="http://www.iodbc.org/">iODBC</ulink>, <ulink url="http://httpd.apache.org/">Apache</ulink>, and <ulink url="http://www.php.net/">PHP</ulink>.</para>
<para>Set some environment variables:</para>
<programlisting>export LD_LIBRARY_PATH=/usr/local/src/odbcsdk/lib:$LD_LIBRARY_PATH
</programlisting><para> - this tells the compiler where to find the driver manager.</para>
<para>If you prefer to statically link iODBC then remove or rename libiodbc.so from the above path, and libiodbc.a will be statically linked instead.</para>
<bridgehead class="http://www.w3.org/1999/xhtml:h2"> Building Apache</bridgehead>
<para>We build apache with support for dynamic modules and APXS:</para>
<para> </para>
<programlisting>cd httpd-1.3.*
./configure --prefix=/usr/local/apache --enable-module=so --enable-mods-shared=[list of modules]
nice make &amp;&amp; su root -c &#39;make install&#39;
</programlisting><para> Choose the list of modules to go with whatever you expect to be loading from your httpd.conf (or similar).
 Among other things, authentication, dav (in the case of Apache 2.x), ssl, virtualhosting, user-tracking, spelling-correction, proxying, SSI, fine control of MIME data, etc.
 -- these are all configurable at this time.</para>
<para>After a while, Apache should finish compiling and install itself into /usr/local/apache/.</para>
<para> </para>
<bridgehead class="http://www.w3.org/1999/xhtml:h2"> Compiling PHP</bridgehead>
<para>Unpack the PHP sources with a command like --</para>
<programlisting>tar xvpfj php-4.3.2.tar.bz2
</programlisting><para> -- and change into the resultant directory.</para>
<para>Note: if you are using iodbc-3.51.0, this will expose a problem in PHP&#39;s configure script whereby it assumes the only library required is -liodbc, when it should be calling &quot;iodbc-config --libs&quot; to determine the LDFLAGS required.
 This causes a debug.log to be created as PHP is configured, and while it may build seemingly to completion, the resultant PHP library will give unresolved symbol errors, and apache will fail to start.
<ulink url="IODBCPHPHOWTO/php-configure-iodbc.diff">This patch</ulink> can be applied to PHP&#39;s ./configure script to avoid the problem.</para>
<para>PHP needs to be configured with a pointer both to Apache that you installed earlier, and to the ODBC SDK (iodbc directory):</para>
<para> </para>
<programlisting>bash$ ./configure --prefix=$HOME/php5 \
--enable-discard-path \
--with-layout=GNU \
--with-openlink=/usr/local/openlink/odbcsdk \
--enable-experimental-zts \
--with-regex=php \
--enable-experimental-zts  \
--enable-debug  \
--enable-calendar \
--with-iodbc=/usr/local/openlink/odbcsdk  \
--without-mysql \
--disable-sockets \
--disable-cli \
--with-apxs=/usr/local/apache/sbin/apxs \
--enable-embed=share{,d}

bash$ nice make
bash$ su root -c &#39;make install&#39;
</programlisting><para> The process of installing here will invoke apxs, Apache&#39;s utility for making installation of modules an awful lot easier.
 This should also include making minor changes to your httpd.conf (so to be safe, back it up first) - namely these:</para>
<programlisting>LoadModule php5_module    extramodules/libphp5.so
</programlisting><para> and</para>
<programlisting>AddModule mod_php5.c
</programlisting><para> Also, the following should be set:</para>
<programlisting>AddType  application/x-httpd-php         .php .php4 .php3 .phtml   
AddType  application/x-httpd-php-source  .phps
</programlisting><para> </para>
<bridgehead class="http://www.w3.org/1999/xhtml:h2"> Restarting Apache</bridgehead>
<para>Use the command:</para>
<programlisting>/usr/local/apache/sbin/apachectl start
</programlisting><para>to start apache.</para>
<para>Should it fail to start, you&#39;ll be best off checking logs/error_log to see why it failed: there are a multitude of possible configuration errors, from typos, through failure to access files to which it should have permission, processes already using the socket configured for listening, and more.</para>
<para> </para>
<bridgehead class="http://www.w3.org/1999/xhtml:h2"> Checking your PHP installation</bridgehead>
<para>Create a simple PHP starter script, e.g., info.php, containing nothing but the line:</para>
<programlisting>&lt;?php phpinfo(); ?&gt;
</programlisting><para> Ensure that the permissions are acceptable - 644 (owner read+write, everyone else read-only) should suffice.</para>
<para>Put it in your htdocs/ directory, or somewhere else accessible under your webserver configuration (e.g., ~/public_html/).</para>
<para>Point your browser to <ulink url="http://localhost/info.php">http://localhost/info.php</ulink> to see all PHP&#39;s configuration information.</para>
<bridgehead class="http://www.w3.org/1999/xhtml:h2"> Environment Variable concerns</bridgehead>
<para>There are two files that your ODBC-using PHP scripts must be able to access:</para>
<para>* libiodbc.so - PHP requires this to be in the list of directories   searched, so if you export LD_LIBRARY_PATH either before starting apache,   or using the SetEnv directive in httpd.conf, it should be able to access   the driver manager.</para>
<para>* odbc.ini - this is accessed by the driver manager, libiodbc.so, and   contains a list of all your DSNs and their connect info, etc.
 In order to   find this, iODBC uses the ODBCINI environment variable, or failing that   it will search /etc/odbc.ini or ~/.odbc.ini instead.
 You can either   export this in httpd.conf, or before Apache starts, or from within your   PHP script itself with the setenv() function call.</para>
<para> </para>
<bridgehead class="http://www.w3.org/1999/xhtml:h2"> Sample PHP script</bridgehead>
<para>The following script effects a connection to a database (Local Virtuoso Demo is the default DSN), and either executes a query or lists tables present in that database.</para>
<programlisting>&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Strict//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&quot;&gt; 

&lt;html&gt;
&lt;head&gt;
&lt;title&gt;OpenLink Virtuoso test of ODBC access through PHP hosting&lt;/title&gt;
&lt;link type=&quot;text/css&quot; rel=&quot;STYLESHEET&quot; 
media=&quot;ALL&quot; href=&quot;../../tutorial.css&quot; /&gt;
&lt;/head&gt;

&lt;body&gt;
&lt;h1&gt;Testing ODBC connectivity from PHP hosted within Virtuoso&lt;/h1&gt;

&lt;hr /&gt;

&lt;?php
# set global variables based on the form thing - see `register global
# variables&#39; and PHP security updates
$query=$_POST[&#39;query&#39;];
$uid=$_POST[&#39;uid&#39;];
$passwd=$_POST[&#39;passwd&#39;];
$listtables=$_POST[&#39;listtables&#39;];
$DSN=$_POST[&#39;DSN&#39;];
$exec=$_POST[&#39;exec&#39;];
?&gt;

&lt;p&gt;Enter the parameters for your query here:&lt;/p&gt;

&lt;form action=&quot;odbc-sample.php&quot; method=&quot;post&quot;&gt; 
&lt;div&gt; 
&lt;span class=&quot;caption&quot;&gt;DSN&lt;/span&gt; 
&lt;input type=&quot;text&quot; name=&quot;DSN&quot; value=&quot;&lt;?php
print ($DSN&lt;&gt;&quot;&quot;)?$DSN:&quot;Local Virtuoso Demo&quot;
?&gt;&quot; /&gt; 

&lt;span class=&quot;caption&quot;&gt;UserID&lt;/span&gt;
&lt;input type=&quot;text&quot; name=&quot;uid&quot; value=&quot;&lt;?php print ($uid&lt;&gt;&quot;&quot;)?$uid:&quot;demo&quot; ?&gt;&quot; /&gt;

&lt;span class=&quot;caption&quot;&gt;Password&lt;/span&gt;
&lt;input type=&quot;password&quot; name=&quot;passwd&quot; value=&quot;&lt;?php print ($passwd&lt;&gt;&quot;&quot;)?$passwd:&quot;demo&quot;?&gt;&quot; /&gt;
&lt;/div&gt;

&lt;div&gt;
&lt;span class=&quot;caption&quot;&gt;Query&lt;/span&gt; 
&lt;input type=&quot;text&quot; name=&quot;query&quot; value=&quot;&lt;?php
print ($query&lt;&gt;&quot;&quot;)?$query:&quot;select top 100 * from Demo..Customers&quot;
?&gt;&quot; /&gt; 
&lt;/div&gt;
&lt;div&gt;
&lt;input type=&quot;submit&quot; name=&quot;exec&quot; value=&quot;Execute query&quot; /&gt;
or
&lt;input type=&quot;submit&quot; name=&quot;listtables&quot; value=&quot;List Tables&quot; /&gt;
&lt;/div&gt;
&lt;/form&gt;

&lt;hr /&gt;

&lt;?php
if($query&lt;&gt;&quot;&quot; &amp;&amp; $DSN&lt;&gt;&quot;&quot; &amp;&amp; $exec!=NULL) {

print &quot;&lt;h2&gt;Results:&lt;/h2&gt;
&quot;;
print &quot;&lt;p&gt;Connecting... &quot;;
$handle=odbc_connect (&quot;$DSN&quot;, &quot;$uid&quot;, &quot;$passwd&quot;);

if(!$handle) {
print &quot;&lt;p&gt;Uh-oh! Failure to connect to DSN [$DSN]: &lt;br /&gt;&quot;;
odbc_errormsg();
}
else {
print &quot;done&lt;/p&gt;
&quot;;
$resultset=odbc_exec ($handle, &quot;$query&quot;);
odbc_result_all($resultset, &quot;border=2&quot;);
odbc_close($handle);
}
}

if($listtables!=NULL) {
print &quot;&lt;h2&gt;List of tables&lt;/h2&gt;&quot;;
print &quot;&lt;p&gt;Connecting... &quot;;
$handle=odbc_connect (&quot;$DSN&quot;, &quot;$uid&quot;, &quot;$passwd&quot;);
print &quot;done&lt;/p&gt;
&quot;;

if(!$handle) {
print &quot;&lt;p&gt;Uh-oh! Failure to connect to DSN [$DSN]: &lt;br /&gt;&quot;;
odbc_errormsg();
}
else {
$resultset=odbc_tables($handle);
odbc_result_all($resultset, &quot;border=2&quot;);
odbc_close($handle);
}
}
?&gt;
&lt;/body&gt;
&lt;/html&gt;
</programlisting><bridgehead class="http://www.w3.org/1999/xhtml:h2"> Concerns and Improvements</bridgehead>
<para> Historically, iODBC has not been fully supported in PHP.
 We made a patch addressing these issues:</para>
<itemizedlist mark="bullet" spacing="compact"><listitem>ODBC 3.52 datatypes are now used, to comply with ODBC64 spec on Win64 and 64-bit *nix platforms </listitem>
<listitem>Enabled use of SQLDriverConnect(), array fetching, and other advanced PHP API functions </listitem>
<listitem>Made the static cursor model the default (instead of dynamic), to speed up advanced drivers.
The cursor model can be selected by a setting in php.ini.</listitem>
</itemizedlist><para>This patch has been incorporated into PHP around version 5.2.11 and above.</para>
<para>To use this patch with older versions of PHP, first download it: <ulink url="IODBCPHPHOWTO/iodbc-php5.diff">iodbc-php5.diff</ulink></para>
<para>Second, apply it using patch(1):</para>
<programlisting>bash$ tar xvfpj php-5.2.5.tar.bz2
php-5.2.5/
php-5.2.5/ext/
php-5.2.5/ext/gd/
php-5.2.5/ext/gd/gd.c
php-5.2.5/ext/gd/gd_ctx.c
...
bash$ patch -p0 &lt; ../iodbc-php5.diff
patching file ext/odbc/php_odbc.c
Hunk #26 succeeded at 1644 (offset 1 line).
Hunk #27 succeeded at 1715 (offset 1 line).
Hunk #28 succeeded at 1777 (offset 1 line).
Hunk #29 succeeded at 1863 (offset 1 line).
Hunk #47 succeeded at 3603 (offset 1 line).
patching file ext/odbc/php_odbc.h
patching file ext/odbc/php_odbc_includes.h
</programlisting><para> You can now resume the build process from the &quot;./configure&quot; step above.</para>
<para> </para>
<bridgehead class="http://www.w3.org/1999/xhtml:h2"> References</bridgehead>
<itemizedlist mark="bullet" spacing="compact"><listitem>PHP on macOS <ulink url="http://www.php.net/manual/en/install.macosx.php">installation instructions</ulink> </listitem>
<listitem><ulink url="http://www.iodbc.org">iODBC.org</ulink> </listitem>
<listitem>History of <ulink url="http://www.iodbc.org/odbcstory.htm">ODBC on Unix</ulink> </listitem>
<listitem><ulink url="http://www.php.net/support.php">PHP main site</ulink> </listitem>
<listitem><ulink url="http://www.openlinksw.com/">OpenLink Software</ulink> <itemizedlist mark="bullet" spacing="compact"><listitem><ulink url="http://community.openlinksw.com/">Community Space</ulink> </listitem>
<listitem><ulink url="http://support.openlinksw.com/">Support Center and Case System</ulink> </listitem>
</itemizedlist></listitem>
</itemizedlist></section></docbook>