<?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>ZeptoBlog</title>
	<atom:link href="http://www.zeptoworld.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.zeptoworld.com</link>
	<description>My tech playground</description>
	<lastBuildDate>Thu, 02 Feb 2012 14:49:28 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>2012 AVC &#8211; Autonomous Vehicle Competition</title>
		<link>http://www.zeptoworld.com/2012/02/02/2012-avc-autonomous-vehicle-competition/</link>
		<comments>http://www.zeptoworld.com/2012/02/02/2012-avc-autonomous-vehicle-competition/#comments</comments>
		<pubDate>Thu, 02 Feb 2012 14:49:08 +0000</pubDate>
		<dc:creator>Russ J</dc:creator>
				<category><![CDATA[Geekfest]]></category>
		<category><![CDATA[Hobbies]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://www.zeptoworld.com/?p=45</guid>
		<description><![CDATA[Well I&#8217;ve done it. I signed up for the Sparkfun AVC. So what is it? The competitors have to build an autonomous vehicle that can circumnavigate the Sparkfun building. The fastest time wins. Sounds easy enough, right? Here is my entry so far: So far all it is using is a compass and a multiplexer [...]]]></description>
			<content:encoded><![CDATA[<p>Well I&#8217;ve done it. I signed up for the <a href="http://www.sparkfun.com/news/767" title="Sparkfun AVC">Sparkfun AVC</a>. So what is it? The competitors have to build an autonomous vehicle that can circumnavigate the Sparkfun building. The fastest time wins. Sounds easy enough, right?</p>
<p>Here is my entry so far:<br />
<a href="http://www.zeptoworld.com/wp-content/uploads/2012/02/IMG_0415.jpg"><img src="http://www.zeptoworld.com/wp-content/uploads/2012/02/IMG_0415-300x224.jpg" alt="" title="Wunser Round" width="300" height="224" class="alignnone size-medium wp-image-48" /></a></p>
<p>So far all it is using is a compass and a multiplexer so I can switch it back and forth from manual to compass driven steering.</p>
<p>Keep watching for more information.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zeptoworld.com/2012/02/02/2012-avc-autonomous-vehicle-competition/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Model Rocketry</title>
		<link>http://www.zeptoworld.com/2011/03/03/model-rocketry/</link>
		<comments>http://www.zeptoworld.com/2011/03/03/model-rocketry/#comments</comments>
		<pubDate>Thu, 03 Mar 2011 21:44:23 +0000</pubDate>
		<dc:creator>Russ J</dc:creator>
				<category><![CDATA[Geekfest]]></category>
		<category><![CDATA[Hobbies]]></category>

		<guid isPermaLink="false">http://www.zeptoworld.com/?p=32</guid>
		<description><![CDATA[For a while now I have been shooting rockets with my kids down at the park. It&#8217;s fun and we get the bug once or twice a year to go out and shoot some more. I have a friend who has taken it to the next level and joined a model rocket club and gotten [...]]]></description>
			<content:encoded><![CDATA[<p>For a while now I have been shooting rockets with my kids down at the park. It&#8217;s fun and we get the bug once or twice a year to go out and shoot some more. I have a friend who has taken it to the next level and joined a model rocket club and gotten his Level 1 certification for high power rockets. This is getting serious. So I am getting the bug to step up my game. I went out to my local club launch the other day and I got more excited. My problem is that it gets expensive quick and I don&#8217;t really want to spend $20 or more for each rocket engine that I use. So I am in the research stage right now. It turns out that there are a lot of different angles when it comes to rocketry. I am going to use this post as a way to store links to sites that I find useful or at least interesting. If these links are useful to you then let me know.</p>
<p>general rocketry information<br />
<a href="http://www.rocketryplanet.com/" target="rocketry">Rocketry Planet</a><br />
<a href="http://www.rocketreviews.com/" target="rocketry">Rocket Reviews</a></p>
<p>rocketry parts<br />
<a href="http://www.redarrowhobbies.com/" target="rocketry">Red Arrow Hobbies</a><br />
<a href="http://www.estesrockets.com/" target="rocketry">Estes Rocketry</a><br />
<a href="http://www.learningthings.com/index.asp?FSCat=271" target="rocketry">learningthings.com</a><br />
<a href="http://www.hobbylinc.com/">HobbyLinc</a> seem to have good discounts on rockets<br />
<a href="http://www.apogeerockets.com/index.asp">Apogee Rockets</a></p>
<p>rocket motors / rocket fuels / rocket chemicals<br />
<a href="http://www.rocketmotorparts.com/" target="rocketry">RCS</a><br />
<a href="http://www.musketeer.ch/blackpowder/bp_menu.html" target="rocketry">Musketeer (black powder)</a><br />
<a href="http://www.youtube.com/watch?v=otVhpDSbHZk" target="rocketry">making charcoal</a><br />
<a href="http://www.skylighter.com/" target="rocketry">Sky Lighter</a><br />
<a href="http://www.oda-ent.com/" target="rocketry">ODA (ignition)</a><br />
<a href="http://www.aeroconsystems.com/electronics/nichrome.htm" target="rocketry">Aerocon (nichrome)</a><br />
<a href="http://www.quickburst.net/e_matchkit.htm" target="rocketry">Quickburst (ematch)</a><br />
<a href="http://www.quickburst.net/quick_dip.htm" target="rocketry">Quickburst (pyrogen)</a><br />
<a href="http://www.rinconrocketry.com/" target="rocketry">shock cords</a><br />
<a href="http://www.firefox-fx.com/" target="rocketry">Firefox FX</a><br />
<a href="http://http://www.pyrocreations.com/">Pyro Creations</a></p>
<p>build your own rocket motor<br />
<a href="http://jamesyawn.net/" target="rocketry">James Yawn</a><br />
<a href="http://www.skylighter.com/fireworks/how-to-make/model-rocket-engine.asp" target="rocketry">black powder motor</a></p>
<p>local rocketry club<br />
<a href="http://sssrocketry.org/"  target="rocketry">Superstition Spacemodeling Society</a><br />
<a href="http://therocketdoc.com/" target="rocketry">rocket doc</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.zeptoworld.com/2011/03/03/model-rocketry/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>URL Shortening Code in PHP</title>
		<link>http://www.zeptoworld.com/2009/07/07/url-shortening-code-in-php/</link>
		<comments>http://www.zeptoworld.com/2009/07/07/url-shortening-code-in-php/#comments</comments>
		<pubDate>Tue, 07 Jul 2009 06:53:32 +0000</pubDate>
		<dc:creator>Russ J</dc:creator>
				<category><![CDATA[Geekfest]]></category>

		<guid isPermaLink="false">http://www.zeptoworld.com/?p=25</guid>
		<description><![CDATA[Someone suggested that I use tr.im to create short urls when sending tweets to twitter from my other web site. I was a little annoyed that they will only allow 10 urls per hour. I didn&#8217;t feel like figuring out their API and then asking for higher limits. I said to myself. It&#8217;s probably just [...]]]></description>
			<content:encoded><![CDATA[<p>Someone suggested that I use tr.im to create short urls when sending tweets to twitter from my other web site. I was a little annoyed that they will only allow 10 urls per hour. I didn&#8217;t feel like figuring out their API and then asking for higher limits. I said to myself. It&#8217;s probably just as easy to write my own. So I did.</p>
<p>First, I needed to store the URL with a key so I could resolve the url when someone clicks on my link. Here is the class that I created for that<br />
<code>class ShortUrl {<br />
  var $database;<br />
  function ShortUrl($database) {<br />
    $this->database = $database;<br />
  }<br />
  function next() {<br />
    $sequence = $this->database."/sequence";<br />
    touch($sequence);<br />
    $handle = fopen($sequence, "r+") or die("can't open sequence file");<br />
    $last = fgets($handle);<br />
    if(empty($last) &#038;&#038; $last != "0") {<br />
      $last = chr(47);<br />
    }<br />
    $next = substr_replace($last, $this->nextASCII(substr($last, -1)), -1);<br />
    rewind($handle);<br />
    fwrite($handle, $next);<br />
    fclose($handle);<br />
    return $next;<br />
  }<br />
// 48-57,65-90,97-122<br />
  function nextASCII($char) {<br />
    $ascii = ord($char);<br />
    if ($ascii < 48) {<br />
      return chr(48);<br />
    } else if ($ascii > 56 &#038;&#038; $ascii < 65) {<br />
      return chr(65);<br />
    } else if ($ascii > 89 &#038;&#038; $ascii < 97) {<br />
      return chr(97);<br />
    } else if ($ascii > 121) {<br />
      return chr(122).chr(48);<br />
    }<br />
    $ascii += 1;<br />
    return chr($ascii);<br />
  }<br />
  function createShorty($URL) {<br />
    $shorty = $this->next();<br />
    $path = $this->database ."/". substr($shorty, 0, 1) . ".db";<br />
    touch($path);<br />
    $fp = fopen($path, "a");<br />
    fwrite($fp, $shorty . ":" . $URL . PHP_EOL);<br />
    return $shorty;<br />
  }<br />
  function resolveShorty($shorty) {<br />
    $path = $this->database ."/". substr($shorty, 0, 1) . ".db";<br />
    touch($path);<br />
    $fp = fopen($path, "r");<br />
    while (!feof($fp)) {<br />
      $line = trim(fgets($fp));<br />
      if(strcmp($shorty, substr($line, 0, strpos($line, ":"))) == 0) {<br />
        $url = substr($line, strpos($line, ":") + 1);<br />
      }<br />
    }<br />
    fclose($fp);<br />
    return $url;<br />
  }<br />
}</code></p>
<p>The $database parameter in the constructor is a subdirectory where the files will be stored. The two functions that will be called are createShorty() and resolveShorty(). createShorty() reads the value that it stored in the file &#8220;sequence&#8221; and increments it by one to be used as the key. Then it saves that value back into the file &#8220;sequence&#8221; and stores it in a .db file along with the URL that is passed in. The generated key is passed back to the calling program to be used in the short url. I will talk about resolveShorty() later.</p>
<p>The key is used to create a short url here:<br />
<code>    $shortObj = new ShortUrl("urldb");<br />
    $shorty = $shortObj->createShorty($item->link);<br />
    $shortUrl = "http://".$_SERVER["HTTP_HOST"]."/.$shorty";</code><br />
The resulting URL looks something like this: http://www.zeptoworld.com/.0A. The key for the URL is &#8220;0A&#8221;. The &#8220;.&#8221; in front of it is what your code will use to recognize this as a short URL that needs to be resolved.</p>
<p>You will need to put something like this in your .htaccess file:<br />
<code>RewriteEngine On<br />
RewriteCond %{REQUEST_FILENAME} !-f<br />
RewriteRule . redirect.php [L]</code></p>
<p>This tells the apache server that if it sees a URL that starts with a &#8220;.&#8221; then run the code in redirect.php. Here is what redirect.php looks like:<br />
<code>$uri = $_SERVER['REQUEST_URI'];<br />
$shorty = substr($uri, 2);<br />
$shortObj = new ShortUrl("urldb");<br />
$url = $shortObj->resolveShorty($shorty);<br />
header("http/1.1 307 temporary redirect");<br />
header("Location: $url");</code></p>
<p>resolveShorty() will find the original URL that was stored in the file. Then you do a redirect to the intended page and you are done.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zeptoworld.com/2009/07/07/url-shortening-code-in-php/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>The 12th War</title>
		<link>http://www.zeptoworld.com/2008/08/03/the-12th-war/</link>
		<comments>http://www.zeptoworld.com/2008/08/03/the-12th-war/#comments</comments>
		<pubDate>Sun, 03 Aug 2008 23:33:59 +0000</pubDate>
		<dc:creator>Russ J</dc:creator>
				<category><![CDATA[Geekfest]]></category>

		<guid isPermaLink="false">http://www.zeptoworld.com/2008/08/03/the-12th-war/</guid>
		<description><![CDATA[Overview You will be given the name of someone in the war that you must eliminate by getting them wet. You may get him/her wet by any, non harmful, means you choose â€“ squirt gun, water balloon, hose, cup of water, etc. Elimination means that you are out of the game. When you eliminate your [...]]]></description>
			<content:encoded><![CDATA[<p>Overview</p>
<p>You will be given the name of someone in the war that you must eliminate by getting them wet. You may get him/her wet by any, non harmful, means you choose â€“ squirt gun, water balloon, hose, cup of water, etc. Elimination means that you are out of the game. When you eliminate your target, he/she must give you the name of his/her target and that person becomes your next target. When you eliminate your target, you will get credit for all of that personâ€™s eliminations. At the Ward Party on August 23rd, a prize will be given for the last player standing or the player with the most eliminations if not all players are eliminated. The game will start on August 4th at 12:00 AM and end August 23rd at 12:00 AM.</p>
<p>Rules of the game</p>
<p>1) You cannot eliminate your target on Sunday. </p>
<p>3) You cannot eliminate your target in any church building. </p>
<p>4) You cannot eliminate your target at any church sponsored activity nor on the way to or from the activity.</p>
<p>5) You cannot eliminate your target while the person is at work or at school. (Please donâ€™t soak your target right before work or school.) </p>
<p>6) You cannot eliminate your target in his/her house or garage.</p>
<p>7) If there is a questionable elimination Russ J is the judge.</p>
<p>Please report eliminations to Russ J, russ@staceyshouse.com or 774-8271, within 24 hours of the deed. </p>
<p>If you would like to share a good story about eliminating someone, add a comment below.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zeptoworld.com/2008/08/03/the-12th-war/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>My PVC Carbide Cannon is a blast</title>
		<link>http://www.zeptoworld.com/2008/01/29/my-pvc-carbide-cannon-is-a-blast/</link>
		<comments>http://www.zeptoworld.com/2008/01/29/my-pvc-carbide-cannon-is-a-blast/#comments</comments>
		<pubDate>Tue, 29 Jan 2008 15:46:08 +0000</pubDate>
		<dc:creator>Russ J</dc:creator>
				<category><![CDATA[Hobbies]]></category>

		<guid isPermaLink="false">http://www.zeptoworld.com/2008/01/29/my-pvc-carbide-cannon-is-a-blast/</guid>
		<description><![CDATA[What is a Carbide Cannon? As it turns out, if you take some Calcium Carbide and mix it with water, it produces lime (which settles in the water) and Acetylene gas. Acetylene gas is explosive. I&#8217;ll bet you are already thinking of how to make use of that information. Well, we gave our boys a [...]]]></description>
			<content:encoded><![CDATA[<p>What is a Carbide Cannon? As it turns out, if you take some Calcium Carbide and mix it with water, it produces lime (which settles in the water) and Acetylene gas. Acetylene gas is explosive. I&#8217;ll bet you are already thinking of how to make use of that information. Well, we gave our boys a book for Christmas called <a href="http://www.amazon.com/Backyard-Ballistics-Cannons-Cincinnati-Dynamite/dp/1556523750/ref=pd_bbs_sr_1?ie=UTF8&#038;s=books&#038;qid=1201615812&#038;sr=1-1">Backyard Ballistics</a>. You are probably thinking that we are bad parents for teaching our 9 and 11 year old boys stuff like that. Your probably right. The book shows you how to make a cannon that will make a lot of noise as it generates and acetylene gas that you ignite. Here are some pictures of my cannon that I built.<br />
<img src="/images/cannon1.jpg" alt="carbide cannon" /><br />
<br />
<img src="/images/cannon2.jpg" alt="pvc carbide cannon" /><br />
<br />
<img src="/images/cannon3.jpg" alt="pvc carbide cannon" /><br />
<br />
<img src="/images/cannon4.jpg" alt="pvc carbide cannon" /></p>
<p>My first attempt did not fire. I think the ignition hole is too big and let the acetylene out too fast. I stuffed a little paper towel in the hole and it worked great.</p>
<p>This is my first successful firing of the carbide cannon: I leaned over it when it went off and nearly took out my eye. Not too smart.<br />
<object width="425" height="355"><param name="movie" value="http://www.youtube.com/v/XEHP_JO1U48&#038;rel=1"></param><param name="wmode" value="transparent"></param><embed src="http://www.youtube.com/v/XEHP_JO1U48&#038;rel=1" type="application/x-shockwave-flash" wmode="transparent" width="425" height="355"></embed></object></p>
<p>So I did it a second time.<br />
<object width="425" height="355"><param name="movie" value="http://www.youtube.com/v/HTrDnxcDsBU&#038;rel=1"></param><param name="wmode" value="transparent"></param><embed src="http://www.youtube.com/v/HTrDnxcDsBU&#038;rel=1" type="application/x-shockwave-flash" wmode="transparent" width="425" height="355"></embed></object></p>
]]></content:encoded>
			<wfw:commentRss>http://www.zeptoworld.com/2008/01/29/my-pvc-carbide-cannon-is-a-blast/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>New York Doll and Endless Summer 2</title>
		<link>http://www.zeptoworld.com/2008/01/27/new-york-doll-and-endless-summer-2/</link>
		<comments>http://www.zeptoworld.com/2008/01/27/new-york-doll-and-endless-summer-2/#comments</comments>
		<pubDate>Sun, 27 Jan 2008 19:28:18 +0000</pubDate>
		<dc:creator>Russ J</dc:creator>
				<category><![CDATA[Movies]]></category>

		<guid isPermaLink="false">http://www.zeptoworld.com/2008/01/27/new-york-doll-and-endless-summer-2/</guid>
		<description><![CDATA[I saw a couple of documentaries this week, both of which I highly recommend. New York Doll is about a guy who was in the band New York Dolls in the early 70s. The band fell apart before they made any real money but they inspired a number of famous artists that came later. Drugs [...]]]></description>
			<content:encoded><![CDATA[<p>I saw a couple of documentaries this week, both of which I highly recommend.</p>
<p>New York Doll is about a guy who was in the band New York Dolls in the early 70s. The band fell apart before they made any real money but they inspired a number of famous artists that came later. Drugs and Alcohol played a big part in the fall. In the late 80s Arthur &#8220;Killer&#8221; Kane joined the LDS Church. Then in 2004 Arthur&#8217;s life-long dream came true as he was ask to do a show with the New York Dolls.</p>
<p>Endless Summer 2 is about a couple of surfers who want to relive what the makers of Endless Summer did 30 years earlier. They travel around the world and surf in a bunch of beautiful spots all over the globe. There is a couple of scenes on the beach in France where the women don&#8217;t have tops on, so beware. If you like great surfing and good commentary, you will enjoy this one.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zeptoworld.com/2008/01/27/new-york-doll-and-endless-summer-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Why Isn&#8217;t There an Index</title>
		<link>http://www.zeptoworld.com/2007/12/05/why-isnt-there-an-index/</link>
		<comments>http://www.zeptoworld.com/2007/12/05/why-isnt-there-an-index/#comments</comments>
		<pubDate>Thu, 06 Dec 2007 05:21:16 +0000</pubDate>
		<dc:creator>Russ J</dc:creator>
				<category><![CDATA[Books]]></category>

		<guid isPermaLink="false">http://www.zeptoworld.com/2007/12/05/why-isnt-there-an-index/</guid>
		<description><![CDATA[As you may or may not know, I am a big reader. I read many books each year mostly in the fantasy genre. I recently finished Book 11 of the Wheel of Time series by Robert Jordan. I think that each of the books in the series is between 700 and 900 pages. When you [...]]]></description>
			<content:encoded><![CDATA[<p>As you may or may not know, I am a big reader. I read many books each year mostly in the fantasy genre. I recently finished Book 11 of the Wheel of Time series by Robert Jordan. I think that each of the books in the series is between 700 and 900 pages. When you consider that there is a year or two between each book release, it can be quite a long time from the time that you start the series to the time you finish it. As I was reading book 11 Knife of Dreams a character became center stage that had been introduced a couple of books back. I can&#8217;t remember his name, but he is the Deathwatch Guard. The problem was that when I was reading I couldn&#8217;t remember anything about him until near the end of the book. It would have been a far more interesting read if I could have gone back and read the earlier sequences with him when he first popped up in the book.</p>
<p>This is where I come to the point of this post. There should be an index for this kind of thing. Why can&#8217;t I see a character and go look him up and get the page and book numbers where I can go back and read the previous interactions. Maybe it is up to people like me to get it started.</p>
<p>What do you think?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zeptoworld.com/2007/12/05/why-isnt-there-an-index/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Writing a PHP Framework (Authentication and Authorization)</title>
		<link>http://www.zeptoworld.com/2007/01/14/writing-a-php-framework-authentication-and-authorization/</link>
		<comments>http://www.zeptoworld.com/2007/01/14/writing-a-php-framework-authentication-and-authorization/#comments</comments>
		<pubDate>Mon, 15 Jan 2007 01:14:52 +0000</pubDate>
		<dc:creator>Russ J</dc:creator>
				<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://www.zeptoworld.com/2007/01/14/writing-a-php-framework-authentication-and-authorization/</guid>
		<description><![CDATA[In my previous post about writing a PHP Framework I mentioned a script called Tower.php. By using Tower as the single point of entry I can handle authentication and authorization all in one place for any page rendered. Authentication is deciding whether a user has access to the system. This is most often accomplished by [...]]]></description>
			<content:encoded><![CDATA[<p>In my <a href="http://www.zeptoworld.com/2006/11/15/writing-a-php-framework/">previous post</a> about writing a PHP Framework I mentioned a script called Tower.php. By using Tower as the single point of entry I can handle authentication and authorization all in one place for any page rendered.</p>
<p>Authentication is deciding whether a user has access to the system. This is most often accomplished by requiring the user to enter a username and password. Tower.php checks the users credentials and sends them to the login page if they are not authenticated. This works whether the user is trying to go to a bookmarked page or if their session has timed out but they still have the application up in their browser.</p>
<p>Authorization, on the other hand, determines what parts of the system the user has access to &#8211; whether they have been authenticated or not. In my framework, I have chosen to implement authorization by require each page to defined the permission required to render the page. I then group the permissions into roles and assign a role to each user. If the page doesn&#8217;t require any permissions, then it is a public page and anyone can view it. This is, of course, the case with the login page.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zeptoworld.com/2007/01/14/writing-a-php-framework-authentication-and-authorization/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Performance tuning my MySQL database</title>
		<link>http://www.zeptoworld.com/2006/12/17/performance-tuning-my-mysql-database/</link>
		<comments>http://www.zeptoworld.com/2006/12/17/performance-tuning-my-mysql-database/#comments</comments>
		<pubDate>Mon, 18 Dec 2006 01:33:56 +0000</pubDate>
		<dc:creator>Russ J</dc:creator>
				<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://www.zeptoworld.com/2006/12/17/performance-tuning-my-mysql-database/</guid>
		<description><![CDATA[I doubt that many of you have ever tried to write your own web tracking software. I mostly did it to see if I could and also to have complete control over my tracker. My wife says I&#8217;m a bit of a control freak. Anyway, I posted on it earlier this year. I have called [...]]]></description>
			<content:encoded><![CDATA[<p>I doubt that many of you have ever tried to write your own web tracking software. I mostly did it to see if I could and also to have complete control over my tracker. My wife says I&#8217;m a bit of a control freak. Anyway, I <a href="http://www.zeptoworld.com/2006/09/18/silentracker/">posted</a> on it earlier this year. I have called it Silentracker.</p>
<p>I wrote it in PHP. Any good software architect out there is probably shaking their head and laughing at me right about now. I know because I&#8217;m a pretty good software architect and I still wonder about my decision. It comes down to the fact that I never expect to make any money from the project and I don&#8217;t feel like spending money to get a server with more capabilities. So my choices where Perl or PHP. I didn&#8217;t feel like learning Perl&#8230; so there you have it. I originally wrote it using flat files to store the data. I changed that to MySQL and there we are.</p>
<p>Everything was fine when I started and was only tracking my mom&#8217;s web site which gets a few hits a day. Now, my brother&#8217;s company has started using it also and it didn&#8217;t take very long before I had 25,000 row in the hit table of the database. It won&#8217;t be long before there are 100,000 or 1,000,000. You get the point. As often happens, this &#8220;prototype&#8221; was in full production and suffering from the lack of fine tuning that you would expect from a prototype.</p>
<p>This week I took some time to clean up the queries and see if I could speed things up a bit. There are a number of things that I have considered and some of them I have implemented. Things are moving along nicely now and I figured I would throw these out there for those who might be having similar problems (I am going to assume that you are administering your database using <a href="http://www.phpmyadmin.net/home_page/index.php" rel="nofollow">phpMyAdmin</a>):</p>
<ul>
<li>Take a look at the queries that you are running most often and the tables that they hit and see if you can add an index or two to help speed things up.<br />
<blockquote>If you are not familiar with indexes, you can create an index on any table and base it on one or more columns in that table. Then when a query is run against the table the database will use an index where available to speed up the query. This ads overhead to inserts, updates, and deletes on the table so don&#8217;t over do it.</p></blockquote>
</li>
<li>Denormalize the data if necessary.<br />
<blockquote>I found that I was performing the same expensive operation in most of my queries. I was doing a complex text comparison between two columns. I was able to do that same comparison as part of the insert and store the result in a separate column as a boolean value and save time on every query. One problem with this is that it is denormalizing your data to a certain degree, but to me it was so worth it. Then I create an index on that new column to speed things up even more.</p></blockquote>
</li>
<li>Use explain to analyze your queries.<br />
<blockquote>When you run any query in phpMyAdmin you can then click on the explain link. This will analyze the query and tell you how it executes. It tells you what kind of search it does on the table and which, if any, index is being used. You may need to go to the MySQL documentation to see exactly what the results mean, but this can be invaluable when you have nested queries and complex table with complex joins.</p></blockquote>
</li>
</ul>
<p>These optimizations were enough to get thing back up to a good speed for now on Silentracker. When the data gets larger I will probably start archiving old data from the table. I may move each site into it&#8217;s own table or even create multiple databases to limit the size of the data. I also may divide types of hits into separate tables. If necessary there are other denormalizations that I can do also. A little analysis can go a long way.</p>
<p>One word of caution. Avoid premature optimization. Optimizations can degrade the maintainability of your software. Only optimize when there is a problem to solve.</p>
<p>Performance tuning is not limited to the database. With a language like PHP, you sometimes have to get performance enhancements wherever you can. For instance, I have graphs that only need to be created once each day. Why not cache those on the disk and check the file modification time to decide when to recreate them. If there is information that is guaranteed to be constant for the length of the session, store it in the session. Feel free to add other performance tuning in the comments below.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zeptoworld.com/2006/12/17/performance-tuning-my-mysql-database/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Writing a PHP Framework</title>
		<link>http://www.zeptoworld.com/2006/11/15/writing-a-php-framework/</link>
		<comments>http://www.zeptoworld.com/2006/11/15/writing-a-php-framework/#comments</comments>
		<pubDate>Thu, 16 Nov 2006 05:40:32 +0000</pubDate>
		<dc:creator>Russ J</dc:creator>
				<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://www.zeptoworld.com/2006/11/15/writing-a-php-framework/</guid>
		<description><![CDATA[I&#8217;m not even sure where to start with this topic. I&#8217;m thinking that a good place to start is how the users get to the framework. .htaccess htaccess is somewhat of a new thing to me. I have extensive experience in writing a Java Framework using Tomcat and JBoss. The way that I choose to [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m not even sure where to start with this topic. I&#8217;m thinking that a good place to start is how the users get to the framework. .htaccess</p>
<p>htaccess is somewhat of a new thing to me. I have extensive experience in writing a Java Framework using Tomcat and JBoss. The way that I choose to write a framework is to have every page request filter through a single controlling entry point. This can really limit the chance of security holes. In Servlet containers this is done using servlet and servlet mapping definitions. You can easily send all requests through a single servlet that takes care of authentication and authorization before a page ever gets displayed. It turns out that the servlet mapping is just a watered down version of Apache&#8217;s mod_rewrite and, of course, .htaccess is processed by mod_rewrite. What I discovered is that you can achieve the same effect by using .htaccess and a well written php script.</p>
<p>This is what my .htaccess looks like:</p>
<blockquote><p>
RewriteEngine On</p>
<p>RewriteRule .*style/(.*) style/$1 [L]</p>
<p>RewriteRule .*images/(.*) images/$1 [L]</p>
<p>RewriteCond %{REQUEST_FILENAME} !-f<br />
RewriteCond %{REQUEST_URI} !(framework/Tower.php)<br />
RewriteRule . framework/Tower.php [L]
</p></blockquote>
<p>First of all, I used the .htacess that comes with <a href="http://wordpress.org/">WordPress</a> as a starting point &#8211; give credit where credit is due. I think there is only one line left from the borrowed file though. If this code looks totally foreign to you then do a <a href="http://google.com/">Google Search</a> for mod_rewrite. I looked at this <a href="http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html#RewriteRule">Apache Doc</a> and this <a href="http://www.ilovejackdaniels.com/mod_rewrite_cheat_sheet.pdf">nice reference sheet</a> when getting familiar with mod_rewrite.</p>
<p>The gist of that code is this. Every request that come to my url will be redirected to a script called Tower.php &#8211; tower is meant to be like an airport tower that directs traffic &#8211; unless the request points to an actual file on the server. This caveat is there because I am building this framework in the middle of a working site and I don&#8217;t want to convert the entire site before using the new features. Also, I added the style/&#8230; and image/&#8230; so that my scripts don&#8217;t have to worry about how many ../../../ are needed to find the css and image files. Of course if your system is always running at the root &#8211; not in a subdirectory &#8211; you don&#8217;t need this little bit.</p>
<p>Now, I&#8217;m not saying that this is the best way to write a .htaccess file to do what I am doing, but it works. If you experts out there have suggestions, please let me know.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zeptoworld.com/2006/11/15/writing-a-php-framework/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

