<?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>PHP vs .Net</title>
	<atom:link href="http://www.phpvs.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.phpvs.net</link>
	<description>ASP.Net and PHP go head to head</description>
	<lastBuildDate>Sat, 24 Dec 2011 18:20:11 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>HTTP Signed Requests with PHP</title>
		<link>http://www.phpvs.net/2011/12/24/http-signed-requests-with-php/</link>
		<comments>http://www.phpvs.net/2011/12/24/http-signed-requests-with-php/#comments</comments>
		<pubDate>Sat, 24 Dec 2011 18:19:27 +0000</pubDate>
		<dc:creator>blake</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://www.phpvs.net/?p=268</guid>
		<description><![CDATA[I thought I'd write a quick primer on a basic implementation of HTTP request signing with PHP. I see a lot of posts dealing with the topic, especially by people writing homebrew REST services. What are signed HTTP requests? Signed HTTP requests are simply a normal HTTP request, such as a GET or a POST, [...]]]></description>
			<content:encoded><![CDATA[<p>I thought I'd write a quick primer on a basic implementation of HTTP request signing with PHP. I see a lot of posts dealing with the topic, especially by people writing homebrew REST services.</p>
<p><a href="http://www.phpvs.net/wp-content/uploads/2011/12/digitalsecurity.jpg"><img src="http://www.phpvs.net/wp-content/uploads/2011/12/digitalsecurity.jpg" alt="" title="Digital Fingerprint" width="353" height="281" class="aligncenter size-full wp-image-288" /></a></p>
<h2>What are signed HTTP requests?</h2>
<p>Signed HTTP requests are simply a normal HTTP request, such as a GET or a POST, that happens to include a signature as part of the request.  A signature is just a string of characters generated in a meaningful way.  This signature can be used by the receiving party (ie. a REST service) to validate the request and ensure that it hasn't been tampered with.</p>
<h4>What are signed requests good for?</h4>
<p>In a nutshell, validating an HTTP request where restricted access to resources are necessary. For example, a service that allows someone to update their personal information needs to ensure that people can only update <em>their own</em> personal information. Signed requests ensure that the service that receives the data can verify that the sender is who they claim they are (or at least possesses the proper secret key, a de-facto assumption it is the right person).</p>
<p>Obviously, having someone log in and create a session is another method of verifying user identity, however, this is not always efficient or possible, especially with web services. As an example, every Facebook application developer gets a secret key when they create an application on Facebook. When Facebook sends information to someone's application, it will include a signed request that is only valid with that developer's key.  By checking the signature, a developer can verify that a request came from Facebook, and isn't someone trying to fool their application.  They also don't need to provide a complicated session procedure or have Facebook "log in" to their application; the signed request is enough.</p>
<h4> What <em>aren't</em> signed requests good for?</h4>
<p>Signed requests are not a form of encryption. If the data being sent is sensitive in nature, such that you wouldn't want it being sniffed in transit over a network connection, then SSL encrypted communication (HTTPS) is the way to go. For simple REST services however, often you just need to limit requests based on a user or other similar scope, and signed requests are sufficient for that.</p>
<h2>A problem that signed requests can solve</h2>
<p>Here is an example situation that has a security problem that can be solved by the use of signed requests. Let's say you operate a network of beer brewing web sites, and the brewers are allowed to send updates via a REST service you have provided. Each brewer has their own user id that they get when they sign up to your service. <strong>Bob's Brewery</strong> (user id <strong>1234</strong>) wants to update their email address. The simplest of implementations might allow for a request to be sent like this: <code>/user/update?email=newbob@example.com&amp;userid=1234</code>. However, if this was the only thing the REST service needed to update an email address, it would be trivial to cause serious mayhem. For example, <strong>Mr. Evil's Brewery</strong> could send in a simple request to change Bob's email address, just by finding Bob's ID somewhere, or even trying random ones:</p>
<p><code>/user/update?email=evil@example.org&amp;userid=1<br />
/user/update?email=evil@example.org&amp;userid=12<br />
/user/update?email=evil@example.org&amp;userid=1234<br />
etc.</code></p>
<p>Too easy! Obviously more security is needed, and this is where the concept of secret keys comes in.</p>
<h2>Secret Keys</h2>
<p>It is a common practice to assign each user a secret key that they use to interact with a web service, often called an API key, generally consisting of randomly generated characters. In this case, you could give Bob a secret key when he signs up with the brewery network, and it would be stored in your database along with the rest of his account information.</p>
<p>Here's where I often see confusion setting in. Many people think it is logical that the secret key be <strong><em>sent</em></strong> as part of the API request, because after all, it uniquely identifies the user and it was given only to that particular person. <strong>However, this is a security problem!</strong></p>
<p>The thing about secret keys is that they have to remain secret, just like any password. As soon as a key is leaked, whoever finds it can impersonate that account, just as easily as Mr. Evil's Brewery did in the previous example. <strong>If you send a secret key as part of an HTTP request, it is no longer secret.</strong> You have just leaked it to whoever cared to be listening! A network sniffer could pick it up, or it could be recorded in proxy logs or web server logs that aren't secured. Perhaps your ISP is doing deep packet inspection, and a rogue employee makes off with the logs. Who knows!</p>
<p>The following is an example of this type of insecurity. Bob is sending his update request along with the secret key:</p>
<p><code>/user/update?email=newbob@example.com&amp;userid=1234&amp;secret_key=bobs-super-secret-key</code></p>
<p>Now, pretend that Bob goes to his local Tarborks coffee shop and jumps on the free open wireless connection. Mr. Evil happens to be there, and fires up his network sniffer program and starts watching all the HTTP traffic on the network. He sees Bob's request go out, since HTTP connections are not secure. Now he has Bob's secret key, and can make any kind of request he wants with it. Maybe he could even delete Bob's account with a request to <code>/user/delete?userid=1234&amp;secret_key=bobs-super-secret-key</code>, or send insults to Bob's customers using a mail endpoint!</p>
<p><strong>Sending the secret key as part of a network request is NOT safe.</strong> So how do we properly identify the sender if the user id can't be trusted and they can't send us their key? Well, you knew I'd get to it eventually... signed requests!</p>
<h2>Signed HTTP Requests</h2>
<p>To produce a signed HTTP request, the sender and the receiver must both know the rules on how to generate a signature. It can be any crazy method you care to dream up, but a common one is as follows:</p>
<ol>
<li>The sender organizes the data they want to send in a logical way, such as sorting it alphabetically.</li>
<li>The data is run through a hashing algorithm using the secret key to produce a <strong>hash</strong>. Hashing algorithms produce short strings of characters that vary based on the input data, and the output is sufficiently unique such that varying the input data by even one character produces a completely different hash.</li>
<li>The hash is added to the original data and sent.</li>
<li>The receiver identifies the user and gets the secret key from their associated account information, and recreates the hash on the received data.</li>
<li>If the recreated hash matches the one included in the request, the request is valid.</li>
</ol>
<p>To return to our Tarborks coffee shop scenario, the request going out might look like this now:</p>
<p><code>/user/update?email=newbob@example.com&amp;userid=1234&amp;sig=x1zz645</code></p>
<p>If Mr. Evil sniffs this request, he might be pretty pleased with himself and try to change it to <code>/user/update?email=evil@example.org&amp;userid=1234&amp;sig=x1zz645</code>. This request would be rejected by the server however, since the <em>signature is now invalid</em>! When Mr. Evil changed the request, he needed to change the signature to match. But since he doesn't have Bob's secret key, he can't generate a correct signature, for this request or any other he cares to make up.  The only valid request he can possibly make is the exact same one he just sniffed, and that's not very malicious at all, since it's what Bob was trying to do anyway.</p>
<h4>Get to the code already</h4>
<p>Assuming Bob's user id is 1234, and the secret key you gave him is "bobs-super-secret-key", he might write the following PHP code.</p>
<h3>User code</h3>
<div class="igBar"><span id="lphp-5"><a href="#" onclick="javascript:showPlainTxt('php-5'); return false;">&gt;&gt; show as plain text</a></span></div>
<div class="syntax_hilite"><span class="langName">PHP:</span>
<div id="php-5">
<div>
<ol>
<li>
<div><span style="color:#0000FF;">$USER_ID</span> = <span style="color:#FF0000;">"1234"</span>;</div>
</li>
<li>
<div><span style="color:#0000FF;">$SECRET_KEY</span> = <span style="color:#FF0000;">"bobs-super-secret-key"</span>;</div>
</li>
<li>
<div>&nbsp;</div>
</li>
<li>
<div><span style="color:#008000;">/**</span></div>
</li>
<li>
<div><span style="color:#008000;"> * @param array $data Array of key/value pairs of data</span></div>
</li>
<li>
<div><span style="color:#008000;"> * @param string $secretKey</span></div>
</li>
<li>
<div><span style="color:#008000;"> * @return string A generated signature for the $data based on $secretKey</span></div>
</li>
<li>
<div><span style="color:#008000;"> */</span></div>
</li>
<li>
<div><span style="color:#000000; font-weight:bold;">function</span> generateSignature<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$data</span>,<span style="color:#0000FF;">$secretKey</span><span style="color:#006600; font-weight:bold;">&#41;</span></div>
</li>
<li>
<div><span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li>
<div>&nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">//sort data array alphabetically by key</span></div>
</li>
<li>
<div>&nbsp; &nbsp; <a href="http://www.php.net/ksort"><span style="color:#000066;">ksort</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$data</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li>
<div>&nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">//combine keys and values into one long string</span></div>
</li>
<li>
<div>&nbsp; &nbsp; <span style="color:#0000FF;">$dataString</span> = <span style="color:#FF0000;">''</span>;</div>
</li>
<li>
<div>&nbsp; &nbsp; <span style="color:#616100;">foreach</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$data</span> <span style="color:#616100;">as</span> <span style="color:#0000FF;">$key</span> =&gt; <span style="color:#0000FF;">$value</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li>
<div>&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$dataString</span> .= <span style="color:#0000FF;">$key</span>.<span style="color:#0000FF;">$value</span>;</div>
</li>
<li>
<div>&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span></div>
</li>
<li>
<div>&nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">//lowercase everything</span></div>
</li>
<li>
<div>&nbsp; &nbsp; <span style="color:#0000FF;">$dataString</span> = <a href="http://www.php.net/strtolower"><span style="color:#000066;">strtolower</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$dataString</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li>
<div>&nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">//generate signature using the SHA256 hashing algorithm</span></div>
</li>
<li>
<div>&nbsp; &nbsp; <span style="color:#616100;">return</span> hash_hmac<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">"sha256"</span>,<span style="color:#0000FF;">$dataString</span>,<span style="color:#0000FF;">$secretKey</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li>
<div><span style="color:#006600; font-weight:bold;">&#125;</span></div>
</li>
<li>
<div>&nbsp;</div>
</li>
<li>
<div><span style="color:#0000FF;">$bobsData</span> = <a href="http://www.php.net/array"><span style="color:#000066;">array</span></a><span style="color:#006600; font-weight:bold;">&#40;</span></div>
</li>
<li>
<div>&nbsp; &nbsp; <span style="color:#FF0000;">"userid"</span> =&gt; <span style="color:#0000FF;">$USER_ID</span>,</div>
</li>
<li>
<div>&nbsp; &nbsp; <span style="color:#FF0000;">"email"</span> =&gt; <span style="color:#FF0000;">"newbob@example.com"</span></div>
</li>
<li>
<div><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li>
<div>&nbsp;</div>
</li>
<li>
<div><span style="color:#0000FF;">$sig</span> = generateSignature<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$bobsData</span>,<span style="color:#0000FF;">$SECRET_KEY</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li>
<div><span style="color:#FF9933; font-style:italic;">//add signature to the outgoing data</span></div>
</li>
<li>
<div><span style="color:#0000FF;">$bobsData</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'sig'</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#0000FF;">$sig</span>;</div>
</li>
<li>
<div><span style="color:#FF9933; font-style:italic;">//generate HTTP query string</span></div>
</li>
<li>
<div><span style="color:#0000FF;">$queryString</span> = http_build_query<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$bobsData</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li>
<div>&nbsp;</div>
</li>
<li>
<div><a href="http://www.php.net/echo"><span style="color:#000066;">echo</span></a> <span style="color:#0000FF;">$queryString</span>; </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>The code above outputs <code>userid=1234&amp;email=newbob%40example.com&amp;sig=efffd9cc30a220f2981b5124e1caa44d91b85aa2d2181f5331f48ca719983c1d</code>.  That's the HTTP query string that Bob would send to the <code>/user/update</code> endpoint to change his email address.  So how does the service verify the request?</p>
<h3>Server-side code</h3>
<div class="igBar"><span id="lphp-6"><a href="#" onclick="javascript:showPlainTxt('php-6'); return false;">&gt;&gt; show as plain text</a></span></div>
<div class="syntax_hilite"><span class="langName">PHP:</span>
<div id="php-6">
<div>
<ol>
<li>
<div><span style="color:#616100;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span><a href="http://www.php.net/empty"><span style="color:#000066;">empty</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$_REQUEST</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'userid'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li>
<div>&nbsp; &nbsp; throw <span style="color:#000000; font-weight:bold;">new</span> Exception<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">"No user id was sent with the request."</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li>
<div><span style="color:#006600; font-weight:bold;">&#125;</span></div>
</li>
<li>
<div>&nbsp;</div>
</li>
<li>
<div><span style="color:#FF9933; font-style:italic;">//look up the account associated with the value in $_REQUEST['userid']</span></div>
</li>
<li>
<div><span style="color:#FF9933; font-style:italic;">//and get the secret key for that account - implement as necessary</span></div>
</li>
<li>
<div><span style="color:#0000FF;">$secretKey</span> = getSecretKeyFromUserId<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$_REQUEST</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'userid'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li>
<div>&nbsp;</div>
</li>
<li>
<div><span style="color:#0000FF;">$data</span> = <span style="color:#0000FF;">$_REQUEST</span>;</div>
</li>
<li>
<div><span style="color:#0000FF;">$receivedSignature</span> = <span style="color:#0000FF;">$data</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'sig'</span><span style="color:#006600; font-weight:bold;">&#93;</span>;</div>
</li>
<li>
<div><span style="color:#FF9933; font-style:italic;">//generate a signature using the data sent by the user, without the 'sig'</span></div>
</li>
<li>
<div><span style="color:#FF9933; font-style:italic;">//parameter of course. Note that the generateSignature() function is the</span></div>
</li>
<li>
<div><span style="color:#FF9933; font-style:italic;">//SAME ONE that the users would use!</span></div>
</li>
<li>
<div><a href="http://www.php.net/unset"><span style="color:#000066;">unset</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$data</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'sig'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li>
<div><span style="color:#0000FF;">$generatedSignature</span> = generateSignature<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$data</span>,<span style="color:#0000FF;">$secretKey</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li>
<div>&nbsp;</div>
</li>
<li>
<div><span style="color:#616100;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$generatedSignature</span> != <span style="color:#0000FF;">$receivedSignature</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li>
<div>&nbsp; &nbsp; throw <span style="color:#000000; font-weight:bold;">new</span> Exception<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">"Received signature is invalid!"</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li>
<div><span style="color:#006600; font-weight:bold;">&#125;</span></div>
</li>
<li>
<div><span style="color:#616100;">else</span> <span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li>
<div>&nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">//continue on, knowing it is the right user making the request.</span></div>
</li>
<li>
<div><span style="color:#006600; font-weight:bold;">&#125;</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>There you have it. Signed requests!</p>
<h4>Advanced Usage</h4>
<p>The signature for a signed request can be sent in different ways. Some services, such as <a href="http://docs.amazonwebservices.com/AmazonS3/latest/dev/RESTAuthentication.html">Amazon's S3 REST API</a>, puts the signature in the HTTP headers. This is arguably a bit cleaner than including it in the parameters of an HTTP request, since the signature doesn't get mixed in with the data, and has implications for caching as well (browser caches and proxies). If you want to do it that way, you might have the user set a header as part of their HTTP request:</p>
<div class="igBar"><span id="lphp-7"><a href="#" onclick="javascript:showPlainTxt('php-7'); return false;">&gt;&gt; show as plain text</a></span></div>
<div class="syntax_hilite"><span class="langName">PHP:</span>
<div id="php-7">
<div>
<ol>
<li>
<div><a href="http://www.php.net/header"><span style="color:#000066;">header</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">"X-Brewery-Sig: "</span>.<span style="color:#0000FF;">$sig</span><span style="color:#006600; font-weight:bold;">&#41;</span>; </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>And the receiving server, instead of looking for the sig parameter in <code>$_REQUEST['sig']</code> (and having to remove it before running the data through the generator function), would find it in:</p>
<div class="igBar"><span id="lphp-8"><a href="#" onclick="javascript:showPlainTxt('php-8'); return false;">&gt;&gt; show as plain text</a></span></div>
<div class="syntax_hilite"><span class="langName">PHP:</span>
<div id="php-8">
<div>
<ol>
<li>
<div><span style="color:#0000FF;">$_SERVER</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'HTTP_X_BREWERY_SIG'</span><span style="color:#006600; font-weight:bold;">&#93;</span>; </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>Hope you found this useful!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.phpvs.net/2011/12/24/http-signed-requests-with-php/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Installing Gearman and gearmand on Windows with Cygwin</title>
		<link>http://www.phpvs.net/2010/11/30/installing-gearman-and-gearmand-on-windows-with-cygwin/</link>
		<comments>http://www.phpvs.net/2010/11/30/installing-gearman-and-gearmand-on-windows-with-cygwin/#comments</comments>
		<pubDate>Wed, 01 Dec 2010 02:51:59 +0000</pubDate>
		<dc:creator>blake</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.phpvs.net/?p=247</guid>
		<description><![CDATA[Recently I've come face-to-face with a significant processing task for a web application written in PHP.  I haven't worked with process control very much, so I started researching ways of distributing the calculations to multiple processes.  PHP offers several libraries for doing this (pcntl, POSIX), but it quickly became clear that if you're running Windows [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I've come face-to-face with a significant processing task for a web application written in PHP.  I haven't worked with process control very much, so I started researching ways of distributing the calculations to multiple processes.  PHP offers several libraries for doing this (<a href="http://php.net/pcntl">pcntl</a>, <a href="http://php.net/posix">POSIX</a>), but it quickly became clear that if you're running Windows these libraries are not an option, and unfortunately at work I have a Windows machine.  After a lot more research, I came across <a href="http://gearman.org">Gearman</a>.</p>
<p>Gearman is essentially a distributed processing framework, and seems to have community support for many programming languages.  It consists of two main components: the job server, and a Client and Worker API.  The Client and Worker API can be used in a wide variety of languages, but the job server is only available as a C library or a Perl library.  This makes it a bit tougher to get the server running on Windows, especially when you start running into some of the dependencies that it requires to build.  As well, the Client/Worker API for PHP can only be installed as a PECL extension, or a very-out-of-date PEAR extension called Net_Gearman.</p>
<p>Nonetheless, after yet more research I decided that I would give it a shot by using <a href="http://www.cygwin.com">Cygwin</a> to get the job server running (if you haven't used Cygwin before, be sure to read about it before attempting to install Gearman this way), and PEAR to use the API.  Pre-built PECL extensions aren't available for Windows anymore, and the  build process for PHP extensions can be pretty painful, so it makes PEAR  look good by comparison even if the code will be out of date.</p>
<p>I had a pretty frustrating time finally getting everything up and running due to various dependency issues, so I went back through the whole process and wrote it out step-by-step.  I used a Windows XP SP3 machine for this, but I also got it working on a Windows 7 machine as well.</p>
<h2>Installing the Gearman job server (gearmand) on Windows with Cygwin</h2>
<h4>Installing Cygwin</h4>
<ol>
<li>If you don't have Cygwin already, you can get it from <a href="http://www.cygwin.com/">http://www.cygwin.com</a>.  The setup file is located <a href="http://cygwin.com/setup.exe">here</a>, and the setup process is pretty straightforward; run it and follow the wizard.  Full installation instructions are available at the Cygwin site.</li>
<li>Keep the Cygwin setup.exe file handy after you've installed the default software packages, as you'll need it in the future to add packages, similar to apt-get, yum, and other Linux/UNIX package managers.</li>
<li>Cygwin installs with some basic packages, including a Cygwin Bash Shell that goes into your Start Menu.  I prefer the mintty emulator instead, as it has less of a DOS Command Prompt feel and better terminal features.  Feel free to use whatever shell you like of course.  You can get mintty by re-running the setup.exe, and at the package selection screen, type 'mintty' into the Search bar at the top left.  Expand the "Shells" category, and click on the word "Skip" under the "New" column beside the mintty package to select it before continuing the install process.</li>
</ol>
<h4>Installing Cygwin Package Dependencies needed for Gearman</h4>
<p>If you're not already in the Cygwin setup, re-run the Cygwin setup.exe and go through to the package selection screen.  The following is a list of dependency packages you will need in order to build the Gearman job server (gearmand).  None of these packages were installed by default with Cygwin:</p>
<ul>
<li>gcc</li>
<li> make</li>
<li> libuuid1-devel</li>
<li> libiconv</li>
</ul>
<p>There's a good <a href="http://www.eecg.utoronto.ca/~aamodt/ece242/cygwin.html">installation tutorial here</a> that walks through getting gcc and make installed for people unfamiliar with Cygwin.  Finding the others is pretty straightforward, the Search bar in the package selector works well.</p>
<h4>Installing libevent</h4>
<p>Gearmand requires an event notification library called <a href="http://monkey.org/~provos/libevent/">libevent </a>that you cannot get as a Cygwin package, which means it has to be installed from source.  You can get the source <a href="http://monkey.org/~provos/libevent/">here</a>.</p>
<ol>
<li>Download and unpack the latest <a href="http://monkey.org/~provos/libevent/">libevent </a>stable release.  At the time of this writing, I used libevent-1.4.14b-stable.<br />
<em><strong>NOTE</strong></em>: Download and unpack to a <strong>directory that does not contain spaces in the name</strong>, such as "C:/cygwin/home/Zombat/libevent-1.4.14b-stable".  If you unpack to something with spaces like "C:/Documents and Settings/Zombat/", the build process might not be able to install libevent correctly (libtool has a hard time with spaces)!</li>
<li>Open a Cygwin shell and <code>cd</code> to the unpacked libevent directory.</li>
<li>Run the following commands:</li>
</ol>
<p style="padding-left: 60px;"><code>./configure<br />
make<br />
make install</code></p>
<p>libevent should now be installed and ready to be used when compiling the Gearman job server.</p>
<h4>Installing the Gearman job server, gearmand.exe</h4>
<ol>
<li>Download and unpack the C implementation of gearmand from http://gearman.org/index.php?id=download</li>
<li>Open a cygwin shell and cd to your unpacked gearmand directory.  Same rules apply as before, make sure you've unpacked in a directory with no spaces in the path!  libtool hates that, and your build may fail.</li>
<li>Run the following commands:</li>
</ol>
<p style="padding-left: 60px;"><code>./configure<br />
make<br />
make install</code></p>
<p>The Gearman job server should now be installed and ready to use!  Mine was installed at /usr/local/sbin/gearmand.exe, and running it with a "triple verbose" flag (<code>-vvv</code>) should produce the following:</p>
<p style="text-align: left;"><a href="http://www.phpvs.net/wp-content/uploads/2010/10/gearmand-output.png"><img class="size-full wp-image-248 aligncenter" title="gearmand-output" src="http://www.phpvs.net/wp-content/uploads/2010/10/gearmand-output.png" alt="gearmand.exe startup debug output" width="355" height="144" /></a></p>
<p>That's it for the job server.  When you want to start it, simply open a Cygwin shell and run <code>gearmand.exe</code>.  Running it with the -d flag will cause the server to run as a daemon in the background, and running with --help will show you the full option list.</p>
<h3 style="text-align: left;">Installing the Gearman Client and Worker API (Net_Gearman)<strong><br />
</strong></h3>
<p style="text-align: left;">I chose to install the PEAR Client and Worker API, as it is native PHP and doesn't involve compiling PECL extensions.  The PEAR package is called Net_Gearman, and was originally written by Joe Stump at Digg.com.  It is old and out of date now, although there appears to be a more recent fork at http://github.com/brianlmoon/net_gearman.  I stuck with the older version, as I suspect it will meet my needs, and was readily available as a PEAR package.</p>
<p style="text-align: left;">This also makes installation relatively painless.  Assuming you've previously set PEAR up, then all you have to do is open a command window (not a Cygwin shell) and run:</p>
<blockquote>
<p style="text-align: left;"><code>pear install Net_Gearman-alpha</code></p>
</blockquote>
<p style="text-align: left;">The "-alpha" portion is necessary, as Net_Gearman apparently never made it to a stable release version.  That being said, it has functioned well for me so far.  Perhaps someone will pick the project up in the future.</p>
<p style="text-align: left;">I'll write more about getting started with the Client and Worker API in the next article, so we can actually use Gearman to get some work done.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.phpvs.net/2010/11/30/installing-gearman-and-gearmand-on-windows-with-cygwin/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>MSB1025 &#8211; Adventures in Visual Studio Project Files with MSBuild</title>
		<link>http://www.phpvs.net/2010/09/17/msb1025-adventures-in-visual-studio-project-files-with-msbuild/</link>
		<comments>http://www.phpvs.net/2010/09/17/msb1025-adventures-in-visual-studio-project-files-with-msbuild/#comments</comments>
		<pubDate>Fri, 17 Sep 2010 23:28:28 +0000</pubDate>
		<dc:creator>morgan</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.phpvs.net/?p=237</guid>
		<description><![CDATA[So we had a Sql Server Integration Services project that wasn't really being used currently, so one of our guys removed the project from our VS2008 solution file and checked it in. Worked fine on his machine - heck, it worked on all our machines. The build server? Not so much. Immediate barfing with the [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.phpvs.net/wp-content/uploads/2010/09/build-server-fail.jpg"><img class="alignleft size-medium wp-image-240" title="MSBuild Fail" src="http://www.phpvs.net/wp-content/uploads/2010/09/build-server-fail-300x201.jpg" alt="MSBuild Fail" width="300" height="201" /></a>So we had a Sql Server Integration Services project that wasn't really being used currently, so one of our guys removed the project from our VS2008 solution file and checked it in.  Worked fine on his machine - heck, it worked on all our machines.</p>
<p>The build server?  Not so much.  Immediate barfing with the cryptic message of "<span style="color: #ff0000;"><code>MSBUILD : error MSB1025: An internal failure occurred while running MSBuild</code></span>". CruiseControl looked at it, sighed, and buckled to its knees under the weight of the aborting MSBuild process.</p>
<p>So what went wrong?  Looking at the diff of the solution file, all that had happened was these two lines were removed:</p>
<p><span style="color: #808000;"><code><br />
Project("{D183A3D8-5FD8-494B-B014-37F57B35E655}") = "DTS", "DTS\DTS.dtproj", "{947C2F56-A7A8-4357-8E42-6A234C1CCCB6}"<br />
EndProject</code></span></p>
<p>Reading up on MSB1025 and seeing that people had fixed it by rebuilding their solution files from scratch, I figured it just had to be a badly configured solution file, and that VS2008's handling of dtproj files was sloppy.</p>
<p>I did a search for the project's GUID (the second guid listed there - 947C2F56-A7A8-4357-8E42-6A234C1CCCB6) and sure enough, there were some references to it left in the solution file.</p>
<p>One project had:</p>
<p><span style="color: #808000;"><code> ProjectSection(ProjectDependencies) = postProject<br />
{947C2F56-A7A8-4357-8E42-6A234C1CCCB6} = {947C2F56-A7A8-4357-8E42-6A234C1CCCB6}<br />
EndProjectSection</code></span></p>
<p>so I removed that entire section, and of course under the GlobalSection that stores the build configuration settings there was a whole whack of:</p>
<p><code><span style="color: #808000;">{947C2F56-A7A8-4357-8E42-6A234C1CCCB6}.Debug|Any CPU.ActiveCfg = Debug<br />
{947C2F56-A7A8-4357-8E42-6A234C1CCCB6}.Debug|Mixed Platforms.ActiveCfg = Debug<br />
{947C2F56-A7A8-4357-8E42-6A234C1CCCB6}.Debug|x86.ActiveCfg = Debug<br />
{947C2F56-A7A8-4357-8E42-6A234C1CCCB6}.Development (Debug)|Any CPU.ActiveCfg = Debug<br />
{947C2F56-A7A8-4357-8E42-6A234C1CCCB6}.Development (Debug)|Mixed Platforms.ActiveCfg = Debug<br />
{947C2F56-A7A8-4357-8E42-6A234C1CCCB6}.Development (Debug)|x86.ActiveCfg = Debug<br />
{947C2F56-A7A8-4357-8E42-6A234C1CCCB6}.Development (Release)|Any CPU.ActiveCfg = Release<br />
{947C2F56-A7A8-4357-8E42-6A234C1CCCB6}.Development (Release)|Mixed Platforms.ActiveCfg = Release<br />
</span>...<br />
...<br />
...</code></p>
<p>so I removed every offending line.  Saved it, handed it back to the build server, and all was good.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.phpvs.net/2010/09/17/msb1025-adventures-in-visual-studio-project-files-with-msbuild/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Manually validate an ASP.Net MVC form on the client side with MicrosoftMvcValidation.js and jQuery</title>
		<link>http://www.phpvs.net/2010/04/26/manually-validate-an-asp-net-mvc-form-on-the-client-side-with-microsoftmvcvalidation-js-and-jquery/</link>
		<comments>http://www.phpvs.net/2010/04/26/manually-validate-an-asp-net-mvc-form-on-the-client-side-with-microsoftmvcvalidation-js-and-jquery/#comments</comments>
		<pubDate>Tue, 27 Apr 2010 06:16:51 +0000</pubDate>
		<dc:creator>morgan</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[AJAX]]></category>
		<category><![CDATA[ASP.Net]]></category>
		<category><![CDATA[ASP.Net MVC]]></category>
		<category><![CDATA[asp.net asp.net-mvc jquery validation]]></category>

		<guid isPermaLink="false">http://www.phpvs.net/?p=196</guid>
		<description><![CDATA[A recent problem cropped up in my Asp.Net MVC application. Its using the standard setup of DataAnnotations + MicrosoftMvcValidation.js + jQuery 1.4.2, and I needed to check the validation state of a form before performing some client-side actions. No problem, right? Obviously not. This second part of this post gets in depth as to what's [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-full wp-image-213" title="check-x" src="http://www.phpvs.net/wp-content/uploads/2010/04/check-x.png" alt="Validation" width="171" height="165" />A recent problem cropped up in my Asp.Net MVC application.  Its using the standard setup of DataAnnotations + MicrosoftMvcValidation.js + jQuery 1.4.2, and I needed to check the validation state of a form before performing some client-side actions. No problem, right?</p>
<p>Obviously not.</p>
<p>This second part of this post gets in depth as to what's going on with the MicrosoftMvcValidation script, but to save you some time, I'll post the solution first.</p>
<p><span style="text-decoration: underline;"><strong>To manually validate your form with MicrosoftMvcValidation.js:</strong></span></p>
<p><del datetime="2010-07-01T05:45:10+00:00">In MicrosoftMvcValidation.js, change line 20 from:</p>
<p style="padding-left: 30px;"><code> return Sys.Mvc._ValidationUtil.$0($2.validate('submit'));})); return $2;</code></p>
<p>to</p>
<p style="padding-left: 30px;"><code> return Sys.Mvc._ValidationUtil.$0($2.validate('submit'));})); <strong>$0.MvcValidationFormContext = $2;</strong> return $2;</code></p>
<p>Alternately, if you're using the debug version of the script, you can achieve the same effect by adding the following to line 196 (the end of the _parseJsonOptions function):</p>
<p style="padding-left: 30px;"><code>formElement.MvcValidationFormContext = formContext;</code></p>
<p></del></p>
<p><strong>UPDATE: </strong> As Morten Christiansen points out in the comments, there is a much cleaner way of accessing the FormContext object, without having to introduce a custom tracking property and modifying the script.  Instead of a custom property, we can just use<br />
<code>$('form')[0]['__MVC_FormValidation']</code>.  Thanks to Morten for pointing this out!</p>
<p>Now we can use the following jQuery/javascript code to manually validate our form:</p>
<pre>
var $form = ("#MyForm");                            // Select our form with jQuery
<del datetime="2010-07-01T05:45:10+00:00">var context = $form[0].MvcValidationFormContext;    // Access the new property we created</del>
var errors;
if ($form[0]['__MVC_FormValidation']) {
    errors = $form[0]['__MVC_FormValidation'].validate("submit");        // Validate the form
}
if (!$form[0]['__MVC_FormValidation'] || errors.length == 0) {
    // No errors, do your stuff
}
</pre>
<hr />
Now for the explanation.</p>
<p>I assumed (incorrectly) that there must be a client-side API to <code>MicrosoftMvcValidation.js</code>, the javascript responsible for dynamic client side form validation that ships with the ASP.Net MVC framework.  Unfortunately, in all my digging, I could not unearth one - and it seems like a huge oversight.  The amount of effort to expose an <code>isValid</code> property or a <code>validate()</code> function on the client would be pretty minimal!</p>
<p>Why would you need to do this?  Doesn't the validation occur automatically?   Well, yes it does - when you submit the form, or click around in it.  However, there are lots of cases where you might want to manually trigger the error messages or perform a client-side action based on whether or not the form is valid, without running the submit handler.   In my case, I wanted to make sure the form was valid <em>before </em>trying to submit it, as our ajax pipeline puts up the "spinner" graphic when a submit event is triggered, which meant it was flashing briefly and looked dumb.</p>
<p>The most common response I ran across when searching for how to manually validate was - <a href="http://stackoverflow.com/questions/2060554/asp-net-mvc-check-form-input-is-valid-on-submit">give up and use the jQuery validate plugin</a>.  This would be my preferred solution to be honest, but I ran into at least two blockers with jQuery validate:</p>
<ol>
<li> it doesn't seem to work with modal dialogs generated from jQuery UI,</li>
<li> it doesn't seem to work with forms that are loaded into the document via an ajax call.</li>
</ol>
<p>So that was out.  Since I already had most of what I needed working with the Microsoft scripts, I went back to them and started exploring the code to see if I could discover any sort of public API.  This is what I came up with.</p>
<p>The key thing that I found was that <code>MicrosoftMvcValidation</code> creates a javascript object called a <code>FormContext</code>, which has a <code>validate(eventName)</code> method.  This <em>seemed </em>promising, so I tried following the code to see how I could get at this validate method. Well - I couldn't.  Not without some modifications.  Here's how it works.</p>
<p>When you include <code>MicrosoftMvcValidation</code>, the main piece of script that executes is this:</p>
<pre>Sys.Mvc.FormContext._Application_Load = function Sys_Mvc_FormContext$_Application_Load() {
    var allFormOptions = window.mvcClientValidationMetadata;
    if (allFormOptions) {
        while (allFormOptions.length &gt; 0) {
            var thisFormOptions = allFormOptions.pop();
            Sys.Mvc.FormContext._parseJsonOptions(thisFormOptions);
        }
    }
}
</pre>
<p>Adding <code>&lt;% Html.EnableClientValidation(); %&gt;</code> to your views causes a bunch of JSON data to be output to the page, and appended to the <code>window.mvcClientValidationMetatdata</code> javascript object.  When the page is ready, the above function runs and calls <code>FormContext._parseJsonOptions()</code> on all the rules and data that were output to that object.</p>
<p><code>_parseJsonOptions </code>is what creates the <code>FormContext </code>object that we're interested in.  In fact, the return value of <code>_parseJsonOptions </code><em>is the FormContext</em>... but sadly, Application_Load ignores the return value, and it's just thrown to the bitbucket, never to be seen again (at least by us).</p>
<p>Judging from the underscores on the function names, it's pretty clear that these are meant to be internal operations, so we can (perhaps) excuse them for not storing and exposing the <code>FormContext </code>for us. From the framework's point of view, it doesn't need to be stored anywhere, because it still has it - <code> _parseJsonOptions</code> internally adds new event handlers for the form, and these handler delegates close over the <code>FormContext </code>object.  The closures means that internally, the form handlers still have a saved reference to what they need, so the application load function doesn't need to do anything with the return value.  The <code>FormContext </code>never surfaces - so if we want to validate the form ourselves, we need to <del datetime="2010-07-01T05:47:53+00:00">expose</del> dig for it.</p>
<p><del datetime="2010-07-01T05:47:53+00:00">All that my code at the top of the post is doing is modifying the <code>_parseJsonOptions</code> function (minified to be named <code>$12</code>), to start adding a new property to the form element in the DOM, which will store the created <code>FormContext</code> object. I named this property <code>MvcValidationFormContext</code>, but you could call it anything you'd like.  You can subsequently access this new property to get the <code>FormContext </code>and call <code>validate("submit")</code> on it, which fires the validation as though we were trying to submit the form, and returns a collection of errors we can check.</del></p>
<p>As Morten pointed out, the reference is, of course, still there.  You can access the closed over FormContext by grabbing the DOM element and digging in it's properties array.  The updated code reflects this.</p>
<hr />I'd love to see an upgrade to <code>MicrosoftMvcValidation.js</code> to include a client API in the future.  Even more, I'd love to see <a href="http://bassistance.de/jquery-plugins/jquery-plugin-validation/">jQuery Validate</a> get some attention to fix the blockers that I ran into, so I can dump the MicrosoftAjax scripts out of my project altogether.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.phpvs.net/2010/04/26/manually-validate-an-asp-net-mvc-form-on-the-client-side-with-microsoftmvcvalidation-js-and-jquery/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>An Exercise in WordPress Integration, or Why WordPress Sucks</title>
		<link>http://www.phpvs.net/2009/12/08/an-exercise-in-wordpress-integration-or-why-wordpress-sucks/</link>
		<comments>http://www.phpvs.net/2009/12/08/an-exercise-in-wordpress-integration-or-why-wordpress-sucks/#comments</comments>
		<pubDate>Tue, 08 Dec 2009 08:23:50 +0000</pubDate>
		<dc:creator>blake</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Software Engineering]]></category>

		<guid isPermaLink="false">http://www.phpvs.net/?p=154</guid>
		<description><![CDATA[I'd like to prefix my upcoming rant with the fact that WordPress is good at what it does: making basic blogs and publishing content. I use it, many other people use it, it works. Heck, I'm using it right now. But from a technical standpoint, WordPress sucks. I'm going to relate my experience here trying [...]]]></description>
			<content:encoded><![CDATA[<p>I'd like to prefix my upcoming rant with the fact that WordPress is good at what it does:  making basic blogs and publishing content.  I use it, many other people use it, it works.  Heck, I'm using it right now.  But from a technical standpoint, WordPress sucks.  I'm going to relate my experience here trying write a quick function to store post output to a file, to be used by a separate application on the same server.</p>
<p>I started off to write a function (let's call it a caching function for simplicity) that stores some HTML from the most recently published post.  Sounds easy enough.  I should be able to just put a function into the functions.php file of the custom template set I'm using.  That's seems to be where the "userland" custom functions go.</p>
<p>So I check the <a href="http://codex.wordpress.org/Function_Reference/" target="_blank">function reference</a> first.  Hey, <a href="http://codex.wordpress.org/Function_Reference/wp_get_recent_posts" target="_blank">wp_get_recent_posts()</a>.  Looks promising, so I give it a shot.  It goes ahead and gets the most recent post just fine.  Things are ok so far.</p>
<h2>A problem appears</h2>
<h2><img class="alignleft size-medium wp-image-160" style="margin-left: 10px; margin-right: 10px;" title="storm-at-sea" src="http://www.phpvs.net/wp-content/uploads/2009/12/storm-at-sea-300x224.jpg" alt="storm-at-sea" width="245" height="183" /></h2>
<p>Now, I want to output the post exactly as it would appear in the blog, and save that output to a file on disk.  Surely there's a basic function that will output a post's content?  You know... take the post_content field from the database record and format it properly?  Suddenly, the skies darken.  Evil laughter booms out.  Ha ha ha!  WordPress mocks the folly of simplistic functional thinking!</p>
<p>The template files use functions like <code>the_content()</code> and <code>the_title()</code>.  Just in case you can't tell from the excellent naming scheme, these actually produce echoed output.  Checking out <code>the_content()</code>, we see it dutifully calls <code>get_the_content()</code>, then runs a couple of lines of formatting stuff on the results.   So how about using <code>get_the_content()</code> for my caching function?  I could run the other few formatting bits manually after that.  Should be ok, right?  After all, the doc comment for <code>get_the_content()</code> says the following:</p>
<p><code>/**<br />
* Retrieve the post content.<br />
*</code></p>
<p>So, I can go ahead assume it simply retrieves the basic post content then?  Ha ha.  <strong>NO</strong>.  <em>WHY WOULD IT DO THAT</em>?  Instead, it takes a bunch of globals that get set who-the-hell-knows-where, runs through a bunch of crap seemingly unrelated to the content of a post, and does a whole lot of textual modifications to <strong>some kind of content</strong>.  Reading through the function is like jabbing red-hot fire pokeys into your eyes.  Here's a portion of it:</p>
<p><code>
<div class="igBar"><span id="lphp-11"><a href="#" onclick="javascript:showPlainTxt('php-11'); return false;">&gt;&gt; show as plain text</a></span></div>
<div class="syntax_hilite"><span class="langName">PHP:</span>
<div id="php-11">
<div>
<ol>
<li>
<div><span style="color:#0000FF;">$content</span> = <span style="color:#0000FF;">$pages</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#0000FF;">$page</span>-<span style="color:#CC66CC;color:#800000;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span>;</div>
</li>
<li>
<div><span style="color:#616100;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span> <a href="http://www.php.net/preg_match"><span style="color:#000066;">preg_match</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'/&amp;lt;<span style="color:#000099; font-weight:bold;">\!</span>--more(.*?)?--&amp;gt;/'</span>, <span style="color:#0000FF;">$content</span>, <span style="color:#0000FF;">$matches</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li>
<div><span style="color:#0000FF;">$content</span> = <a href="http://www.php.net/explode"><span style="color:#000066;">explode</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$matches</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#CC66CC;color:#800000;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span>, <span style="color:#0000FF;">$content</span>, <span style="color:#CC66CC;color:#800000;">2</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li>
<div><span style="color:#616100;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span> !<a href="http://www.php.net/empty"><span style="color:#000066;">empty</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$matches</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#CC66CC;color:#800000;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> &amp;amp;&amp;amp; !<a href="http://www.php.net/empty"><span style="color:#000066;">empty</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$more_link_text</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#41;</span></div>
</li>
<li>
<div><span style="color:#0000FF;">$more_link_text</span> = <a href="http://www.php.net/strip_tags"><span style="color:#000066;">strip_tags</span></a><span style="color:#006600; font-weight:bold;">&#40;</span>wp_kses_no_null<span style="color:#006600; font-weight:bold;">&#40;</span><a href="http://www.php.net/trim"><span style="color:#000066;">trim</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$matches</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#CC66CC;color:#800000;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>&lt;/code&gt;</div>
</li>
<li>
<div>&nbsp;</div>
</li>
<li>
<div><span style="color:#0000FF;">$hasTeaser</span> = <span style="color:#000000; font-weight:bold;">true</span>;</div>
</li>
<li>
<div><span style="color:#006600; font-weight:bold;">&#125;</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p><code>$pages</code> is some kind of global that doesn't seem to have any relation to a post.  Then apparently we're looking for HTML comments of <code>&lt;!--more something --&gt;</code>, and replacing them with... well, something.  I'd hate to think what would happen if I ever wrote a post with an HTML comment in it that happened to hit on whatever random content markers WordPress has decided to use.  (<em>Oh wait!  That</em> <em><strong>just happened to me</strong></em> <em>while I was trying to publish the above code fragment!</em>)  I didn't even bother to look into things like <code>wp_kses_no_null</code>.  It probably involves dark rituals with live chicken sacrifice.  Why is there so much going on in a function called <strong>get</strong>_the_content()?</p>
<p>In the end, it seems that <code>get_the_content()</code> will eventually get the content of a post, but only if you set a half-a-dozen or so globals before you call it.  And <em>what the hell post is it even getting</em>?</p>
<h2>"The Loop"</h2>
<h2><img class="alignright size-medium wp-image-161" style="margin-left: 10px; margin-right: 10px;" title="the-broken-chain1" src="http://www.phpvs.net/wp-content/uploads/2009/12/the-broken-chain1-300x224.jpg" alt="the-broken-chain1" width="300" height="224" /></h2>
<p>Digging further, it's clear that the template functions for output are all like that.  They don't take any kind of parameters; <em>they just operate on globals</em>!  <strong>There's no way to take the post data that I just retrieved with <code>wp_get_recent_posts()</code>, and format it using these functions.</strong> You have to be in "The Loop" in order to do that.  And "The Loop" sucks.  It's not a catchy, easy-to-use method of handling posts, despite WordPress's efforts to pass it off as something neat or fun.  It's a mish-mash of global functions with random naming and variable schemes (incidentally, just like the rest of WordPress).  You can only use "The Loop" if you're accessing WordPress in a "normal", web-requested-and-template-loaded kind of way.  It doesn't work if you're outside a template file (such as in functions.php before a template gets loaded).</p>
<p>So back to square one.  Unfortunately, it appears that if I want to have the regular blog-formatted output, I need to harness "The Loop" somehow, and clearly you can't do that on your own (ie. outside of a template file) without knowing about every global variable in the system.</p>
<p>After some quick googling, I came across the <a href="http://codex.wordpress.org/Template_Tags/query_posts" target="_blank">query_posts()</a> function, which you can use to set up "The Loop".  Reading the documentation on it, you can find this little gem:</p>
<blockquote><p>"The query_posts function overrides and replaces the main query for the page. To save your sanity, do not use it for any other purpose."</p></blockquote>
<p>To paraphrase: "We've created a public API function that is pretty much useless except in a very specific page-dependent situation.  Please enjoy how useless it is.  But don't use it."</p>
<p>The fact that there is a "main query" for a page is another indicator of just how global-happy WordPress is, and that in turn gives you an insight into why it has so many security holes.  How do you keep track of so many globals across so many functions?</p>
<h2>A solution... sort of.</h2>
<p>Fortunately, the <code>query_posts()</code> doc page links to the <a href="http://codex.wordpress.org/Function_Reference/WP_Query" target="_blank">WP_Query docs</a>, which is marginally more helpful, and provides the path for a solution.  Using <code>WP_Query</code> sets up the wacky global stuff necessary to use "The Loop", which means we can hack our way through to getting some formatted post content.  While technically feasible, you have to emulate a bunch of <code>$_REQUEST</code> parameters to the query() method.  I ended up with this:</p>
<p><code>
<div class="igBar"><span id="lphp-12"><a href="#" onclick="javascript:showPlainTxt('php-12'); return false;">&gt;&gt; show as plain text</a></span></div>
<div class="syntax_hilite"><span class="langName">PHP:</span>
<div id="php-12">
<div>
<ol>
<li>
<div><span style="color:#000000; font-weight:bold;">function</span> cacheMostRecentPost<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span></div>
</li>
<li>
<div><span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li>
<div><span style="color:#0000FF;">$featuredPosts</span> = <span style="color:#000000; font-weight:bold;">new</span> WP_Query<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li>
<div><span style="color:#0000FF;">$featuredPosts</span>-&amp;gt;query<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'showposts=1'</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li>
<div><span style="color:#616100;">while</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$featuredPosts</span>-&amp;gt;have_posts<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span></div>
</li>
<li>
<div><span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li>
<div><span style="color:#0000FF;">$featuredPosts</span>-&amp;gt;the_post<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li>
<div><a href="http://www.php.net/ob_start"><span style="color:#000066;">ob_start</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li>
<div><span style="color:#FF9933; font-style:italic;">//do output with stuff like the_title() and the_content()</span></div>
</li>
<li>
<div><span style="color:#0000FF;">$str</span> = <a href="http://www.php.net/ob_get_contents"><span style="color:#000066;">ob_get_contents</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li>
<div><a href="http://www.php.net/ob_end_clean"><span style="color:#000066;">ob_end_clean</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li>
<div><span style="color:#FF9933; font-style:italic;">//write $str to cache fragment</span></div>
</li>
<li>
<div><span style="color:#006600; font-weight:bold;">&#125;</span></div>
</li>
<li>
<div><span style="color:#006600; font-weight:bold;">&#125;</span>&lt;/code&gt;</div>
</li>
<li>
<div>&nbsp;</div>
</li>
<li>
<div><span style="color:#FF9933; font-style:italic;">//set up hooks for this file when a post is changed or deleted</span></div>
</li>
<li>
<div>add_action<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'save_post'</span>, <span style="color:#FF0000;">'cacheMostRecentPost'</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li>
<div>add_action<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'deleted_post'</span>, <span style="color:#FF0000;">'cacheMostRecentPost'</span><span style="color:#006600; font-weight:bold;">&#41;</span>; </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>So despite relying on a specific set up of incoming HTTP parameters (as a string) for the most part, at least you can pass paramters to the query if you know the right ones.  In this case, "showposts=1" seems to be the total number of posts fetched, and they appear to come back ordered by posting date, most recent first.  This works for what I want it to do, but guess what?  It doesn't work if you try to run it anywhere that's not one of those action hooks, because "The Loop" overwrites all the globals necessary for doing output later!  So I can't use that function, say, at the top of the index.php template file if I wanted to.  If I do, thanks to the overwritten globals, WordPress decides that I actually want the "Archive" page instead of the index page(!), and switches templates accordingly. So while I achieved my goal of being able to cache a post to a file with this function, it's certainly not portable, and it's certainly not elegant.</p>
<h2>Wharrgarbl</h2>
<h2><img class="alignright size-medium wp-image-158" title="wharrgarbl" src="http://www.phpvs.net/wp-content/uploads/2009/12/wharrgarbl-300x240.jpg" alt="wharrgarbl" width="300" height="240" /></h2>
<p>The entire code flow is mind-boggling.  Basing the output functions around a bunch of globals reminds me of code someone would have written in PHP 3 a decade ago, or something a very inexperienced programmer would write.  Definitely not something you would expect in an application used by what is probably now millions of people.  What's wrong with having some data fetching functions, and some output functions?  You could, and I know I'm talking crazy here, but you could fetch some data, and then <em>pass it</em> to the output functions.  Then (bear with me here), you could probably fetch posts (or whatever) <em>at any time</em>, and get some formatted output <em>at any time</em>, without overwriting some important global that might be used later in the code flow.  Revolutionary, I know.  Sorry if I went too fast on that.  I'll repeat it louder and/or slower for any WordPress core developers that happen to be reading.</p>
<p>So, WordPress?  How about something like:</p>
<p><code>$postObjects = getRecentPostsByDate(1);<br />
$output = formatPostContent($postObject[0]);</code></p>
<p>The mere concept of having individual posts exist inside their own little encapsulated world would make the APIs a hundred times more useful (and easier to understand).  You could even keep those crap <code>the_title()</code> and <code>the_content()</code> and <code>the_something_lol_naming_scheme_lol()</code> functions if you wanted.  Just make them take parameters.  Better yet, put them inside a formatting object, or even the post object itself.  <code>$post-&gt;the_content()</code> would still work, but it would have context!</p>
<p>The reason this gets me worked up is not that it's so frustrating to use (although that helps).  I've had to deal with a lot of frustrating code in my career.  It's more the fact that it's this kind of thing that gives PHP programmers a bad name.  The code is just bad.  The design is random.  The API functions are random.  The naming schemes are random.  Functions don't do what their name (or their doc comment) indicates they should do.  Integrating wordpress into another application or site is next to impossible (try it, I dare you), and the other way around, integrating another application or site into wordpress is much more difficult than it should be.  Global usage is rampant and ridiculous to follow.</p>
<p>You don't have to look any farther than a single WordPress code file to understand why there have been so many security holes over the last couple of years.  And there's a lot of PHP code out there that's the quality of WordPress, or worse.</p>
<p>To re-iterate my opening, if you don't need to get anything special out of it, WordPress does the job.  They've filled their market niche well, and it's encouraging that development is ongoing and releases occur often.  I've worked with it on occasion over the last few years, and the improvements are obvious, interface-wise especially, and to some extent code-wise as well (the WP_Query object is a step forward).   But working with the code is not fun.  Even modifying the template files is an exercise in counter-intuitiveness.</p>
<p>I'm sure there are reasons the code is what it is at this point, and I'm equally as sure I don't have the full picture to go with my condemnations.  I guess I should just be thankful that I don't have to maintain it.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.phpvs.net/2009/12/08/an-exercise-in-wordpress-integration-or-why-wordpress-sucks/feed/</wfw:commentRss>
		<slash:comments>37</slash:comments>
		</item>
		<item>
		<title>ASP.Net MVC &#8211; How to route to images or other file types</title>
		<link>http://www.phpvs.net/2009/08/06/aspnet-mvc-how-to-route-to-images-or-other-file-types/</link>
		<comments>http://www.phpvs.net/2009/08/06/aspnet-mvc-how-to-route-to-images-or-other-file-types/#comments</comments>
		<pubDate>Fri, 07 Aug 2009 04:23:51 +0000</pubDate>
		<dc:creator>morgan</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[ASP.Net]]></category>
		<category><![CDATA[ASP.Net MVC]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[MVC]]></category>

		<guid isPermaLink="false">http://www.phpvs.net/?p=123</guid>
		<description><![CDATA[A recent question on Stack Overflow (and subsequent answer that I wrote for it) inspired this post. I had recently been discussing URL rewriting in depth with my brother, and have also been doing some introductory work with the routing engine in ASP.Net MVC, and the question piqued my interest since I had been meaning [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.phpvs.net/wp-content/uploads/2009/08/Image.png"><img class="alignright size-full wp-image-228" style="border: 0pt none;" title="Image" src="http://www.phpvs.net/wp-content/uploads/2009/08/Image.png" alt="" width="256" height="256" /></a>A <a href="http://stackoverflow.com/questions/1146652/how-do-i-route-images-using-asp-net-mvc-routing">recent question on Stack Overflow</a> (and subsequent answer that I wrote for it) inspired this post.  I had recently been discussing URL rewriting in depth with my brother, and have also been doing some introductory work with the routing engine in ASP.Net MVC, and the question piqued my interest since I had been meaning to look at this more closely for some time.</p>
<p>The question on Stack Overflow is titled "How do I route images with ASP.Net MVC", but fundamentally the question is really asking "<strong>how can I use ASP.Net MVC to re-route URL's to actual physical files, rather than methods of a controller?</strong>"</p>
<p>To be clear, lets address the conceptual differences between routing and url rewriting.  Url rewriting takes the requested URL and modifies it before your code ever sees it.  As far as your application is concerned, the client requested the rewritten URL.  All that URL rewriting does is to change one URL into another URL, based on pattern matching.</p>
<p>Routing is a different and much more powerful beast.  The ASP.Net routing engine maps an URL to a "resource", based on a set of routes.  The first route to match the requested URL wins the prize, and sends the request off to the resource it chooses.  For the ASP.Net MVC framework (which uses <code>System.Web.Routing</code> under the hood), a resource is something that can handle the request object, which is always a piece of code.</p>
<p>So where does that leave physical files?  If a request is always parsed by the routing engine and then handed off to some function somewhere, how can we ever route a request for an image to actually return the physical image?</p>
<p>Well, it takes a tiny bit of legwork, but once we're through it, I'm confident you will see the huge advantages that routing has over simple url-rewriting.  We will show the equivalent of url-rewriting by handling a request for an image using an URL that doesn't map to a physical path, but be able to return the image anyway.</p>
<h2>Handling the Request</h2>
<p>First off, we need to handle the request that we want to re-route to a physical file.  Out of the box, ASP.Net MVC uses an instance of the <code>MvcRouteHandler </code>object to handle every request.  <code>MvcRouteHandler </code> hides all the complexities of taking the requested URL, breaking it down into parts, finding the right controller in your application, instantiating it and passing it all the data it needs.</p>
<p>The end result of <code>MvcRouteHandler </code>is not what we desire. We want to return an image, not instantiate a controller and run a method.   We want to skip dealing with controllers altogether in this case.  So lets create our own route handler that we'll use instead.</p>
<p>To do so, we simply implement <code>IRouteHandler</code>, an interface exposed by ASP.Net MVC that actually inherits from <code>IHttpHandler</code>.  This means that what we're writing is the ASP.Net MVC equivalent of an .ashx file for a webforms app - we're inserting our own handling module into the ASP.Net pipeline, that will handle the request much closer to the webserver/http level, rather than at the ASP.Net application level.</p>
<p><code>IRouteHandler </code>only has one method that we need to implement, which is <code>GetHttpHandler()</code>.</p>
<pre class="prettyprint"><code><span class="kwd">using</span><span class="pln"> </span><span class="typ">System</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">using</span><span class="pln"> </span><span class="typ">System</span><span class="pun">.</span><span class="typ">Collections</span><span class="pun">.</span><span class="typ">Generic</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">using</span><span class="pln"> </span><span class="typ">System</span><span class="pun">.</span><span class="pln">IO</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">using</span><span class="pln"> </span><span class="typ">System</span><span class="pun">.</span><span class="typ">Linq</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">using</span><span class="pln"> </span><span class="typ">System</span><span class="pun">.</span><span class="typ">Web</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">using</span><span class="pln"> </span><span class="typ">System</span><span class="pun">.</span><span class="typ">Web</span><span class="pun">.</span><span class="typ">Compilation</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">using</span><span class="pln"> </span><span class="typ">System</span><span class="pun">.</span><span class="typ">Web</span><span class="pun">.</span><span class="typ">Routing</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">using</span><span class="pln"> </span><span class="typ">System</span><span class="pun">.</span><span class="typ">Web</span><span class="pun">.</span><span class="pln">UI</span><span class="pun">;</span><span class="pln">

</span><span class="kwd">namespace</span><span class="pln"> MvcApplication1
</span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">ImageRouteHandler</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><span class="typ">IRouteHandler</span><span class="pln">
    </span><span class="pun">{</span><span class="pln">
        </span><span class="kwd">public</span><span class="pln"> </span><span class="typ">IHttpHandler</span><span class="pln"> </span><span class="typ">GetHttpHandler</span><span class="pun">(</span><span class="typ">RequestContext</span><span class="pln"> requestContext</span><span class="pun">)</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            </span><span class="kwd">string</span><span class="pln"> filename </span><span class="pun">=</span><span class="pln"> requestContext</span><span class="pun">.</span><span class="typ">RouteData</span><span class="pun">.</span><span class="typ">Values</span><span class="pun">[</span><span class="str">"filename"</span><span class="pun">]</span><span class="pln"> </span><span class="kwd">as</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">;</span><span class="pln">

            </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="kwd">string</span><span class="pun">.</span><span class="typ">IsNullOrEmpty</span><span class="pun">(</span><span class="pln">filename</span><span class="pun">))</span><span class="pln">
            </span><span class="pun">{</span><span class="pln">
                </span><span class="com">requestContext.HttpContext.Response.Clear();
                requestContext.HttpContext.Response.StatusCode = 404;
                requestContext.HttpContext.Response.End();
</span><span class="pln">            </span><span class="pun">}</span><span class="pln">
            </span><span class="kwd">else</span><span class="pln">
            </span><span class="pun">{</span><span class="pln">
                requestContext</span><span class="pun">.</span><span class="typ">HttpContext</span><span class="pun">.</span><span class="typ">Response</span><span class="pun">.</span><span class="typ">Clear</span><span class="pun">();</span><span class="pln">
                requestContext</span><span class="pun">.</span><span class="typ">HttpContext</span><span class="pun">.</span><span class="typ">Response</span><span class="pun">.</span><span class="typ">ContentType</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">GetContentType</span><span class="pun">(</span><span class="pln">requestContext</span><span class="pun">.</span><span class="typ">HttpContext</span><span class="pun">.</span><span class="typ">Request</span><span class="pun">.</span><span class="typ">Url</span><span class="pun">.</span><span class="typ">ToString</span><span class="pun">());</span><span class="pln">

                </span><span class="com">// find physical path to image here.  </span><span class="pln">
                </span><span class="kwd">string</span><span class="pln"> filepath </span><span class="pun">=</span><span class="pln"> requestContext</span><span class="pun">.</span><span class="typ">HttpContext</span><span class="pun">.</span><span class="typ">Server</span><span class="pun">.</span><span class="typ">MapPath</span><span class="pun">(</span><span class="str">"~/test.jpg"</span><span class="pun">);</span><span class="pln">

                requestContext</span><span class="pun">.</span><span class="typ">HttpContext</span><span class="pun">.</span><span class="typ">Response</span><span class="pun">.</span><span class="typ">WriteFile</span><span class="pun">(</span><span class="pln">filepath</span><span class="pun">);</span><span class="pln">
                requestContext</span><span class="pun">.</span><span class="typ">HttpContext</span><span class="pun">.</span><span class="typ">Response</span><span class="pun">.</span><span class="typ">End</span><span class="pun">();</span><span class="pln">
            </span><span class="pun">}</span><span class="pln">
            </span><span class="kwd">return</span><span class="pln"> </span><span class="kwd">null</span><span class="pun">;</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">

        </span><span class="kwd">private</span><span class="pln"> </span><span class="kwd">static</span><span class="pln"> </span><span class="kwd">string</span><span class="pln"> </span><span class="typ">GetContentType</span><span class="pun">(</span><span class="typ">String</span><span class="pln"> path</span><span class="pun">)</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            </span><span class="kwd">switch</span><span class="pln"> </span><span class="pun">(</span><span class="typ">Path</span><span class="pun">.</span><span class="typ">GetExtension</span><span class="pun">(</span><span class="pln">path</span><span class="pun">))</span><span class="pln">
            </span><span class="pun">{</span><span class="pln">
                </span><span class="kwd">case</span><span class="pln"> </span><span class="str">".bmp"</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">return</span><span class="pln"> </span><span class="str">"Image/bmp"</span><span class="pun">;</span><span class="pln">
                </span><span class="kwd">case</span><span class="pln"> </span><span class="str">".gif"</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">return</span><span class="pln"> </span><span class="str">"Image/gif"</span><span class="pun">;</span><span class="pln">
                </span><span class="kwd">case</span><span class="pln"> </span><span class="str">".jpg"</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">return</span><span class="pln"> </span><span class="str">"Image/jpeg"</span><span class="pun">;</span><span class="pln">
                </span><span class="kwd">case</span><span class="pln"> </span><span class="str">".png"</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">return</span><span class="pln"> </span><span class="str">"Image/png"</span><span class="pun">;</span><span class="pln">
                </span><span class="kwd">default</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">break</span><span class="pun">;</span><span class="pln">
            </span><span class="pun">}</span><span class="pln">
            </span><span class="kwd">return</span><span class="pln"> </span><span class="str">""</span><span class="pun">;</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span></code></pre>
<p>The above <code>IRouteHandler </code>is pretty simple.  Ignoring the <code>GetContentType </code>helper method, there's really only two things happening.  First, we check for a "filename" parameter that got passed in to our handler (more on that in a second).  If it's not there, we return a 404 response.  Otherwise, we attempt to open up the physical file "test.jpg", and stream it to the browser.</p>
<p>Clearly, this should be adapted to your needs by actually using the filename parameter to find the physical files on your system.   But moving on - how do we invoke this from our MVC app?  And how do we pass in the filename parameter, of which we'd like to reroute to some other physical path?</p>
<h2>Routing the Request to the Custom Handler</h2>
<p>Well, this is the easy part.  Where you'd normally define your routes in <code>Global.asax</code>, simply use <code>routes.Add()</code>, instead of <code>routes.MapRoute()</code>.  Just like this:</p>
<pre>routes.Add("ImagesRoute",
                 new Route("graphics/{filename}", new ImageRouteHandler()));</pre>
<p>This method of adding our route allows us to specify our custom <code>IRouteHandler</code>, rather than <code>routes.MapRoute()</code>, which by default uses an instance of <code>MvcRouteHandler</code>.  So now, we've defined a route that matches against any requested URL containing "graphics/", and puts the rest of the URL into the "filename" bucket of the <code>RouteDataDictionary</code>, and hands it off to our <code>IRouteHandler</code>.  This is how we pass the filename parameter into our custom route handler - basically the same way we pass things into controllers, by defining the variables in the route pattern.</p>
<p>We've successfully routed all URL's containing "graphics/", which doesn't physically exist in our web application, and returning "temp.jpg", which could exist anywhere.  With a bit of coding around the file IO, you could return files from anywhere.</p>
<p>And that's pretty much it!  You might be thinking, "this seems like a lot of extra work just to re-route a URL to a physical file that already existed in my web app!".   If you take a step back though, you'll see the power of this approach.  What if you wanted to log every request to the original URL to a special log file?  What if you wanted to also transform the image before returning it?  Perhaps launch a system executable or asynchronously hit a web service?  What if you wanted to...?</p>
<p>In a nutshell, by inserting your own HttpHandlers into the ASP.Net pipeline to handle routed requests, you can code <em>anything that you'd like to happen</em> when a request comes in, rather than just rewriting it to some other URL.</p>
<p><a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fwww.phpvs.net%2f2009%2f08%2f06%2faspnet-mvc-how-to-route-to-images-or-other-file-types%2f"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.phpvs.net%2f2009%2f08%2f06%2faspnet-mvc-how-to-route-to-images-or-other-file-types%2f&amp;bgcolor=FF9933&amp;cbgcolor=D4E1FD" border="0" alt="kick it on DotNetKicks.com" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.phpvs.net/2009/08/06/aspnet-mvc-how-to-route-to-images-or-other-file-types/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Facebook Notifications &#8211; &quot;An unknown error occurred (out of memory)&quot;</title>
		<link>http://www.phpvs.net/2009/07/19/facebook-notifications-an-unknown-error-occurred-out-of-memory/</link>
		<comments>http://www.phpvs.net/2009/07/19/facebook-notifications-an-unknown-error-occurred-out-of-memory/#comments</comments>
		<pubDate>Sun, 19 Jul 2009 18:54:04 +0000</pubDate>
		<dc:creator>blake</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.phpvs.net/?p=103</guid>
		<description><![CDATA[Over the last few months, I've worked with the Facebook Notification system many times, and there has always been a moderate-to-high level of frustration with it. It is difficult to test on a development application, because you simply don't have the same number of users as a live application, and the application settings on a [...]]]></description>
			<content:encoded><![CDATA[<p>Over the last few months, I've worked with the Facebook Notification system many times, and there has always been a moderate-to-high level of frustration with it.  It is difficult to test on a development application, because you simply don't have the same number of users as a live application, and the application settings on a dev app are different, which affects your allocation of allowed notifications.</p>
<p>One of the prevalent errors I was getting for a long time was that a notification sent to a large number of users (application-to-user notification) would invariably fail with an Exception thrown from the Facebook PHP client library.  My notification controller code in a particular application was set up to catch Exceptions and display the error into the administration control panel.  However, "<strong>An unknown error occurred (out of memory)</strong>" is about as helpful as you might imagine.  Yay Facebook.  The only thing going for this particular error is that it's an iota more helpful than Facebook's documentation, which you quickly learn to distrust as out-of-date or just plain wrong.</p>
<h3><strong>The logic</strong></h3>
<p>My notification function logic was fairly simple:  Accept an array of Facebook user ids, run an FQL query against Facebook to make sure the users all had the application installed, remove any ids that didn't, then use the Notifications.send() method (via the PHP client library's <code>$facebook-&gt;api_client-&gt;notifications_send()</code> method) to fire off the message.</p>
<p>No problems on development.  On production, it was a giant party of "An unknown error occurred (out of memory)" errors.</p>
<p>At first I thought that Notifications.send() couldn't handle a lot of user ids (I was giving it at least 5000), so I put a loop in to break it up into several small "chunk sends".  I went all the way down to 500 users per request, and nothing seemed to change, other than I was probably wasting my allocated notifications.  The only silver lining to doing this testing on a production server was that the failed notifications didn't seem to go out to anyone, although that's impossible to tell for sure.</p>
<h3><strong>It's not the size of the notification, it's how you verify it.</strong><span style="text-decoration: underline;"><strong><br />
</strong></span></h3>
<p>I struggled with this for a long while until I realized that there was only one other possible location for Facebook to throw this error, and that was with the FQL query.  I moved my "chunking" loop to work with the FQL as well, and I finally had relief from the "unknown" error.  My conclusion therefore is that <strong>FQL queries <em>might not</em> be able to handle a large result set</strong>.</p>
<p>Since the documentation and forums couldn't give me any help, I thought I'd post my working code and explanation here, in the hopes that someone might find it useful.</p>
<p>Note that the Facebook object has been previously set as a property of the Controller that is executing this function, so it is accessed via <code>$this-&gt;facebook</code> here.  You can see how the original array is broken into separate requests of approximately 500 users each, with each chunk of users being verified in turn.  I have no idea what a safe number of users would be, however 500 seems to be working for me (for now).</p>
<pre><code>/**
 * Sends a Facebook Notification message to all given users of an application.
 *
 * @param array $facebookIds Array of Facebook IDs to send the notification to.
 * @param string $msg Notification message to send.
 * @return int Count of how many users were sent the message.
 * @link http://wiki.developers.facebook.com/index.php/Notifications.send
 */
public function notifyMultipleUsers($facebookIds, $msg)
{
	if (! is_array($facebookIds) || count($facebookIds) == 0) {
		throw new Exception('No user ids given to notifyMultipleUsers().');
	}
	$reqSize = 500;
	$numUsers = 0;
	while(count($facebookIds) &gt; 0) {
		$tmpIds = array_splice($facebookIds,0,$reqSize);
		//Check against Facebook database to verify which users have the app installed.
		$fql = 'SELECT uid FROM user '.
		       'WHERE is_app_user=1 AND uid IN ('.implode(',',$tmpIds).')';
		$fqlRes = $this-&gt;facebook-&gt;api_client-&gt;fql_query($fql);
		$appUsers = array();
		foreach($fqlRes as $a) {
			$appUsers[] = $a['uid'];
		}
		$c = count($appUsers);
		if ($c &gt; 0) {
			$this-&gt;facebook-&gt;api_client-&gt;notifications_send(
				implode(',',$appUsers),$msg,'app_to_user'
			);
			$numUsers += $c;
		}
	}
	return $numUsers;
}</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://www.phpvs.net/2009/07/19/facebook-notifications-an-unknown-error-occurred-out-of-memory/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>.Net Mocking Frameworks &#8211; Capability Comparison</title>
		<link>http://www.phpvs.net/2009/04/25/net-mocking-frameworks-capability-comparison/</link>
		<comments>http://www.phpvs.net/2009/04/25/net-mocking-frameworks-capability-comparison/#comments</comments>
		<pubDate>Sun, 26 Apr 2009 06:04:40 +0000</pubDate>
		<dc:creator>morgan</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[Integration Testing]]></category>
		<category><![CDATA[Mocks]]></category>
		<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[Unit Testing]]></category>

		<guid isPermaLink="false">http://www.phpvs.net/?p=80</guid>
		<description><![CDATA[A chart form summary of some of the features, capabilities and characteristics of four of the most popular mock object frameworks used for test driven development and design with .Net projects.]]></description>
			<content:encoded><![CDATA[<p>I have a couple years of experience of TDD under my belt, but it's only recently that I've felt like I am a relatively decent practitioner of it.  I attribute this to forcing myself to take the plunge into mocking, and the knowledge of patterns and loosely-coupled design that I've gained from it.</p>
<p>You see, I work on a pretty large and complex ASP.Net webforms product, and tests were introduced late into the development cycle of the initial release.  We favored integration testing with real data sources over actual unit tests.  While I did write some tests, I knew that our product was not very testable by design.</p>
<p>Recently we put together a public facing API for programming against the product, that we were able to build from scratch.  This was a natural opening to apply test driven practices and start building unit tests from the get-go.  Due to the service oriented nature of the data that the product consumes, I soon found myself realizing that I needed mocks in a big way.  I gritted my teeth and dove head-first into Rhino.mocks.</p>
<p>Several weeks down the road, it was obvious that Rhino just isn't right for our environment.  The learning curve is too steep to win quick success with all our developers (and therefore by extension, our project managers).  I began looking for another framework.</p>
<p>This led me on a frustrating research mission to find the differences between frameworks without actually trying them all. Due to a lack of in-depth comparisons of the actual capabilities of the various mocking frameworks, I've ended up putting together this chart.  I'm hoping it helps some people.  My interest is very high in this arena, so I will be keeping it up to date.</p>
<p>(Just for interest's sake - we ended up choosing Moq, due to the ease of the API.   The philosophy of Moq jives perfectly with our relatively fast-paced and efficient development environment.  We don't care about purism - we care about getting it done.)</p>
<div id="attachment_98" class="wp-caption aligncenter" style="width: 650px"></p>
<div class="mceTemp mceIEcenter">
<dl id="attachment_101" class="wp-caption aligncenter" style="width: 650px;">
<dt class="wp-caption-dt"><img class="size-full wp-image-101" title=".Net Mocking Frameworks" src="http://www.phpvs.net/wp-content/uploads/2009/05/comparison.png" alt=".Net Mocking Framework Comparison" width="640" height="488" /><p class="wp-caption-text">.Net Mocking Framework Comparison </p></div>
</dt>
</dl>
</div>
<p style="text-align: center;"><strong>Other Notes</strong></p>
<table border="1" cellspacing="0" cellpadding="0" width="690" align="center">
<tbody>
<tr>
<td width="330" valign="top"><strong>Rhino</strong></p>
<ul class="unIndentedList">
<li> Mature, flexible framework</li>
</ul>
<ul class="unIndentedList">
<li> Built on Castle DynamicProxy</li>
</ul>
<ul class="unIndentedList">
<li> Very large array of "syntaxes" leads to extreme   confusion when writing tests - documentation mixed for the new 3.5 fluent syntax</li>
</ul>
<ul class="unIndentedList">
<li> Large community of users</li>
</ul>
</td>
<td width="360" valign="top"><strong>Moq</strong></p>
<ul class="unIndentedList">
<li> New(ish) framework also built on Castle</li>
</ul>
<ul class="unIndentedList">
<li> Requires .Net 3.5 due to its lambda heavy   syntax</li>
</ul>
<ul class="unIndentedList">
<li> No distinction between mocks &amp; stubs,   record/playback (joy!!)</li>
</ul>
<ul class="unIndentedList">
<li> Responsive and active developers and community</li>
</ul>
</td>
</tr>
<tr>
<td width="330" valign="top"><strong>NMock2</strong></p>
<ul class="unIndentedList">
<li> Uses "magic strings" for mocking - makes tests   brittle</li>
</ul>
<ul class="unIndentedList">
<li> Confusing product version #'s - Nmock2 is   actually a new team that picked up NMock and continued development</li>
</ul>
</td>
<td width="360" valign="top"><strong>TypeMock.Net</strong></p>
<ul class="unIndentedList">
<li> Powerful framework that uses redirection at   the IL level to create mocks</li>
</ul>
<ul class="unIndentedList">
<li> Expensive ($450/license)</li>
</ul>
<ul class="unIndentedList">
<li> TDD Purists argue that the power of it leads   to poorer design</li>
</ul>
</td>
</tr>
</tbody>
</table>
<p>The above observations were gleaned from many web pages, documentation repositories and blog posts, and reflect my limited understanding of each framework.  <em><strong> There may be errors</strong></em>.   If you think I'm wrong, or you can think of other capability aspects that I've overlooked, please let me know!</p>
<p><a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fwww.phpvs.net%2f2009%2f04%2f25%2fnet-mocking-frameworks-capability-comparison%2f"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.phpvs.net%2f2009%2f04%2f25%2fnet-mocking-frameworks-capability-comparison%2f&amp;bgcolor=FF9933&amp;cbgcolor=D4E1FD" border="0" alt="kick it on DotNetKicks.com" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.phpvs.net/2009/04/25/net-mocking-frameworks-capability-comparison/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Fixing &quot;Error 320 (net::ERR_INVALID_RESPONSE): Unknown error&quot; with Google Chrome</title>
		<link>http://www.phpvs.net/2009/03/26/fixing-error-320-neterr_invalid_response-unknown-error-with-google-chrome/</link>
		<comments>http://www.phpvs.net/2009/03/26/fixing-error-320-neterr_invalid_response-unknown-error-with-google-chrome/#comments</comments>
		<pubDate>Thu, 26 Mar 2009 16:29:11 +0000</pubDate>
		<dc:creator>blake</dc:creator>
				<category><![CDATA[Browsers]]></category>
		<category><![CDATA[LAMP]]></category>

		<guid isPermaLink="false">http://www.phpvs.net/?p=75</guid>
		<description><![CDATA[Without starting a browser flamewar, I'll just say that Google Chrome is a nice idea, but I won't be switching any time soon. As software evolves, competitors always appear, distilling out the good parts of existing products to create their take on something, and make it better. Google has done that with Chrome; it's light [...]]]></description>
			<content:encoded><![CDATA[<p>Without starting a browser flamewar, I'll just say that Google Chrome is a nice idea, but I won't be switching any time soon.  As software evolves, competitors always appear, distilling out the good parts of existing products to create their take on something, and make it better.  Google has done that with Chrome; it's light and fast and responsive.  Unfortunately, it's still a bit green on the battlefield.</p>
<p>Take this particular error for instance:  <strong>Error 320 (net::ERR_INVALID_RESPONSE): Unknown error</strong>.  Have you seen this?  I was emailed the other day by someone who was browsing a site I am responsible for that "the site is down!  when will it be fixed?!".  Seeing that it was fine in all my "normal" test browsers (Firefox, Safari, Opera, IE6, IE7), I gritted my teeth against the inevitable email conversation to follow that would be necessary to get even the slightest helpful detail out of this person.</p>
<p>Eventually, it came out that this person was using Chrome, and sure enough, I immediately got the same error when I fired it up.  Not only was this particular site down, but every site on the server gave the same response.  Chrome would not load a single page from any site, complaining only that "Error 320 (net::ERR_INVALID_RESPONSE): Unknown error" was upon it, like some kind of HTTP Götterdämmerung.</p>
<p>Googling wasn't immediately helpful; mostly forum threads complaining about the same problem, but no real fixes were presented.  Amusingly, it seemed that at one time a lot of Chrome users couldn't use Chrome to access Gmail because of this error.  However, I managed to find <a href="http://code.google.com/p/chromium/issues/detail?id=138">a thread on Google code</a>  which turned out to be somewhat enlightening.  The problem appears to be in the way that Chrome handles HTTP headers, where certain forms of some HTTP headers will trigger the error, causing Chrome to pack it in.  To be fair, it's really a Windows/Microsoft problem, as the bug is apparently in the underlying <a href="http://msdn.microsoft.com/en-us/library/aa384273(VS.85).aspx">WinHTTP</a> service, which Chrome utilizes.</p>
<p>The good news is that the Google devs have apparently solved the problem by switching away from WinHTTP, and it has apparently been fixed in the development branches already.  Unfortunately, that's only good news if your average user has downloaded the development version of Chrome, and not if you're a website owner and someone is complaining about your site.</p>
<p>Armed with the knowledge that it was a header problem, without doing any further research I went ahead and upgraded Apache.  The server in question had been running version 2.2.6, and I upgraded to Apache 2.2.11.</p>
<p>I was extremely pleased to discover that this <strong><em>actually fixed the problem</em></strong>.  Chrome immediately worked just fine, and I immediately cracked open a self-congratulatory beer.</p>
<p>Without examining the Apache changelogs to discover what might have fixed it, I'm happy to just give kudos to those people that deal with that level of the web, and were clever enough to change/fix whichever header it was (I have a hunch it was a mod_rewrite issue, but I'm talking out my posterior on that one).  That being said, Chrome (and WinHTTP) should be able to handle invalid HTTP headers, especially if it's an unimportant one and the page content can be salvaged.  It's the web... things get garbled and junky all the time (have you ever seen a MySpace page?)</p>
<p>Unfortunately, the end result of this is that now I have <strong>yet another browser</strong> that I have to check things with when doing web development.</p>
<p>Just what I wanted Chrome to be.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.phpvs.net/2009/03/26/fixing-error-320-neterr_invalid_response-unknown-error-with-google-chrome/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Defend PHP</title>
		<link>http://www.phpvs.net/2009/03/21/defend-php/</link>
		<comments>http://www.phpvs.net/2009/03/21/defend-php/#comments</comments>
		<pubDate>Sun, 22 Mar 2009 04:27:47 +0000</pubDate>
		<dc:creator>morgan</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.phpvs.net/?p=71</guid>
		<description><![CDATA[I ran across a great discussion at StackOverflow today that started with this question: I made a tongue-in-cheek comment in another question thread calling PHP a terrible language and it got down-voted like crazy. Apparently there are lots of people here who love PHP. So I'm genuinely curious. What am I missing? Why makes PHP [...]]]></description>
			<content:encoded><![CDATA[<p>I ran across <a title="Convince me that PHP isn't horrible" href="http://stackoverflow.com/questions/309300/defend-php-convince-me-it-isnt-horrible" target="_blank">a great discussion at StackOverflow</a> today that started with this question:</p>
<blockquote><p>I made a tongue-in-cheek comment in another question thread calling PHP a terrible language and it got down-voted like crazy. Apparently there are lots of people here who love PHP.</p>
<p>So I'm genuinely curious. What am I missing? Why makes PHP a good language?</p></blockquote>
<p>The article lists a dozen or so "flaws" with the language, and then continues:</p>
<blockquote><p>Worst of all, PHP convinces people that designing web applications is easy. And it does indeed make much of the effort involved much easier. But the fact is, designing a web application that is both secure and efficient is a very difficult task.</p>
<p>By convincing so many to take up programming, PHP has taught an entire subgroup of programmers bad habits and bad design. It's given them access to capabilities that they lack the understanding to use safely. This has led to PHP's reputation as being insecure.</p></blockquote>
<p>Are the flaws in PHP really any different from any other language?</p>
<p>I'm a C# programmer, and I have to disagree with what some of what the original poster asserted were flaws with PHP.  Overly broad implicit type conversions?  Too easy to couple presentation with logic?  Heck, those are the reasons it's so popular in the first place!  Making web programming easy is a flaw?  Wut?</p>
<p>After wrestling with the back and forth in that discussion, I came to a simple conclusion.    This person has fallaciously concluded that PHP is a bad language based on his perception of its compliance with ivory-tower, computer science academia concepts.   Most of his criteria could basically describe Perl, Javascript, VBScript, heck, even VB6, HTML and C.</p>
<p>Of course PHP isn't a horrible language.  It's simply a tool, and based on its wild popularity and simple learning curve, only a fool could conclude that it was a bad one.  Even if it breeds more "unsafe programmers" (which I doubt highly), it's simply not the language's responsibility to restrict what you can do just because you might do it.</p>
<p>Every programmer should be able to see that.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.phpvs.net/2009/03/21/defend-php/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

