<?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>Life Scaling &#187; LAMP</title>
	<atom:link href="http://orensol.com/category/lamp/feed/" rel="self" type="application/rss+xml" />
	<link>http://orensol.com</link>
	<description>Oren Solomianik's Blog</description>
	<lastBuildDate>Mon, 21 Jun 2010 08:10:03 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>ERROR 2026 (HY000): SSL connection error &#8212; The Solution</title>
		<link>http://orensol.com/2010/06/21/error-2026-hy000-ssl-connection-error-the-solution/</link>
		<comments>http://orensol.com/2010/06/21/error-2026-hy000-ssl-connection-error-the-solution/#comments</comments>
		<pubDate>Mon, 21 Jun 2010 08:09:40 +0000</pubDate>
		<dc:creator>Oren</dc:creator>
				<category><![CDATA[LAMP]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[error]]></category>
		<category><![CDATA[ERROR 2026]]></category>
		<category><![CDATA[SSL]]></category>

		<guid isPermaLink="false">http://orensol.com/?p=303</guid>
		<description><![CDATA[<p>If you&#8217;re using mysql server with SSL, and ever encountered this error whenever you try to access the database after it&#8217;s running:</p>
ERROR 2026 (HY000): SSL connection error
<p>One thing to check is if your client certificate and server certificate have the same common name. You&#8217;ve probably went through the <a href="http://dev.mysql.com/doc/refman/5.0/en/secure-create-certs.html" target="_blank">certificate generation procedure</a>, and (like [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re using mysql server with SSL, and ever encountered this error whenever you try to access the database after it&#8217;s running:</p>
<pre>ERROR 2026 (HY000): SSL connection error</pre>
<p>One thing to check is if your client certificate and server certificate have the same common name. You&#8217;ve probably went through the <a href="http://dev.mysql.com/doc/refman/5.0/en/secure-create-certs.html" target="_blank">certificate generation procedure</a>, and (like I did) just entered the same common name for both without noticing.</p>
<p>This is a nasty error message that doesn&#8217;t tell you anything, and there&#8217;s nothing in the error log to imply what went wrong. So remember &#8211; when generating your own certificates for a mysql server, use different common names for client and server!</p>
]]></content:encoded>
			<wfw:commentRss>http://orensol.com/2010/06/21/error-2026-hy000-ssl-connection-error-the-solution/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Improving Wordpress Caching: Batcache and Redirects</title>
		<link>http://orensol.com/2009/09/15/improving-wordpress-caching-batcache-and-redirects/</link>
		<comments>http://orensol.com/2009/09/15/improving-wordpress-caching-batcache-and-redirects/#comments</comments>
		<pubDate>Tue, 15 Sep 2009 13:27:33 +0000</pubDate>
		<dc:creator>Oren</dc:creator>
				<category><![CDATA[LAMP]]></category>
		<category><![CDATA[Memcached]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[batcache]]></category>
		<category><![CDATA[object cache]]></category>
		<category><![CDATA[redirect]]></category>
		<category><![CDATA[Wordpress]]></category>
		<category><![CDATA[wp-super-cache]]></category>
		<category><![CDATA[wp_redirect]]></category>

		<guid isPermaLink="false">http://orensol.com/?p=279</guid>
		<description><![CDATA[<p>There&#8217;s a great plugin for Wordpress called <a href="http://wordpress.org/extend/plugins/batcache/" target="_blank">Batcache</a> by <a href="http://skeltoac.com/" target="_blank">Andy Skelton</a>, which uses memcached as the cache backend for object cache and full page caches. It&#8217;s a great piece of code, and using it is a must if you want a scalable distributed cache for your Wordpress install (avoiding the local [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignright size-medium wp-image-285" src="http://orensol.com/files/2009/09/BatmanAccent2-215x300.jpg" alt="Batman" width="215" height="300" />There&#8217;s a great plugin for Wordpress called <a href="http://wordpress.org/extend/plugins/batcache/" target="_blank">Batcache</a> by <a href="http://skeltoac.com/" target="_blank">Andy Skelton</a>, which uses memcached as the cache backend for object cache and full page caches. It&#8217;s a great piece of code, and using it is a must if you want a scalable distributed cache for your Wordpress install (avoiding the local file system caching <a href="http://wordpress.org/extend/plugins/wp-super-cache/" target="_blank">WP-Super-Cache</a> offers).</p>
<p>I&#8217;ve been running batcache for a while, and noticed that although I set up a query-heavy homepage to be cached for a long while, the homepage query was still running every couple of minutes. So after some digging and logging I came to realize that batcache was missing an important part &#8212; caching redirects.</p>
<p>Why is it important to cache redirects? Here&#8217;s an example. If I go to http://example.com/, my homepage will be cached. But when I go to http://www.example.com/, the homepage query still runs. This is because the default www to no-www redirect happens at &#8216;template-redirect&#8217; action time (with canonical_redirect()), which occurs after the main posts query is run. And, batcache wouldn&#8217;t cache the redirect itself nor would it associate the www with the no-www version (it differentiates pages by a couple of parameters, including HTTP_HOST, which is different in this case). So any request to http://www.example.com would actually first run the homepage query, then redirect to http://example.com and serve the cached version only then.</p>
<p>After a short correspondence with Andy, he committed a <a href="http://plugins.trac.wordpress.org/changeset/153608" target="_blank">changeset</a> to advanced-cache.php (and readme.txt <img src='http://orensol.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  ) that now enables to cache redirects (off by default, be sure to turn it on!). Great to see such responsiveness from a plugin author, and I hope it helps others as well.</p>
]]></content:encoded>
			<wfw:commentRss>http://orensol.com/2009/09/15/improving-wordpress-caching-batcache-and-redirects/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Apache mod_ssl Makes Your Clients Crawl Compared To Nginx SSL Module</title>
		<link>http://orensol.com/2009/07/27/apache-mod_ssl-makes-your-clients-crawl-compared-to-nginx-ssl-module/</link>
		<comments>http://orensol.com/2009/07/27/apache-mod_ssl-makes-your-clients-crawl-compared-to-nginx-ssl-module/#comments</comments>
		<pubDate>Mon, 27 Jul 2009 07:39:26 +0000</pubDate>
		<dc:creator>Oren</dc:creator>
				<category><![CDATA[Browsers]]></category>
		<category><![CDATA[LAMP]]></category>
		<category><![CDATA[Nginx]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[CPU]]></category>
		<category><![CDATA[Load]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[SSL]]></category>
		<category><![CDATA[TLS]]></category>

		<guid isPermaLink="false">http://orensol.com/?p=264</guid>
		<description><![CDATA[<p>The <a href="http://en.wikipedia.org/wiki/Transport_Layer_Security" target="_blank">SSL/TLS</a> process is a heavy one, it involves algorithm negotiation between client and server, key exchanges, cyphering, decyphering and authentication. But what&#8217;s surprising is, that the server you&#8217;re connecting to can directly influence the performance of your client and its CPU consumption.</p>
<p>I had a php command line process spawning child processes and [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://en.wikipedia.org/wiki/Transport_Layer_Security" target="_blank">SSL/TLS</a> process is a heavy one, it involves algorithm negotiation between client and server, key exchanges, cyphering, decyphering and authentication. But what&#8217;s surprising is, that the server you&#8217;re connecting to can directly influence the performance of your client and its CPU consumption.</p>
<p>I had a php command line process spawning child processes and connecting through SSL to a web server, in 2 scenarios. The first scenario was to an out of the box <a href="http://httpd.apache.org/docs/2.2/ssl/" target="_blank">Apache httpd server with mod_ssl</a>, and the second scenario was to an out of the box <a href="http://wiki.nginx.org/NginxHttpSslModule" target="_blank">Nginx with the SSL module</a>. Both were using the exact same box, and were &#8220;out of the box&#8221; meaning I used the default configuration for both.</p>
<p>In the first scenario I was able to spawn no more than 6 (!) php processes before the box running them began to show load, and the CPU queue started to fill up. Each php child was taking between 15%-30% cpu at any given moment.</p>
<p>In the second scenario, I was able to spawn 40 (!!) php child processes without the box being loaded. Each php child was taking around 1.5% cpu.</p>
<p>I&#8217;m no SSL expert, and there might be a way to configure Apache to inflict less load on the connecting client. There is also <a href="http://httpd.apache.org/docs/2.2/mod/mod_ssl.html#sslsessioncache" target="_blank">SSLSessionCache</a> which might relieve load from both the server and the client. But the &#8220;out of the box&#8221; configuration shows that Nginx is a real winner again.</p>
<p>If you can, avoid SSL altogether. If not, terminate it at a front-end before proceeding to Apache.</p>
]]></content:encoded>
			<wfw:commentRss>http://orensol.com/2009/07/27/apache-mod_ssl-makes-your-clients-crawl-compared-to-nginx-ssl-module/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Google Chrome 2, CSS Content-Type and Amazon S3</title>
		<link>http://orensol.com/2009/07/14/google-chrome-2-css-content-type-and-amazon-s3/</link>
		<comments>http://orensol.com/2009/07/14/google-chrome-2-css-content-type-and-amazon-s3/#comments</comments>
		<pubDate>Tue, 14 Jul 2009 11:30:15 +0000</pubDate>
		<dc:creator>Oren</dc:creator>
				<category><![CDATA[Browsers]]></category>
		<category><![CDATA[Cloud Computing]]></category>
		<category><![CDATA[LAMP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[Content-Type]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Google Chrome]]></category>
		<category><![CDATA[Headers]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[S3]]></category>
		<category><![CDATA[WebKit]]></category>

		<guid isPermaLink="false">http://orensol.com/?p=258</guid>
		<description><![CDATA[<p>It seems that ever since <a href="http://gizmodo.com/5265565/google-chrome-2-released-with-much-faster-rendering-full-screen" target="_blank">Google Chrome 2 was released</a>, some of the CSS files I was serving from S3 were not being treated as valid by it, and the page layouts would break because of it. Firefox and IE were fine with it, and Chrome 1 was ok with it too. It [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignright size-full wp-image-260" src="http://orensol.com/files/2009/07/google-chrome-logo.jpg" alt="Google Chrome" width="278" height="198" />It seems that ever since <a href="http://gizmodo.com/5265565/google-chrome-2-released-with-much-faster-rendering-full-screen" target="_blank">Google Chrome 2 was released</a>, some of the CSS files I was serving from S3 were not being treated as valid by it, and the page layouts would break because of it. Firefox and IE were fine with it, and Chrome 1 was ok with it too. It was just Chrome 2.</p>
<p>A little inspection showed that the CSS files I stored on S3 were not being served with a Content-Type header, while from a standard apache web server they were. This combined with the new strictness of Chrome 2 (actually resulting from <a href="http://groups.google.com/group/chromium-discuss/browse_thread/thread/3dae053171a48104/0399d333ca51419b" target="_blank">a new strictness in WebKit</a>) made Chrome not treat these files as actual CSS, and break the page.</p>
<p>So the obvious solution was to make the CSS files be delivered from S3 with the correct &#8220;Content-Type: text/css&#8221; header. Fortunately enough, this is <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTObjectPUT.html" target="_blank">very easy to do with S3 API</a>. Just pass the &#8220;Content-Type:text/css&#8221; header when you&#8217;re uploading the file to S3, and it will be present in the response headers whenever someone requests the file.</p>
<p>Here&#8217;s to the browser wars, that never end and got more complicated with the new player in town, Google Chrome.</p>
]]></content:encoded>
			<wfw:commentRss>http://orensol.com/2009/07/14/google-chrome-2-css-content-type-and-amazon-s3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cross Domain AJAX Calls and Iframe Communication How To</title>
		<link>http://orensol.com/2009/06/07/cross-domain-ajax-calls-and-iframe-communication-how-to/</link>
		<comments>http://orensol.com/2009/06/07/cross-domain-ajax-calls-and-iframe-communication-how-to/#comments</comments>
		<pubDate>Sun, 07 Jun 2009 13:50:37 +0000</pubDate>
		<dc:creator>Oren</dc:creator>
				<category><![CDATA[Browsers]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[LAMP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[communication]]></category>
		<category><![CDATA[cross domain]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[fragment]]></category>
		<category><![CDATA[hash]]></category>
		<category><![CDATA[HTML 5]]></category>
		<category><![CDATA[iframe]]></category>
		<category><![CDATA[postMessage]]></category>
		<category><![CDATA[xd]]></category>
		<category><![CDATA[xd_receiver]]></category>

		<guid isPermaLink="false">http://orensol.com/?p=238</guid>
		<description><![CDATA[<p>I set out to write a short tutorial about cross domain ajax calls and communication between iframes using url hashes (fragments), but I found this <a href="http://softwareas.com/cross-domain-communication-with-iframes" target="_blank">great tutorial by Michael Mahemoff</a> covering the subject inside and out.</p>
<p>It is important to note that the code on his demo uses window.location.hash, although it seems this practice [...]]]></description>
			<content:encoded><![CDATA[<p>I set out to write a short tutorial about cross domain ajax calls and communication between iframes using url hashes (fragments), but I found this <a href="http://softwareas.com/cross-domain-communication-with-iframes" target="_blank">great tutorial by Michael Mahemoff</a> covering the subject inside and out.</p>
<p>It is important to note that the code on his demo uses <code>window.location.hash</code>, although it seems this practice should currently be avoided because of a <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=483304" target="_blank">known</a> <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=378962" target="_blank">open</a> <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=277456" target="_blank">bugs</a> in the way Firefox URI-decodes document.location.hash when getting its value (could be considered an expected behavior and not a bug, but still different than any other browser). <a href="http://static.ak.connect.facebook.com/js/api_lib/v0.4/XdCommReceiver.debug.js" target="_blank">Facebook&#8217;s code</a> uses substring on <code>pathname</code>, and it seems to work cross browser. Facebook also have on their wiki a <a href="http://wiki.developers.facebook.com/index.php/Cross_Domain_Communication" target="_blank">nice visual explanation</a> of how it works:</p>
<p><img src="http://wiki.developers.facebook.com/images/a/a7/Docs_xdcomm.png" alt="" width="495" height="447" /></p>
<p>Until the <a href="https://developer.mozilla.org/En/DOM:window.postMessage" target="_blank">HTML 5 postMessage</a> is widely adopted, we will have to keep using this somewhat of a hack, but it works, that&#8217;s what&#8217;s important.</p>
]]></content:encoded>
			<wfw:commentRss>http://orensol.com/2009/06/07/cross-domain-ajax-calls-and-iframe-communication-how-to/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Network Latency Inside And Across Amazon EC2 Availability Zones</title>
		<link>http://orensol.com/2009/05/24/network-latency-inside-and-across-amazon-ec2-availability-zones/</link>
		<comments>http://orensol.com/2009/05/24/network-latency-inside-and-across-amazon-ec2-availability-zones/#comments</comments>
		<pubDate>Sun, 24 May 2009 12:40:55 +0000</pubDate>
		<dc:creator>Oren</dc:creator>
				<category><![CDATA[Cloud Computing]]></category>
		<category><![CDATA[EC2]]></category>
		<category><![CDATA[LAMP]]></category>
		<category><![CDATA[Scaling]]></category>
		<category><![CDATA[Availability Zones]]></category>
		<category><![CDATA[Clusters]]></category>
		<category><![CDATA[High Availability]]></category>
		<category><![CDATA[latency]]></category>
		<category><![CDATA[Network]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[ping]]></category>
		<category><![CDATA[RTT]]></category>
		<category><![CDATA[throughput]]></category>

		<guid isPermaLink="false">http://orensol.com/?p=226</guid>
		<description><![CDATA[<p>I couldn&#8217;t find any info out there comparing network latency across <a target="_blank" href="http://aws.amazon.com/ec2/">EC2 Availability Zones</a> and inside any single Availability Zone. So I took 6 instances (2 on each US zone), ran some test using a simple ping, and measured 10 Round Trip Times (<a target="_blank" href="http://en.wikipedia.org/wiki/Round-trip_delay_time">RTT</a>). Here are the results.</p>
Single Availablity Zone Latency



Availability [...]]]></description>
			<content:encoded><![CDATA[<p>I couldn&#8217;t find any info out there comparing network latency across <a target="_blank" href="http://aws.amazon.com/ec2/">EC2 Availability Zones</a> and inside any single Availability Zone. So I took 6 instances (2 on each US zone), ran some test using a simple ping, and measured 10 Round Trip Times (<a target="_blank" href="http://en.wikipedia.org/wiki/Round-trip_delay_time">RTT</a>). Here are the results.</p>
<h3>Single Availablity Zone Latency</h3>
<table border="0">
<tbody>
<tr>
<th>Availability Zone</th>
<th>Minimum RTT</th>
<th>Maximum RTT</th>
<th>Average RTT</th>
</tr>
<tr>
<td>us-east-1a</td>
<td>0.215ms</td>
<td>0.348ms</td>
<td>0.263ms</td>
</tr>
<tr>
<td>us-east-1b</td>
<td>0.200ms</td>
<td>0.327ms</td>
<td>0.259ms</td>
</tr>
<tr>
<td>us-east-1c</td>
<td>0.342ms</td>
<td>0.556ms</td>
<td>0.410ms</td>
</tr>
</tbody>
</table>
<p>It seems that at the time of my testing, zone us-east-1c had the worst RTT between 2 instances in it, almost twice as slow as the other 2 zones.</p>
<h3>Cross Availablity Zone Latency</h3>
<table border="0">
<tbody>
<tr>
<th>Availability Zones</th>
<th>Minimum RTT</th>
<th>Maximum RTT</th>
<th>Average RTT</th>
</tr>
<tr>
<td>Between us-east-1a and us-east-1b</td>
<td>0.885ms</td>
<td>1.110ms</td>
<td>0.937ms</td>
</tr>
<tr>
<td>Between us-east-1a and us-east-1c</td>
<td>0.937ms</td>
<td>1.080ms</td>
<td>1.031ms</td>
</tr>
<tr>
<td>Between us-east-1b and us-east-1c</td>
<td>1.060ms</td>
<td>1.250ms</td>
<td>1.126ms</td>
</tr>
</tbody>
</table>
<p>It&#8217;s worth noting that in cross availability zones traffic, the first ping was usually off the chart, so I disregarded it. For example, it could be anywhere between 300ms to 400ms, and the the rest would fall down to ~0.300. Probably some lazy routing techniques by Amazon&#8217;s routers.</p>
<h3>Conclusions</h3>
<ol>
<li>Zones are created different! &#8212; At least at the time of the testing, if you have a cluster on us-east-1b it performs almost twice as fast with regards to RTT between machines than a cluster on us-east-1c.</li>
<li>Cross Availability Zones latency can be 6 times higher than inner zone latency. For a network intensive application, better keep your instances crowded in the same zone.</li>
</ol>
<p>I should probably also make a throughput comparison between and across Availability Zones. I promise to share if I get to test it.</p>
]]></content:encoded>
			<wfw:commentRss>http://orensol.com/2009/05/24/network-latency-inside-and-across-amazon-ec2-availability-zones/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Connecting Several PHP Processes To The Same MySQL Transaction</title>
		<link>http://orensol.com/2009/04/20/connecting-several-php-processes-to-the-same-mysql-transaction/</link>
		<comments>http://orensol.com/2009/04/20/connecting-several-php-processes-to-the-same-mysql-transaction/#comments</comments>
		<pubDate>Mon, 20 Apr 2009 09:55:32 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[LAMP]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Commit]]></category>
		<category><![CDATA[InnoDB]]></category>
		<category><![CDATA[Multi-Process]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Rollback]]></category>
		<category><![CDATA[Semaphore]]></category>
		<category><![CDATA[Transaction]]></category>
		<category><![CDATA[XML-RPC]]></category>

		<guid isPermaLink="false">http://orensol.com/?p=198</guid>
		<description><![CDATA[<p>The following concept is still under examination, but my initial tests proved successful, so I thought it&#8217;s time to share.</p>
<p>Here is a problem: There is a batch job reading remote data through XML-RPC, and updating a local MySQL database according to the XML-RPC responses. The db is InnoDB, and the entire batch job should be [...]]]></description>
			<content:encoded><![CDATA[<p>The following concept is still under examination, but my initial tests proved successful, so I thought it&#8217;s time to share.</p>
<p>Here is a problem: There is a batch job reading remote data through XML-RPC, and updating a local MySQL database according to the XML-RPC responses. The db is InnoDB, and the entire batch job should be transacted. That is, in any case of failure, there should be rollback, and on success there should be commit.</p>
<p>So, the simple way is of course a single process script that uses a linear workflow:</p>
<ol>
<li>START TRANSACTION locally.</li>
<li>Make XML-RPC request, fetch data.</li>
<li>Insert data into db as needed.</li>
<li>Repeat 2-3 until Error or Finish.</li>
<li>If Error ROLLBACK, if Finish COMMIT.</li>
</ol>
<p>This works, but you may notice a bottleneck, being the XML-RPC request. It&#8217;s using http, and it&#8217;s connecting to a remote server. Sometimes the XML-RPC server also takes time to perform the work that generates the response. Add the network latency, and you get a single process that most of the time sits idle and waits for response.</p>
<p>So if we have a process that just sits and waits most of the time, let&#8217;s spread its work over several processes, and assume that while most of the processes will be waiting, at least one can be free to deal with the local database. This way we will get maximum utilization of our resources.</p>
<p>So the multi-process workflow:</p>
<ol>
<li>START TRANSACTION locally.</li>
<li>Fork children as necessary.</li>
<li>From child, make XML-RPC request, fetch data.</li>
<li>From child, acquire database access through semaphore.</li>
<li>From child, insert data into db as needed.</li>
<li>From child, release database access through semaphore.</li>
<li>From child, repeat 3-6 until Error or Finish.</li>
<li>From parent, monitor children until Error or Finish.</li>
<li>From parent, if Error ROLLBACK, if FINISH COMMIT.</li>
</ol>
<p>Now, the workflow seems all and well in theory, but can it work in practice? Can we connect to the same transaction from several different PHP processes?</p>
<p>I was surprised to find out that the answer is positive. As long as all processes share the same connection resource, they all use the same connection. And in MySQL, <a href="http://dev.mysql.com/doc/refman/5.0/en/commit.html">the same connection means the same transaction</a>, given that a transaction was started and not yet committed or rolled back (either explicitly or implictly).</p>
<p>The secret is to create the connection resource with the parent, and when <a href="http://us.php.net/manual/en/function.pcntl-fork.php">forking</a> children, they have a reference to the same connection. The caveat is that they must access the resource atomically, otherwise unexpected behavior occurs (usually the connection hangs, I am guessing that it is when one child tries to read() from the socket and the other to write() to it). So in order to streamline the access to the db connection, we use a <a href="http://us.php.net/manual/en/book.sem.php">semaphore</a>. Each child can access the connection only when it&#8217;s available, and it&#8217;s blocking if not available.</p>
<p>In the end of the workflow, our parent process acts much like a Transaction Manager in an <a href="http://dev.mysql.com/doc/refman/5.0/en/xa.html" target="_blank">XA Transaction</a>, and according to what the children report, decides whether to commit or rollback.</p>
<p>Here is a proof of concept code (not tested in this version, but similar code tested and succeeded):</p>
<h3>The DBHandler Class</h3>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> DBHandler
<span style="color: #009900;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$link</span><span style="color: #339933;">;</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$result</span><span style="color: #339933;">;</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$sem</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">const</span> SEMKEY <span style="color: #339933;">=</span> <span style="color: #0000ff;">'123456'</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #000088;">$host</span><span style="color: #339933;">,</span> <span style="color: #000088;">$dbname</span><span style="color: #339933;">,</span> <span style="color: #000088;">$user</span><span style="color: #339933;">,</span> <span style="color: #000088;">$pass</span><span style="color: #339933;">,</span> <span style="color: #000088;">$new_link</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">false</span><span style="color: #339933;">,</span> <span style="color: #000088;">$client_flags</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">link</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_connect</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$host</span><span style="color: #339933;">,</span> <span style="color: #000088;">$user</span><span style="color: #339933;">,</span> <span style="color: #000088;">$pass</span><span style="color: #339933;">,</span> <span style="color: #000088;">$new_link</span><span style="color: #339933;">,</span> <span style="color: #000088;">$client_flags</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">link</span><span style="color: #009900;">&#41;</span>
			throw <span style="color: #000000; font-weight: bold;">new</span> Exception <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Could not connect to db. MySQL error was: '</span><span style="color: #339933;">.</span> <span style="color: #990000;">mysql_error</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$isDb</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_select_db</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$dbname</span><span style="color: #339933;">,</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">link</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$isDb</span><span style="color: #009900;">&#41;</span>
			throw <span style="color: #000000; font-weight: bold;">new</span> Exception <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Could not select db. MySQL error was: '</span><span style="color: #339933;">.</span> <span style="color: #990000;">mysql_error</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">function</span> enterSemaphore<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">sem</span> <span style="color: #339933;">=</span> <span style="color: #990000;">sem_get</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">SEMKEY</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #990000;">sem_acquire</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">sem</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">function</span> exitSemaphore<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #990000;">sem_release</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">sem</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> query<span style="color: #009900;">&#40;</span><span style="color: #000088;">$sql</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">enterSemaphore</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">result</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_unbuffered_query</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$sql</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">link</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">result</span><span style="color: #009900;">&#41;</span>
			throw <span style="color: #000000; font-weight: bold;">new</span> Exception <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Could not query: {'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$sql</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'}. MySQL error was: '</span><span style="color: #339933;">.</span> <span style="color: #990000;">mysql_error</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">result</span> <span style="color: #339933;">===</span> <span style="color: #000000; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span>
		<span style="color: #009900;">&#123;</span>
			<span style="color: #666666; font-style: italic;">// INSERT, UPDATE, etc..., no result set</span>
			<span style="color: #000088;">$ret</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">true</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
		<span style="color: #b1b100;">else</span>
		<span style="color: #009900;">&#123;</span>
			<span style="color: #666666; font-style: italic;">// SELECT etc..., we have a result set</span>
			<span style="color: #000088;">$retArray</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$row</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_fetch_assoc</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">result</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
				<span style="color: #000088;">$retArray</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$row</span><span style="color: #339933;">;</span>
			<span style="color: #990000;">mysql_free_result</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">result</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #000088;">$ret</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$retArray</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
&nbsp;
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">exitSemaphore</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #b1b100;">return</span> <span style="color: #000088;">$ret</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> beginTransaction<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'SET AUTOCOMMIT = 0'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'SET NAMES utf8'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'START TRANSACTION'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> rollback<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'ROLLBACK'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> commit<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'COMMIT'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<h3>The Forking Process</h3>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$pid</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'initial'</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$maxProcs</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$argv</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$maxProcs</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	 <span style="color: #000088;">$maxProcs</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">3</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000088;">$runningProcs</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// will be $runningProcs[pid] = status;</span>
<span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'PRIORITY_SUCCESS'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'-20'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'PRIORITY_FAILURE'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'-19'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
try 
<span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$dbh</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> DBHandler<span style="color: #009900;">&#40;</span>DBHOST<span style="color: #339933;">,</span>DBNAME<span style="color: #339933;">,</span>DBUSER<span style="color: #339933;">,</span>DBPASS<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #000088;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">beginTransaction</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">// fork all needed children</span>
		<span style="color: #000088;">$currentProcs</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$pid</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$currentProcs</span> <span style="color: #339933;">&lt;</span> <span style="color: #000088;">$maxProcs</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
		<span style="color: #009900;">&#123;</span>
			<span style="color: #000088;">$pid</span> <span style="color: #339933;">=</span> pcntl_fork<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #000088;">$currentProcs</span><span style="color: #339933;">++;</span>
			<span style="color: #000088;">$runningProcs</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$pid</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
&nbsp;
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$pid</span><span style="color: #339933;">==-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span>
		<span style="color: #009900;">&#123;</span>
			throw <span style="color: #000000; font-weight: bold;">new</span> Exception <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;fork failed&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
		<span style="color: #b1b100;">elseif</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$pid</span><span style="color: #009900;">&#41;</span>
		<span style="color: #009900;">&#123;</span>
			<span style="color: #666666; font-style: italic;">// parent</span>
			<span style="color: #990000;">echo</span> <span style="color: #0000ff;">&quot;+++ in parent +++<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
			<span style="color: #990000;">echo</span> <span style="color: #0000ff;">&quot;+++ children are: &quot;</span> <span style="color: #339933;">.</span> <span style="color: #990000;">implode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;,&quot;</span><span style="color: #339933;">,</span><span style="color: #990000;">array_keys</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$runningProcs</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
&nbsp;
			<span style="color: #666666; font-style: italic;">// wait for children</span>
			<span style="color: #666666; font-style: italic;">// NOTE -- here we do it with priority signaling</span>
			<span style="color: #666666; font-style: italic;">// @TBD -- posix signaling or IPC signaling.</span>
			<span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">in_array</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span><span style="color: #000088;">$runningProcs</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
			<span style="color: #009900;">&#123;</span>
				<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">in_array</span><span style="color: #009900;">&#40;</span>PRIORITY_FAILURE<span style="color: #339933;">,</span><span style="color: #000088;">$runningProcs</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
				<span style="color: #009900;">&#123;</span>
					<span style="color: #990000;">echo</span> <span style="color: #0000ff;">&quot;+++ some child failed, finish waiting for children +++<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
					<span style="color: #b1b100;">break</span><span style="color: #339933;">;</span>
				<span style="color: #009900;">&#125;</span>
				<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$runningProcs</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$child_pid</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$status</span><span style="color: #009900;">&#41;</span>
				<span style="color: #009900;">&#123;</span>
					<span style="color: #000088;">$runningProcs</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$child_pid</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> pcntl_getpriority<span style="color: #009900;">&#40;</span><span style="color: #000088;">$child_pid</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
					<span style="color: #990000;">echo</span> <span style="color: #0000ff;">&quot;+++ children status: <span style="color: #006699; font-weight: bold;">$child_pid</span>, <span style="color: #006699; font-weight: bold;">$status</span> +++<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
				<span style="color: #009900;">&#125;</span>
				<span style="color: #990000;">echo</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
				<span style="color: #990000;">sleep</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
&nbsp;
			<span style="color: #990000;">echo</span> <span style="color: #0000ff;">&quot;+++ checking if should commit or rollback +++<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
			<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">in_array</span><span style="color: #009900;">&#40;</span>PRIORITY_FAILURE<span style="color: #339933;">,</span><span style="color: #000088;">$runningProcs</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span> <span style="color: #990000;">in_array</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span><span style="color: #000088;">$runningProcs</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
			<span style="color: #009900;">&#123;</span>		
				<span style="color: #990000;">echo</span> <span style="color: #0000ff;">&quot;+++ some child had problem! rollback! +++<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
				<span style="color: #000088;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">rollback</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
			<span style="color: #b1b100;">else</span>
			<span style="color: #009900;">&#123;</span>
				<span style="color: #990000;">echo</span> <span style="color: #0000ff;">&quot;+++ all my sons successful! committing! +++<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
				<span style="color: #000088;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">commit</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
&nbsp;
			<span style="color: #666666; font-style: italic;">// signal all children to exit</span>
			<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$runningProcs</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$child_pid</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$status</span><span style="color: #009900;">&#41;</span>
			<span style="color: #009900;">&#123;</span>
				<span style="color: #990000;">echo</span> <span style="color: #0000ff;">&quot;+++ killing child <span style="color: #006699; font-weight: bold;">$child_pid</span> +++<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
				<span style="color: #990000;">posix_kill</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$child_pid</span><span style="color: #339933;">,</span>SIGTERM<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
		<span style="color: #009900;">&#125;</span>
		<span style="color: #b1b100;">else</span>
		<span style="color: #009900;">&#123;</span>
			<span style="color: #666666; font-style: italic;">// child</span>
			<span style="color: #000088;">$mypid</span> <span style="color: #339933;">=</span> <span style="color: #990000;">getmypid</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #990000;">echo</span> <span style="color: #0000ff;">&quot;--- in child <span style="color: #006699; font-weight: bold;">$mypid</span> ---<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
			<span style="color: #666666; font-style: italic;">//sleep(1);</span>
			<span style="color: #990000;">echo</span> <span style="color: #0000ff;">&quot;--- child <span style="color: #006699; font-weight: bold;">$mypid</span> current priority is &quot;</span> <span style="color: #339933;">.</span> pcntl_getpriority<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot; ---<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
&nbsp;
			<span style="color: #666666; font-style: italic;">// NOTE -- following queries do not work, for example only</span>
			<span style="color: #000088;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;select ...&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
			<span style="color: #990000;">echo</span> <span style="color: #0000ff;">&quot;--- child <span style="color: #006699; font-weight: bold;">$mypid</span> finished, setting priority to success and halting ---<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
			pcntl_setpriority<span style="color: #009900;">&#40;</span>PRIORITY_SUCCESS<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span>
			<span style="color: #009900;">&#123;</span>
				<span style="color: #990000;">echo</span> <span style="color: #0000ff;">&quot;--- child <span style="color: #006699; font-weight: bold;">$mypid</span> waiting to be killed ---<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
				<span style="color: #990000;">sleep</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
		<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span> 
catch <span style="color: #009900;">&#40;</span>Exception <span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span> 
<span style="color: #009900;">&#123;</span>
	<span style="color: #666666; font-style: italic;">// output error</span>
	<span style="color: #990000;">print</span> <span style="color: #0000ff;">&quot;Error!: &quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$e</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getMessage</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// if parent -- rollback, signal children to exit</span>
	<span style="color: #666666; font-style: italic;">// if child  -- make priority failure to signal</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$pid</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;">// rollback</span>
		<span style="color: #000088;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">rollBack</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$runningProcs</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$child_pid</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$status</span><span style="color: #009900;">&#41;</span>
			<span style="color: #990000;">posix_kill</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$child_pid</span><span style="color: #339933;">,</span>SIGTERM<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
	<span style="color: #b1b100;">else</span>
	<span style="color: #009900;">&#123;</span>
		pcntl_setpriority<span style="color: #009900;">&#40;</span>PRIORITY_FAILURE<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$mypid</span> <span style="color: #339933;">=</span> <span style="color: #990000;">getmypid</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span>
		<span style="color: #009900;">&#123;</span>
			<span style="color: #990000;">echo</span> <span style="color: #0000ff;">&quot;--- child <span style="color: #006699; font-weight: bold;">$mypid</span> waiting to be killed ---<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
			<span style="color: #990000;">sleep</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Well, all of this sounds well, and also worked well on a development environment. But it should be taken out of the lab and tested on a production environment. Once I give it a shot, I will update with benchmarks.</p>
]]></content:encoded>
			<wfw:commentRss>http://orensol.com/2009/04/20/connecting-several-php-processes-to-the-same-mysql-transaction/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Zend Framework Database Admin</title>
		<link>http://orensol.com/2009/04/02/zend-framework-database-admin/</link>
		<comments>http://orensol.com/2009/04/02/zend-framework-database-admin/#comments</comments>
		<pubDate>Thu, 02 Apr 2009 11:23:58 +0000</pubDate>
		<dc:creator>Oren</dc:creator>
				<category><![CDATA[LAMP]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Admin]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[DB]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[Interface]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[phpMyAdmin]]></category>
		<category><![CDATA[zdbform]]></category>
		<category><![CDATA[Zend]]></category>

		<guid isPermaLink="false">http://orensol.com/?p=179</guid>
		<description><![CDATA[<p>If you&#8217;re looking for a simple tool that uses Zend Framework&#8217;s robust database classes (such as Zend_Db and Zend_Db_Table), you can check out <a href="http://www.gregphoto.net/index.php/2006/03/25/zdbform-simple-database-admin-forms-with-the-zend-framework/" target="_blank">zdbform</a>. It&#8217;s a short yet effective library that let&#8217;s you perform simple administration tasks on your database, with minimal coding.</p>
<p>It&#8217;s not a full blown phpMyAdmin, but it&#8217;s a simple way [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re looking for a simple tool that uses Zend Framework&#8217;s robust database classes (such as Zend_Db and Zend_Db_Table), you can check out <a href="http://www.gregphoto.net/index.php/2006/03/25/zdbform-simple-database-admin-forms-with-the-zend-framework/" target="_blank">zdbform</a>. It&#8217;s a short yet effective library that let&#8217;s you perform simple administration tasks on your database, with minimal coding.</p>
<p>It&#8217;s not a full blown phpMyAdmin, but it&#8217;s a simple way to view, edit and add your tables rows in a web interface. Also, don&#8217;t expect it to scale, because I am sure this library was written to serve some quick table administration needs, and that it is not ready to handle large datasets. But, it is very convenient if you have a small database to administer.</p>
<p>I implemented it with the Zend MVC components, and following is a brief overview.</p>
<p>In the front controller, or front plugin, or any class that your controller subclasses:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">db</span> <span style="color: #339933;">=</span> Zend_Db<span style="color: #339933;">::</span><span style="color: #004000;">factory</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Pdo_Mysql'</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
				<span style="color: #0000ff;">'host'</span>     <span style="color: #339933;">=&gt;</span> DB_HOST<span style="color: #339933;">,</span>
				<span style="color: #0000ff;">'username'</span> <span style="color: #339933;">=&gt;</span> DB_USER<span style="color: #339933;">,</span>
				<span style="color: #0000ff;">'password'</span> <span style="color: #339933;">=&gt;</span> DB_PASS<span style="color: #339933;">,</span>
				<span style="color: #0000ff;">'dbname'</span>   <span style="color: #339933;">=&gt;</span> DB_NAME
		<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
Zend_Db_Table_Abstract<span style="color: #339933;">::</span><span style="color: #004000;">setDefaultAdapter</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">db</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Then set your controller and view scripts as necessary. Let&#8217;s say you have two tables to admin, &#8220;clients&#8221; and &#8220;history&#8221;. First make sure they are declared as subclasses of Zend_Db_Table:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">require_once</span> <span style="color: #0000ff;">&quot;Zend/Db/Table/Abstract.php&quot;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> Clients <span style="color: #000000; font-weight: bold;">extends</span> Zend_Db_Table_Abstract
<span style="color: #009900;">&#123;</span>
    protected <span style="color: #000088;">$_name</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'clients'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> History <span style="color: #000000; font-weight: bold;">extends</span> Zend_Db_Table_Abstract
<span style="color: #009900;">&#123;</span>
    protected <span style="color: #000088;">$_name</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'history'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Your controller would look like:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">require_once</span> <span style="color: #0000ff;">&quot;Zend/Controller/Action.php&quot;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> AdminController <span style="color: #000000; font-weight: bold;">extends</span> Zend_Controller_Action
<span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> init<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">require_once</span> <span style="color: #0000ff;">'zdbform/zdbform.class.php'</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">require_once</span> <span style="color: #0000ff;">'zdbform/zdbform_widgets.class.php'</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">require_once</span> <span style="color: #0000ff;">'zdbform/zdbform_validations.php'</span><span style="color: #339933;">;</span>
&nbsp;
		parent<span style="color: #339933;">::</span><span style="color: #004000;">init</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">view</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">headLink</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">appendStylesheet</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/zdbform/zdbform.css'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_helper<span style="color: #339933;">-&gt;</span><span style="color: #004000;">viewRenderer</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'index'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> indexAction<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> clientsAction<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">view</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">dbform</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Zdbform<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Clients'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">view</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">dbform</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setWidget</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'description'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'textarea'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">view</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">dbform</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">processForms</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> historyAction<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">view</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">dbform</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Zdbform<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'History'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">view</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">dbform</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">processForms</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>And the single view script you need is admin/index.phtml:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #990000;">echo</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">headLink</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">include_once</span> <span style="color: #0000ff;">&quot;Zend/Filter/Word/CamelCaseToDash.php&quot;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">include_once</span> <span style="color: #0000ff;">&quot;Zend/Filter/Word/CamelCaseToUnderscore.php&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$cctd</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Zend_Filter_Word_CamelCaseToDash<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$cctu</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Zend_Filter_Word_CamelCaseToUnderscore<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$classes</span> <span style="color: #339933;">=</span> <span style="color: #990000;">get_declared_classes</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$classes</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$class</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">is_subclass_of</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$class</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'Zend_Db_Table_Abstract'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">?&gt;</span>
		&lt;a href=&quot;/admin/<span style="color: #000000; font-weight: bold;">&lt;?=</span> <span style="color: #990000;">strtolower</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$cctd</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">filter</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$class</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&quot;&gt;<span style="color: #000000; font-weight: bold;">&lt;?=</span> <span style="color: #990000;">strtolower</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$cctu</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">filter</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$class</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&lt;/a&gt;&amp;nbsp;&amp;nbsp;
	<span style="color: #000000; font-weight: bold;">&lt;?php</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">dbform</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">?&gt;</span>
	&lt;h1&gt;Table: <span style="color: #000000; font-weight: bold;">&lt;?=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">dbform</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">tableName</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&lt;/h1&gt;
	<span style="color: #000000; font-weight: bold;">&lt;?php</span>
	<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">dbform</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">showForms</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">dbform</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">showTable</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>There were also a couple things that needed changing in the zdbform class itself:</p>
<ul>
<li>Replace all PHP_SELF with REQUEST_URL. On the mvc case, PHP_SELF is empty or index.php, and we don&#8217;t want all the forms posted there, we want them to go back to /admin/clients or /admin/history</li>
<li>After this line

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">pk</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$tableInfo</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'primary'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></pre></div></div>

<p>I had to add this:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">is_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">pk</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
	<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">pk</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">pk</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></pre></div></div>

</li>
<li>zdbform-&gt;orderBy is treated as a single column, of you want multiple column sorting you have to hack a bit with getAllRows().</li>
</ul>
<p>That&#8217;s it, point your browser to /admin and you&#8217;re good to go. In a very short time and with a little bit of code, you can get something similar to a stripped down version of phpMyAdmin, using the power of Zend Framework.</p>
]]></content:encoded>
			<wfw:commentRss>http://orensol.com/2009/04/02/zend-framework-database-admin/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Make Sure Those 404 and 500 Responses Are Long Enough</title>
		<link>http://orensol.com/2009/02/17/make-sure-those-404-and-500-responses-are-long-enough/</link>
		<comments>http://orensol.com/2009/02/17/make-sure-those-404-and-500-responses-are-long-enough/#comments</comments>
		<pubDate>Tue, 17 Feb 2009 15:40:52 +0000</pubDate>
		<dc:creator>Oren</dc:creator>
				<category><![CDATA[Browsers]]></category>
		<category><![CDATA[LAMP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[404]]></category>
		<category><![CDATA[500]]></category>
		<category><![CDATA[Content-Length]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[IE7]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[Reponse]]></category>
		<category><![CDATA[Status Code]]></category>

		<guid isPermaLink="false">http://orensol.com/?p=116</guid>
		<description><![CDATA[<p>Internet Explorer is a term you can&#8217;t stay indifferent to. Whenever you hear somebody say it, they either say it with a respectful awe, or they utter it with a developer&#8217;s pain. Today I was on the latter side of this indifference, when I fought a Wordpress bug.</p>
<p>Internet Explorer <a href="http://support.microsoft.com/kb/q218155/" target="_blank">expects a minimum sized [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft" src="http://www.ucc.ie/en/tcentre/InternetExplorer7/imgcol,40650,en.jpg" alt="" width="150" height="150" />Internet Explorer is a term you can&#8217;t stay indifferent to. Whenever you hear somebody say it, they either say it with a respectful awe, or they utter it with a developer&#8217;s pain. Today I was on the latter side of this indifference, when I fought a Wordpress bug.</p>
<p>Internet Explorer <a href="http://support.microsoft.com/kb/q218155/" target="_blank">expects a minimum sized response content</a> when receiving HTTP errors in the 400-500 area. If the content size received in the response is lower than this minimum, an arguably &#8220;Friendly HTTP Error Message&#8221; takes over, and displayed instead of the content.</p>
<p>This (rather obtrusive) behavior doesn&#8217;t go well with Wordpress wp_die() function, which is invoked on many occasions throughout the Wordpress code. This function sets the HTTP response status to 500, and then sends a very short html code containing any error message you&#8217;d like. These error messages are usually no more than a brief sentence, which results in a very small response content.</p>
<p>So take an IE7 browser, and try to post an empty comment on any Wordpress that is not upgraded to version 2.7 yet. See that friendly browser message? The same in Firefox produces the expected &#8220;Error: please type a comment.&#8221; message. Wordpress had already <a href="http://core.trac.wordpress.org/browser/trunk/wp-includes/functions.php?rev=10312" target="_blank">fixed this in 2.7</a> (you can copy their workaround) after some <a href="http://wordpress.org/support/topic/187581?replies=7" target="_blank">bug</a> <a href="http://wordpress.org/support/topic/144438?replies=7" target="_blank">reports</a>, but any installation prior to 2.7 which is still not upgraded (and many <a href="http://mu.wordpress.org/" target="_blank">MU</a> installations which always trail behind in the version releases) has this.</p>
<p>For any application other than Wordpress, be sure to go over <a href="http://www.404-error-page.com/404-error-page-too-short-problem-microsoft-ie.shtml" target="_blank">this table of minimum content size</a> for each HTTP status error code, and make sure your responses are long enough.</p>
<p>Apparently, sometimes being laconic is bad.</p>
]]></content:encoded>
			<wfw:commentRss>http://orensol.com/2009/02/17/make-sure-those-404-and-500-responses-are-long-enough/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Memcached Storage Class for Zend_OpenId_Provider</title>
		<link>http://orensol.com/2009/02/05/memcached-storage-class-for-zend_openid_provider/</link>
		<comments>http://orensol.com/2009/02/05/memcached-storage-class-for-zend_openid_provider/#comments</comments>
		<pubDate>Thu, 05 Feb 2009 16:03:08 +0000</pubDate>
		<dc:creator>Oren</dc:creator>
				<category><![CDATA[LAMP]]></category>
		<category><![CDATA[Memcached]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://orensol.com/?p=83</guid>
		<description><![CDATA[<p>I experimented a bit with creating an <a href="http://openid.net/" target="_blank">OpenID</a> provider entity using <a href="http://framework.zend.com/manual/en/zend.openid.provider.html" target="_blank">Zend_OpenId_Provider</a>. It was not a hard task to implement, but seeing that the default storage class is file based made me shiver. There are two reasons why I hate anything to do with local disk access:</p>

It&#8217;s s-l-o-w-w-w. Disk I/O is [...]]]></description>
			<content:encoded><![CDATA[<p>I experimented a bit with creating an <a href="http://openid.net/" target="_blank">OpenID</a> provider entity using <a href="http://framework.zend.com/manual/en/zend.openid.provider.html" target="_blank">Zend_OpenId_Provider</a>. It was not a hard task to implement, but seeing that the default storage class is file based made me shiver. There are two reasons why I hate anything to do with local disk access:</p>
<ul>
<li>It&#8217;s s-l-o-w-w-w. Disk I/O is the pitfall of performance for web applications. Avoid when possible.</li>
<li>It&#8217;s usually not fitting for clustered environments. If you have a cluster of application servers (running php for example), and you are using disk access, it will only update the disk on the application node you were directed to in the current request. On the next request to the application, you might not be directed to the same application server (if the load balancing is not ip-hashed or session based). Of course this is not always the case &#8211; sometimes there&#8217;s a network storage, sometimes several directories can be rsynced across the cluster &#8212; but as a rule of thumb, local disk access is not good for clustered environments.</li>
</ul>
<p>So the obvious thing when implementing an OpenID provider using Zend Framework is to change the default Storage class, and use a storage that&#8217;s not a traditional filesystem. Before jumping into using a MySQL backend for this, and coming up with a full blown OpenID provider, I needed something quick that will replace disk storage, but will also work on a clustered environment. So it was really natural to turn to <a href="http://www.danga.com/memcached/" target="_blank">memcached</a>.</p>
<p>I am not sure that using memcached as a final storage engine for an OpenID provider is really a good call. Caches expire, keys are being purged, and whole memcached nodes can evaporate. However, it might fit a provider that is not a full blown OpenID service. If you can find a way to addUser() to the storage every time before a user starts an authentication attempt (and it&#8217;s not that difficult, considering the 10-stage authentication process), and if you can handle associations and other info being deleted from time to time (and if your users can handle it&#8230;) &#8212; memcached storage can be what you need.</p>
<p>In any case, even if just for testing purposes, here&#8217;s a <a href="http://orensol.files.wordpress.com/2009/02/openid_provider_storage_memcached.doc" target="_self">memcached storage class for Zend Framework&#8217;s OpenID Provider</a> I wrote (it&#8217;s a plain text file, apologies for the doc/msword file type).</p>
]]></content:encoded>
			<wfw:commentRss>http://orensol.com/2009/02/05/memcached-storage-class-for-zend_openid_provider/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
<!-- WP Super Cache is installed but broken. The path to wp-cache-phase1.php in wp-content/advanced-cache.php must be fixed! -->