<?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>andrewfreiday.com</title>
	<atom:link href="http://andrewfreiday.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://andrewfreiday.com</link>
	<description>Useless web programming tips and code snippets</description>
	<lastBuildDate>Mon, 23 Aug 2010 19:19:45 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Experiment update: revised Django-like PHP (5.3 compatible) querying interface</title>
		<link>http://andrewfreiday.com/2010/08/23/experiment-update-revised-django-like-php-5-3-compatible-querying-interface/</link>
		<comments>http://andrewfreiday.com/2010/08/23/experiment-update-revised-django-like-php-5-3-compatible-querying-interface/#comments</comments>
		<pubDate>Mon, 23 Aug 2010 19:12:09 +0000</pubDate>
		<dc:creator>Andrew</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[5.2]]></category>
		<category><![CDATA[5.3]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[storm]]></category>

		<guid isPermaLink="false">http://andrewfreiday.com/?p=102</guid>
		<description><![CDATA[After some research, discussion and a bit of hacking together some poorly organized code, I&#8217;ve come up with a revised interface from my previous post An experiment: Django Framework-like querying/model interface in PHP. Now there existed a few problems I was well aware that I wanted to address if I was going to spend any [...]]]></description>
			<content:encoded><![CDATA[<p>After some research, discussion and a bit of hacking together some poorly organized code, I&#8217;ve come up with a revised interface from my previous post <a href="http://andrewfreiday.com/2010/08/10/an-experiment-django-framework-like-queryingmodel-interface-in-php/"><em>An experiment: Django Framework-like querying/model interface in PHP</em></a>.</p>
<p>Now there existed a few problems I was well aware that I wanted to address if I was going to spend any more time on a good, clean interface that promoted rapid development and readable code:</p>
<ul>
<li>It was dependent on a PECL extension that was nearly 4 years old</li>
<li>It only worked with PHP 5.2.x (as per above)</li>
<li>The actual query-building interface wasn&#8217;t pretty and hindered readability</li>
</ul>
<p>I sat down and revised a good portion of the old code I had put together and came up with something that fixes these problems. I wrote a new collection of classes with PHP 5.3 in mind and it uses a lot of the new language features (especially <a href="http://php.net/manual/en/language.oop5.late-static-bindings.php" target="_blank">late static bindings</a> and the <a href="http://php.net/manual/en/language.oop5.overloading.php" target="_blank">__callStatic magic method</a>). Now, because of the use of these new features my code is now dependent on PHP version 5.3 (developed using 5.3.1) &#8212; but, I suppose it&#8217;s better to code looking to the future rather than being locked into an older version.<span id="more-102"></span>Thanks to reader Robert P who introduced me to Python&#8217;s <a href="https://storm.canonical.com/FrontPage" target="_blank">Storm ORM</a> and how it&#8217;s querying interface looked and functioned. After digging my way through its docs, I came up with something that is quite like a <span style="text-decoration: line-through;">hybrid</span> morbid mix of Django and Storm for use in PHP.</p>
<p>Let&#8217;s get to it: here&#8217;s how my interface has changed.</p>
<p><strong>Basic Querying</strong></p>
<p>I wanted to get away from what I hated the most: an unreadable querying interface that prevented the creation of self-explainable queries. What before was like:</p>
<pre>Product::get(<strong>array("make__contains" =&gt; "Sony")</strong>);</pre>
<p>has now become:</p>
<pre>Product::get(<strong>Field::make__contains("Sony")</strong>);</pre>
<p>which, using the __callStatic method, allowed me to create an interface that is actually quite readable aloud: &#8220;get <strong>Products</strong> where <strong>field</strong> <strong>make</strong> <strong>contains &#8220;Sony</strong>.&#8221; This is quite a bit better than using the array() function, where in reality it is completely unnecessary to the interface. This also works when combining expressions:</p>
<pre>$q = Product::get(Field::make__contains("Sony"), Field::price__gt(100));
print $q-&gt;create_statement();
// output: SELECT id FROM products WHERE (make LIKE '%Sony%' AND price &gt; '100')</pre>
<p><strong>Complex Expressions</strong></p>
<p>One of the things I love about Django is the ability to create more complex AND/OR queries using the Q interface and operator overloading (which I was using before, dependent on the PECL operator extension). Storm has this too, but it also offered up an <a href="https://storm.canonical.com/Manual#Expressions" target="_blank">alternative interface using AND() and OR() functions</a>.</p>
<p>I wasn&#8217;t able to do this exactly in PHP (&#8220;and&#8221; and &#8220;or&#8221; are reserved keywords), but I was able to make something slightly similar:</p>
<pre>require_once("Model.class.php");

class Product extends Model { }

$q = Product::get(_AND(Field::make__contains("Sony"), Field::price__gt(100)));
print $q-&gt;create_statement();
// output: SELECT id FROM products WHERE make LIKE '%Sony%' AND price &gt; '100'

$q = Product::get(_OR(Field::make__contains("Panasonic"), Field::make__contains("LG")));
print $q-&gt;create_statement();
// output: SELECT id FROM products WHERE make LIKE '%Panasonic%' OR make LIKE '%LG%'</pre>
<p><strong>Self-Referencing Fields in Expressions</strong></p>
<p>Again, another favourite feature of Django was the ability to use F objects to create expressions that references a table&#8217;s own fields. My basic research didn&#8217;t show anything like this in Storm, but using the __callStatic method and the same style interface, I was able to create a readable interface for these sorts of queries:</p>
<pre>$q = Product::get(Field::price__gt(<strong>Field::cost__times(2)</strong>));
print $q-&gt;create_statement();
// output: SELECT id FROM products WHERE price &gt; cost * 2

$q = Product::get(Field::price__gt(Field::cost__times("quantity_sold")));
print $q-&gt;create_statement();
// output: SELECT id FROM products WHERE price &gt; cost * quantity_sold</pre>
<p>Using [field]__times (or __plus, __minus, __divided_by), complex field-references can be created and is still fairly readable, as for the above example: &#8220;get <strong>Products</strong> where <strong>field price</strong> is <strong>greater than field cost times 2,&#8221;</strong> and the output should be as expected.</p>
<p>I&#8217;m still not entirely happy with this portion of my code at the moment. It is fairly limited in the sorts of queries you can create (for example, it&#8217;s not possible to create an expression such as &#8220;cost * 2 &#8211; price&#8221;).</p>
<p>I&#8217;m more than happy to offer up what code I have to date. I tried to document as much as possible, but some of the code is admittedly messy and could use a clean-up &#8212; which I&#8217;m sure I&#8217;ll get to at some point or another.</p>
<p><a href="http://andrewfreiday.com/source.php?f=django2/Expression.class.php" target="_blank">Download/view Expression.class.php</a> &#8212; defines how Expressions are created and handled using the Field interface</p>
<p><a href="http://andrewfreiday.com/source.php?f=django2/ExpressionNode.class.php" target="_blank">Download/view ExpressionNode.class.php</a> &#8212; slightly revised from the previous code, defines classes for Q and F objects, along with _AND() and _OR() functions for creating more complex expressions.</p>
<p><a href="http://andrewfreiday.com/source.php?f=django2/Model.class.php" target="_blank">Download/view Model.class.php</a> &#8212; basic class for creating models and queries.</p>
<p><a href="http://andrewfreiday.com/source.php?f=django2/QuerySet.class.php" target="_blank">Download/view QuerySet.class.php</a> &#8212; defines how filter/exclude/get queries are chained together in a linked list structure.</p>
]]></content:encoded>
			<wfw:commentRss>http://andrewfreiday.com/2010/08/23/experiment-update-revised-django-like-php-5-3-compatible-querying-interface/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>An experiment: Django Framework-like querying/model interface in PHP</title>
		<link>http://andrewfreiday.com/2010/08/10/an-experiment-django-framework-like-queryingmodel-interface-in-php/</link>
		<comments>http://andrewfreiday.com/2010/08/10/an-experiment-django-framework-like-queryingmodel-interface-in-php/#comments</comments>
		<pubDate>Tue, 10 Aug 2010 20:08:36 +0000</pubDate>
		<dc:creator>Andrew</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[5.2]]></category>
		<category><![CDATA[5.3]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[operator]]></category>
		<category><![CDATA[overloading]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://andrewfreiday.com/?p=84</guid>
		<description><![CDATA[I have continued with this experiment and created a new querying interface compatible with PHP 5.3 and has no dependent PECL extensions: Experiment update: revised Django-like PHP (5.3 compatible) querying interface. So this is an experiment I&#8217;ve had in the making for quite some time. I&#8217;ve been working for years trying to build a reusable [...]]]></description>
			<content:encoded><![CDATA[<pre>I have continued with this experiment and created a new querying interface compatible with PHP 5.3 and has no dependent PECL extensions: <a href="http://andrewfreiday.com/2010/08/23/experiment-update-revised-django-like-php-5-3-compatible-querying-interface/" target="_blank"><em><strong>Experiment update: revised Django-like PHP (5.3 compatible) querying interface</strong></em></a>.</pre>
<p>So this is an experiment I&#8217;ve had in the making for quite some time. I&#8217;ve been working for years trying to build a reusable &#8220;generic object&#8221; querying framework that I made my PHP applications easier to maintain and faster to develop. I originally started with a small library of classes, including a &#8216;GenericObject&#8217; class and a &#8216;Collection&#8217;, which allowed for proper iteration using the Iterator interface &#8212; all wrapped around a very messy Factory design pattern.</p>
<p>Up until about a year, I used hacked and modified versions of these classes for all of my projects and was getting tired of the mess. After doing some casual research I finally came across the <a href="http://www.djangoproject.com/" target="_blank">Django Framework</a> and found the object creation and database <a href="http://docs.djangoproject.com/en/1.2/topics/db/queries/" target="_blank">querying</a> quite phenomenal as a programming interface. I didn&#8217;t want to spend years trying to get my Python up to par with my abilities with PHP, so I decided to try and replicate it. For the last year, again, I&#8217;ve been using a pretty hacked up version of what seemed to me like a &#8220;Django-like&#8221; interface, combined together with my old GenericObject and Collection classes from long before. With this, I was previously able to perform really simple database queries with an interface like so:</p>
<pre>$users = User::get(array("fullname__contains" =&gt; "Andrew"));

foreach($users as $user) {
  // ...
}</pre>
<p><span id="more-84"></span>Extending this interface, I could further create more complex queries with AND and OR&#8217;s by how I passed a series of function arguments and array items. This worked pretty great actually, definitely increased my productivity when adding to an existing application, but made maintenance somewhat difficult due to hard-to-read queries that took a lot of pausing and mental analysis.</p>
<p>My research went deeper into the Django documentation and I decided: what&#8217;s stopping me from making an <em>almost</em> (this being the key word here) identical interface/framework for PHP, complete with complex querying using <a href="http://docs.djangoproject.com/en/1.2/topics/db/queries/#complex-lookups-with-q-objects" target="_blank">Q()</a> and <a href="http://docs.djangoproject.com/en/1.2/topics/db/queries/#query-expressions" target="_blank">F()</a> objects? Well, ultimately: a lot. But I&#8217;ve started, and I&#8217;m proud of my work that I want to share.</p>
<p><strong>The Problems</strong></p>
<p>First and foremost, the biggest hurdle in my goal was the lack of <a href="http://en.wikipedia.org/wiki/Operator_overloading" target="_blank">operator overloading</a> in PHP. This is what I would need in order to successfully achieve complex querying with Q() and F() objects, such as listed in the Django examples:</p>
<pre>Q(question__startswith='Who') | Q(question__startswith='What')</pre>
<p>I also discovered this topic has been brought up <a href="http://bugs.php.net/46128" target="_blank">many</a> <a href="http://bugs.php.net/bug.php?id=9331" target="_blank">times</a> <a href="http://bugs.php.net/bug.php?id=50969" target="_blank">before</a>, with the final word being an unquestionable <em>&#8220;never.&#8221; </em>This was obviously disappointing for two reason: 1) it meant my goal was out of reach; and 2) PHP is a mature language which I have based my career around up to this point, and now I&#8217;ve come across what I believe to be a major limitation for the future.</p>
<p>Some more research turned up the PECL <a href="http://pecl.php.net/package/operator" target="_blank">operator Package</a>, which does override PHP&#8217;s functionality and allow for some basic operator overloading. Perfect! But another roadblock: it took me long enough to dig up a precompiled version of the package (since PECL doesn&#8217;t compile on Windows systems) and I only had a version that was compatible with PHP 5.2.x. Tough news. This meant I didn&#8217;t have access to beautiful things in PHP 5.3 such as <a href="http://php.net/manual/en/language.oop5.late-static-bindings.php" target="_blank">late static bindings</a> and other new additions to the language. I was able to overcome this by writing my own hacked-up, squirrely version of the <a href="http://php.net/manual/en/function.get-called-class.php" target="_blank">get_called_class function</a> and <span style="text-decoration: line-through;">gratuitous</span> cringe-worthy use of the <a href="http://php.net/manual/en/function.eval.php" target="_blank">eval function</a>.</p>
<p>My final problem was Python&#8217;s beautiful ability to pass arguments to functions/methods in a format such as:</p>
<pre>Entry.objects.filter(<strong>headline__startswith="What"</strong>)</pre>
<p>As much research as I could possibly stand to do, there really is no way around this in PHP. there is no way of passing a variable name a value as a function argument. My work around, despite being what I originally wanted to get away from, was to do something as follows:</p>
<pre>Entry::get(<strong>array("headline__startswith" =&gt; "What")</strong>);</pre>
<p>Obviously this creates some unfortunate coding overhead and reduces fast readability, it&#8217;s my only solution thus far.</p>
<p>Despite these trade-offs, I now had just about everything I needed to create a respectable PHP equivalent of Django querying.</p>
<p><strong>The Solution</strong></p>
<p>I went through the Django document on making queries up and down, left and right, and tried to get the best grasp the concepts of the interface and how they could be applied in PHP. Before even getting to code, I spent a couple nights just thinking about how this could be done in the back-end code of my framework/interface, and finally began coding backwards: first I started writing out some of the Django examples in PHP, then writing backwards through all the classes and objects that I would require in order for these examples to output what I wanted.</p>
<p>Before I get into the nitty gritty of how all the code works together, I&#8217;ll provide a few examples of my interface looks like so far and the queries it&#8217;s able to generate. I&#8217;m not yet at the point where I have QuerySets and usable objects, but I&#8217;ve done the hard part by creating the MySQL statement query building.</p>
<p>First I start by creating my initial database Model:</p>
<pre>require_once("<a href="http://andrewfreiday.com/source.php?f=django/Model.class.php" target="_blank">Model.class.php</a>");

class Product extends Model {
// optional: table name is automatically generated
// using the class name and pluralizing it
//const table_name = "products";
}</pre>
<p>From here, I can use my static get() method to create queries:</p>
<pre>$r = Product::get();
print $r-&gt;create_statement();
// output: SELECT id FROM products

$r = Product::get(array("make__contains" =&gt; "Sony"));
print $r-&gt;create_statement();
// output: SELECT id FROM products WHERE make LIKE '%Sony%'

$r = Product::get(array("make__contains" =&gt; "Sony"), array("category__exact" =&gt; "TV"));
print $r-&gt;create_statement();
// output: SELECT id FROM products WHERE (make LIKE '%Sony%' AND category = 'TV')</pre>
<p>I can then filter() and exclude() these Query objects like with Django:</p>
<pre>$r = Product::get(array("make__contains" =&gt; "Sony"));
$r = $r-&gt;exclude(array("model__contains" =&gt; "RD3"));
print $r-&gt;create_statement();
// output: SELECT id FROM products WHERE make LIKE '%Sony%' AND NOT model LIKE '%RD3%'

$r = Product::get(array("category__contains" =&gt; "Stereo"));
$r = $r-&gt;filter(array("make__exact" =&gt; "Panasonic"));
print $r-&gt;create_statement();
// output: SELECT id FROM products WHERE category LIKE '%Stereo%' AND make = 'Panasonic'</pre>
<p>And I can also use the critical Q() and F() functions, along with operator overloading to create complex queries:</p>
<pre>$r = Product::get(Q(array("make__contains" =&gt; "Sony")) | ~Q(array("category__exact" =&gt; "TV")));
print $r-&gt;create_statement();
// output: SELECT id FROM products WHERE (make LIKE '%Sony%' OR  NOT category = 'TV')

$r = Product::get(array("selling_price__gte" =&gt; F("cost") * 2));
print $r-&gt;create_statement();
// output: SELECT id FROM products WHERE selling_price &gt;= cost * 2</pre>
<p>Of course, this isn&#8217;t as perfectly pretty as the Django interface, but it is quite readable and more maintainable than any other existing PHP solution I am aware of.</p>
<p>Additionally, I also added basic functionality for delete() and update() methods:</p>
<pre>$r = Product::get(array("selling_price__gte" =&gt; F("cost") * 2));

print $r-&gt;delete();
// output: DELETE FROM products WHERE selling_price &gt;= cost * 2

print $r-&gt;update(array("make" =&gt; "Sony", "category" =&gt; "TV"));
// output: UPDATE products SET make = 'Sony', category = 'TV' WHERE selling_price &gt;= cost * 2</pre>
<p>Use of limiting (through the <a href="http://php.net/manual/en/class.arrayaccess.php" target="_blank">ArrayAccess interface</a>) and order_by() methods is also available:</p>
<pre>$r = Product::get(array("make__exact" =&gt; "Sony"))-&gt;order_by("-model");
print $r-&gt;create_statement();
// output: SELECT id FROM products WHERE make = 'Sony' ORDER BY model DESC

$r = Product::get(array("make__exact" =&gt; "Sony"));
print $r["5:10"]-&gt;create_statement();
// output: SELECT id FROM products WHERE make = 'Sony' LIMIT 5 OFFSET 5

print $r[":10"]-&gt;create_statement();
// output: SELECT id FROM products WHERE make = 'Sony' LIMIT 10</pre>
<p>At the moment, as mentioned previously, this interface is only good for creating MySQL queries. But now that my base functionality exists, applying this to full iterable query sets and database objects should be easy in comparison.</p>
<p>I still have a lot of work to go to round this all together, but I&#8217;m quite happy with my progress so far with a couple days of on-and-off investment of time.</p>
<p>I&#8217;m more than happy to offer up my code so far, but before there is any severe judgment in the quality of it, I should point out that I made little to no reference to the core Django code (except for <a href="http://code.djangoproject.com/svn/django/trunk/django/db/models/query_utils.py" target="_blank">one small piece</a> that originally lead me to object overloading). If any readers show interest in my code, then I&#8217;ll do a small explanatory write-up of the classes and design patterns in another blog at a later date.</p>
<p><a href="http://andrewfreiday.com/source.php?f=django/Model.class.php" target="_blank">View/download the Model abstract class</a>.</p>
<p><a href="http://andrewfreiday.com/source.php?f=django/get_called_class.php" target="_blank">View/download my hacked up get_called_class function</a>.</p>
<p><a href="http://andrewfreiday.com/source.php?f=django/Query.class.php" target="_blank">View/download the Query class</a>.</p>
<p><a href="http://andrewfreiday.com/source.php?f=django/S.class.php" target="_blank">View/download the S class</a> (used for Q and F objects, shows operator overloading).</p>
<p><a href="http://andrewfreiday.com/source.php?f=django/examples.php" target="_blank">View/download the examples used in this blog entry</a>.</p>
<p>Of course, please let me know if any of this code piques any interest in you or if you use any of the code in your applications.</p>
<p><strong>Update &#8211; August 11, 2010</strong> &#8211; So I caved and took a good hard look at the <a href="http://www.djangoproject.com/download/">Django source</a>. It&#8217;s not nearly as complicated as I imagined and my suspicions about how the back-end works just from looking at the docs is pretty close. I&#8217;m now either considering a full line-for-line port of Django to PHP or continuing with what I currently have and making it my own.</p>
]]></content:encoded>
			<wfw:commentRss>http://andrewfreiday.com/2010/08/10/an-experiment-django-framework-like-queryingmodel-interface-in-php/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Google Charts-like Provincial Data Map For Canada</title>
		<link>http://andrewfreiday.com/2010/05/03/google-charts-like-provincial-data-map-for-canada/</link>
		<comments>http://andrewfreiday.com/2010/05/03/google-charts-like-provincial-data-map-for-canada/#comments</comments>
		<pubDate>Mon, 03 May 2010 14:51:55 +0000</pubDate>
		<dc:creator>Andrew</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[charts]]></category>
		<category><![CDATA[gd]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[maps]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://andrewfreiday.com/?p=49</guid>
		<description><![CDATA[This is PHP class I developed for work when I needed a Canada-specific map chart in some reporting tools I was creating. Obviously Google&#8217;s Map Charts API would&#8217;ve been my first choice, but it didn&#8217;t support Canada as it&#8217;s zoom level for reporting province-based data sets. This is where I sat down, thought about a [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_52" class="wp-caption alignright" style="width: 214px"><a href="http://andrewfreiday.com/wp-content/uploads/2010/05/canada.chart_.php_.png"><img class="size-medium wp-image-52 " style="margin: 10px;" title="canada.chart.php" src="http://andrewfreiday.com/wp-content/uploads/2010/05/canada.chart_.php_-300x290.png" alt="" width="204" height="197" /></a><p class="wp-caption-text">Map of Canada chart with province value colour coding.</p></div>
<p>This is PHP class I developed for work when I needed a Canada-specific map chart in some reporting tools I was creating. Obviously Google&#8217;s Map Charts API would&#8217;ve been my first choice, but it didn&#8217;t support Canada as it&#8217;s zoom level for reporting province-based data sets.</p>
<p>This is where I sat down, thought about a quick and dirty way to create this chart and went to work. I was able to create a chart as show on the right, with full control of output dimensions and colours.</p>
<p>Before I jump right into the full code, I want give a brief explanation of some of the techniques I used to accomplish this task.</p>
<p><span id="more-49"></span></p>
<div id="attachment_66" class="wp-caption alignleft" style="width: 231px"><a href="http://andrewfreiday.com/wp-content/uploads/2010/05/canada.png"><img class="size-full wp-image-66 " style="margin: 10px;" title="Canada" src="http://andrewfreiday.com/wp-content/uploads/2010/05/canada.png" alt="" width="221" height="214" /></a><p class="wp-caption-text">Map of Canada chart with each province uniquely coloured</p></div>
<p>The idea I had was to have a pre-coloured map of Canada such that each province has it&#8217;s own very distinct colour (as shown on left). From this starting point, I could replace each unique province colour with a degree of color based on a primary foreground color (e.g. red, #FF0000, as in the example above). To do this properly, I set up an array based on province short-forms (for data entry) and their unique colour on the base map:</p>
<pre>$provs = array(
  "AB" =&gt; "00DF6A",
  "BC" =&gt; "8AC707",
  "MB" =&gt; "3D5DFE",
  "NB" =&gt; "FF6BAA",
  "NL" =&gt; "C0FF00",
  "NT" =&gt; "FF8029",
  "NS" =&gt; "FFE26B",
  "NU" =&gt; "FFE328",
  "ON" =&gt; "D43CFF",
  "PE" =&gt; "6BFF7C",
  "QC" =&gt; "FF3DC0",
  "SK" =&gt; "01D7DF",
  "YT" =&gt; "FE293D"
);
</pre>
<p>and I was able to use <a href="http://www.php.happycodings.com/Graphics/code8.html" target="_blank">an excellent function that I found</a> which can take a HTML/hex color code and make it lighter by a percentage factor:</p>
<pre>function hexLighter($hex,$factor = 30) {
  $new_hex = '';

  $base['R'] = hexdec($hex{0}.$hex{1});
  $base['G'] = hexdec($hex{2}.$hex{3});
  $base['B'] = hexdec($hex{4}.$hex{5});

  foreach ($base as $k =&gt; $v)
      {
      $amount = 255 - $v;
      $amount = $amount / 100;
      $amount = round($amount * $factor);
      $new_decimal = $v + $amount;

      $new_hex_component = dechex($new_decimal);
      if(strlen($new_hex_component) &lt; 2)
          { $new_hex_component = "0".$new_hex_component; }
      $new_hex .= $new_hex_component;
      }

  return $new_hex;
}
</pre>
<p>From here, <a href="http://stackoverflow.com/questions/1548534/php-replace-colour-within-image" target="_blank">replacing one colour with another</a> is quite a simple task:</p>
<pre>function colorReplace($image, $oldcolor, $newcolor) {
  // find old color
  $oldcolor = $this-&gt;html2rgb($oldcolor);
  $old = imagecolorexact($image, $oldcolor['r'], $oldcolor['g'], $oldcolor['b']);
  // replace with new color
  $newcolor = $this-&gt;html2rgb($newcolor);
  imagecolorset($image, $old, $newcolor['r'], $newcolor['g'], $newcolor['b']);
}
</pre>
<p>&#8230;the rest is simply basic PHP image manipulation.</p>
<pre><a href="http://andrewfreiday.com/source.php?f=chart_canada/canada.chart.php" target="_blank">View/download the complete Canada Chart PHP class.</a>
<a href="http://andrewfreiday.com/code/chart_canada/canada.png" target="_blank">Click here to download the full-size coloured map of Canada required by the class.</a></pre>
<p>Now since I was already using Google&#8217;s Charts API, I wanted to make my own URL API to be relatively similar in fashion. So you could use this class like so, click to see result:</p>
<pre><a href="http://andrewfreiday.com/code/chart_canada/canada.chart.php?chld=ON,QC,AB,NL,BC,NB,MB,PE,NS,SK&amp;chd=1000,450,132,56,6,775,320,950,100,645&amp;chf=ff0000&amp;w=450&amp;h=450" target="_blank">canada.chart.php?chld=ON,QC,AB,NL,BC,NB,MB,PE,NS,SK&amp;chd=1000,450,132,56,6,775,320,950,100,645&amp;chf=ff0000&amp;w=450&amp;h=450</a></pre>
<p>This should make using this class in a project in which you&#8217;re already using Google Charts API fairly consistent.</p>
<p>I did add basic support for data labeling, but this wasn&#8217;t something I specifically needed so I didn&#8217;t pretty it up too much, but you can see an example here:</p>
<pre><a href="http://andrewfreiday.com/code/chart_canada/canada.chart.php?chld=ON,QC,AB,NL,BC,NB,MB,PE,NS,SK&amp;chd=1000,450,132,56,6,775,320,950,100,645&amp;chf=ff0000&amp;w=450&amp;h=450&amp;clb=1" target="_blank">canada.chart.php?chld=ON,QC,AB,NL,BC,NB,MB,PE,NS,SK&amp;chd=1000,450,132,56,6,775,320,950,100,645&amp;chf=ff0000&amp;w=450&amp;h=450&amp;<strong>clb=1</strong></a></pre>
<p>This requires a <a href="http://andrewfreiday.com/code/chart_canada/arial.gdf" target="_blank">GDF conversion of the Arial font</a> for use with <a href="http://php.net/manual/en/function.imageloadfont.php" target="_blank">PHP&#8217;s GD library</a>. Feel free to never use this functionality, take it out completely, or make it better.</p>
<p>If you successfully use this code, take it apart, or make it better &#8212; please let me know! I love to be constantly improving reusable classes like this, and it&#8217;s great to share good code with everyone.</p>
]]></content:encoded>
			<wfw:commentRss>http://andrewfreiday.com/2010/05/03/google-charts-like-provincial-data-map-for-canada/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Retrieving coordinates of two addresses using Google Maps and calculating distance</title>
		<link>http://andrewfreiday.com/2010/04/30/retrieving-coordinates-of-two-addresses-using-google-maps-and-calculating-distance/</link>
		<comments>http://andrewfreiday.com/2010/04/30/retrieving-coordinates-of-two-addresses-using-google-maps-and-calculating-distance/#comments</comments>
		<pubDate>Fri, 30 Apr 2010 17:31:51 +0000</pubDate>
		<dc:creator>Andrew</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[maps]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://andrewfreiday.com/?p=27</guid>
		<description><![CDATA[So here&#8217;s a quick couple snippets of code that will allow you to retrieve the coordinates of two locations using Google Maps API &#8212; no API key necessary. This first function will return the coordinates of specific address (I find pretty much anything works, whether it&#8217;s a full address with street number, or just a [...]]]></description>
			<content:encoded><![CDATA[<p>So here&#8217;s a quick couple snippets of code that will allow you to retrieve the coordinates of two locations using Google Maps API &#8212; no API key necessary.</p>
<p>This first function will return the coordinates of specific address (I find pretty much anything works, whether it&#8217;s a full address with street number, or just a postal code, or simply a city name) as an array of coordinates:</p>
<pre style="background: transparent;">
<div class="codesnip-container" >
<div class="php codesnip" style="font-family:monospace;"><span class="kw2">function</span> getCoordinates<span class="br0">&#40;</span><span class="re0">$address</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; <span class="re0">$url</span> <span class="sy0">=</span> <span class="st0">&quot;http://maps.google.com/maps/geo?q=&quot;</span> <span class="sy0">.</span> <a href="http://www.php.net/urlencode"><span class="kw3">urlencode</span></a><span class="br0">&#40;</span><span class="re0">$address</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="sy0">.</span> <span class="st0">&quot;&amp;amp;output=json&quot;</span><span class="sy0">;</span>
&nbsp; <span class="re0">$result</span> <span class="sy0">=</span> <a href="http://www.php.net/file_get_contents"><span class="kw3">file_get_contents</span></a><span class="br0">&#40;</span><span class="re0">$url</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp; <span class="re0">$result</span> <span class="sy0">=</span> <a href="http://www.php.net/json_decode"><span class="kw3">json_decode</span></a><span class="br0">&#40;</span><span class="re0">$result</span><span class="sy0">,</span> 1<span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><a href="http://www.php.net/isset"><span class="kw3">isset</span></a><span class="br0">&#40;</span><span class="re0">$result</span><span class="br0">&#91;</span><span class="st_h">'Placemark'</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; <a href="http://www.php.net/list"><span class="kw3">list</span></a><span class="br0">&#40;</span><span class="re0">$lat</span><span class="sy0">,</span> <span class="re0">$long</span><span class="br0">&#41;</span> <span class="sy0">=</span> <span class="re0">$result</span><span class="br0">&#91;</span><span class="st_h">'Placemark'</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st_h">'Point'</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st_h">'coordinates'</span><span class="br0">&#93;</span><span class="sy0">;</span>
&nbsp; <span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="re0">$lat</span> <span class="sy0">=</span> <span class="re0">$long</span> <span class="sy0">=</span> <span class="kw4">false</span><span class="sy0">;</span>
&nbsp; <span class="br0">&#125;</span>
&nbsp; <span class="kw1">return</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="re0">$lat</span><span class="sy0">,</span> <span class="re0">$long</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span></div>
</div>
</pre>
<p><span id="more-27"></span>and the following function will accept the lat/long coordinates of two separate points and return their distance (not road/traveling distance, but straight-shot distance) in KM:</p>
<pre style="background: transparent;">
<div class="codesnip-container" >
<div class="php codesnip" style="font-family:monospace;"><span class="kw2">function</span> calculateDistance<span class="br0">&#40;</span><span class="re0">$lat1</span><span class="sy0">,</span> <span class="re0">$long1</span><span class="sy0">,</span> <span class="re0">$lat2</span><span class="sy0">,</span> <span class="re0">$long2</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; <span class="re0">$R</span> <span class="sy0">=</span> <span class="nu0">6371</span><span class="sy0">;</span> <span class="co1">// earth's mean radius in km</span>
&nbsp; <span class="re0">$dLat</span> <span class="sy0">=</span> <a href="http://www.php.net/deg2rad"><span class="kw3">deg2rad</span></a><span class="br0">&#40;</span><span class="re0">$lat2</span><span class="sy0">-</span><span class="re0">$lat1</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp; <span class="re0">$dLon</span> <span class="sy0">=</span> <a href="http://www.php.net/deg2rad"><span class="kw3">deg2rad</span></a><span class="br0">&#40;</span><span class="re0">$long2</span><span class="sy0">-</span><span class="re0">$long1</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp; <span class="re0">$lat1</span> <span class="sy0">=</span> <a href="http://www.php.net/deg2rad"><span class="kw3">deg2rad</span></a><span class="br0">&#40;</span><span class="re0">$lat1</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp; <span class="re0">$lat2</span> <span class="sy0">=</span> <a href="http://www.php.net/deg2rad"><span class="kw3">deg2rad</span></a><span class="br0">&#40;</span><span class="re0">$lat2</span><span class="br0">&#41;</span><span class="sy0">;</span>

&nbsp; <span class="re0">$a</span> <span class="sy0">=</span> <a href="http://www.php.net/sin"><span class="kw3">sin</span></a><span class="br0">&#40;</span><span class="re0">$dLat</span><span class="sy0">/</span>2<span class="br0">&#41;</span> <span class="sy0">*</span> <a href="http://www.php.net/sin"><span class="kw3">sin</span></a><span class="br0">&#40;</span><span class="re0">$dLat</span><span class="sy0">/</span>2<span class="br0">&#41;</span> <span class="sy0">+</span>
&nbsp; &nbsp; &nbsp; <a href="http://www.php.net/cos"><span class="kw3">cos</span></a><span class="br0">&#40;</span><span class="re0">$lat1</span><span class="br0">&#41;</span> <span class="sy0">*</span> <a href="http://www.php.net/cos"><span class="kw3">cos</span></a><span class="br0">&#40;</span><span class="re0">$lat2</span><span class="br0">&#41;</span> <span class="sy0">*</span>
&nbsp; &nbsp; &nbsp; <a href="http://www.php.net/sin"><span class="kw3">sin</span></a><span class="br0">&#40;</span><span class="re0">$dLon</span><span class="sy0">/</span>2<span class="br0">&#41;</span> <span class="sy0">*</span> <a href="http://www.php.net/sin"><span class="kw3">sin</span></a><span class="br0">&#40;</span><span class="re0">$dLon</span><span class="sy0">/</span>2<span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp; <span class="re0">$c</span> <span class="sy0">=</span> 2 <span class="sy0">*</span> <a href="http://www.php.net/atan2"><span class="kw3">atan2</span></a><span class="br0">&#40;</span><a href="http://www.php.net/sqrt"><span class="kw3">sqrt</span></a><span class="br0">&#40;</span><span class="re0">$a</span><span class="br0">&#41;</span><span class="sy0">,</span> <a href="http://www.php.net/sqrt"><span class="kw3">sqrt</span></a><span class="br0">&#40;</span>1<span class="sy0">-</span><span class="re0">$a</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp; <span class="re0">$d</span> <span class="sy0">=</span> <span class="re0">$R</span> <span class="sy0">*</span> <span class="re0">$c</span><span class="sy0">;</span>

&nbsp; <span class="co1">// return distance in KM</span>
&nbsp; <span class="kw1">return</span> <span class="re0">$d</span><span class="sy0">;</span>
<span class="br0">&#125;</span></div>
</div>
</pre>
<p>Now it certainly may be worthwhile to cache coordinates for a given location, depending on your usage, because retrieving the coordinates from Google for a large quantity of addresses at once can take some time.</p>
]]></content:encoded>
			<wfw:commentRss>http://andrewfreiday.com/2010/04/30/retrieving-coordinates-of-two-addresses-using-google-maps-and-calculating-distance/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Generating MP3 waveforms with PHP</title>
		<link>http://andrewfreiday.com/2010/04/29/generating-mp3-waveforms-with-php/</link>
		<comments>http://andrewfreiday.com/2010/04/29/generating-mp3-waveforms-with-php/#comments</comments>
		<pubDate>Thu, 29 Apr 2010 14:49:16 +0000</pubDate>
		<dc:creator>Andrew</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[audio]]></category>
		<category><![CDATA[charts]]></category>
		<category><![CDATA[gd]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://andrewfreiday.com/?p=4</guid>
		<description><![CDATA[I don&#8217;t quite know what gave me the desire to ever generate audio (specifically MP3) waveforms with PHP &#8212; it&#8217;s not something I&#8217;ll likely ever use &#8212; but after doing some research and coming up a bit short I decided to make it happen. A few days of Googling, I did come up with a [...]]]></description>
			<content:encoded><![CDATA[<p>I don&#8217;t quite know what gave me the desire to ever generate audio (specifically MP3) waveforms with PHP &#8212; it&#8217;s not something I&#8217;ll likely ever use &#8212; but after doing some research and coming up a bit short I decided to make it happen.</p>
<div id="attachment_10" class="wp-caption alignright" style="width: 260px"><img class="size-full wp-image-10 " style="margin: 10px;" title="MP3 waveform" src="http://andrewfreiday.com/wp-content/uploads/2010/04/waveform.png" alt="" width="250" height="100" /><p class="wp-caption-text">Waveform generated using Dancing With Paris&#39; &quot;(Boardwalk)&quot; MP3.</p></div>
<p>A few days of Googling, I did come up with a couple solutions but none seemed to really produce the results I wanted. All I was looking to generate was a simple waveform like that in Cubase or other recording software. I don&#8217;t need axis labels or left/right audio splits, just a simple mono waveform from an MP3. I also didn&#8217;t want to go through hundreds of audio files and convert them into WAV files just to do this &#8212; if I was going to do this as an experiment, I wanted it on the fly. I did come across some interesting links though:</p>
<p><span id="more-4"></span></p>
<p>The <a href="http://sox.sourceforge.net/" target="_blank">Sound eXchange</a> (SoX) audio tool kit has a lot of great features that might come in handy later on, including audio effects, but support for MP3 wasn&#8217;t built-in and seemed a bit too much work to bother<a href="http://www.codeproject.com/KB/aspnet/Compiling_SOX_with_Lame.aspx" target="_blank"> compiling</a> just for a side experiment. SoX can generate spectrograms, but this wasn&#8217;t particularly what I was looking for.</p>
<p>I did find this <a href="http://phpclasses.cfappsinc.ca/browse/file/1582.html" target="_blank">classAudioFile.php</a>, which does support generating waveforms from WAV files, but this seemed a bit more hefty than I really needed &#8212; and not as accomplishing as doing it myself. That being said, and though I never bothered testing it out, it does seem (based on the code) to create a simple waveform image that I was aiming to create.</p>
<p>Ultimately, I wanted something flexible: upload MP3s files without pre-converting them, adjust size of the image easily, and change foreground and background colours. The key that makes my script different, and most flexible, is converting the files to WAV on the fly. Though this is time consuming, it&#8217;s ultimately a lot easier than batch processing them on my computer first.</p>
<pre><a href="http://andrewfreiday.com/source.php?f=waveform/waveform.php" target="_blank"><strong>Click here to see the source code for the script.</strong></a></pre>
<p>The key to making this convenient has been using the <a href="http://lame.sourceforge.net/index.php" target="_blank">LAME MP3 encoder/decoder</a> through the command line (on Windows for my script, I haven&#8217;t yet tested with any flavour of Linux). I simply downloaded a windows build of LAME, threw the executable into my script directory and ran the following command:</p>
<pre>lame original_file.mp3 -f -m m -b 16 --resample 8 resampled.mp3 &amp;&amp; lame --decode resampled.mp3 final_file_for_processing.wav</pre>
<p>Because you don&#8217;t really need a high quality audio file for generating a waveform, this set of commands will resample the original MP3 to a 16 bit, 8 KHz, mono MP3 file and then turn that into a WAV file for processing the image from. Processing does take some time, but it&#8217;s significantly faster than processing a huge 40+ MB WAV file from the start. Also, no amount of research showed a way to directly downsample an MP3 straight to a WAV file, hence the intermediary step.</p>
<p>After that, I used an <a href="http://forums.devshed.com/php-development-5/reading-16-bit-wav-file-318740.html?" target="_blank">algorithm I found on the DevShed forums</a> for processing 16 bit WAV files, and used the data it generates to create the waveform (which, ultimately, is pretty simple).</p>
<p>If this is something you have a use for, feel free to use it as you wish and give credit where it&#8217;s due (see the source comments for where I pulled some code snippets from to make this work). You may want to fix it up a bit for better error checking and so forth though.</p>
<p>A note of warning: it&#8217;s not fast. Far from it. A couple basic tests showed anywhere between 10-30+ seconds to generate the waveforms for an average sized MP3 (decent quality, 2-4 minutes in length). If you will be generating and re-generating waveforms multiple times for the same audio file, you may want to cache the WAV data in a database for future use, as using that data to create the image itself is comparatively quite quick.</p>
<p>I may use this, along with the SoX library, later on to create &#8212; simply for fun and discovery &#8212; an online audio mixer/editor similar to Cubase, which I&#8217;ve been working with quite a lot lately. This would be a great way to create a new web-based interface with a lot of widgets and controls not commonly used, as well as using SoX to add audio effects, mix, combine files, in a multi-layered audio interface. I&#8217;ll see if I ever get around to this however.</p>
<p>Environment tested in, your results may vary:</p>
<ul>
<li>Windows Server 2003</li>
<li>PHP 5.2.10</li>
<li>LAME 3.98.4</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://andrewfreiday.com/2010/04/29/generating-mp3-waveforms-with-php/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
