<?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>The Why and The How &#187; PHP</title> <atom:link href="http://www.thewhyandthehow.com/category/php/feed/" rel="self" type="application/rss+xml" /><link>http://www.thewhyandthehow.com</link> <description>Just another WordPress weblog</description> <lastBuildDate>Fri, 09 Jul 2010 02:32:51 +0000</lastBuildDate> <generator>http://wordpress.org/?v=2.8.4</generator> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <item><title>Signing AWS requests in PHP</title><link>http://www.thewhyandthehow.com/signing-aws-requests-in-php/</link> <comments>http://www.thewhyandthehow.com/signing-aws-requests-in-php/#comments</comments> <pubDate>Wed, 19 Aug 2009 22:58:15 +0000</pubDate> <dc:creator>admin</dc:creator> <category><![CDATA[Development]]></category> <category><![CDATA[PHP]]></category><guid
isPermaLink="false">http://www.thewhyandthehow.com/?p=750</guid> <description><![CDATA[Recently Amazon added the requirement that all requests must be signed. The process of signing requests is documented on this product advertising API page. Based on the steps listed there, and with a lot of help from @giltotherescue, I was able to create a PHP function to create a signed request URI based on a [...]]]></description> <content:encoded><![CDATA[<p>Recently Amazon added the requirement that all requests must be signed. The process of signing requests is documented on this <a
href="http://docs.amazonwebservices.com/AWSECommerceService/latest/DG/index.html?rest-signature.html">product advertising API</a> page. Based on the steps listed there, and with a lot of help from <a
href="http://twitter.com/giltotherescue">@giltotherescue</a>, I was able to create a PHP function to create a signed request URI based on a simple set of request parameters.</p><div
id="wp_codebox_msgheader"><span
class="right"><a
href="javascript:;" onclick="toggle_collapse('p7504');">[<span
id="p7504_symbol">-</span>]</a><sup><a
href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span
style="color: #99cc00">?</span></a></sup></span><span
class="left"><a
href="javascript:;" onclick="javascript:showCodeTxt('p750code4'); return false;">View Code</a> PHP</span><div
class="codebox_clear"></div></div><div
id="wp_codebox"><table
width="100%" ><tr
id="p7504"><td
class="code" id="p750code4"><pre class="php"><span style="color: #000000; font-weight: bold;">function</span> makeAWSUrl<span style="color: #009900;">&#40;</span><span style="color: #000033;">$parameters</span><span style="color: #339933;">,</span> <span style="color: #000033;">$associate_tag</span><span style="color: #339933;">,</span> <span style="color: #000033;">$access_key</span><span style="color: #339933;">,</span> <span style="color: #000033;">$secret_key</span><span style="color: #339933;">,</span> <span style="color: #000033;">$aws_version</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'2009-06-01'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000033;">$host</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'ecs.amazonaws.com'</span><span style="color: #339933;">;</span>
  <span style="color: #000033;">$path</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'/onca/xml'</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000033;">$query</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span>        
    <span style="color: #0000ff;">'Service'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'AWSECommerceService'</span><span style="color: #339933;">,</span>
    <span style="color: #0000ff;">'AWSAccessKeyId'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000033;">$access_key</span><span style="color: #339933;">,</span>
    <span style="color: #0000ff;">'AssociateTag'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000033;">$associate_tag</span><span style="color: #339933;">,</span>
    <span style="color: #0000ff;">'Timestamp'</span> <span style="color: #339933;">=&gt;</span> <a href="http://www.php.net/gmdate"><span style="color: #990000;">gmdate</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Y-m-d<span style="color: #000099; font-weight: bold;">\T</span>H:i:s<span style="color: #000099; font-weight: bold;">\Z</span>'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    <span style="color: #0000ff;">'Version'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000033;">$aws_version</span><span style="color: #339933;">,</span>
  <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// Merge in any options that were passed in</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><a href="http://www.php.net/is_array"><span style="color: #990000;">is_array</span></a><span style="color: #009900;">&#40;</span><span style="color: #000033;">$parameters</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000033;">$query</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/array_merge"><span style="color: #990000;">array_merge</span></a><span style="color: #009900;">&#40;</span><span style="color: #000033;">$query</span><span style="color: #339933;">,</span> <span style="color: #000033;">$parameters</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// Do a case-insensitive, natural order sort on the array keys.</span>
  <a href="http://www.php.net/ksort"><span style="color: #990000;">ksort</span></a><span style="color: #009900;">&#40;</span><span style="color: #000033;">$query</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// create the signable string</span>
  <span style="color: #000033;">$temp</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000033;">$query</span> <span style="color: #b1b100;">as</span> <span style="color: #000033;">$k</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000033;">$v</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000033;">$temp</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/str_replace"><span style="color: #990000;">str_replace</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'%7E'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'~'</span><span style="color: #339933;">,</span> <a href="http://www.php.net/rawurlencode"><span style="color: #990000;">rawurlencode</span></a><span style="color: #009900;">&#40;</span><span style="color: #000033;">$k</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'='</span> <span style="color: #339933;">.</span> <a href="http://www.php.net/str_replace"><span style="color: #990000;">str_replace</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'%7E'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'~'</span><span style="color: #339933;">,</span> <a href="http://www.php.net/rawurlencode"><span style="color: #990000;">rawurlencode</span></a><span style="color: #009900;">&#40;</span><span style="color: #000033;">$v</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  <span style="color: #000033;">$signable</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/implode"><span style="color: #990000;">implode</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'&amp;'</span><span style="color: #339933;">,</span> <span style="color: #000033;">$temp</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000033;">$stringToSign</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;GET<span style="color: #000099; font-weight: bold;">\n</span>$host<span style="color: #000099; font-weight: bold;">\n</span>$path<span style="color: #000099; font-weight: bold;">\n</span>$signable&quot;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// Hash the AWS secret key and generate a signature for the request.</span>
  <span style="color: #000033;">$hex_str</span> <span style="color: #339933;">=</span> hash_hmac<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'sha256'</span><span style="color: #339933;">,</span> <span style="color: #000033;">$stringToSign</span><span style="color: #339933;">,</span> <span style="color: #000033;">$secret_key</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000033;">$raw</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000033;">$i</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> <span style="color: #000033;">$i</span> <span style="color: #339933;">&lt;</span> <a href="http://www.php.net/strlen"><span style="color: #990000;">strlen</span></a><span style="color: #009900;">&#40;</span><span style="color: #000033;">$hex_str</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000033;">$i</span> <span style="color: #339933;">+=</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000033;">$raw</span> <span style="color: #339933;">.=</span> <a href="http://www.php.net/chr"><span style="color: #990000;">chr</span></a><span style="color: #009900;">&#40;</span><a href="http://www.php.net/hexdec"><span style="color: #990000;">hexdec</span></a><span style="color: #009900;">&#40;</span><a href="http://www.php.net/substr"><span style="color: #990000;">substr</span></a><span style="color: #009900;">&#40;</span><span style="color: #000033;">$hex_str</span><span style="color: #339933;">,</span> <span style="color: #000033;">$i</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000033;">$query</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'Signature'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/base64_encode"><span style="color: #990000;">base64_encode</span></a><span style="color: #009900;">&#40;</span><span style="color: #000033;">$raw</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <a href="http://www.php.net/ksort"><span style="color: #990000;">ksort</span></a><span style="color: #009900;">&#40;</span><span style="color: #000033;">$query</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000033;">$temp</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000033;">$query</span> <span style="color: #b1b100;">as</span> <span style="color: #000033;">$k</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000033;">$v</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000033;">$temp</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/rawurlencode"><span style="color: #990000;">rawurlencode</span></a><span style="color: #009900;">&#40;</span><span style="color: #000033;">$k</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'='</span> <span style="color: #339933;">.</span> <a href="http://www.php.net/rawurlencode"><span style="color: #990000;">rawurlencode</span></a><span style="color: #009900;">&#40;</span><span style="color: #000033;">$v</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  <span style="color: #000033;">$final</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/implode"><span style="color: #990000;">implode</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'&amp;'</span><span style="color: #339933;">,</span> <span style="color: #000033;">$temp</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #b1b100;">return</span> <span style="color: #0000ff;">'http://'</span> <span style="color: #339933;">.</span> <span style="color: #000033;">$host</span> <span style="color: #339933;">.</span> <span style="color: #000033;">$path</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'?'</span> <span style="color: #339933;">.</span> <span style="color: #000033;">$final</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div><p>Using the function is simple. The first parameter is a PHP array of AWS parameters, the others are standard associate tags and keys. Here&#8217;s an example:</p><div
id="wp_codebox_msgheader"><span
class="right"><a
href="javascript:;" onclick="toggle_collapse('p7505');">[<span
id="p7505_symbol">-</span>]</a><sup><a
href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span
style="color: #99cc00">?</span></a></sup></span><span
class="left"><a
href="javascript:;" onclick="javascript:showCodeTxt('p750code5'); return false;">View Code</a> PHP</span><div
class="codebox_clear"></div></div><div
id="wp_codebox"><table
width="100%" ><tr
id="p7505"><td
class="code" id="p750code5"><pre class="php"><span style="color: #000033;">$url</span> <span style="color: #339933;">=</span> makeAWSUrl<span style="color: #009900;">&#40;</span><a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Keywords'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Jaco Pastorius'</span><span style="color: #339933;">,</span>                           
                      <span style="color: #0000ff;">'Operation'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'ItemSearch'</span><span style="color: #339933;">,</span>                          
                      <span style="color: #0000ff;">'ResponseGroup'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Medium'</span><span style="color: #339933;">,</span>                           
                      <span style="color: #0000ff;">'SearchIndex'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Music'</span><span style="color: #339933;">,</span>                           
                      <span style="color: #0000ff;">'salesrank'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Bestselling'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>  
  <span style="color: #0000ff;">'YOUR_ASSOC_TAG'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'YOUR_ACCESS_KEY'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'YOUR_SECRET_KEY'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div><p>The result of the above call (using my tags and keys) is:</p><div
id="wp_codebox_msgheader"><span
class="right"><a
href="javascript:;" onclick="toggle_collapse('p7506');">[<span
id="p7506_symbol">-</span>]</a><sup><a
href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span
style="color: #99cc00">?</span></a></sup></span><span
class="left"><a
href="javascript:;" onclick="javascript:showCodeTxt('p750code6'); return false;">View Code</a> PHP</span><div
class="codebox_clear"></div></div><div
id="wp_codebox"><table
width="100%" ><tr
id="p7506"><td
class="code" id="p750code6"><pre class="php">http<span style="color: #339933;">:</span><span style="color: #666666; font-style: italic;">//ecs.amazonaws.com/onca/xml?AWSAccessKeyId=[MYKEY]&amp;AssociateTag=blakesblogand-20&amp;Keywords=Jaco%20Pastorius&amp;Operation=ItemSearch&amp;ResponseGroup=Medium&amp;SearchIndex=Music&amp;Service=AWSECommerceService&amp;Signature=qZ%2BheDqfZi79b2Xg0JSP2kgG2FgQn823GLn0m1sVmnM%3D&amp;Timestamp=2009-08-19T22%3A53%3A29Z&amp;Version=2009-06-01&amp;salesrank=Bestselling</span></pre></td></tr></table></div><p>As always, give me some feedback, take the code and make it better. Share it and include it in your libraries &#8230; have fun!</p> ]]></content:encoded> <wfw:commentRss>http://www.thewhyandthehow.com/signing-aws-requests-in-php/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>SCP for Komodo IDE</title><link>http://www.thewhyandthehow.com/scp-for-komodo-ide/</link> <comments>http://www.thewhyandthehow.com/scp-for-komodo-ide/#comments</comments> <pubDate>Tue, 18 Aug 2009 00:15:33 +0000</pubDate> <dc:creator>admin</dc:creator> <category><![CDATA[Development]]></category> <category><![CDATA[Javascript]]></category> <category><![CDATA[PHP]]></category> <category><![CDATA[Technology]]></category><guid
isPermaLink="false">http://www.thewhyandthehow.com/?p=746</guid> <description><![CDATA[I have just finished developing my first Komodo IDE plugin. I love Komodo. It&#8217;s the first IDE for PHP that I&#8217;ve been very, very happy using. I&#8217;ve run it on Windows, Linux and now on a MacBook. The only frustration I&#8217;ve had is that Komodo doesn&#8217;t support basic integrated file uploading via SCP. While it [...]]]></description> <content:encoded><![CDATA[<p>I have just finished developing my first <a
href="http://www.activestate.com/komodo/">Komodo IDE</a> plugin. I love Komodo. It&#8217;s the first IDE for PHP that I&#8217;ve been very, very happy using. I&#8217;ve run it on Windows, Linux and now on a MacBook. The only frustration I&#8217;ve had is that Komodo doesn&#8217;t support basic integrated file uploading via SCP. While it is possible to save a file remotely, there is no simple way to save a file locally and upload it to a mapped location on a remote server from within the IDE.</p><p>Fortunately Komodo also provides a simple method for creating extensions within the IDE itself, so I gave it a try. Within a few hours I was able to build an extension to do exactly what I needed and configure it on a per-project basis. I&#8217;ve made the extension available as an <a
href="http://code.google.com/p/scp-for-komodo-ide/">MIT-licensed, open-source project</a>. As always, this project is included on the <a
href="http://www.thewhyandthehow.com/open-source-tools/">open source tools page</a>.</p> ]]></content:encoded> <wfw:commentRss>http://www.thewhyandthehow.com/scp-for-komodo-ide/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Another way to cache</title><link>http://www.thewhyandthehow.com/another-way-to-cache/</link> <comments>http://www.thewhyandthehow.com/another-way-to-cache/#comments</comments> <pubDate>Thu, 11 Jun 2009 23:23:40 +0000</pubDate> <dc:creator>admin</dc:creator> <category><![CDATA[PHP]]></category> <category><![CDATA[Technology]]></category><guid
isPermaLink="false">http://www.thewhyandthehow.com/?p=731</guid> <description><![CDATA[Obviously, I&#8217;m a big fan of the performance increases that can be achieved by using memcache. Another potential cache-based tool for enhancing your server-side PHP code is to use an opcode compiler and caching tool such as APC.
In addition to being a fantastic piece of technology by itself, APC also provides meaningful tuning options and [...]]]></description> <content:encoded><![CDATA[<p>Obviously, I&#8217;m a big fan of the performance increases that can be achieved by using <a
href="http://www.thewhyandthehow.com/memcache-memcache-memcache/">memcache</a>. Another potential cache-based tool for enhancing your server-side PHP code is to use an <a
href="http://en.wikipedia.org/wiki/PHP_accelerator">opcode compiler and caching tool</a> such as <a
href="http://us2.php.net/apc">APC</a>.</p><p><img
src="http://www.thewhyandthehow.com/wp-content/uploads/2009/06/apc-stats-graph-286x300.png" alt="apc-stats-graph" title="apc-stats-graph" width="286" height="300" class="left border size-medium wp-image-732" />In addition to being a fantastic piece of technology by itself, APC also provides meaningful <a
href="http://us3.php.net/manual/en/apc.configuration.php">tuning options</a> and detailed statistics. The screen shot here shows just a fraction of the information collected by APC.</p><p>So far, my experience with APC has been very positive, but don&#8217;t take my word for it. Check out some of the performance results: <a
href="http://coder1.com/articles/php-apc-performance-tests-apache-ab">here</a>, <a
href="http://mediakey.dk/~cc/php-52-and-apc-alternative-php-cache-performance/">here</a> and <a
href="http://blog.digitalstruct.com/2007/12/23/php-accelerators-apc-vs-zend-vs-xcache-with-zend-framework/">here</a>.</p><p>As always, tuning to a particular application or server is critical. Be sure to <a
href="http://us2.php.net/apc">read the manual</a>!</p> ]]></content:encoded> <wfw:commentRss>http://www.thewhyandthehow.com/another-way-to-cache/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Memcache, memcache, memcache!</title><link>http://www.thewhyandthehow.com/memcache-memcache-memcache/</link> <comments>http://www.thewhyandthehow.com/memcache-memcache-memcache/#comments</comments> <pubDate>Wed, 20 May 2009 23:31:29 +0000</pubDate> <dc:creator>Blake Schwendiman</dc:creator> <category><![CDATA[General]]></category> <category><![CDATA[PHP]]></category> <category><![CDATA[REST]]></category> <category><![CDATA[Technology]]></category> <category><![CDATA[memcache]]></category> <category><![CDATA[programming]]></category><guid
isPermaLink="false">http://www.thewhyandthehow.com/?p=706</guid> <description><![CDATA[Possibly the single-most important piece of advice I give to every software developer right now is to use memcache (or memcached to be specific). I&#8217;ve become an evangelist of the software since working for Squidoo.
Memcache is just exactly what it says it is &#8212; a memory cache daemon (service). It&#8217;s lightweight and very fast and [...]]]></description> <content:encoded><![CDATA[<p>Possibly the single-most important piece of advice I give to every software developer right now is to <strong>use <a
href="http://www.danga.com/memcached/">memcache</a></strong> (or memcached to be specific). I&#8217;ve become an evangelist of the software since working for <a
href="http://www.squidoo.com/building-squidoo">Squidoo</a>.</p><p>Memcache is just exactly what it says it is &#8212; a memory cache daemon (service). It&#8217;s lightweight and very fast and can be used for all kinds of caching: page, database, remote data, etc., etc.</p><p>I use it on this blog in conjunction with fetching the Twitter comments that appear in the right-hand sidebar on the home page, for example. Here&#8217;s the general pseudo code for how memcache is used:</p><pre>
  key = generate_cache_key()
  if (value = is_key_in_cache(key))
    return value
  get_uncached_value() // DB, REST, complex code, etc.
  save_to_cache(key, value)
</pre><p>My actual implementation for the Twitter backtweets looks something like this:</p><div
id="wp_codebox_msgheader"><span
class="right"><a
href="javascript:;" onclick="toggle_collapse('p7069');">[<span
id="p7069_symbol">-</span>]</a><sup><a
href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span
style="color: #99cc00">?</span></a></sup></span><span
class="left"><a
href="javascript:;" onclick="javascript:showCodeTxt('p706code9'); return false;">View Code</a> PHP</span><div
class="codebox_clear"></div></div><div
id="wp_codebox"><table
width="100%" ><tr
id="p7069"><td
class="code" id="p706code9"><pre class="php"><span style="color: #000033;">$uri</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'http://backtweets.com/search.json?q=www.thewhyandthehow.com&amp;key=API-KEY'</span><span style="color: #339933;">;</span>
<span style="color: #000033;">$cache_key</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'rest-service-'</span> <span style="color: #339933;">.</span> <a href="http://www.php.net/md5"><span style="color: #990000;">md5</span></a><span style="color: #009900;">&#40;</span><span style="color: #000033;">$uri</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000033;">$result</span> <span style="color: #339933;">=</span> Helpers<span style="color: #339933;">::</span><span style="color: #004000;">cacheGet</span><span style="color: #009900;">&#40;</span><span style="color: #000033;">$cache_key</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>  
  <span style="color: #b1b100;">return</span> <span style="color: #000033;">$result</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000033;">$result</span> <span style="color: #339933;">=</span> Helpers<span style="color: #339933;">::</span><span style="color: #004000;">remoteLoad</span><span style="color: #009900;">&#40;</span><span style="color: #000033;">$uri</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// check valid $result here</span>
&nbsp;
Helpers<span style="color: #339933;">::</span><span style="color: #004000;">cacheSet</span><span style="color: #009900;">&#40;</span><span style="color: #000033;">$cache_key</span><span style="color: #339933;">,</span> <span style="color: #000033;">$result</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">20</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">return</span> <span style="color: #000033;">$result</span><span style="color: #339933;">;</span></pre></td></tr></table></div><p>The helper functions look like this (class declaration not shown for brevity):</p><div
id="wp_codebox_msgheader"><span
class="right"><a
href="javascript:;" onclick="toggle_collapse('p70610');">[<span
id="p70610_symbol">-</span>]</a><sup><a
href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span
style="color: #99cc00">?</span></a></sup></span><span
class="left"><a
href="javascript:;" onclick="javascript:showCodeTxt('p706code10'); return false;">View Code</a> PHP</span><div
class="codebox_clear"></div></div><div
id="wp_codebox"><table
width="100%" ><tr
id="p70610"><td
class="code" id="p706code10"><pre class="php">    <span style="color: #000000; font-weight: bold;">public</span> <a href="http://www.php.net/static"><span style="color: #990000;">static</span></a> <span style="color: #000000; font-weight: bold;">function</span> getCache<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>self<span style="color: #339933;">::</span><span style="color: #000033;">$cache</span> <span style="color: #339933;">==</span> <span style="color: #000000; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
         <span style="color: #000033;">$temp</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Memcache<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
         <span style="color: #000033;">$temp</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">connect</span><span style="color: #009900;">&#40;</span>MEMCACHE_HOST<span style="color: #339933;">,</span> MEMCACHE_PORT<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
         self<span style="color: #339933;">::</span><span style="color: #000033;">$cache</span> <span style="color: #339933;">=</span> <span style="color: #000033;">$temp</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
&nbsp;
      <span style="color: #b1b100;">return</span> self<span style="color: #339933;">::</span><span style="color: #000033;">$cache</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">/**
     * set a value to the memcache
     *
     * @param string key name
     * @param mixed value
     * @param integer timeout (default 1 day)
     * @param boolean compression flag
     * @return boolean success
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <a href="http://www.php.net/static"><span style="color: #990000;">static</span></a> <span style="color: #000000; font-weight: bold;">function</span> cacheSet<span style="color: #009900;">&#40;</span><span style="color: #000033;">$key</span><span style="color: #339933;">,</span> <span style="color: #000033;">$value</span><span style="color: #339933;">,</span> <span style="color: #000033;">$timeout</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">86400</span><span style="color: #339933;">,</span> <span style="color: #000033;">$compress</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000033;">$cache</span> <span style="color: #339933;">=</span> self<span style="color: #339933;">::</span><span style="color: #004000;">getCache</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #000033;">$result</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">false</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000033;">$timeout</span> <span style="color: #339933;">&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000033;">$timeout</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/min"><span style="color: #990000;">min</span></a><span style="color: #009900;">&#40;</span><span style="color: #000033;">$timeout</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">2592000</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
&nbsp;
      <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000033;">$compress</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000033;">$result</span> <span style="color: #339933;">=</span> <span style="color: #000033;">$cache</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">set</span><span style="color: #009900;">&#40;</span><span style="color: #000033;">$key</span><span style="color: #339933;">,</span> <span style="color: #000033;">$value</span><span style="color: #339933;">,</span> MEMCACHE_COMPRESSED<span style="color: #339933;">,</span> <span style="color: #000033;">$timeout</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000033;">$result</span> <span style="color: #339933;">=</span> <span style="color: #000033;">$cache</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">set</span><span style="color: #009900;">&#40;</span><span style="color: #000033;">$key</span><span style="color: #339933;">,</span> <span style="color: #000033;">$value</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: #000033;">$timeout</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">/**
     * get an item from the cache
     *
     * @param string key
     * @return mixed value or false
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <a href="http://www.php.net/static"><span style="color: #990000;">static</span></a> <span style="color: #000000; font-weight: bold;">function</span> cacheGet<span style="color: #009900;">&#40;</span><span style="color: #000033;">$key</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000033;">$cache</span> <span style="color: #339933;">=</span> self<span style="color: #339933;">::</span><span style="color: #004000;">getCache</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #b1b100;">return</span> <span style="color: #000033;">$cache</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #000033;">$key</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span></pre></td></tr></table></div><p>As you can see the code is very simple. The <strong>cacheGet</strong> function is trivial, so no discussion is needed. The <strong>cacheSet</strong> function is a little more complex, but basically that is to support a very simple calling convention and to ensure that the parameters are sane. One obviously missing check is to ensure that the Memcache variable returned by <strong>getCache</strong> is valid &#8212; I guess I have some work to do.</p><p>The advantage for using caching in this manner should be obvious. Instead of requiring an actual HTTP request per pageview, this method keeps a copy around for 20 minutes before initiating another request to the <a
href="http://backtweets.com/">backtweets.com</a> servers. This is friendly to the remote servers while also increasing the responsiveness of my application.</p><p>This logic applies to any big, slow or heavy processes that might occur on a web server, not just remote HTTP requests. If your application generates lots of mostly-static HTML markup that is re-used or requested frequently, it could be cached in memcache. If you have any big or frequently-requested database queries, throw the results in memcache and take the load off of your DB server.</p><p>AND&#8230;</p><p>Since memcache is based on TCP/IP, it doesn&#8217;t have to run locally relative to your application server. Have one big memcache box, or two, or three, and make requests from all of your application servers.</p><p>If your application is falling over because of load, you might want to take a look at the problem spots. You&#8217;ll probably find that using memcache will reduce overall load on your database and application servers and increase the responsiveness of your site.</p> ]]></content:encoded> <wfw:commentRss>http://www.thewhyandthehow.com/memcache-memcache-memcache/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Amazon web services change for associates</title><link>http://www.thewhyandthehow.com/amazon-web-services-change-for-associates/</link> <comments>http://www.thewhyandthehow.com/amazon-web-services-change-for-associates/#comments</comments> <pubDate>Sat, 09 May 2009 00:36:00 +0000</pubDate> <dc:creator>Blake Schwendiman</dc:creator> <category><![CDATA[Development]]></category> <category><![CDATA[PHP]]></category> <category><![CDATA[REST]]></category> <category><![CDATA[Technology]]></category> <category><![CDATA[aws]]></category> <category><![CDATA[tech]]></category><guid
isPermaLink="false">http://www.thewhyandthehow.com/?p=677</guid> <description><![CDATA[Although I haven&#8217;t written about it yet, for me the most important set of web services and APIs for my work are provided by Amazon. Without a doubt I use these services more than any others. Today I received this message:Effective immediately, we are renaming the Amazon Associates Web Service as the “Product Advertising API.” [...]]]></description> <content:encoded><![CDATA[<p>Although I haven&#8217;t written about it yet, for me the most important set of web services and APIs for my work are provided by Amazon. Without a doubt I use these services more than any others. Today I received this message:</p><div
class="quote"><p>Effective immediately, we are renaming the Amazon Associates Web Service as the “Product Advertising API.” This new name more accurately reflects the purpose of the API, which is to enable developers to advertise products offered on the Amazon sites and thereby receive advertising fees from us.</p><p
class="para-break">In addition to the new name, signatures will be necessary to authenticate each call to the Product Advertising API. This requirement will be phased in starting May 11, 2009, and by August 15, 2009, all calls to the Product Advertising API must be authenticated or they will not be processed.</p></div><p>Because this will have a big impact on any developer, I wanted to share a couple of links I found today. First is the documentation page: <a
href="http://docs.amazonwebservices.com/AWSECommerceService/latest/DG/rest-signature.html">Signing AWS Commerce API requests</a>. The second is a recommendation from <a
href="http://twitter.com/giltotherescue">Gil</a> (the genius that keeps <a
href="http://www.squidoo.com/">Squidoo</a> running): <a
href="http://tarzan-aws.com/">Tarzan: A fast, powerful PHP toolkit for building web applications with Amazon Web Services</a>. This library looks like a great resource for developing against many of the AWS services. I&#8217;ll be doing some investigation and will follow up when I can talk more intelligently about it.</p><p>For now, good luck with your current AWS projects!</p> ]]></content:encoded> <wfw:commentRss>http://www.thewhyandthehow.com/amazon-web-services-change-for-associates/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Building an Ajax content proxy in PHP</title><link>http://www.thewhyandthehow.com/building-an-ajax-content-proxy-in-php/</link> <comments>http://www.thewhyandthehow.com/building-an-ajax-content-proxy-in-php/#comments</comments> <pubDate>Tue, 05 May 2009 17:21:47 +0000</pubDate> <dc:creator>Blake Schwendiman</dc:creator> <category><![CDATA[Development]]></category> <category><![CDATA[Javascript]]></category> <category><![CDATA[PHP]]></category> <category><![CDATA[Technology]]></category> <category><![CDATA[Tutorial]]></category> <category><![CDATA[jQuery]]></category> <category><![CDATA[Ajax]]></category><guid
isPermaLink="false">http://www.thewhyandthehow.com/?p=644</guid> <description><![CDATA[Last week I wanted to write an article about using Google docs as a data store for use in Javascript, but in order to do so, I first need to provide a basic article about content proxies.
For security reasons, Ajax requests are only allowed to domains from which the code originates. For example, if your [...]]]></description> <content:encoded><![CDATA[<p>Last week I wanted to write an article about using Google docs as a data store for use in Javascript, but in order to do so, I first need to provide a basic article about content proxies.</p><p>For security reasons, Ajax requests are only allowed to domains from which the code originates. For example, if your site is at example.com, and your Javascript is served from that domain, you may only use Ajax to make HTTP requests to the same domain, example.com. If you want to retrieve data from other web services such as <a
href="http://developer.yahoo.com/finance/">financial information</a> or <a
href="http://developer.yahoo.com/finance/">weather</a> from <a
href="http://developer.yahoo.com/">Yahoo!</a>, you cannot make a direct Ajax request to yahoo.com, but you can make a request to a content proxy on example.com that gets the data from Yahoo! and returns it for you.</p><p>A very simple content proxy in PHP is implemented (using curl) like this:</p><div
id="wp_codebox_msgheader"><span
class="right"><a
href="javascript:;" onclick="toggle_collapse('p64414');">[<span
id="p64414_symbol">-</span>]</a><sup><a
href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span
style="color: #99cc00">?</span></a></sup></span><span
class="left"><a
href="javascript:;" onclick="javascript:showCodeTxt('p644code14'); return false;">View Code</a> PHP</span><div
class="codebox_clear"></div></div><div
id="wp_codebox"><table
width="100%" ><tr
id="p64414"><td
class="code" id="p644code14"><pre class="php"><span style="color: #666666; font-style: italic;">/**
* perform a remote connection request and return the results
* 
* @param string uri of remote resource
* @param int timeout in seconds
* @param int connection timeout in seconds
* 
* @return string data returned from uri or null
*/</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> remote_load<span style="color: #009900;">&#40;</span><span style="color: #000033;">$uri</span><span style="color: #339933;">,</span> <span style="color: #000033;">$timeout</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">10</span><span style="color: #339933;">,</span> <span style="color: #000033;">$connect_timeout</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">3</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000033;">$curl_handle</span> <span style="color: #339933;">=</span> curl_init<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  curl_setopt<span style="color: #009900;">&#40;</span><span style="color: #000033;">$curl_handle</span><span style="color: #339933;">,</span> CURLOPT_USERAGENT<span style="color: #339933;">,</span> <span style="color: #0000ff;">'example.com'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  curl_setopt<span style="color: #009900;">&#40;</span><span style="color: #000033;">$curl_handle</span><span style="color: #339933;">,</span> CURLOPT_URL<span style="color: #339933;">,</span> <span style="color: #000033;">$uri</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  curl_setopt<span style="color: #009900;">&#40;</span><span style="color: #000033;">$curl_handle</span><span style="color: #339933;">,</span> CURLOPT_RETURNTRANSFER<span style="color: #339933;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  curl_setopt<span style="color: #009900;">&#40;</span><span style="color: #000033;">$curl_handle</span><span style="color: #339933;">,</span> CURLOPT_CONNECTTIMEOUT<span style="color: #339933;">,</span> <span style="color: #000033;">$connect_timeout</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  curl_setopt<span style="color: #009900;">&#40;</span><span style="color: #000033;">$curl_handle</span><span style="color: #339933;">,</span> CURLOPT_TIMEOUT<span style="color: #339933;">,</span> <span style="color: #000033;">$timeout</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  curl_setopt<span style="color: #009900;">&#40;</span><span style="color: #000033;">$curl_handle</span><span style="color: #339933;">,</span> CURLOPT_FOLLOWLOCATION<span style="color: #339933;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000033;">$buffer</span>   <span style="color: #339933;">=</span> curl_exec<span style="color: #009900;">&#40;</span><span style="color: #000033;">$curl_handle</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000033;">$curlinfo</span> <span style="color: #339933;">=</span> curl_getinfo<span style="color: #009900;">&#40;</span><span style="color: #000033;">$curl_handle</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  curl_close<span style="color: #009900;">&#40;</span><span style="color: #000033;">$curl_handle</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #000033;">$curlinfo</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'http_code'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&lt;</span> <span style="color: #cc66cc;">400</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #009900;">&#40;</span><span style="color: #000033;">$curlinfo</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'http_code'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">!=</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #000033;">$buffer</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #b1b100;">return</span> <span style="color: #000000; font-weight: bold;">null</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div><p>The above code would be included in a simple page such as:</p><div
id="wp_codebox_msgheader"><span
class="right"><a
href="javascript:;" onclick="toggle_collapse('p64415');">[<span
id="p64415_symbol">-</span>]</a><sup><a
href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span
style="color: #99cc00">?</span></a></sup></span><span
class="left"><a
href="javascript:;" onclick="javascript:showCodeTxt('p644code15'); return false;">View Code</a> PHP</span><div
class="codebox_clear"></div></div><div
id="wp_codebox"><table
width="100%" ><tr
id="p64415"><td
class="code" id="p644code15"><pre class="php"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
  <span style="color: #b1b100;">include_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'the_function_above'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// you really should check for and handle errors</span>
  <a href="http://www.php.net/print"><span style="color: #990000;">print</span></a><span style="color: #009900;">&#40;</span>remote_load<span style="color: #009900;">&#40;</span><span style="color: #000033;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'uri'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div><p>If the above page is called proxy.php on your site, then you can now make Ajax requests that look like:</p><div
id="wp_codebox_msgheader"><span
class="right"><a
href="javascript:;" onclick="toggle_collapse('p64416');">[<span
id="p64416_symbol">-</span>]</a><sup><a
href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span
style="color: #99cc00">?</span></a></sup></span><span
class="left"><a
href="javascript:;" onclick="javascript:showCodeTxt('p644code16'); return false;">View Code</a> JAVASCRIPT</span><div
class="codebox_clear"></div></div><div
id="wp_codebox"><table
width="100%" ><tr
id="p64416"><td
class="code" id="p644code16"><pre class="javascript">jQuery.<span style="color: #006600;">get</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'http://www.example.com/proxy.php?uri=http://www.google.com/'</span><span style="color: #339933;">,</span>
  <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>result<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    do_something_with_result<span style="color: #009900;">&#40;</span>result<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div><p>There are several considerations to make when developing a content proxy that haven&#8217;t been shown here. The first two that come to mind are security and caching. Requests to third-party services should be cached locally on your server to ensure that your application doesn&#8217;t make too many requests and potentially become blacklisted by the third-party service. Additionally, if you build a content proxy, you should ensure that only requests from your approved callers are satisfied. You don&#8217;t want other sites making proxy requests through your servers for many reasons.</p><p>The proxy shown above may be used as a starting point for a more secure and robust content proxy, though, and will be the basis for some of my upcoming Ajax articles.</p> ]]></content:encoded> <wfw:commentRss>http://www.thewhyandthehow.com/building-an-ajax-content-proxy-in-php/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>jQuery autocomplete</title><link>http://www.thewhyandthehow.com/jquery-autocomplete/</link> <comments>http://www.thewhyandthehow.com/jquery-autocomplete/#comments</comments> <pubDate>Wed, 29 Apr 2009 00:44:12 +0000</pubDate> <dc:creator>Blake Schwendiman</dc:creator> <category><![CDATA[Javascript]]></category> <category><![CDATA[PHP]]></category> <category><![CDATA[Technology]]></category> <category><![CDATA[Tutorial]]></category> <category><![CDATA[jQuery]]></category> <category><![CDATA[Ajax]]></category><guid
isPermaLink="false">http://www.thewhyandthehow.com/?p=603</guid> <description><![CDATA[Autocompletion of web-based forms has become so common that it has reached the point of being an expectation. Fortunately (again), there is a jQuery solution that makes this a simple addition to any form.
The first step is to download the jQuery Autocomplete plugin and check out the documentation. Make sure that you include the script [...]]]></description> <content:encoded><![CDATA[<link
rel="stylesheet" href="/wp-content/themes/thesis/custom/css/jquery.autocomplete.css" /><script type="text/javascript" src="/wp-content/themes/thesis/custom/js/jquery.autocomplete.min.js"></script><p>Autocompletion of web-based forms has become so common that it has reached the point of being an expectation. Fortunately (again), there is a jQuery solution that makes this a simple addition to any form.</p><p>The first step is to download the <a
href="http://bassistance.de/jquery-plugins/jquery-plugin-autocomplete/">jQuery Autocomplete plugin</a> and check out the <a
href="http://docs.jquery.com/Plugins/Autocomplete">documentation</a>. Make sure that you include the script and the CSS file, then build your form as normal and add a single call to the autocomplete plugin.</p><div
id="wp_codebox_msgheader"><span
class="right"><a
href="javascript:;" onclick="toggle_collapse('p60320');">[<span
id="p60320_symbol">-</span>]</a><sup><a
href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span
style="color: #99cc00">?</span></a></sup></span><span
class="left"><a
href="javascript:;" onclick="javascript:showCodeTxt('p603code20'); return false;">View Code</a> JAVASCRIPT</span><div
class="codebox_clear"></div></div><div
id="wp_codebox"><table
width="100%" ><tr
id="p60320"><td
class="code" id="p603code20"><pre class="javascript"><span style="color: #339933;">&lt;</span>form<span style="color: #339933;">&gt;</span>
  <span style="color: #339933;">&lt;</span>fieldset<span style="color: #339933;">&gt;</span>
    <span style="color: #339933;">&lt;</span>label<span style="color: #339933;">&gt;</span>Type <span style="color: #000066; font-weight: bold;">in</span> your favorite color<span style="color: #339933;">:</span> <span style="color: #339933;">&lt;</span>input type<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;text&quot;</span> id<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;color_input&quot;</span> <span style="color: #339933;">/&gt;&lt;/</span>label<span style="color: #339933;">&gt;</span>
  <span style="color: #339933;">&lt;/</span>fieldset<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;/</span>form<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;</span>script type<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;text/javascript&quot;</span><span style="color: #339933;">&gt;</span>
  jQuery<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#color_input'</span><span style="color: #009900;">&#41;</span>.<span style="color: #006600;">autocomplete</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'black'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'white'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'red'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'green'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'blue'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'yellow'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'purple'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'brown'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'silver'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'magenta'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'cyan'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'gold'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'goldenrod'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #339933;">&lt;/</span>script<span style="color: #339933;">&gt;</span></pre></td></tr></table></div><p>As you can see, the example above uses a simple Javascript array as the input to the <strong>autocomplete</strong> method. This implies a local, static list of lookup items. Here is the example:</p><form
class="example"><fieldset><label>Type in your favorite color:<br
/> <input
type="text" id="color_input" /></label></fieldset></form><p><script type="text/javascript">jQuery('#color_input').autocomplete(['black','white','red','green','blue','yellow','purple','brown','silver','magenta','cyan','gold','goldenrod']);</script></p><p>Now, if you want to make things really interesting, take the above idea and tie it together with an Ajax lookup. That way, the suggested items can be any list that pertains to the specific user and action related to the input. For example, the input box may be a list of counties for a specific state in the US. It may be a list of friends from a social network. It may be a book title or author from Amazon.</p><p>The basic code for an Ajax-based lookup is the same, but the parameter to the <strong>autocomplete</strong> function is a string URL instead of an array of items.</p><div
id="wp_codebox_msgheader"><span
class="right"><a
href="javascript:;" onclick="toggle_collapse('p60321');">[<span
id="p60321_symbol">-</span>]</a><sup><a
href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span
style="color: #99cc00">?</span></a></sup></span><span
class="left"><a
href="javascript:;" onclick="javascript:showCodeTxt('p603code21'); return false;">View Code</a> JAVASCRIPT</span><div
class="codebox_clear"></div></div><div
id="wp_codebox"><table
width="100%" ><tr
id="p60321"><td
class="code" id="p603code21"><pre class="javascript"><span style="color: #339933;">&lt;</span>form<span style="color: #339933;">&gt;</span>
  <span style="color: #339933;">&lt;</span>fieldset<span style="color: #339933;">&gt;</span>
    <span style="color: #339933;">&lt;</span>label<span style="color: #339933;">&gt;</span>Type <span style="color: #000066; font-weight: bold;">in</span> your favorite color<span style="color: #339933;">:</span> <span style="color: #339933;">&lt;</span>input type<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;text&quot;</span> id<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;color_input&quot;</span> <span style="color: #339933;">/&gt;&lt;/</span>label<span style="color: #339933;">&gt;</span>
  <span style="color: #339933;">&lt;/</span>fieldset<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;/</span>form<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;</span>script type<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;text/javascript&quot;</span><span style="color: #339933;">&gt;</span>
  jQuery<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#color_input'</span><span style="color: #009900;">&#41;</span>.<span style="color: #006600;">autocomplete</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'/relative/path/to/script'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #339933;">&lt;/</span>script<span style="color: #339933;">&gt;</span></pre></td></tr></table></div><p>The path to the script file can be either a relative or absolute URL. When the autocomplete function calls your custom script, it passes two parameters, <strong>q</strong> and <strong>limit</strong>. The <strong>q</strong> parameter is the value that the end-user has typed into the box and the <strong>limit</strong> is the number of items to return. See the <a
href="http://docs.jquery.com/Plugins/Autocomplete/autocomplete#url_or_dataoptions">jQuery autocomplete documentation</a> for more details.</p><p>For this example, I have written a very simple PHP script that shows how this might work on a typical web site. In the example, I use the <a
href="http://www.geonames.org/export/geonames-search.html">Geonames service</a> to lookup place names based on what is being typed. The PHP script looks like this:</p><div
id="wp_codebox_msgheader"><span
class="right"><a
href="javascript:;" onclick="toggle_collapse('p60322');">[<span
id="p60322_symbol">-</span>]</a><sup><a
href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span
style="color: #99cc00">?</span></a></sup></span><span
class="left"><a
href="javascript:;" onclick="javascript:showCodeTxt('p603code22'); return false;">View Code</a> PHP</span><div
class="codebox_clear"></div></div><div
id="wp_codebox"><table
width="100%" ><tr
id="p60322"><td
class="code" id="p603code22"><pre class="php">  <span style="color: #b1b100;">include_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'custom_functions.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000033;">$query</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/array_key_exists"><span style="color: #990000;">array_key_exists</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'q'</span><span style="color: #339933;">,</span> <span style="color: #000033;">$_GET</span><span style="color: #009900;">&#41;</span> ? <span style="color: #000033;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'q'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">:</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000033;">$url</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'http://ws.geonames.org/search?q='</span> <span style="color: #339933;">.</span> <span style="color: #000033;">$query</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'&amp;maxRows=10&amp;type=json'</span><span style="color: #339933;">;</span>
  <span style="color: #000033;">$result</span> <span style="color: #339933;">=</span> Helpers<span style="color: #339933;">::</span><span style="color: #004000;">remoteLoad</span><span style="color: #009900;">&#40;</span><span style="color: #000033;">$url</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">10</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">3</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">3</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'geoname-'</span> <span style="color: #339933;">.</span> <a href="http://www.php.net/md5"><span style="color: #990000;">md5</span></a><span style="color: #009900;">&#40;</span><span style="color: #000033;">$url</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">20</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000033;">$result</span> <span style="color: #339933;">=</span> json_decode<span style="color: #009900;">&#40;</span><span style="color: #000033;">$result</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000033;">$output_items</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000033;">$result</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">geonames</span> <span style="color: #b1b100;">as</span> <span style="color: #000033;">$item</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000033;">$output_items</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000033;">$item</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">name</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <a href="http://www.php.net/print"><span style="color: #990000;">print</span></a><span style="color: #009900;">&#40;</span><a href="http://www.php.net/implode"><span style="color: #990000;">implode</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> <span style="color: #000033;">$output_items</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div><p>I haven&#8217;t included the full include file source, but obviously there is a class which does remote URL loading. This portion is not important to the example. The relevant information is that the script looks up a list of place names by calling out to the remote service and then prints a carriage-return delimited list of names.</p><p>The autocomplete plug-in takes care of all the rest. Here is the resulting form. For example, type in <strong>London</strong> or <strong>New York</strong> to see how it works:</p><form
class="example"><fieldset><label>Enter a place name:<br
/> <input
type="text" id="place_input" /></label></fieldset></form><p><script type="text/javascript">jQuery('#place_input').autocomplete('/wp-content/themes/thesis/custom/ajax/places.php');</script></p><p>There are many other options to the autocomplete plugin that you should explore on the <a
href="http://docs.jquery.com/Plugins/Autocomplete">documentation page</a>, however you can see how quickly and simply a basic autocomplete field can be created using the defaults.</p> ]]></content:encoded> <wfw:commentRss>http://www.thewhyandthehow.com/jquery-autocomplete/feed/</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>Geeking out</title><link>http://www.thewhyandthehow.com/geeking-out/</link> <comments>http://www.thewhyandthehow.com/geeking-out/#comments</comments> <pubDate>Thu, 26 Mar 2009 12:42:11 +0000</pubDate> <dc:creator>Blake Schwendiman</dc:creator> <category><![CDATA[Development]]></category> <category><![CDATA[Javascript]]></category> <category><![CDATA[PHP]]></category> <category><![CDATA[jQuery]]></category> <category><![CDATA[api]]></category> <category><![CDATA[facebook]]></category> <category><![CDATA[twitter]]></category><guid
isPermaLink="false">http://www.thewhyandthehow.com/?p=381</guid> <description><![CDATA[I&#8217;ve enjoyed geeking out the past few days, but the example I wanted to show today is taking longer than I had expected, so I have to delay that one. I&#8217;m going to do more mini-tutorials and examples over the next few weeks, so stay tuned.
If you&#8217;re new to this site, please take a look [...]]]></description> <content:encoded><![CDATA[<p>I&#8217;ve enjoyed geeking out the past few days, but the example I wanted to show today is taking longer than I had expected, so I have to delay that one. I&#8217;m going to do more mini-tutorials and examples over the next few weeks, so stay tuned.</p><p>If you&#8217;re new to this site, please take a look at a few of the recent articles covering topics such as <a
href="http://www.thewhyandthehow.com/integrating-facebook-connect-using-the-thesis-theme/">Facebook Connect integration</a>, <a
href="http://www.thewhyandthehow.com/javascript-geolocation-using-google-ajax-apis/">geolocation</a>, and <a
href="http://www.thewhyandthehow.com/tracking-events-with-google-analytics/">event tracking using Google Analytics</a>. I also highly recommend familiarity with the following:</p><ol><li><a
href="http://code.google.com/">Google Code</a>. This site is awesome. Google is constantly updating their public APIs making integrations richer and easier.</li><li><a
href="http://aws.amazon.com/">Amazon Web Services</a>. I haven&#8217;t touched on this much, but as far as mashups and integrations go, Amazon is the service to beat.</li><li><a
href="http://jquery.com/">jQuery</a>. You better believe that you&#8217;re going to need to know Javascript today. If you&#8217;re still hacking away at it without a good library, repent now and learn jQuery.</li><li><a
href="http://jqueryui.com/">jQuery UI</a>. An amazing set of well-developed UI components and themes for use with jQuery.</li><li><a
href="http://apiwiki.twitter.com/">Twitter API</a> and <a
href="http://developers.facebook.com/">Facebook API</a>. Not as fundamental as the above for general web development and integration, but core to social integrations.</li><li><a
href="http://php.net/">PHP</a>. Okay, you can use Python or Ruby or Java or ASP or whatever in the back end. My examples are going to be either PHP or Python, though.</li></ol><p>Read up. There will be a quiz.</p> ]]></content:encoded> <wfw:commentRss>http://www.thewhyandthehow.com/geeking-out/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>Tracking events with Google Analytics</title><link>http://www.thewhyandthehow.com/tracking-events-with-google-analytics/</link> <comments>http://www.thewhyandthehow.com/tracking-events-with-google-analytics/#comments</comments> <pubDate>Tue, 24 Mar 2009 12:10:50 +0000</pubDate> <dc:creator>Blake Schwendiman</dc:creator> <category><![CDATA[PHP]]></category> <category><![CDATA[Tutorial]]></category> <category><![CDATA[jQuery]]></category> <category><![CDATA[analytics]]></category> <category><![CDATA[how-to]]></category> <category><![CDATA[Javascript]]></category> <category><![CDATA[trackevents]]></category><guid
isPermaLink="false">http://www.thewhyandthehow.com/?p=346</guid> <description><![CDATA[If you have any type of web site at all, you&#8217;ve heard about Google Analytics by now. It&#8217;s the Google solution to analyzing your web traffic. One of the more recent features in Analytics is the ability to track events that occur on your page that aren&#8217;t traditional page views. For example, if you have [...]]]></description> <content:encoded><![CDATA[<p>If you have any type of web site at all, you&#8217;ve heard about <a
href="http://www.google.com/analytics/">Google Analytics</a> by now. It&#8217;s the Google solution to analyzing your web traffic. One of the more recent features in Analytics is the ability to <a
href="http://code.google.com/apis/analytics/docs/eventTrackerGuide.html">track events</a> that occur on your page that aren&#8217;t traditional page views. For example, if you have a Flash animation on your page, you might want to track interactions with the animation using Google Analytics. I&#8217;m using event tracking to track the downloads of my <a
href="http://www.thewhyandthehow.com/building-custom-php-extensions/">eBook</a>.</p><p>Setting up event tracking with the <a
href="http://diythemes.com/thesis/?a_aid=pointe&#038;a_bid=47c5a620">Thesis theme</a> and jQuery is a cinch. Here&#8217;s how it breaks down:</p><ol><li>Make sure jQuery is loaded</li><li>Update appropriate &lt;a&gt; tags to call trackEvent()</li></ol><p>Since the <a
href="http://diythemes.com/thesis/?a_aid=pointe&#038;a_bid=47c5a620">Thesis theme</a> provides its own hooks, the code for both of these changes is implemented with two hooks and a few lines of code.</p><div
id="wp_codebox_msgheader"><span
class="right"><a
href="javascript:;" onclick="toggle_collapse('p34625');">[<span
id="p34625_symbol">-</span>]</a><sup><a
href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span
style="color: #99cc00">?</span></a></sup></span><span
class="left"><a
href="javascript:;" onclick="javascript:showCodeTxt('p346code25'); return false;">View Code</a> PHP</span><div
class="codebox_clear"></div></div><div
id="wp_codebox"><table
width="100%" ><tr
id="p34625"><td
class="code" id="p346code25"><pre class="php">add_action<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'wp_head'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'add_jquery'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
add_action<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'thesis_hook_footer'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'custom_footer'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> add_jquery<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span>
<span style="color: #339933;">&lt;</span>script type<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;text/javascript&quot;</span> src<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js&quot;</span><span style="color: #339933;">&gt;&lt;/</span>script<span style="color: #339933;">&gt;</span>
<span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> custom_footer<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span>
<span style="color: #339933;">&lt;</span>script type<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;text/javascript&quot;</span><span style="color: #339933;">&gt;</span>
  jQuery<span style="color: #009900;">&#40;</span>document<span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span>ready<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    jQuery<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'a.track-download'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><a href="http://www.php.net/each"><span style="color: #990000;">each</span></a><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      jQuery<span style="color: #009900;">&#40;</span>this<span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span>bind<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'click'</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>pageTracker<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
          pageTracker<span style="color: #339933;">.</span>_trackEvent<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Download'</span><span style="color: #339933;">,</span> jQuery<span style="color: #009900;">&#40;</span>this<span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span>attr<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'rel'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> jQuery<span style="color: #009900;">&#40;</span>this<span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span>attr<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'title'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
      <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">&lt;/script&gt;</span>
<span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div><p>As you can see, I load jQuery from the <a
href="http://code.google.com/apis/ajaxlibs/documentation/index.html#jquery">Google API content delivery network</a>. I like this method because it uses Google&#8217;s servers for delivery (not my bandwidth) and it increases the chance that the browser has already cached the jQuery code.</p><p>The actual jQuery code is a very simple method that locates all <strong>anchor</strong> tags with the class <strong>track-download</strong> and binds a new click method. The method itself simply calls the analytics method <strong>_trackEvent</strong> with the parameters:</p><ul><li>&#8216;Download&#8217; (the category)</li><li>the <em>rel</em> attribute of the anchor tag (action)</li><li>the <em>title</em> attribute of the anchor (optional_label)</li></ul><p>In the page that contains the download links, the code looks like this:</p><div
id="wp_codebox_msgheader"><span
class="right"><a
href="javascript:;" onclick="toggle_collapse('p34626');">[<span
id="p34626_symbol">-</span>]</a><sup><a
href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span
style="color: #99cc00">?</span></a></sup></span><span
class="left"><a
href="javascript:;" onclick="javascript:showCodeTxt('p346code26'); return false;">View Code</a> HTML</span><div
class="codebox_clear"></div></div><div
id="wp_codebox"><table
width="100%" ><tr
id="p34626"><td
class="code" id="p346code26"><pre>&lt;a class=&quot;track-download&quot; href=&quot;http://www.thewhyandthehow.com/wp-content/uploads/2009/02/building-custom-php-extensions.pdf&quot; alt=&quot;Download Building Custom PHP Extensions PDF&quot; rel=&quot;PDF&quot; title=&quot;Building Custom PHP Extensions&quot;&gt;PDF Version&lt;/a&gt;&lt;br /&gt;
&lt;a class=&quot;track-download&quot; href='http://www.thewhyandthehow.com/wp-content/uploads/2009/02/building-custom-php-extensions.doc' alt=&quot;Download Building Custom PHP Extensions Word Doc&quot; rel=&quot;DOC&quot; title=&quot;Building Custom PHP Extensions&quot;&gt;MS Word DOC version&lt;/a&gt;&lt;br /&gt;
&lt;a class=&quot;track-download&quot; href='http://www.thewhyandthehow.com/wp-content/uploads/2009/02/building-custom-php-extensions.odt' alt=&quot;Download Building Custom PHP Extensions Open Office odt&quot; rel=&quot;ODT&quot; title=&quot;Building Custom PHP Extensions&quot;&gt;Open Office ODT version&lt;/a&gt;&lt;/p&gt;</pre></td></tr></table></div><p>As you can see, a very simple change to the &lt;a&gt; tag structure on my pages now provides me with a richer depth of analytic information. Adding new downloadable items with analytics is as easy as adding a <em>class</em>, a <em>rel</em> and a <em>title</em> attribute to the new anchor tag.</p><p><a
href="http://www.thewhyandthehow.com/wp-content/uploads/2009/03/analytics-event-tracking.png"><img
src="http://www.thewhyandthehow.com/wp-content/uploads/2009/03/analytics-event-tracking-300x179.png" alt="analytics-event-tracking" title="analytics-event-tracking" width="300" height="179" class="alignleft size-medium wp-image-350" /></a></p><p>The screen grab here shows the event tracking overview page in Google Analytics. You can see that Google Analytics breaks down the event tracking by event by category and action (for me, that&#8217;s &#8216;Download&#8217; and file type). There are sub-reports available for each action as you would expect from Google Analytics.</p><p>Notwithstanding the pathetic numbers in my example (I obviously need some marketing help), you can see that event tracking can be a valuable addition to general page view tracking for a web site if you have custom actions that can be triggered using JavaScript.</p> ]]></content:encoded> <wfw:commentRss>http://www.thewhyandthehow.com/tracking-events-with-google-analytics/feed/</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>Integrating Facebook Connect using the Thesis theme</title><link>http://www.thewhyandthehow.com/integrating-facebook-connect-using-the-thesis-theme/</link> <comments>http://www.thewhyandthehow.com/integrating-facebook-connect-using-the-thesis-theme/#comments</comments> <pubDate>Mon, 16 Mar 2009 12:58:32 +0000</pubDate> <dc:creator>Blake Schwendiman</dc:creator> <category><![CDATA[PHP]]></category> <category><![CDATA[Technology]]></category> <category><![CDATA[connect]]></category> <category><![CDATA[facebook]]></category> <category><![CDATA[integration]]></category> <category><![CDATA[Javascript]]></category><guid
isPermaLink="false">http://www.thewhyandthehow.com/?p=318</guid> <description><![CDATA[Propeller-head alert! This is a very technical article.
I&#8217;ve received a number of questions about how I integrated Facebook Connect with my blog, so I thought I&#8217;d go ahead and explain exactly how I did it. I&#8217;m still working on making a very simple open-source Wordpress plugin that does the same thing, but you should be [...]]]></description> <content:encoded><![CDATA[<p><strong><a
href="http://www.thewhyandthehow.com/dont-fear-the-propeller-head/">Propeller-head alert</a>! This is a very technical article.</strong></p><p>I&#8217;ve received a number of questions about how I integrated Facebook Connect with my blog, so I thought I&#8217;d go ahead and explain exactly how I did it. I&#8217;m still working on making a very simple open-source Wordpress plugin that does the same thing, but you should be able to get the ideas from this post to help you do it yourself if you like.</p><p>The first thing to mention is that I&#8217;m using the <a
href="http://diythemes.com/thesis/?a_aid=pointe&#038;a_bid=47c5a620">Thesis theme</a> for Wordpress. Besides being a very professional-looking theme, the <a
href="http://diythemes.com/thesis/?a_aid=pointe&#038;a_bid=47c5a620">Thesis theme</a> also provides a direct mechanism for extending it through the use of <a
href="http://diythemes.com/thesis/rtfm/customizing-with-hooks/">hooks</a>. The hooks allow for customization of the theme without meddling directly with the theme code. All customizations live in their own files, so the them can be upgraded without impacting the customizations.</p><p><a
href="http://www.thewhyandthehow.com/wp-content/uploads/2009/03/fb-connect-settings.png"><img
src="http://www.thewhyandthehow.com/wp-content/uploads/2009/03/fb-connect-settings-218x300.png" alt="fb-connect-settings" title="fb-connect-settings" width="218" height="300" class="alignleft size-medium wp-image-322" /></a>To build a Facebook Connect application, the first thing to do is go over to Facebook and add the <a
href="http://www.facebook.com/developers">Developer</a> application. Then you can create a new application. A Facebook Connect application is just another Facebook application, so you&#8217;ll get a new application ID, API key and secret. You&#8217;ll need this information to set up your Connect app on your blog. I&#8217;m going to assume that you know enough about Facebook Connect to set up the basic application. If not, you need to read the <a
href="http://wiki.developers.facebook.com/index.php/Facebook_Connect">Facebook Connect documentation</a>. The screenshot shows the settings for my blog&#8217;s Connect application.</p><p>I had to add two very small files to my site to support Facebook Connect. The first is the xd_receiver file which provides the cross-domain support for Facebook Connect. The second is a simple callback page &#8212; mine doesn&#8217;t actually do anything, but it exists to support the callback for the application if I ever choose to do anything with the data it can provide. I put both files in the /custom directory of the <a
href="http://diythemes.com/thesis/?a_aid=pointe&#038;a_bid=47c5a620">Thesis theme</a> so they won&#8217;t be affected when I upgrade Thesis or Wordpress in general. (Note: Another option for managing Wordpress and theme upgrades may be to find appropriate <a
href="http://www.webhostingsearch.com/wordpress-hosting.php">Wordpress hosting</a>.)</p><p>Here is the code for the xd_receiver.html file I created (the code is provided by Facebook &#8212; I made no changes at all).</p><div
id="wp_codebox_msgheader"><span
class="right"><a
href="javascript:;" onclick="toggle_collapse('p31831');">[<span
id="p31831_symbol">-</span>]</a><sup><a
href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span
style="color: #99cc00">?</span></a></sup></span><span
class="left"><a
href="javascript:;" onclick="javascript:showCodeTxt('p318code31'); return false;">View Code</a> HTML</span><div
class="codebox_clear"></div></div><div
id="wp_codebox"><table
width="100%" ><tr
id="p31831"><td
class="code" id="p318code31"><pre>&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Strict//EN&quot;
   &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; &gt;
&lt;head&gt;
    &lt;title&gt;Cross-Domain Receiver Page&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;script src=&quot;http://static.ak.facebook.com/js/api_lib/v0.4/XdCommReceiver.js?v2&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</pre></td></tr></table></div><p>Here is my callback script:</p><div
id="wp_codebox_msgheader"><span
class="right"><a
href="javascript:;" onclick="toggle_collapse('p31832');">[<span
id="p31832_symbol">-</span>]</a><sup><a
href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span
style="color: #99cc00">?</span></a></sup></span><span
class="left"><a
href="javascript:;" onclick="javascript:showCodeTxt('p318code32'); return false;">View Code</a> PHP</span><div
class="codebox_clear"></div></div><div
id="wp_codebox"><table
width="100%" ><tr
id="p31832"><td
class="code" id="p318code32"><pre class="php"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
  <span style="color: #666666; font-style: italic;">/**
   * This is the Facebook callback page.
   *
   */</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span>
Visit <span style="color: #339933;">&lt;</span>a href<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;http://www.thewhyandthehow.com/&quot;</span><span style="color: #339933;">&gt;</span>The Why and The How<span style="color: #339933;">&lt;/</span>a<span style="color: #339933;">&gt;</span></pre></td></tr></table></div><p>Now, here&#8217;s where it gets cool! To add all of the Facebook commenting functionality, I added the following hooks and code to my Thesis theme custom_functions.php file.</p><div
id="wp_codebox_msgheader"><span
class="right"><a
href="javascript:;" onclick="toggle_collapse('p31833');">[<span
id="p31833_symbol">-</span>]</a><sup><a
href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span
style="color: #99cc00">?</span></a></sup></span><span
class="left"><a
href="javascript:;" onclick="javascript:showCodeTxt('p318code33'); return false;">View Code</a> PHP</span><div
class="codebox_clear"></div></div><div
id="wp_codebox"><table
width="100%" ><tr
id="p31833"><td
class="code" id="p318code33"><pre class="php">add_action<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'thesis_hook_after_post'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'fb_comment_box'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
add_action<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'thesis_hook_after_post'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'fb_comment_plug'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
add_filter<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'language_attributes'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'add_fb_xml_ns'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> add_fb_xml_ns<span style="color: #009900;">&#40;</span><span style="color: #000033;">$content</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #b1b100;">return</span> <span style="color: #0000ff;">' xmlns:fb=&quot;http://www.facebook.com/2008/fbml&quot; '</span> <span style="color: #339933;">.</span> <span style="color: #000033;">$content</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> fb_comment_box<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>is_single<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">?&gt;</span>
<span style="color: #339933;">&lt;</span>a name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;fb_comments&quot;</span><span style="color: #339933;">&gt;&lt;/</span>a<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;</span>p <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;fb-comments&quot;</span><span style="color: #339933;">&gt;</span>Comments<span style="color: #339933;">:&lt;/</span>p<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;</span>script src<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php&quot;</span> type<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;text/javascript&quot;</span><span style="color: #339933;">&gt;&lt;/</span>script<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;</span>fb<span style="color: #339933;">:</span>comments<span style="color: #339933;">&gt;&lt;/</span>fb<span style="color: #339933;">:</span>comments<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;</span>script type<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;text/javascript&quot;</span><span style="color: #339933;">&gt;</span> FB<span style="color: #339933;">.</span>init<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;[API_KEY]&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;http://www.thewhyandthehow.com/wp-content/themes/thesis/custom/xd_receiver.html&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">&lt;/script&gt;</span>
  <span style="color: #000000; font-weight: bold;">&lt;?php</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> fb_comment_plug<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>is_single<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #339933;">!</span>is_page<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span>
  <span style="color: #339933;">&lt;</span>p <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;fb-comments&quot;</span><span style="color: #339933;">&gt;&lt;</span>a href<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;&lt;?php echo get_permalink(); ?&gt;#fb_comments&quot;</span><span style="color: #339933;">&gt;</span>Add a comment<span style="color: #339933;">&lt;/</span>a<span style="color: #339933;">&gt;&lt;/</span>p<span style="color: #339933;">&gt;</span>
<span style="color: #000000; font-weight: bold;">&lt;?</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div><p>As you can see, I added one filter and two hooks. The filter allows me to insert the required namespace information into the <strong>&lt;html&gt;</strong> tag. I cheated and used the <strong>language_attributes</strong> filter because that filter is the first one I found that would allow me to tweak any part of the <strong>&lt;html&gt;</strong> tag. You can view the source of this page to see that the namespace has been added.</p><p>The two hooks both fire after a post is rendered. The first hook function, <strong>fb_comment_box</strong> renders the actual Facebook Connect comment box. It only renders on single post pages, not on the main page that has many posts. The complete HTML that gets rendered for the comment box is simply this:</p><div
id="wp_codebox_msgheader"><span
class="right"><a
href="javascript:;" onclick="toggle_collapse('p31834');">[<span
id="p31834_symbol">-</span>]</a><sup><a
href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span
style="color: #99cc00">?</span></a></sup></span><span
class="left"><a
href="javascript:;" onclick="javascript:showCodeTxt('p318code34'); return false;">View Code</a> HTML</span><div
class="codebox_clear"></div></div><div
id="wp_codebox"><table
width="100%" ><tr
id="p31834"><td
class="code" id="p318code34"><pre>&lt;a name=&quot;fb_comments&quot;&gt;&lt;/a&gt;
&lt;p class=&quot;fb-comments&quot;&gt;Comments:&lt;/p&gt;
&lt;script src=&quot;http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
&lt;fb:comments&gt;&lt;/fb:comments&gt;
&lt;script type=&quot;text/javascript&quot;&gt; FB.init(&quot;[API_KEY]&quot;, &quot;http://www.thewhyandthehow.com/wp-content/themes/thesis/custom/xd_receiver.html&quot;)<SEMI> &lt;/script&gt;</pre></td></tr></table></div><p>You can see that the only custom options in that section are in the <strong>FB.init</strong> function. The API key for the application and the URL to the xd_receiver file are the required parameters. I also add an anchor tag right above the comments box so I can jump to the comments from the main page. That is referenced in the function <strong>fb_comments_plug</strong> which is displayed only on pages with multiple posts.</p><p>The last step for me was to disable regular Wordpress comments. That&#8217;s not actually necessary, but I thought that having two commenting systems on one site would be confusing.</p><h4>Last words</h4><p>The Facebook Connect comment box is an incredibly powerful way to bring the power of Facebook to your blog or web site, but it&#8217;s still very much a first-generation implementation. While it is possible for the application owner to manage comments posted through the comment box, there is currently no mechanism in place to notify the application owner when a new comment is made. So if you add the Facebook comment box to your site today, you&#8217;ll have to keep a close eye on your pages to check for abuse.</p><p>I didn&#8217;t cover any of the <a
href="http://wiki.developers.facebook.com/index.php/Fb:comments_(XFBML)">options available for the comments box</a>. There are many options you can tweak, but you&#8217;ll need to <a
href="http://wiki.developers.facebook.com/index.php/Fb:comments_(XFBML)">read the manual</a> for more information.</p><p>Go ahead and take my code. There&#8217;s not much there that&#8217;s really mine, so I&#8217;m certainly not going to try to protect it. Also, if you have questions, please leave me a <strong>comment</strong>.</p> ]]></content:encoded> <wfw:commentRss>http://www.thewhyandthehow.com/integrating-facebook-connect-using-the-thesis-theme/feed/</wfw:commentRss> <slash:comments>17</slash:comments> </item> </channel> </rss><!--
This site's performance optimized by W3 Total Cache:

W3 Total Cache improves the user experience of your blog by caching
frequent operations, reducing the weight of various files and providing
transparent content delivery network integration.

Learn more about our WordPress Plugins: http://www.w3-edge.com/wordpress-plugins/

Minified using memcached
Page Caching using memcached
Database Caching 0/17 queries in 0.012 seconds using memcached

Served from: a2.c0.354a.static.theplanet.com @ 2010-09-10 04:08:10 -->