<?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>Building Browsergames &#187; Uncategorized</title>
	<atom:link href="http://buildingbrowsergames.com/category/uncategorized/feed/" rel="self" type="application/rss+xml" />
	<link>http://buildingbrowsergames.com</link>
	<description>Ever wanted to build a browsergame?</description>
	<lastBuildDate>Mon, 29 Mar 2010 14:00:39 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Offline for a while</title>
		<link>http://buildingbrowsergames.com/2008/07/24/offline-for-a-while/</link>
		<comments>http://buildingbrowsergames.com/2008/07/24/offline-for-a-while/#comments</comments>
		<pubDate>Fri, 25 Jul 2008 00:27:58 +0000</pubDate>
		<dc:creator>Luke</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://buildingbrowsergames.com/?p=103</guid>
		<description><![CDATA[Building Browsergames will be going offline for a few days &#8211; I&#8217;m going to be transferring the site(and all related files) to a new server.
]]></description>
			<content:encoded><![CDATA[<p>Building Browsergames will be going offline for a few days &#8211; I&#8217;m going to be transferring the site(and all related files) to a new server.</p>
]]></content:encoded>
			<wfw:commentRss>http://buildingbrowsergames.com/2008/07/24/offline-for-a-while/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Building Browsergames: Reducing Repetition (Perl)</title>
		<link>http://buildingbrowsergames.com/2008/07/08/building-browsergames-reducing-repetition-perl/</link>
		<comments>http://buildingbrowsergames.com/2008/07/08/building-browsergames-reducing-repetition-perl/#comments</comments>
		<pubDate>Tue, 08 Jul 2008 14:00:57 +0000</pubDate>
		<dc:creator>Luke</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://buildingbrowsergames.com/?p=79</guid>
		<description><![CDATA[While working on your own browsergame project, one of the things that will slow you down the most is re-writing the exact same code. Unfortunately, we&#8217;ve been doing that with our stats code &#8211; as reader sepp helpfully pointed out.
In the programming world, there is a concept known as &#8216;DRY&#8217; &#8211; which stands for &#8220;Don&#8217;t [...]]]></description>
			<content:encoded><![CDATA[<p>While working on your own browsergame project, one of the things that will slow you down the most is re-writing the exact same code. Unfortunately, we&#8217;ve been doing that with our stats code &#8211; as reader <a href='http://www.seelenradio.de/'>sepp</a> helpfully pointed out.</p>
<p>In the programming world, there is a concept known as &#8216;DRY&#8217; &#8211; which stands for &#8220;Don&#8217;t Repeat Yourself&#8221;. Applying DRY to your code means that you should never have to write code to do almost the same thing twice &#8211; you should be writing code flexible enough to do both. Using a DRY approach can drastically cut down our development time, in addition to improving our code&#8217;s maintainability(because there&#8217;s less of it to worry about). So today, we&#8217;re going to convert our stats code from being 3 different pieces of code to a single piece of DRY code.</p>
<p>So far, we have 3 helper modules that retrieve our stats for us &#8211; each from different tables and columns, but for the most part they&#8217;re the exact same code. Here&#8217;s a refresher on what our <strong>stats::getStat</strong> function looks like:</p>

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">sub</span> getStat <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>
	<span style="color: #000000; font-weight: bold;">use</span> config<span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> DBI<span style="color: #339933;">-&gt;</span><span style="color: #006600;">connect</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;DBI:mysql:$dbname:$dbhost&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$dbuser</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$dbpass</span><span style="color: #339933;">,</span><span style="color: #009900;">&#123;</span>RaiseError <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	createIfNotExists<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT value FROM user_stats WHERE stat_id = (SELECT id FROM stats WHERE display_name = ? OR short_name = ?) AND user_id = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$value</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\$value</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
	<span style="color: #000066;">return</span> <span style="color: #0000ff;">$value</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>While that would be fine if we were only going to use this code for retrieving user stats, it&#8217;s organically grown into 3 different places with the exact same code &#8211; which is bad. Let&#8217;s rewrite the code slightly, so that any of our stats code can call it:</p>

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">sub</span> getStatDRY <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$tableName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$columnName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>
	<span style="color: #000000; font-weight: bold;">use</span> config<span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> DBI<span style="color: #339933;">-&gt;</span><span style="color: #006600;">connect</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;DBI:mysql:$dbname:$dbhost&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$dbuser</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$dbpass</span><span style="color: #339933;">,</span><span style="color: #009900;">&#123;</span>RaiseError <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	createIfNotExistsDRY<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$tableName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$columnName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT value FROM $tableName WHERE stat_id = (SELECT id FROM stats WHERE display_name = ? OR short_name = ?) AND $columnName = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$value</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\$value</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
	<span style="color: #000066;">return</span> <span style="color: #0000ff;">$value</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>And with that done, we can now use that function to retrieve any of our stats &#8211; not just user stats. All we have to do is pass in the table and column name for the stat table, in addition to the information for which stat value we want to retrieve.</p>
<p>Doing it this way works because our stats tables are laid out in virtually the same way &#8211; they all have a name, and they&#8217;re virtually exactly the same, except for the name of the one column that tracks the ID number of whatever we are storing stats for. If our stats tables were very different from each other, this might not work quite as easily.</p>
<p>One thing that you need to notice and be aware of is the fact that neither the table name or the column name are escaped when we build our SQL query &#8211; which means that there&#8217;s potential for a SQL injection vulnerability there. You can get around this and keep your system safer by <strong>never using user input for the table or column names</strong> in your calls to this code.</p>
<p>We&#8217;ve seen how the change works for the <strong>getStat</strong> function &#8211; now let&#8217;s see how it goes for the other two:</p>

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">sub</span> setStatDRY <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$tableName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$columnName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statValue</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>
	<span style="color: #000000; font-weight: bold;">use</span> config<span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> DBI<span style="color: #339933;">-&gt;</span><span style="color: #006600;">connect</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;DBI:mysql:$config{dbName}:$config{dbHost}&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$config</span><span style="color: #009900;">&#123;</span>dbUser<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$config</span><span style="color: #009900;">&#123;</span>dbPass<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #009900;">&#123;</span>RaiseError <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	createIfNotExistsDRY<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$tableName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$columnName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;UPDATE $tableName SET value = ? WHERE stat_id = (SELECT id FROM stats WHERE display_name = ? OR short_name = ?) AND $columnName = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statValue</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">sub</span> createIfNotExistsDRY <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$tableName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$columnName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>	
	<span style="color: #000000; font-weight: bold;">use</span> config<span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> DBI<span style="color: #339933;">-&gt;</span><span style="color: #006600;">connect</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;DBI:mysql:$config{dbName}:$config{dbHost}&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$config</span><span style="color: #009900;">&#123;</span>dbUser<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$config</span><span style="color: #009900;">&#123;</span>dbPass<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #009900;">&#123;</span>RaiseError <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT count(value) FROM $tableName WHERE stat_id = (SELECT id FROM stats WHERE display_name = ? OR short_name = ?) AND $columnName = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$count</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\$count</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$count</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;"># no entry for that stat/user combination - insert one with a value of 0</span>
		<span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;INSERT INTO $tableName(stat_id,$columnName,value) VALUES ((SELECT id FROM stats WHERE display_name = ? OR short_name = ?),?,?)&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>	
<span style="color: #009900;">&#125;</span></pre></div></div>

<p><p>As you can now see, there isn&#8217;t a big change being made for this &#8211; all we do is add two more arguments to our functions, and then modify the way we create our queries. But the gains we&#8217;re making in terms of development are <strong>huge</strong>.</p>
<p>You might be wondering why these functions now have the word &#8216;DRY&#8217; at the end of their names &#8211; the reason for this is that we can now use these functions for one of the cooler aspects of DRY &#8211; being able to replace whole chunks of backend logic, without having to modify the primary codebase. If you save the current file as <strong>statsDRY.pm</strong>, you can now modify <strong>stats.pm</strong> to look like this:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #000066;">package</span> stats<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> DBI<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> statsDRY<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> constant TABLE <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'user_stats'</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> constant COLUMN <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'user_id'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">sub</span> getStat <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>
	<span style="color: #000066;">return</span> statsDRY<span style="color: #339933;">::</span><span style="color: #006600;">getStatDRY</span><span style="color: #009900;">&#40;</span>TABLE<span style="color: #339933;">,</span>COLUMN<span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">sub</span> setStat <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statValue</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>
	statsDRY<span style="color: #339933;">::</span><span style="color: #006600;">setStatDRY</span><span style="color: #009900;">&#40;</span>TABLE<span style="color: #339933;">,</span>COLUMN<span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statValue</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>And this is where you see the <strong>real</strong> gains of DRY &#8211; now, all of our stats logic is inside of <strong>statsDRY.pm</strong>, and if we ever need to modify it we&#8217;ll only need to modify that one file. We can change the way that <strong>all</strong> of our stats code works, from a single file &#8211; and those changes will seamlessly work accross item stats, user stats, monster stats, and any other stats we decide to implement in the future.</p>
<p>While our current codebase is relatively small, this isn&#8217;t a big deal &#8211; but what if you were making this change and had 20 different files calling <strong>stats::getStat()</strong>? You wouldn&#8217;t want to go through each and every one of them and modify the call &#8211; by moving our stats code out into its own module, we&#8217;ve made it so that you only have to edit a file or two, instead of having to edit every file that ever uses your stats code. That&#8217;s a real time-saver, and one of the great aspects of using the DRY approach to writing code.</p>
<p>There isn&#8217;t anything &#8216;new&#8217; to this code, with the except of the two constants we set up &#8211; <em>TABLE</em>, and <em>COLUMN</em>. These two constants are what are passed to our DRY stats retrieval code, and creating them allows us to make another DRY change. Now, if you ever decide to modify where your user stats are stored, you only need to modify those two constants &#8211; and not go through every file that uses <em>user_stats</em>, changing it to the name of whatever table you switched to. While this will probably never happen, it&#8217;s still a good idea to have this in place &#8211; just in case.</p>
<p>Here&#8217;s what the finished <strong>statsDRY.pm</strong> looks like:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #000066;">package</span> statsDRY<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> DBI<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">sub</span> getStatDRY <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$tableName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$columnName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>
	<span style="color: #000000; font-weight: bold;">use</span> config<span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> DBI<span style="color: #339933;">-&gt;</span><span style="color: #006600;">connect</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;DBI:mysql:$config{dbName}:$config{dbHost}&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$config</span><span style="color: #009900;">&#123;</span>dbUser<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$config</span><span style="color: #009900;">&#123;</span>dbPass<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #009900;">&#123;</span>RaiseError <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	createIfNotExistsDRY<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$tableName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$columnName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT value FROM $tableName WHERE stat_id = (SELECT id FROM stats WHERE display_name = ? OR short_name = ?) AND $columnName = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$value</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\$value</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
	<span style="color: #000066;">return</span> <span style="color: #0000ff;">$value</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">sub</span> setStatDRY <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$tableName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$columnName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statValue</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>
	<span style="color: #000000; font-weight: bold;">use</span> config<span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> DBI<span style="color: #339933;">-&gt;</span><span style="color: #006600;">connect</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;DBI:mysql:$config{dbName}:$config{dbHost}&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$config</span><span style="color: #009900;">&#123;</span>dbUser<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$config</span><span style="color: #009900;">&#123;</span>dbPass<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #009900;">&#123;</span>RaiseError <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	createIfNotExistsDRY<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$tableName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$columnName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;UPDATE $tableName SET value = ? WHERE stat_id = (SELECT id FROM stats WHERE display_name = ? OR short_name = ?) AND $columnName = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statValue</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">sub</span> createIfNotExistsDRY <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$tableName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$columnName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>	
	<span style="color: #000000; font-weight: bold;">use</span> config<span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> DBI<span style="color: #339933;">-&gt;</span><span style="color: #006600;">connect</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;DBI:mysql:$config{dbName}:$config{dbHost}&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$config</span><span style="color: #009900;">&#123;</span>dbUser<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$config</span><span style="color: #009900;">&#123;</span>dbPass<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #009900;">&#123;</span>RaiseError <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT count(value) FROM $tableName WHERE stat_id = (SELECT id FROM stats WHERE display_name = ? OR short_name = ?) AND $columnName = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$count</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\$count</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$count</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;"># no entry for that stat/user combination - insert one with a value of 0</span>
		<span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;INSERT INTO $tableName(stat_id,$columnName,value) VALUES ((SELECT id FROM stats WHERE display_name = ? OR short_name = ?),?,?)&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>	
<span style="color: #009900;">&#125;</span>
&nbsp;
&nbsp;
<span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p><p>I&#8217;ve also rewritten <strong>stats.pm</strong> to use this new code &#8211; you could do this for all your stats code, or(if you preferred, and are fairly certain your database structure won&#8217;t change) you could even swap all the code to just use the DRY functions instead of working off of the stats modules. Here&#8217;s what <strong>stats.pm</strong> looks like now:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #000066;">package</span> stats<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> DBI<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> statsDRY<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> constant TABLE <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'user_stats'</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> constant COLUMN <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'user_id'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">sub</span> getStat <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>
	<span style="color: #000066;">return</span> statsDRY<span style="color: #339933;">::</span><span style="color: #006600;">getStatDRY</span><span style="color: #009900;">&#40;</span>TABLE<span style="color: #339933;">,</span>COLUMN<span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">sub</span> setStat <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statValue</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>
	statsDRY<span style="color: #339933;">::</span><span style="color: #006600;">setStatDRY</span><span style="color: #009900;">&#40;</span>TABLE<span style="color: #339933;">,</span>COLUMN<span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statValue</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://buildingbrowsergames.com/2008/07/08/building-browsergames-reducing-repetition-perl/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Building Browsergames: Reducing Repetition (PHP)</title>
		<link>http://buildingbrowsergames.com/2008/07/07/reducing-repetition-ph/</link>
		<comments>http://buildingbrowsergames.com/2008/07/07/reducing-repetition-ph/#comments</comments>
		<pubDate>Mon, 07 Jul 2008 14:00:26 +0000</pubDate>
		<dc:creator>Luke</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://buildingbrowsergames.com/?p=78</guid>
		<description><![CDATA[One of the things that will slow you down and bore you the most about working on your own browsergame project is re-writing the exact same code. Unfortunately, that&#8217;s what we&#8217;ve been doing with our stats code &#8211; as reader sepp helpfully pointed out.
There&#8217;s a concept in the programming world known as &#8216;DRY&#8217; &#8211; which [...]]]></description>
			<content:encoded><![CDATA[<p>One of the things that will slow you down and bore you the most about working on your own browsergame project is re-writing the exact same code. Unfortunately, that&#8217;s what we&#8217;ve been doing with our stats code &#8211; as reader <a href='http://www.seelenradio.de/'>sepp</a> helpfully pointed out.</p>
<p>There&#8217;s a concept in the programming world known as &#8216;DRY&#8217; &#8211; which stands for &#8220;Don&#8217;t Repeat Yourself&#8221;. What that means is that <strong>you should only ever write code to do something once</strong> &#8211; and if there are only slight variations between one piece of the code and another, you should merge them until the only differences are the ones that <strong>have</strong> to exist. By adhering to DRY principles, we can drastically cut down our development time, <strong>and</strong> make sure that we have less code overall to maintain(always a plus). Today, we&#8217;ll be using the concept of DRY to trim down our stats code.</p>
<p>So far, we&#8217;ve written three mostly-the-same-but-different pieces of stats code &#8211; one for item stats, one for monster stats, and one for user stats. The code for these pieces of logic are mostly the same &#8211; all that&#8217;s different between them is a few table and column names. Here&#8217;s what one of our <strong>getStat</strong> functions looks like:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> getStat<span style="color: #009900;">&#40;</span><span style="color: #000088;">$statName</span><span style="color: #339933;">,</span><span style="color: #000088;">$userID</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">include</span> <span style="color: #0000ff;">'config.php'</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$conn</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_connect</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$dbhost</span><span style="color: #339933;">,</span><span style="color: #000088;">$dbuser</span><span style="color: #339933;">,</span><span style="color: #000088;">$dbpass</span><span style="color: #009900;">&#41;</span>
		or <span style="color: #990000;">die</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Error connecting to mysql:'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #990000;">mysql_select_db</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$dbname</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	createIfNotExists<span style="color: #009900;">&#40;</span><span style="color: #000088;">$statName</span><span style="color: #339933;">,</span><span style="color: #000088;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$query</span> <span style="color: #339933;">=</span> <span style="color: #990000;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;SELECT value FROM user_stats WHERE stat_id = (SELECT id FROM stats WHERE display_name = '<span style="color: #009933; font-weight: bold;">%s</span>' OR short_name = '<span style="color: #009933; font-weight: bold;">%s</span>') AND user_id = '<span style="color: #009933; font-weight: bold;">%s</span>'&quot;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$statName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$statName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$query</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #990000;">list</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_fetch_row</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$result</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">return</span> <span style="color: #000088;">$value</span><span style="color: #339933;">;</span>		
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>While that&#8217;s fine for a single use, we&#8217;re now using almost exactly the same code in three different places &#8211; <strong>and</strong> three different files. We&#8217;re going to apply the DRY principle, and rewrite the code slightly so that any of our stats code can call it:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> getStatDRY<span style="color: #009900;">&#40;</span><span style="color: #000088;">$tableName</span><span style="color: #339933;">,</span><span style="color: #000088;">$columnName</span><span style="color: #339933;">,</span><span style="color: #000088;">$statName</span><span style="color: #339933;">,</span><span style="color: #000088;">$trackingID</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">include</span> <span style="color: #0000ff;">'config.php'</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$conn</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_connect</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$dbhost</span><span style="color: #339933;">,</span><span style="color: #000088;">$dbuser</span><span style="color: #339933;">,</span><span style="color: #000088;">$dbpass</span><span style="color: #009900;">&#41;</span>
		or <span style="color: #990000;">die</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Error connecting to mysql:'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #990000;">mysql_select_db</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$dbname</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	createIfNotExistsDRY<span style="color: #009900;">&#40;</span><span style="color: #000088;">$tableName</span><span style="color: #339933;">,</span><span style="color: #000088;">$columnName</span><span style="color: #339933;">,</span><span style="color: #000088;">$statName</span><span style="color: #339933;">,</span><span style="color: #000088;">$trackingID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$query</span> <span style="color: #339933;">=</span> <span style="color: #990000;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;SELECT value FROM <span style="color: #009933; font-weight: bold;">%s</span> WHERE stat_id = (SELECT id FROM stats WHERE display_name = '<span style="color: #009933; font-weight: bold;">%s</span>' OR short_name = '<span style="color: #009933; font-weight: bold;">%s</span>') AND <span style="color: #009933; font-weight: bold;">%s</span> = '<span style="color: #009933; font-weight: bold;">%s</span>'&quot;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$tableName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$statName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$statName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$columnName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$trackingID</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$query</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #990000;">list</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_fetch_row</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$result</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">return</span> <span style="color: #000088;">$value</span><span style="color: #339933;">;</span>		
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>And with that, we can now use that single getStat function from any of our stats code &#8211; all we need to do is pass in the table and column names, in addition to which stats we want to retrieve.</p>
<p>Refactoring the code in this way works because our stat tables are all set up in the same way &#8211; one column has values, one column has the stat ID, and one column has the ID of whatever we&#8217;re tracking the stat for. If our tables were too varied, this might not work as easily.</p>
<p>If you look at the line where we create our <em>$query</em> variable using sprintf, you&#8217;ll notice that there are no quotes around the token for the table name &#8211; this is because MySQL won&#8217;t allow you to use quotes around your table name in select statements. You need to be aware that this has the potential to grow into a SQL injection vulnerability &#8211; so make sure that you aren&#8217;t using user input for your table name.</p>
<p>With that change made, let&#8217;s also make the change in our other functions:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> setStatDRY<span style="color: #009900;">&#40;</span><span style="color: #000088;">$tableName</span><span style="color: #339933;">,</span><span style="color: #000088;">$columnName</span><span style="color: #339933;">,</span><span style="color: #000088;">$statName</span><span style="color: #339933;">,</span><span style="color: #000088;">$trackingID</span><span style="color: #339933;">,</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">include</span> <span style="color: #0000ff;">'config.php'</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$conn</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_connect</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$dbhost</span><span style="color: #339933;">,</span><span style="color: #000088;">$dbuser</span><span style="color: #339933;">,</span><span style="color: #000088;">$dbpass</span><span style="color: #009900;">&#41;</span>
		or <span style="color: #990000;">die</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Error connecting to mysql'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #990000;">mysql_select_db</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$dbname</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	createIfNotExistsDRY<span style="color: #009900;">&#40;</span><span style="color: #000088;">$tableName</span><span style="color: #339933;">,</span><span style="color: #000088;">$columnName</span><span style="color: #339933;">,</span><span style="color: #000088;">$statName</span><span style="color: #339933;">,</span><span style="color: #000088;">$trackingID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$query</span> <span style="color: #339933;">=</span> <span style="color: #990000;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;UPDATE <span style="color: #009933; font-weight: bold;">%s</span> SET value = '<span style="color: #009933; font-weight: bold;">%s</span>' WHERE stat_id = (SELECT id FROM stats WHERE display_name = '<span style="color: #009933; font-weight: bold;">%s</span>' OR short_name = '<span style="color: #009933; font-weight: bold;">%s</span>') AND <span style="color: #009933; font-weight: bold;">%s</span> = '<span style="color: #009933; font-weight: bold;">%s</span>'&quot;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$tableName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$statName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$statName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$columnName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$trackingID</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$query</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> createIfNotExistsDRY<span style="color: #009900;">&#40;</span><span style="color: #000088;">$tableName</span><span style="color: #339933;">,</span><span style="color: #000088;">$columnName</span><span style="color: #339933;">,</span><span style="color: #000088;">$statName</span><span style="color: #339933;">,</span><span style="color: #000088;">$trackingID</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">include</span> <span style="color: #0000ff;">'config.php'</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$conn</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_connect</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$dbhost</span><span style="color: #339933;">,</span><span style="color: #000088;">$dbuser</span><span style="color: #339933;">,</span><span style="color: #000088;">$dbpass</span><span style="color: #009900;">&#41;</span>
		or <span style="color: #990000;">die</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Error connecting to mysql:'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #990000;">mysql_select_db</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$dbname</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$query</span> <span style="color: #339933;">=</span> <span style="color: #990000;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;SELECT count(value) FROM <span style="color: #009933; font-weight: bold;">%s</span> WHERE stat_id = (SELECT id FROM stats WHERE display_name = '<span style="color: #009933; font-weight: bold;">%s</span>' OR short_name = '<span style="color: #009933; font-weight: bold;">%s</span>') AND <span style="color: #009933; font-weight: bold;">%s</span> = '<span style="color: #009933; font-weight: bold;">%s</span>'&quot;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$tableName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$statName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$statName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$columnName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$trackingID</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$query</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #990000;">list</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$count</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_fetch_row</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$result</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$count</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;">// the stat doesn't exist; insert it into the database</span>
		<span style="color: #000088;">$query</span> <span style="color: #339933;">=</span> <span style="color: #990000;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;INSERT INTO <span style="color: #009933; font-weight: bold;">%s</span>(stat_id,<span style="color: #009933; font-weight: bold;">%s</span>,value) VALUES ((SELECT id FROM stats WHERE display_name = '<span style="color: #009933; font-weight: bold;">%s</span>' OR short_name = '<span style="color: #009933; font-weight: bold;">%s</span>'),'<span style="color: #009933; font-weight: bold;">%s</span>','<span style="color: #009933; font-weight: bold;">%s</span>')&quot;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$tableName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$columnName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$statName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$statName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$trackingID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #0000ff;">'0'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$query</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>	
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>As you can see, it isn&#8217;t that big of a change &#8211; we just add the <em>$tableName</em> and <em>$columnName</em> arguments to our functions, and then modify the way that our queries are created.</p>
<p>You might be wondering why these functions have been showing up with the word &#8216;DRY&#8217; after them &#8211; and that&#8217;s because I&#8217;m about to show you one of the cooler aspects of doing this. Now that we&#8217;ve created these versions of our functions, we can save them as <strong>stats-dry.php</strong>, and then modify our current stats code to work off of them. Here&#8217;s an example of what the new <strong>stats.php</strong> looks like:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #b1b100;">require_once</span> <span style="color: #0000ff;">'stats-dry.php'</span><span style="color: #339933;">;</span>
<span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'TABLE'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'user_stats'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'COLUMN'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'user_id'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> getStat<span style="color: #009900;">&#40;</span><span style="color: #000088;">$statName</span><span style="color: #339933;">,</span><span style="color: #000088;">$trackingID</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">return</span> getStatDRY<span style="color: #009900;">&#40;</span>TABLE<span style="color: #339933;">,</span>COLUMN<span style="color: #339933;">,</span><span style="color: #000088;">$statName</span><span style="color: #339933;">,</span><span style="color: #000088;">$trackingID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">function</span> setStat<span style="color: #009900;">&#40;</span><span style="color: #000088;">$statName</span><span style="color: #339933;">,</span><span style="color: #000088;">$trackingID</span><span style="color: #339933;">,</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	setStatDRY<span style="color: #009900;">&#40;</span>TABLE<span style="color: #339933;">,</span>COLUMN<span style="color: #339933;">,</span><span style="color: #000088;">$statName</span><span style="color: #339933;">,</span><span style="color: #000088;">$trackingID</span><span style="color: #339933;">,</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p>And that&#8217;s where you start to see the <strong>real</strong> gains of DRY &#8211; now, all of our stats logic is inside <strong>stats-dry.php</strong>. We can go to our other code and change the way that our functions work, so that they call the DRY versions &#8211; without having to change any of the other code on the pages that are using it(like the index page, healer, forest, etc.). While our codebase is still relatively small and this could be accomplished relatively easily, this technique is valid for big or small codebases &#8211; it just gives you the flexibility to be able to do whatever you need to. And if your codebase is small enough that you feel like making the switch to only using the DRY code, you can remove the three extra stat libraries entirely.</p>
<p>One new thing that you may not understand with this code is the calls to <a href='http://ca.php.net/manual/en/function.define.php'>define()</a>. We are using <strong>define()</strong> to set up constants for our code &#8211; that way, if we ever decide that user stats should be stored inside <em>user_stats_table</em> instead of <em>user_stats</em>, or we decide to change the column name to something different, we only need to change it in the one place &#8211; another benefit of DRY.</p>
<p>Here&#8217;s what the finished code for <strong>stats-dry.php</strong> looks like:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> getStatDRY<span style="color: #009900;">&#40;</span><span style="color: #000088;">$tableName</span><span style="color: #339933;">,</span><span style="color: #000088;">$columnName</span><span style="color: #339933;">,</span><span style="color: #000088;">$statName</span><span style="color: #339933;">,</span><span style="color: #000088;">$trackingID</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">include</span> <span style="color: #0000ff;">'config.php'</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$conn</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_connect</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$dbhost</span><span style="color: #339933;">,</span><span style="color: #000088;">$dbuser</span><span style="color: #339933;">,</span><span style="color: #000088;">$dbpass</span><span style="color: #009900;">&#41;</span>
		or <span style="color: #990000;">die</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Error connecting to mysql:'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #990000;">mysql_select_db</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$dbname</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	createIfNotExistsDRY<span style="color: #009900;">&#40;</span><span style="color: #000088;">$tableName</span><span style="color: #339933;">,</span><span style="color: #000088;">$columnName</span><span style="color: #339933;">,</span><span style="color: #000088;">$statName</span><span style="color: #339933;">,</span><span style="color: #000088;">$trackingID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$query</span> <span style="color: #339933;">=</span> <span style="color: #990000;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;SELECT value FROM <span style="color: #009933; font-weight: bold;">%s</span> WHERE stat_id = (SELECT id FROM stats WHERE display_name = '<span style="color: #009933; font-weight: bold;">%s</span>' OR short_name = '<span style="color: #009933; font-weight: bold;">%s</span>') AND <span style="color: #009933; font-weight: bold;">%s</span> = '<span style="color: #009933; font-weight: bold;">%s</span>'&quot;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$tableName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$statName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$statName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$columnName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$trackingID</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$query</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #990000;">list</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_fetch_row</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$result</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">return</span> <span style="color: #000088;">$value</span><span style="color: #339933;">;</span>		
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> setStatDRY<span style="color: #009900;">&#40;</span><span style="color: #000088;">$tableName</span><span style="color: #339933;">,</span><span style="color: #000088;">$columnName</span><span style="color: #339933;">,</span><span style="color: #000088;">$statName</span><span style="color: #339933;">,</span><span style="color: #000088;">$trackingID</span><span style="color: #339933;">,</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">include</span> <span style="color: #0000ff;">'config.php'</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$conn</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_connect</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$dbhost</span><span style="color: #339933;">,</span><span style="color: #000088;">$dbuser</span><span style="color: #339933;">,</span><span style="color: #000088;">$dbpass</span><span style="color: #009900;">&#41;</span>
		or <span style="color: #990000;">die</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Error connecting to mysql'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #990000;">mysql_select_db</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$dbname</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	createIfNotExistsDRY<span style="color: #009900;">&#40;</span><span style="color: #000088;">$tableName</span><span style="color: #339933;">,</span><span style="color: #000088;">$columnName</span><span style="color: #339933;">,</span><span style="color: #000088;">$statName</span><span style="color: #339933;">,</span><span style="color: #000088;">$trackingID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$query</span> <span style="color: #339933;">=</span> <span style="color: #990000;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;UPDATE <span style="color: #009933; font-weight: bold;">%s</span> SET value = '<span style="color: #009933; font-weight: bold;">%s</span>' WHERE stat_id = (SELECT id FROM stats WHERE display_name = '<span style="color: #009933; font-weight: bold;">%s</span>' OR short_name = '<span style="color: #009933; font-weight: bold;">%s</span>') AND <span style="color: #009933; font-weight: bold;">%s</span> = '<span style="color: #009933; font-weight: bold;">%s</span>'&quot;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$tableName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$statName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$statName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$columnName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$trackingID</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$query</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> createIfNotExistsDRY<span style="color: #009900;">&#40;</span><span style="color: #000088;">$tableName</span><span style="color: #339933;">,</span><span style="color: #000088;">$columnName</span><span style="color: #339933;">,</span><span style="color: #000088;">$statName</span><span style="color: #339933;">,</span><span style="color: #000088;">$trackingID</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">include</span> <span style="color: #0000ff;">'config.php'</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$conn</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_connect</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$dbhost</span><span style="color: #339933;">,</span><span style="color: #000088;">$dbuser</span><span style="color: #339933;">,</span><span style="color: #000088;">$dbpass</span><span style="color: #009900;">&#41;</span>
		or <span style="color: #990000;">die</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Error connecting to mysql:'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #990000;">mysql_select_db</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$dbname</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$query</span> <span style="color: #339933;">=</span> <span style="color: #990000;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;SELECT count(value) FROM <span style="color: #009933; font-weight: bold;">%s</span> WHERE stat_id = (SELECT id FROM stats WHERE display_name = '<span style="color: #009933; font-weight: bold;">%s</span>' OR short_name = '<span style="color: #009933; font-weight: bold;">%s</span>') AND <span style="color: #009933; font-weight: bold;">%s</span> = '<span style="color: #009933; font-weight: bold;">%s</span>'&quot;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$tableName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$statName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$statName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$columnName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$trackingID</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$query</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #990000;">list</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$count</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_fetch_row</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$result</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$count</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;">// the stat doesn't exist; insert it into the database</span>
		<span style="color: #000088;">$query</span> <span style="color: #339933;">=</span> <span style="color: #990000;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;INSERT INTO <span style="color: #009933; font-weight: bold;">%s</span>(stat_id,<span style="color: #009933; font-weight: bold;">%s</span>,value) VALUES ((SELECT id FROM stats WHERE display_name = '<span style="color: #009933; font-weight: bold;">%s</span>' OR short_name = '<span style="color: #009933; font-weight: bold;">%s</span>'),'<span style="color: #009933; font-weight: bold;">%s</span>','<span style="color: #009933; font-weight: bold;">%s</span>')&quot;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$tableName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$columnName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$statName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$statName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$trackingID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #0000ff;">'0'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$query</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>	
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p>And here&#8217;s what the new code inside <strong>stats.php</strong>, which was used to retrieve our user&#8217;s stats, looks like. You will need to modify the other stats code yourself &#8211; although it shouldn&#8217;t be too difficult, and you could even just swap all the code to using the DRY functions instead(as long as you&#8217;re sure your database structure won&#8217;t change):</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #b1b100;">require_once</span> <span style="color: #0000ff;">'stats-dry.php'</span><span style="color: #339933;">;</span>
<span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'TABLE'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'user_stats'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'COLUMN'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'user_id'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> getStat<span style="color: #009900;">&#40;</span><span style="color: #000088;">$statName</span><span style="color: #339933;">,</span><span style="color: #000088;">$trackingID</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">return</span> getStatDRY<span style="color: #009900;">&#40;</span>TABLE<span style="color: #339933;">,</span>COLUMN<span style="color: #339933;">,</span><span style="color: #000088;">$statName</span><span style="color: #339933;">,</span><span style="color: #000088;">$trackingID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">function</span> setStat<span style="color: #009900;">&#40;</span><span style="color: #000088;">$statName</span><span style="color: #339933;">,</span><span style="color: #000088;">$trackingID</span><span style="color: #339933;">,</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	setStatDRY<span style="color: #009900;">&#40;</span>TABLE<span style="color: #339933;">,</span>COLUMN<span style="color: #339933;">,</span><span style="color: #000088;">$statName</span><span style="color: #339933;">,</span><span style="color: #000088;">$trackingID</span><span style="color: #339933;">,</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://buildingbrowsergames.com/2008/07/07/reducing-repetition-ph/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>So you want to build a browsergame, do you?</title>
		<link>http://buildingbrowsergames.com/2008/04/14/so-you-want-to-build-a-browsergame-do-you/</link>
		<comments>http://buildingbrowsergames.com/2008/04/14/so-you-want-to-build-a-browsergame-do-you/#comments</comments>
		<pubDate>Tue, 15 Apr 2008 00:00:05 +0000</pubDate>
		<dc:creator>Luke</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.buildingbrowsergames.com/blog/?p=5</guid>
		<description><![CDATA[Well, this seems like a good place to start.
Right now it&#8217;s kind of sparse. But hopefully, soon, this website will be chock full of content that you&#8217;ll be able to use and share to help you get closer to building your own browsergame(or maybe even improve on one you&#8217;ve already built).
Good Luck!
]]></description>
			<content:encoded><![CDATA[<p>Well, this seems like a good place to start.</p>
<p>Right now it&#8217;s kind of sparse. But hopefully, soon, this website will be chock full of content that you&#8217;ll be able to use and share to help you get closer to building your own browsergame(or maybe even improve on one you&#8217;ve already built).</p>
<p>Good Luck!</p>
]]></content:encoded>
			<wfw:commentRss>http://buildingbrowsergames.com/2008/04/14/so-you-want-to-build-a-browsergame-do-you/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

