<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Juozas devBlog &#187; wiinphp</title>
	<atom:link href="http://dev.juokaz.com/tag/wiinphp/feed" rel="self" type="application/rss+xml" />
	<link>http://dev.juokaz.com</link>
	<description>Random ideas, scripts and facts</description>
	<lastBuildDate>Mon, 22 Mar 2010 10:48:42 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>SQL Native Client as MSSQL driver for Zend Framework</title>
		<link>http://dev.juokaz.com/winphp-2009/sql-native-client-as-mssql-driver-for-zend-framework</link>
		<comments>http://dev.juokaz.com/winphp-2009/sql-native-client-as-mssql-driver-for-zend-framework#comments</comments>
		<pubDate>Thu, 07 May 2009 01:39:53 +0000</pubDate>
		<dc:creator>Juozas</dc:creator>
				<category><![CDATA[WinPhp 2009]]></category>
		<category><![CDATA[competition]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[driver]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[mssql]]></category>
		<category><![CDATA[odbc]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[sql native client]]></category>
		<category><![CDATA[sqlsrv]]></category>
		<category><![CDATA[wiinphp]]></category>
		<category><![CDATA[zend framework]]></category>

		<guid isPermaLink="false">http://dev.juokaz.com/?p=648</guid>
		<description><![CDATA[Stuart Herbert in his blog more than a year ago pointed some key Microsoft Sql extension for PHP pros:
What’s Wrong With The Existing MSSQL Extension For PHP?
… or, why do we need an improved SQL Server extension for PHP? :)
The existing MSSQL extension works well, but has a few practical limitations that have to be [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://dev.juokaz.com/wp-content/uploads/2009/05/ms_sql_logo2.jpg" alt="Microsoft Sql server" title="Microsoft Sql server" width="163" height="56" class="alignnone size-full wp-image-672" /><a href="http://blog.stuartherbert.com/php/">Stuart Herbert</a> in his blog more than a year ago <a href="http://blog.stuartherbert.com/php/2007/10/16/microsofts-first-php-extension-sql-server-2005-support/">pointed</a> some key Microsoft Sql extension for PHP pros:</p>
<blockquote><p><strong>What’s Wrong With The Existing MSSQL Extension For PHP?</strong></p>
<p>… or, why do we need an improved SQL Server extension for PHP? :)</p>
<p>The existing MSSQL extension works well, but has a few practical limitations that have to be worked around.</p>
<ul>
<li><em>Limited to varchar(255) support</em></li>
<li><em>No support for unicode columns like nvarchar</em></li>
<li><em>No PDO drivers</em></li>
<li><em>Poor error reporting</em></li>
</ul>
</blockquote>
<p>Now some of these issues are fixed, however Microsoft native Sql driver is still not used. As I&#8217;ve mentioned <a href="http://dev.juokaz.com/winphp-2009/zend-framework-and-microsoft-iis">before</a>, there are to ways to use <a href="http://www.microsoft.com/sqlserver/2005/en/us/PHP-Driver.aspx">native driver</a> in PHP now:</p>
<ol>
<li> As <a href="http://devzone.zend.com/article/1021">PHP extension</a></li>
<li>Through <a href="http://en.wikipedia.org/wiki/Open_Database_Connectivity">ODBC</a></li>
</ol>
<p>However, none of these is available in Zend Framwork. So my task now (because of <a href="http://wiki.phpconference.nl/2009_WinPHP_Challenge">Winphp competition</a>) is to come up with something what can be used to connect to Microsft Sql database with the new driver. To start with, lets look how standard DB config looks like:</p>

<div class="wp_syntax"><div class="code"><pre class="ini" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">;application/config/application.ini, ZF 1.8</span>
resources.db.adapter <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> PDO_MYSQL</span>
resources.db.params.host <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> localhost</span>
resources.db.params.username <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> usr</span>
resources.db.params.password <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> psw</span>
resources.db.params.dbname <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> zf-tutorial</span></pre></div></div>

<p><a href="http://dev.juokaz.com/wp-content/uploads/2009/05/lfzl3021.gif"><img src="http://dev.juokaz.com/wp-content/uploads/2009/05/lfzl3021-150x150.gif" alt="ODBC" title="ODBC" width="100" height="100" style="float: right; margin-left: 5px;" class="alignnone size-thumbnail wp-image-674" /></a>My goal is to change it as minimal as possible to allow easy db&#8217;s migration. To test <a href="http://en.wikipedia.org/wiki/Open_Database_Connectivity"><strong>ODBC</strong></a> connector I downloaded this <a href="http://framework.zend.com/issues/browse/ZF-905">class</a> and renamed it to <strong>Add_Db_Adapter_Pdo_Odbc</strong> (because it&#8217;s not a good idea to change something in actual Zend Framework library). To use it in your code you need to change config file to something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="ini" style="font-family:monospace;">resources.db.adapter <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> PDO_ODBC</span>
resources.db.params.adapterNamespace <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> App_Db_Adapter</span>
resources.db.params.username <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> usr</span>
resources.db.params.password <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> psw</span>
resources.db.params.dbname <span style="color: #000066; font-weight:bold;">=</span> <span style="color: #933;">&quot;Driver={SQL Native Client};
Server=localhost\SQLEXPRESS;Database=zf-tutorial;&quot;</span></pre></div></div>

<p>Note <em>dbname</em> string &#8211; now it has not only database name, but also driver information and host. I guess such format is chosen because dns&#8217; for ODBC are very different for different providers, so to make things easier you just supply whole string, not it&#8217;s parts (driver, server/file, etc.). Don&#8217;t forget to use correct server host &#8211; for some strange reasons 127.0.0.1 refused to work for me.</p>
<p>Problem with ODBC is that it&#8217;s too general: ODBC supports <a href="http://www.connectionstrings.com/">a lot</a> databases, hence they each can have something different (correct me if I&#8217;m wrong). That&#8217;s why I&#8217;m thinking about refactoring this class to <em>App_Db_Adapter_Pdo_Odbc_Abstract</em> abstract class and separate classes for different drivers. Although this class works fine for MSSQL, so can be used as is.</p>
<p>To test <strong>PHP extension</strong> there are no classes at all (at least I haven&#8217;t found, only in <a href="http://adodb.sourceforge.net/">Adodb</a>). So I decided to implement one myself &#8211; with a help of <a href="http://msdn.microsoft.com/en-us/library/cc296152(SQL.90).aspx">SqlSrv API Reference</a> and <a href="http://framework.zend.com/apidoc/core/Zend_Db/Adapter/Zend_Db_Adapter_Abstract.html">Zend_Db_Adapter_Abstract</a> abstract class I quite quickly came up with a working solution <strong>App_Db_Adapter_Mssql</strong>. Connection configuration looks the same:</p>

<div class="wp_syntax"><div class="code"><pre class="ini" style="font-family:monospace;">resources.db.adapter <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> MSSQL</span>
resources.db.params.adapterNamespace <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> App_Db_Adapter</span>
resources.db.params.host <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> localhost\SQLEXPRESS</span>
resources.db.params.username <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> usr</span>
resources.db.params.password <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> psw</span>
resources.db.params.dbname <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> zf-tutorial</span></pre></div></div>

<p>I&#8217;ve tested both classes with the same application from <a href="http://dev.juokaz.com/winphp-2009/zend-framework-and-microsoft-iis">previous post</a> and benchmark results surprised me. They were <strong>equal</strong>! With a small variations page generation times were about 140 <em>ms</em> (all default settings, IIS7, MSSQL Express). Why? SQL server driver for PHP is open source, so if you look at it&#8217;s source you would find (C++):</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;">SQLRETURN build_connection_string_and_set_conn_attr<span style="color: #008000;">&#40;</span>
       sqlsrv_conn <span style="color: #0000ff;">const</span><span style="color: #000040;">*</span> conn, <span style="color: #0000ff;">const</span> <span style="color: #0000ff;">char</span><span style="color: #000040;">*</span> server, zval <span style="color: #0000ff;">const</span><span style="color: #000040;">*</span> options,
       __inout std<span style="color: #008080;">::</span><span style="color: #007788;">string</span><span style="color: #000040;">&amp;</span> connection_string TSRMLS_DC <span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
   ...
&nbsp;
   <span style="color: #007788;">connection_string</span> <span style="color: #000080;">=</span> <span style="color: #FF0000;">&quot;Driver={SQL Native Client};Server=&quot;</span><span style="color: #008080;">;</span>
   connection_string <span style="color: #000040;">+</span><span style="color: #000080;">=</span> server<span style="color: #008080;">;</span>
   connection_string <span style="color: #000040;">+</span><span style="color: #000080;">=</span> <span style="color: #FF0000;">&quot;;&quot;</span><span style="color: #008080;">;</span>
&nbsp;
   ...
&nbsp;
   <span style="color: #0000ff;">for</span><span style="color: #008000;">&#40;</span> zend_hash_internal_pointer_reset<span style="color: #008000;">&#40;</span> oht <span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
         zend_hash_has_more_elements<span style="color: #008000;">&#40;</span> oht <span style="color: #008000;">&#41;</span> <span style="color: #000080;">==</span> SUCCESS<span style="color: #008080;">;</span>
         zend_hash_move_forward<span style="color: #008000;">&#40;</span> oht <span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
&nbsp;
      ...
&nbsp;
       <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span> NO_ATTRIBUTE <span style="color: #000080;">==</span> ret.<span style="color: #007788;">attr</span> <span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
           <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span> ret.<span style="color: #007788;">add</span> <span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
               connection_string <span style="color: #000040;">+</span><span style="color: #000080;">=</span> key<span style="color: #008080;">;</span>
               connection_string <span style="color: #000040;">+</span><span style="color: #000080;">=</span> <span style="color: #FF0000;">&quot;={&quot;</span><span style="color: #008080;">;</span>
               connection_string <span style="color: #000040;">+</span><span style="color: #000080;">=</span> ret.<span style="color: #007788;">str_value</span><span style="color: #008080;">;</span>
               connection_string <span style="color: #000040;">+</span><span style="color: #000080;">=</span> <span style="color: #FF0000;">&quot;};&quot;</span><span style="color: #008080;">;</span>
           <span style="color: #008000;">&#125;</span>
       <span style="color: #008000;">&#125;</span>
       ...
   <span style="color: #008000;">&#125;</span>
&nbsp;
   ...
&nbsp;
   <span style="color: #0000ff;">return</span> SQL_SUCCESS<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>If you are familiar with C++ you can look at full source at <a href="http://sql2k5php.codeplex.com/SourceControl/changeset/view/33567#265058">codeplex.com</a>. What this function does is it creates ODBC connection string, so basically it&#8217;s the same thing as using <a href="http://php.oregonstate.edu/manual/en/ref.pdo-odbc.php">PDO_ODBC</a> (no?). Both are implemented as extensions (not as PHP code) so there are no performance differences, test proves that.</p>
<p>After today&#8217;s analysis I can&#8217;t say which driver is better to use: ODBC or native driver. However, since <a href="http://php.oregonstate.edu/manual/en/intro.pdo.php">Pdo</a> driver is already being used in Zend Framework it&#8217;s easier and faster to use ODBC. Also, ODBC doesn&#8217;t require Sql PHP extension to be installed, so as long as you have Sql server and <a href="http://msdn.microsoft.com/en-us/data/aa937733.aspx">native client</a> it will work without <em>php.ini</em> modifications.</p>
<p>In conclusion, if you want to use SQL Native driver with Zend Framework solutions are almost here. I can promise, that something stable and proven to be working by actual application will be released before middle of June. I would love to hear comments from Microsoft people or ODBC users &#8211; I&#8217;m confused a little bit, because I didn&#8217;t have a lot of experience with Microsoft&#8217;s Sql and ODBC (you can share find me in twitter also <a href="http://twitter.com/juokaz">@juokaz</a>).</p>
]]></content:encoded>
			<wfw:commentRss>http://dev.juokaz.com/winphp-2009/sql-native-client-as-mssql-driver-for-zend-framework/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
