<?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>@ fake&#039;s &#187; learning</title>
	<atom:link href="http://plind.dk/category/learning/feed/" rel="self" type="application/rss+xml" />
	<link>http://plind.dk</link>
	<description>customized rants from a PHP dev&#039;s viewpoint</description>
	<lastBuildDate>Wed, 11 Aug 2010 12:52:33 +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>Dependency injection and Zend Framework</title>
		<link>http://plind.dk/2010/08/11/dependency-injection-and-zend-framework/</link>
		<comments>http://plind.dk/2010/08/11/dependency-injection-and-zend-framework/#comments</comments>
		<pubDate>Wed, 11 Aug 2010 12:52:33 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[learning]]></category>
		<category><![CDATA[Dependency Injection]]></category>
		<category><![CDATA[DI]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[ZF]]></category>

		<guid isPermaLink="false">http://plind.dk/?p=419</guid>
		<description><![CDATA[Lately I&#8217;ve been working on a site based on the Zend Framework. It&#8217;s been a good chance to get more intimate with ZF, learning the inner workings and quirks of the framework. Today I came across the question of how to do dependency injection for your controllers &#8211; I was looking for a way to [...]]]></description>
			<content:encoded><![CDATA[<p>Lately I&#8217;ve been working on a site based on the Zend Framework. It&#8217;s been a good chance to get more intimate with ZF, learning the inner workings and quirks of the framework. Today I came across the question of how to do dependency injection for your controllers &#8211; I was looking for a way to rid the code of the &#8216;new&#8217; keyword as well as static methods, coupling things more loosely.</p>
<p>Controllers aren&#8217;t meant to override the __construct() method in ZF &#8211; sure you can do it, but there are meant to be better ways. That leads to the question: how? Well, if you do have a look at the __construct() method of Zend_Controller_Action, you&#8217;ll notice that it takes three parameters. The last one is the interesting one here: it&#8217;s an array called invokeArgs. This should immediately set you off testing what gets passed in &#8211; a bunch of goodies, it turns out. Among other things, you&#8217;ll be getting a copy of the Bootstrap object.</p>
<h2>ZF Controller Dependency Injection, #1</h2>
<p>The above leads to the first, not too good way of injecting things. Just stick whatever you want injected into the bootstrap object &#8211; your controller has access to that through the invokeArgs parameter. That&#8217;s not a very good solution though, as you&#8217;ll be breaking <a href="http://en.wikipedia.org/wiki/Law_of_Demeter">the Law of Demeter</a>: your controller needs to know that your injected param sits inside the bootstrap element, so you&#8217;ll be accessing the injected elemented indirectly. Not nice.</p>
<h2>ZF Controller Dependency Injection, #2</h2>
<p>I googled a bit and came across <a href="http://www.ibuildings.co.uk/blog/archives/1181-Dependency-Injection-and-Zend-Framework-Controllers.html">Dependency Injection and Zend Framework Controllers</a>, which has a nice solution to the problem. As the param name suggests, invokeArgs can be modified &#8211; you can add to the args to your heart&#8217;s content. You need to use the setParam() method of Zend_Controller_Front &#8211; so, in the bootstrap object for instance, you can do the following:</p>
<pre>$front = Zend_Controller_Front::getInstance();
$front-&gt;setParam('factory', new MyFactory);</pre>
<p>Your object will then get passed to the controller in the invokeArgs array. You can access this either through $this-&gt;_invokeArgs['factory'] or the getInvokeArg() method of Zend_Controller_Action &#8211; the latter being preferable.</p>
]]></content:encoded>
			<wfw:commentRss>http://plind.dk/2010/08/11/dependency-injection-and-zend-framework/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Sorting algorithms: Heap sort</title>
		<link>http://plind.dk/2010/05/23/sorting-algorithms-heap-sort/</link>
		<comments>http://plind.dk/2010/05/23/sorting-algorithms-heap-sort/#comments</comments>
		<pubDate>Sun, 23 May 2010 16:09:30 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[learning]]></category>
		<category><![CDATA[algorithms]]></category>
		<category><![CDATA[heapsort]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[sorting algorithms]]></category>

		<guid isPermaLink="false">http://plind.dk/?p=161</guid>
		<description><![CDATA[It&#8217;s been a while since I did the last post (merge sort) in my sorting algorithms in PHP series (new readers start with Sorting algorithms: bubblesort) so I thought it about time that I add the next part. This time I&#8217;m going for heap sort. This algorithm has some similarities with merge sort, mainly the [...]]]></description>
			<content:encoded><![CDATA[<div class='series_toc'><h3>Series: Sorting Algorithms</h3><ol><li><a href='http://plind.dk/2009/11/06/sorting-algorithms-bubblesort/' title='Sorting algorithms: bubblesort'>Sorting algorithms: bubblesort</a></li><li><a href='http://plind.dk/2009/11/07/sorting-algorithms-quick-update/' title='Sorting algorithms: quick update'>Sorting algorithms: quick update</a></li><li><a href='http://plind.dk/2009/11/16/sorting-algorithms-insertion-sort/' title='Sorting algorithms: Insertion Sort'>Sorting algorithms: Insertion Sort</a></li><li><a href='http://plind.dk/2009/11/30/sorting-algorithms-shell-sort/' title='Sorting algorithms: Shell sort'>Sorting algorithms: Shell sort</a></li><li><a href='http://plind.dk/2010/01/07/sorting-algorithms-selection-sort/' title='Sorting algorithms: Selection sort'>Sorting algorithms: Selection sort</a></li><li><a href='http://plind.dk/2010/01/10/sorting-algorithms-merge-sort/' title='Sorting algorithms: Merge sort'>Sorting algorithms: Merge sort</a></li><li>Sorting algorithms: Heap sort</li></ol></div> <p>It&#8217;s been a while since I did the last post (<a href="http://plind.dk/2010/01/10/sorting-algorithms-merge-sort/">merge sort</a>) in my sorting algorithms in PHP series (new readers start with <a href="http://plind.dk/2009/11/06/sorting-algorithms-bubblesort/">Sorting algorithms: bubblesort</a>) so I thought it about time that I add the next part. This time I&#8217;m going for <a href="http://en.wikipedia.org/wiki/Heapsort">heap sort</a>. This algorithm has some similarities with merge sort, mainly the recursive nature, the divide and conquer idea: heap sort treats an array like a tree of elements instead of just one big pool of elements. Other than that, like some of the other sort algorithms presented it can be sorted in place, leading to less memory use &#8211; however it is not a stable sort, as the elements can quite easily change order.</p>
<p>In details, heap sort works by imposing a hierarchical tree structure on the set of elements and that the structure satisfies the heap requirement: that any given node be of equal to or less value than it&#8217;s parent. This is actually only a requirement for one type of heaps, the max-heaps &#8211; the other type, min-heaps, work in the opposite way, namely by having a parent node be always equal to or less than a child node. The reason this is significant is that you will always know which element is the largest: it&#8217;s the root node (in a max-heap, still). Hence, if we have a heap in proper order, we can then take the root node out of the heap and put it at the end of the array to sort. After bringing the heap in order again, we can repeat this, popping off the next largest element and putting it at the second to last position in the array.</p>
<p>Laying it out in steps, it looks like:</p>
<ol>
<li>heapify array</li>
<li>pop root element off and store at end of array</li>
<li>heapify remaining heap</li>
<li>repeat step 2-3 while constantly moving one step back when storing popped element</li>
</ol>
<p>And that&#8217;s it! Well, it obviously gets a bit harder once you get into the details &#8211; and without those, no sorting :) As with merge sort, it&#8217;s the recursive function that&#8217;s most important to the algorithm: the heapify thing. This is where the time will be spent so this is where it&#8217;s most important that things are optimized and that the algorithm works out.</p>
<p>So how does the heapify function work? It&#8217;s rather simple: it compares a node with it&#8217;s two leaves and if one of the is (or both are) larger than the root a swap is made &#8211; the largest leaf takes the place of the root node and vice versa. Because of the hierarchical structure of the heap, every node can have at most two leaves. If a swap is made, the heapify function recursively calls itself with the index of the swapped out leaf (the previous root, now a leaf) because this may now be a new root node in another local heap which then has to be checked. If on the other hand a swap is not made the heapify function simply returns: the heap is in order.</p>
<p>In terms of sorting, this means that you first heapify the array once and then of course once per element you pop off the array. As the algorithm swaps out the root node (the one to be popped off the heap) with the last leaf in the array the heapify function then has to be called to get the heap back into shape. Because the last element of the heap is smaller than any of it&#8217;s ancestors, the heapify function will recursively call itself a maximum of log<sub>2</sub>(n)-1 times. As the heap grows smaller, the number of recursions drops but this obviously happens on a log<sub>2</sub> scale as well so this is not a major factor in the speed &#8211; the biggest speed factor lies in a combination of the fact that sorting a heap when a new root is introduced, given that the heap has previously been heapified, only takes log<sub>2</sub>(n) moves and that the first heapification of an array is quite fast too.</p>
<p>Enough talk, now code.</p>
<h2>The Code</h2>
<pre>&lt;?php
class HeapSort extends BaseSort
{
    public function sortFunction()
    {
        $array = $this-&gt;store;
        $heap_length = count($array);
        $this-&gt;buildHeap($array, $heap_length);
        while ($heap_length)
        {
            $temp = $array[0];
            $array[0] = $array[$heap_length - 1];
            $array[$heap_length - 1] = $temp;
            $heap_length--;
            $this-&gt;heapify($array, 1, $heap_length);
        }
        $this-&gt;store = $array;
    }
    private function buildHeap(&amp;$array, $heap_length)
    {
        for ($i = floor($heap_length / 2); $i &gt; 0; $i--)
        {
            $this-&gt;heapify($array, $i, $heap_length);
        }
    }
    private function heapify(&amp;$array, $index, $heap_length)
    {
        $largest = $index;
        $comp = $array[$largest-1];
        $r = $index &lt;&lt; 1;
        $l = $r++;
        if (($l &lt;= $heap_length) &amp;&amp; ($array[$l-1] &gt; $comp))
        {
            $largest = $l;
            $comp = $array[$l-1];
        }
        if (($r &lt;= $heap_length) &amp;&amp; ($array[$r-1] &gt; $comp))
        {
            $largest = $r;
            $comp = $array[$r-1];
        }
        if ($largest != $index)
        {
            $temp = $array[$index-1];
            $array[$index-1] = $comp;
            $array[$largest-1] = $temp;
            $this-&gt;heapify($array, $largest, $heap_length);
        }
    }
}</pre>
<p>Quick walkthrough: first, the heap is built (or rather, the array is treated like a heap that&#8217;s out of order) after which the main loop is entered. Here, with each iteration, the root node is popped of the array (shifted, in PHP terms) and the heap is heapified again. The main action takes part in the heapify() method: it&#8217;s called with the heap, the index of the node to heapify and the length of the heap. The method checks the indexed node against it&#8217;s leaves and if any of them are larger than it a swap is made and the method is called recursively.</p>
<p>I&#8217;ve experimented a bit with optimizing the code and the version above is the fastest I&#8217;ve got it to. The biggest payoffs came from passing the array by reference instead of using a property of the class as well as passing the array length into functions &#8211; I hadn&#8217;t expected either to be a speed improvement but going that way shaved off 5 (five) seconds of the running time when sorting 100,000 elements. Which, I guess, leads me to the results.</p>
<h2>Results</h2>
<pre>1000 elements to sort.
Sanity check. PHP native sort() algorithm took: 0.000878 seconds. Memory used: 64360 bytes
Running Heapsort sort. Algorithm took: 0.089941 seconds. Memory used: 64360 bytes</pre>
<p>At 1,000 elements the algorithm it&#8217;s running in about 1.25 times the time of the merge sort implementation I made.</p>
<pre>10000 elements to sort.
Sanity check. PHP native sort() algorithm took: 0.012138 seconds. Memory used: 665804 bytes
Running Heapsort sort. Algorithm took: 1.208370 seconds. Memory used: 665800 bytes</pre>
<p>At 10,000 elements it&#8217;s running in 1.5 times the merge sort &#8211; pretty good but not quite the same.</p>
<pre>100000 elements to sort.
Sanity check. PHP native sort() algorithm took: 0.222491 seconds. Memory used: 6524576 bytes
Running Heapsort sort. Algorithm took: 14.997653 seconds. Memory used: 6524560 bytes</pre>
<p>With 100,000 elements the pattern is fairly clear in terms of how the algorithm is doing &#8211; a bit less than a straight O(n log n). Final test is 1,000,000 elements.</p>
<pre>1000000 elements to sort.
Sanity check. PHP native sort() algorithm took: 3.602368 seconds. Memory used: 64194572 bytes
Running Heapsort sort. Algorithm took: 188.843620 seconds. Memory used: 64194576 bytes</pre>
<p>Increasing the number of elements to sort by an order of magnitude increases the run time by 12.5 &#8211; which is pretty good (compare to the internal PHP algorithm which increases by a factor 15).</p>
 <div class='series_links'><a href='http://plind.dk/2010/01/10/sorting-algorithms-merge-sort/' title='Sorting algorithms: Merge sort'>Previous in series</a> </div>]]></content:encoded>
			<wfw:commentRss>http://plind.dk/2010/05/23/sorting-algorithms-heap-sort/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>.htaccess voodoo</title>
		<link>http://plind.dk/2010/04/08/htaccess-voodoo/</link>
		<comments>http://plind.dk/2010/04/08/htaccess-voodoo/#comments</comments>
		<pubDate>Thu, 08 Apr 2010 23:16:06 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[learning]]></category>
		<category><![CDATA[.htaccess]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[URL rewriting]]></category>

		<guid isPermaLink="false">http://plind.dk/?p=353</guid>
		<description><![CDATA[Every once in a while I have to do some .htaccess rewriting and every time I end up deeply fascinated at the possibilities that it offers. This time round the situation was as follows: for a client we had done some advanced search functionality, which uses fairly detailed URLs to store the search (the search [...]]]></description>
			<content:encoded><![CDATA[<p>Every once in a while I have to do some <a title="Wikipedia on .htaccess" href="http://en.wikipedia.org/wiki/.htaccess">.htaccess</a> rewriting and every time I end up deeply fascinated at the possibilities that it offers. This time round the situation was as follows: for a client we had done some advanced search functionality, which uses fairly detailed URLs to store the search (the search is parsed into an abstract syntax tree, then serialized to a URL). The problem now was that we had rewritten the serialized syntax &#8230; and somehow a famous search engine had picked up on the URLs and was getting bad results from them. What to do?</p>
<p>The solution was URL rewriting using .htaccess. However, it wasn&#8217;t straight forward URL rewriting &#8211; the serialized search was encoded in the query string, and that was the only part that needed a rewrite. How does the Apache Rewrite module handle this? Very well, it turns out.</p>
<h2>Solution &#8211; part 1</h2>
<p>The first thing to realise is that <a title="RewriteRule specs" href="http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html#RewriteRule">RewriteRules</a> by themselves won&#8217;t do any good &#8211; they only work on the base part of the URL, ignoring the query string. This means you have to turn to the second part of the rewrite: the <a title="RewriteCond specs" href="http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html#RewriteCond">RewriteCond</a>. Now, this presented the first part of my eye-opening experience: RewriteCond allows for using regexes. This means you can do the following:</p>
<pre>RewriteCond %{QUERY_STRING} ^id=([0-9]+)
</pre>
<p>And you&#8217;ll match on query strings that start with id = some number of digits. You can use pretty much any extended regular expression you desire &#8230; which makes it very powerful!</p>
<h2>Solution &#8211; part 2</h2>
<p>As you can probably guess from the above code bit, you can also use capturing groups in the RewriteCond regexes. Not only that, though: you can reference these captured groups in a RewriteRule. It&#8217;s done slightly different from capture reference in RewriteRule regexes (these are done using $) in that a reference to a captured group from a RewriteCond uses a % as prefix. Hence, you can do:</p>
<pre>RewriteCond %{QUERY_STRING} ^id=([0-9]+)
RewriteRule ^product.php /product/%1? [R=301,L]
</pre>
<p>And you&#8217;ll be redirecting product.php?id=123 to product/123 using a 301. Notice the ? at the end of the rewritten URL &#8211; it&#8217;s there to make sure ModRewrite doesn&#8217;t append the original query string.</p>
<p>At this point, my woes were almost over &#8211; there was just one obstacle left.</p>
<h2>Solution &#8211; part 3</h2>
<p>When the Rewrite module does redirects, it normally also escapes characters in the URL, that could otherwise turn out problematic. One such character is %. However, this escaping is itself very problematic upon redirects, because any url_encode()d URL will contain lots of % characters followed by a character code. When ModRewrite is done with the URL, it&#8217;ll have substituted all %2F with %252F, for instance &#8230; not what you want.</p>
<p>There&#8217;s a very simple solution to this, though: you can set a flag to stop the Rewrite module from doing any escaping. What you do is:</p>
<pre>RewriteCond %{QUERY_STRING} ^id=([0-9]+)
RewriteRule ^product.php /product/%1? [R=301,L,NE]
</pre>
<p>This stops ModRewrite from escaping the URL, leaving you with whatever was in the original.</p>
<p>Using the above bits and pieces you can rewrite a URL like</p>
<pre>/search?blah=hum%20dinger%20and%what%20not%3Aliteral
</pre>
<p>to</p>
<pre>/search?q=hum%20dinger%20and%what%20not%3Aliteral&amp;rewritten=true
</pre>
<p>It&#8217;s voodoo for sure, but damned cool.</p>
]]></content:encoded>
			<wfw:commentRss>http://plind.dk/2010/04/08/htaccess-voodoo/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Ubuntu and swap partitions</title>
		<link>http://plind.dk/2010/03/04/ubuntu-and-swap-partitions/</link>
		<comments>http://plind.dk/2010/03/04/ubuntu-and-swap-partitions/#comments</comments>
		<pubDate>Thu, 04 Mar 2010 10:30:23 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[learning]]></category>
		<category><![CDATA[fstab]]></category>
		<category><![CDATA[panic]]></category>
		<category><![CDATA[swap partition]]></category>

		<guid isPermaLink="false">http://plind.dk/?p=334</guid>
		<description><![CDATA[This is a note to self and any others that may find themselves in a similar situation. Should you happen to one day start your computer, wait for your linux distro to boot up and then see the following message swap: waiting for UUID=xxxxxxxx-xxxx-xxxx without anything else happening, then don&#8217;t panic! At least not yet. [...]]]></description>
			<content:encoded><![CDATA[<p>This is a note to self and any others that may find themselves in a similar situation. Should you happen to one day start your computer, wait for your linux distro to boot up and then see the following message</p>
<pre>swap: waiting for UUID=xxxxxxxx-xxxx-xxxx</pre>
<p>without anything else happening, then don&#8217;t panic! At least not yet. Before you start pulling hair out of your head, try the following:</p>
<ul>
<li>boot into recovery mode, using grub, a live-cd or the excellent <a href="http://www.sysresccd.org/Main_Page">system rescue cd</a></li>
<li>check which UUIDs your disks <strong>actually</strong> use (and by now, you should have an idea of where this is going)
<ul>
<li>easiest is: ls /dev/disk/by-uuid/ &#8211; however, if you have many disks then the output will be unwieldy</li>
<li>easy as well: sudo blkid &#8211; this will list all disks with extra info</li>
</ul>
</li>
<li>mount your linux boot partition, then check the fstab file on it
<ul>
<li>if you mounted it on /mnt/disk then do vim /mnt/disk/etc/fstab or nano /mnt/disk/etc/fstab</li>
</ul>
</li>
<li>check the partition that&#8217;s marked as swap &#8211; compare the UUID it&#8217;s loading by against the list obtained above</li>
<li>if the UUID matches, go ahead, panic. If the UUID in the fstab file <strong>doesn&#8217;t match</strong> then change the fstab file (either to load the partition by /dev/sda-something or the proper UUID) and then try rebooting.</li>
</ul>
<p>As I didn&#8217;t have access to the above list when this happened, I panicked (after the third or fourth reboot with the same result). Luckily I had access to another computer and could google for solutions &#8211; and came across this in a forum which I figured needed to be spread some more.</p>
<p>Why did the UUID of the swap partition suddenly change? I have no idea. Perhaps it wasn&#8217;t even the UUID changing, it was something else in the system that suddenly started caring about the mismatch (that&#8217;s rather farfetched, but so is the whole situation). My best bet is that it was down to a bootup to Windows and some work there &#8211; perhaps trusty old WinXP decided to play nasty and change stuff at random. No matter what, though &#8230; the relief when I finally got the thing working was massive (among other things, I have some webdev work to hand in soon).</p>
]]></content:encoded>
			<wfw:commentRss>http://plind.dk/2010/03/04/ubuntu-and-swap-partitions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Back from holidays</title>
		<link>http://plind.dk/2010/02/26/back-from-holidays/</link>
		<comments>http://plind.dk/2010/02/26/back-from-holidays/#comments</comments>
		<pubDate>Fri, 26 Feb 2010 16:41:22 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Random]]></category>
		<category><![CDATA[learning]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[gitosis]]></category>
		<category><![CDATA[server]]></category>
		<category><![CDATA[site migration]]></category>

		<guid isPermaLink="false">http://plind.dk/?p=323</guid>
		<description><![CDATA[After great holidays on the Canarian Islands I&#8217;m now back in front of the trusty computer. The trip was super, resulting in some much needed extra energy and motivation for &#8230; well, lots of things, really :) The first bigger thing I&#8217;ve done after coming back is moving plphp.dk from a server I have at [...]]]></description>
			<content:encoded><![CDATA[<p>After great holidays on the Canarian Islands I&#8217;m now back in front of the trusty computer. The trip was super, resulting in some much needed extra energy and motivation for &#8230; well, lots of things, really :) The first bigger thing I&#8217;ve done after coming back is moving <a href="http://plphp.dk/">plphp.dk</a> from a server I have at home to my VPS. The reason is rather simple, really: the connection here is simply not stable enough for me to have my company site running over it (it&#8217;s a combination of crappy router plus wrong linux install, I think).</p>
<p>Before moving stuff I thought it might take a bit of effort getting things working without problems but it turned out I had no reason to worry. A combination of git and gitosis made the basic transfer easy and the rest was handled with a database dump + import and a new virtualhost for Apache. Replicating the install looked like this:</p>
<h2>Step 1 &#8211; setup local repo</h2>
<p>Make sure the site you&#8217;re moving is in a git working repo. Skip this if you&#8217;re in a working git repo, otherwise just do something like</p>
<pre>git init
git add --all
git commit -am "setting up git repo for myproject"</pre>
<p>Your repo is now ready to move &#8211; need a place to move it to, though.</p>
<h2>Step 2 &#8211; add group to gitosis</h2>
<p>If you&#8217;ve not already setup gitosis on your server (local or remote) <a title="Hosting Git repositories, The Easy (and Secure) Way" href="http://scie.nti.st/2007/11/14/hosting-git-repositories-the-easy-and-secure-way">have a read on the scie.nti.st blog</a>. When gitosis is running, you need to modify your gitosis.conf to add a new group for the site you want to move (unless you&#8217;ve got one group for everything, which I wouldn&#8217;t recommend though). In your gitosis.conf, add</p>
<pre>[group mygroup]
writable = myprojectname
members = user1 user2 user3@host</pre>
<p>Save and move on.</p>
<h2>Step 3 &#8211; add remote repo to your local working directory</h2>
<p>If like me your gitosis daemon is running on a remote server, you need to do something like</p>
<pre>git remote add remote_repo_name ssh://git@host/myproject.git</pre>
<p>If gitosis is running locally, you can do away with the ssh protocol bit</p>
<h2>Step 4 &#8211; push</h2>
<p>Time to do the actual copy. Do</p>
<pre>git push remote_repo_name master</pre>
<p>Your repo is now copied to gitosis.</p>
<h2>Step 5 &#8211; clone</h2>
<p>Check out a working copy by cloning the site to where you need it &#8211; i.e. do</p>
<pre>cd /var/www
git clone /path/to/gitosis/repos mysite</pre>
<p>If your new site is on the same server as the gitosis server, that is. Otherwise, use the ssh protocol for the path.</p>
<h2>Step 6 &#8211; dump database</h2>
<p>PL PHP is running on MySQL &#8211; hence, dumping the database and copying it across to the new site can be done by</p>
<pre>mysqldump -u user -p database &gt; dump.sql &amp;&amp; scp dump.sql user@host:~/</pre>
<h2>Step 7 &#8211; setup proper user</h2>
<p>Setup a user with access to the database using the same details as on the current site &#8211; a create &#8216;user&#8217;@'localhost&#8217; will probably suffice.</p>
<h2>Step 8 &#8211; import database</h2>
<p>Create the database, then import using your sql</p>
<pre>mysql&gt; create database mydb default charset utf8;</pre>
<p>and</p>
<pre>bash:~/$ mysql -u user -p -D mydb &lt; dump.sql</pre>
<p>And done</p>
<h2>Step 9 &#8211; create new virtualhost</h2>
<p>Get Apache to serve up the site by creating a new virtualhost file. Then check your Apache config with apache2ctl configtest &#8211; if it&#8217;s working fine, then restart apache.</p>
<h2>Step 10 &#8211; change DNS records</h2>
<p>Last thing is to switch DNS records so your domain points to the new IP.</p>
<h2></h2>
<p>That&#8217;s it &#8211; 10 steps and PL PHP was migrated to a different server with the added benefit of having a repo copy added to my gitosis daemon. If you skip the gitosis bit then you can truncate step 1-5 &#8211; just clone the repo straight away.</p>
<p>On the other hand, if your site is bigger than PL PHP, you probably want to add some extra steps, such as having your current site proxy the new site, so that no traffic will hit the current site (and thus the current database). An alternative to this would be to setup the new site to use the current database and only migrate the database when you&#8217;re sure DNS records have been changed (i.e. when you no longer see hits on the old IP).</p>
<p>With this out of my mind, I can focus on other interesting stuff, such as <a href="http://plind.dk/2010/02/05/typo3-book-review/">the Typo3 book review I&#8217;ll be doing</a> (expect that in a little over a week) and an interesting project focusing on the craft community which I&#8217;m doing with my fiancee :)</p>
]]></content:encoded>
			<wfw:commentRss>http://plind.dk/2010/02/26/back-from-holidays/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
