<?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; database</title>
	<atom:link href="http://dev.juokaz.com/tag/database/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>Service Layer in Web applications</title>
		<link>http://dev.juokaz.com/programming/service-layer-in-web-applications</link>
		<comments>http://dev.juokaz.com/programming/service-layer-in-web-applications#comments</comments>
		<pubDate>Thu, 26 Nov 2009 16:53:47 +0000</pubDate>
		<dc:creator>Juozas</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[acl]]></category>
		<category><![CDATA[authentication]]></category>
		<category><![CDATA[dao]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[doctrine]]></category>
		<category><![CDATA[matthew]]></category>
		<category><![CDATA[models]]></category>
		<category><![CDATA[patterns]]></category>
		<category><![CDATA[permissions]]></category>
		<category><![CDATA[saas]]></category>
		<category><![CDATA[users]]></category>
		<category><![CDATA[zend framework]]></category>
		<category><![CDATA[zf]]></category>

		<guid isPermaLink="false">http://dev.juokaz.com/?p=888</guid>
		<description><![CDATA[In my professional live I mostly work with enterprise web applications which are quite demanding for big layer of business logic (that&#8217;s another article I guess) and decoupling of application layers. During this year I invested quite a lot for a search of a good ways to architecture a big application and make it simply [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://dev.juokaz.com/wp-content/uploads/2009/11/ServiceLayerSketch.gif"><img class="alignnone size-full wp-image-889" title="Service layer sketch" src="http://dev.juokaz.com/wp-content/uploads/2009/11/ServiceLayerSketch.gif" alt="Service Layer Sketch" width="199" height="229" style="float: right;" /></a>In my professional live I mostly work with enterprise web applications which are quite demanding for big layer of business logic (that&#8217;s another article I guess) and decoupling of application layers. During this year I invested quite a lot for a search of a good ways to architecture a big application and make it simply good. Quite a while ago <a href="http://weierophinney.net/matthew/">Matthew Weier O&#8217;Phinney</a> introduced service layer in one of his great talks about models, since then service layer become one of the key architectural component one my applications. Here I&#8217;m going to show a few examples and use cases where it&#8217;s very useful. </p>
<h5>&#8220;Old-style&#8221; interaction with data</h5>
<p>I&#8217;ve used it for different projects, but one of the best examples of how great this concept is <a href="http://en.wikipedia.org/wiki/Software_as_a_service">SaaS</a> or any other users-based application. Some years ago I used to have code which worked like this (let&#8217;s say this is controller action):</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> userInfo<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
     <span style="color: #000088;">$userDao</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Users<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
     <span style="color: #000088;">$user</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$userDao</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getUser</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_SESSION</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'id'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>And then in my database access class <em>Users</em> I just execute sql query with a given user id. However, after some thinking I looked at it again and though &#8211; why does controller need to know the userId? I mean, of course it&#8217;s a job of controller to process requests and control application flow, but logically &#8211; if an action is named <em>userInfo</em> and we got to the point where we need the user info (hence the user is authenticated and validated) why do we need to pass user id? It&#8217;s clear that some part of code already knows it.</p>
<p>One more case: if a site is a e-commerce it&#8217;s clear that user has only access to his orders, addresses information etc. but in a <a href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller">basic MVC</a> you either fetch by <em>Id</em> and then check if it&#8217;s in fact user&#8217;s order or create a method like in a first example. Again, not very clear and not easy to maintain. There are more problems too: by passing user id and id of a record you assume that controller knows that this is a key to get the information. But it&#8217;s wrong &#8211; business layer knows that user has orders; controller only knows that there is such a thing like orders and it can be retrieved by id. <a href="http://www.mikebernat.com/blog/MVC_-_Fat_Models_and_Skinny_Controllers_">That&#8217;s it</a>.</p>
<h5>Service layer</h5>
<p>For such things I use service layer: it has user info injected from bootstrap (or directly to a constructor) and operates with data only accessible to the user. So previous method becomes to:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> userInfo<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
     <span style="color: #000088;">$service</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> UsersService<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
     <span style="color: #000088;">$user</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$service</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getUser</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>of course you would have a separate method to fetch other users data, but for sake of simplicity let&#8217;s just say that this method returns some private info (like address for example). Here my action is completely unaware of what user id actually is &#8211; it expects a user object, it gets it. Very simple, very clean and very easy to maintain. </p>
<p>Getting back to the e-commerce example, action for a view order would look like this:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> viewOrder<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
     <span style="color: #000088;">$service</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> OrdersService<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
     <span style="color: #000088;">$order</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$service</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getOrder</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'id'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Again &#8211; this controller action doesn&#8217;t care what user id is in current session, it just gets an order by its id. If this action returns false (or throws exception with error type) then it means order cannot be retrieved, or in other words &#8211; service cannot return id by given id. It can be permissions problem, it can be something else &#8211; but controller is completely freed from checking all this unnecessary things.</p>
<h5>Practical usage</h5>
<p>As you might have noticed, service layer is intermediate layer between models and controllers &#8211; in the same way as you would use Flickr or <a href="http://code.google.com/apis/youtube/overview.html">Youtube API</a> to work with remote data, you use service layer API to work with application resources. All the business logic resides in service layer, where also using other service layer, models are retrieved, changed, saved, returned etc. Controller has zero lines which contain a word <em>Doctrine</em> (or any other database layer class). None.</p>
<p><img src="http://dev.juokaz.com/wp-content/uploads/2009/11/soa-additional-service-layer.jpg" alt="Service layer " title="Service layer " width="450" height="322" class="alignnone size-full wp-image-905" /></p>
<p>Another advantage of using a service layer &#8211; it&#8217;s a good place to merge information sources. I think it&#8217;s more like a style of mine, but I tend to have models very clean &#8211; only with logic on that model. This is mainly because I usually use <a href="http://dev.juokaz.com/tag/doctrine">Doctrine</a> models and I don&#8217;t want to put anything in them. For example just yesterday Adam from <em>jazzslider.org</em> posted a very good article about <a href="http://www.phpquebec.org/modules/news/article.php?storyid=103">using Acl with models</a> by creating custom listeners. With all respect, even though it works really great, I don&#8217;t think it&#8217;s a clean approach &#8211; I see models and permissions control as separate layers.</p>
<p>Furthermore, having this layer makes replacing database layer (or even models layer) a little bit easier &#8211; because all the other code communicates with data using given <a href="http://en.wikipedia.org/wiki/Application_programming_interface">API</a> (from service layer) so as long as results returned are the same, they don&#8217;t care how they are actually retrieved (for example they can come from cache, text file or created on-the-fly). But if you would have <a href="http://framework.zend.com/manual/en/zend.db.select.html">Zend_Db_Select</a> calls all other the place, migrating to Doctrine&#8217;s <a href="http://www.doctrine-project.org/documentation/manual/1_0/en/dql-doctrine-query-language">DQL</a> can be a pain. From my personal experience, I successfully migrated my own ORM code with about 50 models to Doctrine in about 4 days without changing a line in controllers (also because of tests I had).</p>
<p>To be honest, I&#8217;ve only tried various service layer implementations with <a href="http://framework.zend.com/">Zend Framework</a>. Even a default autoloader has a resource namespace <em>Service_</em> with <em>services</em> folder inside application, so I didn&#8217;t need to do any hacking to get it working. Nevertheless, this pattern doesn&#8217;t require any specific framework futures, but if a framework has good dependency injector (like <a href="http://components.symfony-project.org/dependency-injection/">this</a> one from Symfony) it can make things even cleaner. </p>
<h5>Conclusion</h5>
<p>I don&#8217;t know if I have convinced you to look at this pattern, but I definitely recommend looking at it. Especially when your application gets quite big and you need some sort of functionality to work with all these models (on average, I used service layer with applications having roughly 80 models). Nevertheless, there are tons of different ways to do this, so I definitely recommend reading a book by M. Fowler called <a href="http://martinfowler.com/eaaCatalog/">&#8220;Patterns of Enterprise Application Architecture (P of EAA)&#8221;</a>. One of the best sources for enterprise applications I&#8217;ve read so far.</p>
<p><em><sup>*</sup> Image copyright: <a href="http://martinfowler.com/eaaCatalog/serviceLayer.html">http://martinfowler.com/eaaCatalog/serviceLayer.html</a> and <a href="http://www.tutorialspoint.com/images/soa-additional-service-layer.jpg">http://www.tutorialspoint.com/images/soa-additional-service-layer.jpg</a></em></p>
]]></content:encoded>
			<wfw:commentRss>http://dev.juokaz.com/programming/service-layer-in-web-applications/feed</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>Zend Framework and Doctrine. Part 2</title>
		<link>http://dev.juokaz.com/php/zend-framework-and-doctrine-part-2</link>
		<comments>http://dev.juokaz.com/php/zend-framework-and-doctrine-part-2#comments</comments>
		<pubDate>Wed, 18 Nov 2009 10:05:32 +0000</pubDate>
		<dc:creator>Juozas</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[application.ini]]></category>
		<category><![CDATA[cli]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[doctrine]]></category>
		<category><![CDATA[example]]></category>
		<category><![CDATA[models]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[orm]]></category>
		<category><![CDATA[zend framework]]></category>

		<guid isPermaLink="false">http://dev.juokaz.com/?p=866</guid>
		<description><![CDATA[Today we start actual development with Doctrine and Zend Framework. Base of this post is my code which I have been using for quite a few projects and it worked really well.
These are the steps required to setup Doctrine:

Create MySQL (or any other adapter supported by Doctrine) database
Download Doctrine 1.2 (as of today &#8211; 1.2.0beta3). [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://dev.juokaz.com/wp-content/uploads/2009/11/doctrine-orm-php5.png" alt="doctrine-orm-php5" title="doctrine-orm-php5" width="191" height="53" class="size-full wp-image-847" style="float: left; margin-right: 5px;" />Today we start actual development with Doctrine and Zend Framework. Base of this post is my code which I have been using for quite a few projects and it worked really well.</p>
<p>These are the steps required to setup Doctrine:</p>
<ol>
<li>Create MySQL (or any other adapter <a href="http://www.doctrine-project.org/documentation/manual/1_2/en/introduction-to-connections">supported</a> by Doctrine) database</li>
<li>Download Doctrine 1.2 (as of today &#8211; <a href="http://www.doctrine-project.org/download/1_2_0_BETA3/format/tgz/package/">1.2.0beta3</a>). Believe, it&#8217;s stable enough (no problems at all for me) and supports functions all functions we are going to use later</li>
<li>Setup <em>application.ini</em> and <a href="http://framework.zend.com/manual/en/zend.application.quick-start.html#zend.application.quick-start.resources">application resource</a></li>
<li>Generate models from database</li>
<li>Profit!</li>
</ol>
<p>To start with, <strong>download</strong> this <a href="http://dev.juokaz.com/examples/doctrine/doctrine_v1.zip">archive</a> (or get updated version from my public <a href="http://github.com/juokaz/php-examples/tree/master/doctrine-application-resource/">repository</a>). It has everything you will need. Some of the files are quite long so I&#8217;m not going to post them here, it&#8217;s better that you download them and have them ready to be used as the article progresses. </p>
<h5>Create MySQL database</h5>
<p>For MySQL databases I use a product called &#8220;<a href="http://dev.mysql.com/downloads/workbench/5.1.html">MySQL Workbench</a>&#8220;. If you haven&#8217;t tried it I definitely recommend to give it a go &#8211; it basically allows you create a database as a <a href="http://forge.mysql.com/w/images/a/a8/Mysql_workbench_tbl_editor.png">diagram</a> and then export it to sql file or update actual database (can be risky). Since I expect you to have enough knowledge how to create a database I won&#8217;t write anything more &#8211; you can find <a href="http://www.webpronews.com/topnews/2005/06/06/mysql-for-beginners-how-to-create-a-mysql-database">tutorials</a> all over the web.</p>
<h5>Download Doctrine</h5>
<p>After downloading Doctrine extract it to <em>library</em> folder. You should have <em>./library/Doctrine.php</em> in your library folder. Although, you can use <em>svn:externals</em> (if you are using SVN at all) to remove Doctrine code from repository, but in this case you probably need to setup paths in application resource file explain below to use Doctrine_Core if you just get Doctrine folder contents (from <a href="http://svn.doctrine-project.org/tags/1.2.0-BETA3/lib/Doctrine/">here</a>).</p>
<p>Most important point here &#8211; don&#8217;t forget to <a href="http://www.doctrine-project.org/download">download</a> <strong>1.2</strong>, not version 1.1. Even though it doesn&#8217;t have a stable release, 1.1 doesn&#8217;t support models generation as we want them to be (auto-loadable). Also this week all bugs have been fixed which I reported and now models generation works perfectly. From my personal experience, I haven&#8217;t even used 1.1 at all (started with 1.2 when it was in alpha) and didn&#8217;t had any problems, so my recommendation &#8211; use 1.2. </p>
<h5>Setup application.ini and application resource</h5>
<p>From the file listed above open a file called <em>application.ini</em>. Append you current configuration (more on getting Zend Framework project running can be found <a href="http://framework.zend.com/docs/quickstart/create-your-project">here</a>) with settings in that file (leave compiled and cache options to false for now). Doctrine uses DNS strings to connect to a database, there are quite a few <a href="http://www.doctrine-project.org/documentation/manual/1_2/en/introduction-to-connections#dsn,-the-data-source-name:examples">examples</a> in the documentation. If you have used <a href="http://php.net/manual/en/book.pdo.php">PDO</a> before you be very familiar.</p>
<p>In archive there is a file called <em>library/resource.php</em>. Depending on what namespace you use for outside-Zend code, paste it to chosen folder. If you choose to have &#8220;App&#8221; as a namespace, just copy that file to <em>library/App/Application/Resource/Doctrine.php</em>. And don&#8217;t forget to have:</p>

<div class="wp_syntax"><div class="code"><pre class="ini" style="font-family:monospace;">autoloaderNamespaces<span style="">&#91;</span><span style="">&#93;</span> <span style="color: #000066; font-weight:bold;">=</span> <span style="color: #933;">&quot;App_&quot;</span>
pluginpaths.App_Application_Resource <span style="color: #000066; font-weight:bold;">=</span> <span style="color: #933;">&quot;App/Application/Resource&quot;</span></pre></div></div>

<p>in <em>application.ini</em> also, otherwise library code won&#8217;t be auto-loaded. I don&#8217;t recommend putting any code in Zend folder, because it will create tons of problems in the future. Having App or ProjectName library folders allows to have your own code in separate packages which you can use in later projects (I usually have App, ProjectName, CompanyName). </p>
<p>Provided <em>application.ini</em> file isn&#8217;t that much configurable, mainly because it wasn&#8217;t supposed to be released at all. If you are looking for something more dynamic, look no further than this <a href="http://framework.zend.com/wiki/display/ZFPROP/Zend_Application_Resource_Doctrine+-+Matthew+Lurz">proposal</a> in Zend incubator. Nevertheless, my code should work fine &#8211; it has all options required to get you started and have been tweaked with settings which I found to be really useful. </p>
<h5>Generate models from database</h5>
<p>This part is the most awesome. To start, just copy and paste everything from <em>scripts</em> folder in the zip archive to your scripts folder in application (I have scripts folder in the same level as application and library, in the root of project). There actually only two files &#8211; <em>doctrine-cli.php</em> and custom task in <em>Doctrine/Task/GenerateModels.php</em>. You can run doctrine-cli.php like this:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">php doctrine-cli.php</pre></div></div>

<p>and you should get a list of <a href="http://www.doctrine-project.org/documentation/manual/1_2/en/utilities#command-line-interface">all the possible tasks</a> (if you setup everything properly). To run my custom task, append &#8220;generate-models&#8221; to the end of previous command to get:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">php doctrine-cli.php generate-models</pre></div></div>

<p>This task will load your database schema and create all classes (table, base model, model) required for models. Doctrine also supports generating models from <em><a href="http://en.wikipedia.org/wiki/YAML">yaml</a></em> configuration files, though I&#8217;ve never used it before, but configuration should be almost the same.</p>
<h5>It works</h5>
<p>To test the models you can look at the generate code or start coding you application (or even run <em><a href="http://www.doctrine-project.org/documentation/manual/1_2/en/dql-doctrine-query-language">dql</a></em> task from <em>doctrine-cli.php</em>). For example you can test simply like this (adjust by models you have):</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$product</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Model_Product<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$product</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">title</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'Product name'</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$product</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">save</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #990000;">print_r</span><span style="color: #009900;">&#40;</span>Doctrine_Core<span style="color: #339933;">::</span><span style="color: #004000;">getTable</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Model_Product'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">findAll</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">toArray</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>If everything has been configured properly you shouldn&#8217;t get any errors and this code (put it in controller) should output array of your saved data. Because of the settings in application resource, save() method also runs <a href="http://www.doctrine-project.org/documentation/manual/1_2/en/data-validation">validation</a> so if you missed a field and it breaks a <em>not null</em> constrain, this code will throw a validator exception. </p>
<h5>What&#8217;s next?</h5>
<p>This article has enough information to get you started and almost all the code provided it left as simple as possible and open for further modifications. I hope that in coming months code for Doctrine and Zend Framework integration will be completed and you can use Doctrine without any outside code.</p>
<p>Since we have application running now we can dive into actual usage, testing and more advanced stuff. I have code for these also and will be posting more articles very soon, even though the best resource for Doctrine is <a href="http://www.doctrine-project.org/documentation/manual/1_2/en/introduction">documentation</a>. If you have any problems with this code just leave a comment here or find my on twitter (<a href="http://www.twitter.com/juokaz">here</a>) and I will try to explain more.</p>
<p><strong>All parts</strong>:</p>
<ol>
<li><a href="http://dev.juokaz.com/php/zend-framework-and-doctrine-part-1">Zend Framework and Doctrine. Part 1</a></li>
<li><a href="http://dev.juokaz.com/php/zend-framework-and-doctrine-part-2">Zend Framework and Doctrine. Part 2</a></li>
<li><a href="http://dev.juokaz.com/php/zend-framework-and-doctrine-part-3">Zend Framework and Doctrine. Part 3</a></li>
</ol>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://dev.juokaz.com/php/zend-framework-and-doctrine-part-2/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<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>
