<?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>Andrew Kirkpatrick</title>
	<atom:link href="http://www.andrew-kirkpatrick.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.andrew-kirkpatrick.com</link>
	<description></description>
	<lastBuildDate>Fri, 27 Jan 2012 22:29:51 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>&#8220;concrete5 cannot parse the PATH_INFO or ORIG_PATH_INFO information provided by your server.&#8221;</title>
		<link>http://www.andrew-kirkpatrick.com/2012/01/concrete5-cannot-parse-the-path_info-or-orig_path_info-information-provided-by-your-server/</link>
		<comments>http://www.andrew-kirkpatrick.com/2012/01/concrete5-cannot-parse-the-path_info-or-orig_path_info-information-provided-by-your-server/#comments</comments>
		<pubDate>Fri, 27 Jan 2012 22:29:51 +0000</pubDate>
		<dc:creator>Andrew Kirkpatrick</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.andrew-kirkpatrick.com/?p=538</guid>
		<description><![CDATA[Thought I&#8217;d take a look into concrete5 to see what is was like, and it&#8217;s the first open source PHP project installer I&#8217;ve come across in ages that complained about [...]]]></description>
			<content:encoded><![CDATA[<p>Thought I&#8217;d take a look into concrete5 to see what is was like, and it&#8217;s the first open source PHP project installer I&#8217;ve come across in ages that complained about anything other than filesystem permissions. PATH_INFO? Most other projects use different mechanisms/variables to do a similar job I assume&#8230;</p>
<p>Anyways, go to the concrete5 install directory and create a .htaccess file there with the following contents:</p>
<pre class="brush: bash; gutter: true">php_flag display_errors off
AcceptPathInfo On</pre>
<p>If you don&#8217;t suppress PHP errors it won&#8217;t work, which I read may be related to an Ajax callback failing because the response is full of errors (the installer isn&#8217;t written properly? I&#8217;ve no idea&#8230;)</p>
<p>I&#8217;ve also heard that some hosting providers (like GoDaddy) don&#8217;t play well with .htaccess files, which unfortunately if that&#8217;s the case you&#8217;ll have to get in touch with them!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.andrew-kirkpatrick.com/2012/01/concrete5-cannot-parse-the-path_info-or-orig_path_info-information-provided-by-your-server/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Enable hibernation on HP MicroServer for Windows Home Server v1</title>
		<link>http://www.andrew-kirkpatrick.com/2012/01/enable-hibernation-on-hp-microserver-for-windows-home-server-v1/</link>
		<comments>http://www.andrew-kirkpatrick.com/2012/01/enable-hibernation-on-hp-microserver-for-windows-home-server-v1/#comments</comments>
		<pubDate>Sun, 01 Jan 2012 19:15:11 +0000</pubDate>
		<dc:creator>Andrew Kirkpatrick</dc:creator>
				<category><![CDATA[hibernation]]></category>
		<category><![CDATA[home]]></category>
		<category><![CDATA[hp]]></category>
		<category><![CDATA[lights out]]></category>
		<category><![CDATA[microserver]]></category>
		<category><![CDATA[server]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://www.andrew-kirkpatrick.com/?p=525</guid>
		<description><![CDATA[Since I got my HP ProLiant MicroServer setup with Windows Home Server v1 (instead of 2011) I haven&#8217;t been able to suspend or hibernate it. Whilst I thought this would [...]]]></description>
			<content:encoded><![CDATA[<p>Since I got my HP ProLiant MicroServer setup with Windows Home Server v1 (instead of 2011) I haven&#8217;t been able to suspend or hibernate it. Whilst I thought this would be a straightforward fix it turns out it can be a bit tricky. Whilst you can enable hibernation <strong>it is not possible to enable suspend</strong> as the hardware itself does not support it.</p>
<p>To go into hibernation, open the command prompt and use the following command:</p>
<pre class="brush: powershell; gutter: true">powercfg -h on</pre>
<pre class="brush: powershell; gutter: true">powercfg /hibernate on</pre>
<p>To <a href="http://forum.wegotserved.com/index.php/topic/18119-cannot-suspend-or-hibernate-on-proliant-microserver-vail/">check what sleep states are available</a> on your system you can use the following command:</p>
<pre class="brush: powershell; gutter: true">powercfg -a</pre>
<p>If this doesn&#8217;t work and gives you an error message it might be for one (or more) of the following reasons&#8230;</p>
<h2>Standard VGA Graphics Adapter</h2>
<p>If you haven&#8217;t installed the VGA graphics adapter for the Mobility Radeon HD 4200 then this will prevent the computer from going into hibernation. Whilst the rest of the drivers aren&#8217;t that hard to get from HP, installing the VGA driver it seems you may have to do manually. Luckily I found some <a href="http://forums.overclockers.com.au/showpost.php?p=13183786&amp;postcount=150">instructions on the OCAU Forum</a></p>
<p>If you go to the AMD website and get the Radeon Mobility drivers for the 785E chipset, if you extract the contents (installing it normally didn&#8217;t work for me) then use the Update Driver option in the Device Manager and use the following path:</p>
<pre class="brush: powershell; gutter: true">\Drivers\Display\XP_INF\</pre>
<h2>PAE mode</h2>
<p>In the case that 32-bit processes would like to use more than 4GB of system memory, <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa366796(v=vs.85).aspx">Physical Address Extension</a> allows it to do just that (as far as I&#8217;m aware, I&#8217;m a Mac/Linux user most of the time now) but having it enabled prevents WHS from hibernating. However, displaying PAE on it&#8217;s own won&#8217;t work, as having DEP enabled will enable it anyway (so setting <a href="http://msdn.microsoft.com/en-us/library/ff557146.aspx">/nopae</a> in boot.ini won&#8217;t do anything) so you will need to disable both.</p>
<p><a href="http://support.microsoft.com/kb/289022">Editing boot.ini to change the boot options</a> is the same as in Windows XP it seems. Here&#8217;s an extract from the Microsoft knowledge base:</p>
<ol>
<li>Right-click <strong>My Computer</strong>, and then click <strong>Properties</strong>. -or-<br />
Click <strong>Start</strong>, click <strong>Run</strong>, type <strong>sysdm.cpl</strong>, and then click <strong>OK</strong>.</li>
<li>On the <strong>Advanced</strong> tab, click <strong>Settings</strong> under <strong>Startup and Recovery</strong>.</li>
<li>Under <strong>System Startup</strong>, click <strong>Edit</strong>.</li>
</ol>
<p>Then delete <a href="http://msdn.microsoft.com/en-us/library/ff557134.aspx">/noexecute=optout</a> and replace it with /execute then reboot the server. <a href="http://msdn.microsoft.com/en-us/library/ff542275.aspx">More information about PAE and DEP</a> can be found from Microsoft.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.andrew-kirkpatrick.com/2012/01/enable-hibernation-on-hp-microserver-for-windows-home-server-v1/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>VirtualBox Guest Additions with Shared Folders on Mac OS X</title>
		<link>http://www.andrew-kirkpatrick.com/2011/12/virtualbox-guest-additions-with-shared-folders-on-mac-os-x/</link>
		<comments>http://www.andrew-kirkpatrick.com/2011/12/virtualbox-guest-additions-with-shared-folders-on-mac-os-x/#comments</comments>
		<pubDate>Mon, 05 Dec 2011 11:24:37 +0000</pubDate>
		<dc:creator>Andrew Kirkpatrick</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[Virtualization]]></category>

		<guid isPermaLink="false">http://www.andrew-kirkpatrick.com/?p=499</guid>
		<description><![CDATA[In order to access certain aspects of a virtual machine in VirtualBox, you will need to install Guest Additions (similar to VMWare Tools I guess) There is a manual page [...]]]></description>
			<content:encoded><![CDATA[<p>In order to access certain aspects of a virtual machine in VirtualBox, you will need to install Guest Additions (similar to VMWare Tools I guess)</p>
<p>There is a <a href="http://www.virtualbox.org/manual/ch04.html">manual page for installing Guest Additions</a> but not all of it is self-explanatory&#8230;</p>
<h3>Install DKMS</h3>
<p>This part is relatively straightforward.</p>
<pre class="brush: bash; gutter: true">sudo apt-get update
sudo apt-get upgrade
sudo apt-get install dkms</pre>
<h3>Where to find VBoxGuestAdditions.iso</h3>
<p>Usefully Oracle don&#8217;t tell you in their guide, but it is available with the rest of the downloads at <a href="http://download.virtualbox.org/virtualbox/">http://download.virtualbox.org/virtualbox/</a></p>
<p>So for example for version 4.1.6 the VBoxGuestAdditions_4.1.6.iso is located at <a href="http://download.virtualbox.org/virtualbox/4.1.6/VBoxGuestAdditions_4.1.6.iso">http://download.virtualbox.org/virtualbox/4.1.6/VBoxGuestAdditions_4.1.6.iso</a></p>
<h4>How to mount the image</h4>
<p>Since I can&#8217;t remember the last time I had to mount something in *nix from the command-line, here&#8217;s a quick way.</p>
<pre class="brush: bash; gutter: true">sudo mkdir /dev/dvd
sudo mount /dev/dvd1 /mnt/dvd/
cd /mnt/dvd</pre>
<p>Then you should see VBoxLinuxAdditions, which you need to run as per the manual. If the above doesn&#8217;t work it might be because your DVD drive in VirtualBox is called something else, like dvd (instead of dvd1) which probably differs depending on which distro you&#8217;re using.</p>
<p>Then you need to run the installer.</p>
<pre class="brush: bash; gutter: true">sudo sh ./VBoxLinuxAdditions.run</pre>
<p>Once that&#8217;s done you can restart.</p>
<pre class="brush: bash; gutter: true">sudo reboot now</pre>
<h4>Kernel header problems</h4>
<p>I got some missing kernel header problems when trying to install Guest Additions, which if building the main Guest Additions module fails will be logged.</p>
<pre class="brush: bash; gutter: true">cat /var/log/vboxadd-install.log</pre>
<p>If you see something like this&#8230;</p>
<pre class="brush: bash; gutter: true">Error! Your kernel headers for kernel 2.6.35-28-generic cannot be found at
/lib/modules/2.6.35-28-generic/build or 
/lib/modules/2.6.35-28-generic/source.</pre>
<pre class="brush: bash; gutter: true">You can use the --kernelsourcedir option to tell DKMS where it's located,
or you could install the linux-headers-2.6.35-28-generic package.</pre>
<p>So you can do just that!</p>
<pre class="brush: bash; gutter: true">sudo apt-get install linux-headers-2.6.35-28-generic
sudo ./VBoxLinuxAdditions.run</pre>
<p>Hopefully this should install now (although the XFree86 bit will fail, assuming you&#8217;re using the command-line) and you may need to restart the VM, although I&#8217;m not sure.</p>
<h3>Mount the host folder</h3>
<p>You can create the host folder in the VirtualBox Manager in the Shared Folders tab on the Settings for that VM. If you add it on the command-line it&#8217;ll appear under the machine folders anyways. If you want to type it though, here&#8217;s what you&#8217;d type into the Mac OS X terminal (note this is the only thing that you&#8217;d type into the host itself)</p>
<pre class="brush: bash; gutter: true">VBoxManage sharedfolder add "my-ubuntu-vm" \
--name "websites" --hostpath "/Users/andrew/pizza"</pre>
<p>To mount the Shared Folder from within the guest, the <a href="https://help.ubuntu.com/community/VirtualBox/SharedFolders">instructions from Ubuntu</a> (as my guest is Ubuntu, although I think this is a better way to mount it anyways) were very useful.</p>
<pre class="brush: bash; gutter: true">sharename="whatever.you.want.to.call.it";
sudo mkdir /mnt/$sharename \
sudo chmod 777 /mnt/$sharename \
sudo mount -t vboxsf -o uid=1000,gid=1000 $sharename /mnt/$sharename \
ln -s /mnt/$sharename $HOME/Desktop/$sharename</pre>
<p>Just change the target to be wherever you want the Shared Folder to be mounted in the guest. Now in theory if you go to that path in the guest, it should be the same as the directory you shared from the host!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.andrew-kirkpatrick.com/2011/12/virtualbox-guest-additions-with-shared-folders-on-mac-os-x/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Using PHP late static binding to define static arrays as subsets for child classes</title>
		<link>http://www.andrew-kirkpatrick.com/2011/12/using-php-late-static-binding-to-define-static-arrays-as-subsets-for-child-classes/</link>
		<comments>http://www.andrew-kirkpatrick.com/2011/12/using-php-late-static-binding-to-define-static-arrays-as-subsets-for-child-classes/#comments</comments>
		<pubDate>Fri, 02 Dec 2011 23:01:26 +0000</pubDate>
		<dc:creator>Andrew Kirkpatrick</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.andrew-kirkpatrick.com/?p=504</guid>
		<description><![CDATA[OK, the title might sound a little confusing, but the concept it relatively simple. Basically it&#8217;s using an array in a child class that contains some of the items that [...]]]></description>
			<content:encoded><![CDATA[<p>OK, the title might sound a little confusing, but the concept it relatively simple. Basically it&#8217;s using an array in a child class that contains some of the items that appear in the array in the parent class.</p>
<p>Which just means you have a list of all of the things in the parent, and a list of some of those things in every child. Like a list of options such as colours, types, etc.</p>
<p>Imagine that you have a class that represents all the cars you sell:</p>
<pre class="brush: php; gutter: true">class Cars</pre>
<p>To make sure that an enumerated database field matches up when you pick the colour of the car, you use class constants; this is so that when you set you use the same constant, as opposed to typing it in each time (which reduces error, and means you can change it in one place only)</p>
<pre class="brush: php; gutter: true">class Car
{
const COLOUR_GREEN = 'green';
const COLOUR_RED = 'red';
const COLOUR_YELLOW = 'yellow';
const COLOUR_BLUE = 'blue';</pre>
<p>If you want to find out what colours the cars are available in, you could use an array. Because you can&#8217;t declare constant arrays (because they aren&#8217;t scalar) you could use a variable; using a static variable will allow you to use it in static methods.</p>
<pre class="brush: php; gutter: true">class Car
{

const COLOUR_GREEN = 'green';
const COLOUR_RED = 'red';
const COLOUR_YELLOW = 'yellow';
const COLOUR_BLUE = 'blue';

static array $colours = array(
COLOUR_GREEN,
COLOUR_RED,
COLOUR_YELLOW,
COLOUR_BLUE,
);

}</pre>
<p>Then, if you want to make child classes of the cars class, to represent each type of car, you don&#8217;t need to redine the constants; all the types of cars can be those colours. However, each type of car might not be available in every colour; the colours are the same but which colours are available are different.</p>
<p>For example if you had trucks that were available in green, red and yellow, and vans that were available in red and blue.</p>
<pre class="brush: php; gutter: true">class Truck extends Car
{

static array $colours = array(
COLOUR_GREEN,
COLOUR_RED,
COLOUR_YELLOW,
);

}

class Van extends Car
{

static array $colours = array(
COLOUR_RED,
COLOUR_BLUE,
);

}</pre>
<p>This might look all well and dandy, but the problem comes when you check what is in self::$colours in a static method of the child class. Despite the values being different in the child class, it will still contain the values in the class where it was originally declared.</p>
<p>Therefore, if you ran the following method:</p>
<pre class="brush: php; gutter: true">static method colours()
{

print_r(self::$colours);

}</pre>
<p>You would get the following result in all 3 classes, even if you declared self::colours() in every class.</p>
<pre class="brush: bash; gutter: true">Array
(
    [0] =&gt; green
    [1] =&gt; red
    [2] =&gt; yellow
    [3] =&gt; blue
)</pre>
<p>To make sure that PHP gets the values from the most recently declared (in the class hierarchy) version of that array, is to use the static keyword.</p>
<pre class="brush: php; gutter: true">static method colours()
{

print_r(static::$colours);

}</pre>
<p>Using the static keyword, you would only need to write the static colours() in the parent class, as it will still use the static variable in the child class if it is called from the child class, even if the method is declared in the parent class. Calling Car::colours() will tell you all of the colours that are available, Truck::colours() will tell you what colours trucks come in, and likewise with Van::colours()</p>
<p>Note that you do need PHP 5.3 to make this work.</p>
<p>p.s. I wouldn&#8217;t actually put colour constants in a car class! It was just the first example that I could think of that wasn&#8217;t what I actually used it for at work&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.andrew-kirkpatrick.com/2011/12/using-php-late-static-binding-to-define-static-arrays-as-subsets-for-child-classes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL socket missing at /tmp/mysql.sock with Zend Server CE on Mac OS X</title>
		<link>http://www.andrew-kirkpatrick.com/2011/12/mysql-socket-missing-at-tmpmysql-sock-with-zend-server-ce-on-mac-os-x/</link>
		<comments>http://www.andrew-kirkpatrick.com/2011/12/mysql-socket-missing-at-tmpmysql-sock-with-zend-server-ce-on-mac-os-x/#comments</comments>
		<pubDate>Thu, 01 Dec 2011 22:31:26 +0000</pubDate>
		<dc:creator>Andrew Kirkpatrick</dc:creator>
		
		<guid isPermaLink="false">http://www.andrew-kirkpatrick.com/?p=496</guid>
		<description><![CDATA[Just a quick post, for something that seems to happen for no particular reason. If (like me) you don&#8217;t fancy changing where MySQL places the unix socket, simply create a [...]]]></description>
			<content:encoded><![CDATA[<p>Just a quick post, for something that seems to happen for no particular reason. If (like me) you don&#8217;t fancy changing where MySQL places the unix socket, simply create a symbolic link from where it puts it by default in Zend Server CE.</p>
<pre class="brush: bash; gutter: true">sudo ln -s /usr/local/zend/mysql/tmp/mysql.sock /tmp/mysql.sock</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.andrew-kirkpatrick.com/2011/12/mysql-socket-missing-at-tmpmysql-sock-with-zend-server-ce-on-mac-os-x/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zend Server lighttp not running (phpMyAdmin) but Apache is? How to start it manually</title>
		<link>http://www.andrew-kirkpatrick.com/2011/11/zend-server-lighttp-not-running-phpmyadmin-but-apache-is-how-to-start-it-manually/</link>
		<comments>http://www.andrew-kirkpatrick.com/2011/11/zend-server-lighttp-not-running-phpmyadmin-but-apache-is-how-to-start-it-manually/#comments</comments>
		<pubDate>Wed, 30 Nov 2011 11:04:56 +0000</pubDate>
		<dc:creator>Andrew Kirkpatrick</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[Zend Server]]></category>

		<guid isPermaLink="false">http://www.andrew-kirkpatrick.com/?p=491</guid>
		<description><![CDATA[If for some reason you&#8217;ve powered on and while Apache seems to be running OK, lighttp isn&#8217;t (for example phpMyAdmin isn&#8217;t working on localhost:10081/phpmyadmin) then you will need to start [...]]]></description>
			<content:encoded><![CDATA[<p>If for some reason you&#8217;ve powered on and while Apache seems to be running OK, lighttp isn&#8217;t (for example phpMyAdmin isn&#8217;t working on localhost:10081/phpmyadmin) then you will need to start it manually. This is probably caused by a dirty restart, such as a power failure. On Mac OS X run this command&#8230;</p>
<pre class="brush: bash; gutter: true">sudo /usr/local/zend/bin/lighttpdctl.sh start</pre>
<p>For Windows, I&#8217;m afraid I will have to find that out!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.andrew-kirkpatrick.com/2011/11/zend-server-lighttp-not-running-phpmyadmin-but-apache-is-how-to-start-it-manually/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zend Framework 1.8+ Module/Library Autoloading</title>
		<link>http://www.andrew-kirkpatrick.com/2011/11/zend-framework-1-8-modulelibrary-autoloading/</link>
		<comments>http://www.andrew-kirkpatrick.com/2011/11/zend-framework-1-8-modulelibrary-autoloading/#comments</comments>
		<pubDate>Tue, 08 Nov 2011 22:40:46 +0000</pubDate>
		<dc:creator>Andrew Kirkpatrick</dc:creator>
				<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://www.andrew-kirkpatrick.com/?p=482</guid>
		<description><![CDATA[Given the problems I had for the 1st Zend Framework website I did, I figured the next time I started one from scratch I would document how to get the [...]]]></description>
			<content:encoded><![CDATA[<p>Given the problems I had for the 1st Zend Framework website I did, I figured the next time I started one from scratch I would document how to get the autoloading working, since almost nowhere has it documented correctly. I forgot then too, so 3rd time lucky&#8230;</p>
<p>The following code assumes the following:</p>
<ul>
<li>You have no model, controller or view directories at the root of application/ because they should all be within application/modules/modulename/</li>
<li>The default module is located at application/modules/default/</li>
<li>The default module is not namespaced, so the index controller is called IndexController, not Default_IndexController</li>
</ul>
<div>You can change all of the above in application.ini and/or Bootstrap.php if so desired.</div>
<p>The key things you need to add, excluding the directory structure that will be created for you by Zend Tool is the following entry in application.ini in application/configs/</p>
<pre class="brush: actionscript3; gutter: true">resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"</pre>
<p>Then put the following code in the Application (not any of the Modules) Bootstrap.php in application/</p>
<pre class="brush: php; gutter: true">protected function _initAutoloader()
{

	$moduleAutoloader =
		new Zend_Application_Module_Autoloader(array(
			'namespace' =&gt; '',
			'basePath' =&gt; APPLICATION_PATH.'/modules/default'
		));

}</pre>
<p>Why? No idea, as according to Zend you can do it all from setting the Module Resource in application.ini, although I have never gotten that to work with a variety of different configuration options&#8230;</p>
<p>If you need to register a namespace for the library you can add this to Bootstrap.php also</p>
<pre class="brush: php; gutter: true">$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader-&gt;registerNamespace('MyNamespace_');</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.andrew-kirkpatrick.com/2011/11/zend-framework-1-8-modulelibrary-autoloading/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Testing and timing RDS/MySQL scheduled downtime with PHP</title>
		<link>http://www.andrew-kirkpatrick.com/2011/10/testing-and-timing-rdsmysql-scheduled-downtime-with-php/</link>
		<comments>http://www.andrew-kirkpatrick.com/2011/10/testing-and-timing-rdsmysql-scheduled-downtime-with-php/#comments</comments>
		<pubDate>Fri, 21 Oct 2011 13:41:16 +0000</pubDate>
		<dc:creator>Andrew Kirkpatrick</dc:creator>
				<category><![CDATA[Amazon Web Services]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.andrew-kirkpatrick.com/?p=469</guid>
		<description><![CDATA[Something I was asked at work recently was &#8220;if we do this to the server, how long will it be unavailable for?&#8221; and usually the answer would be easy&#8230; however [...]]]></description>
			<content:encoded><![CDATA[<p>Something I was asked at work recently was &#8220;if we do this to the server, how long will it be unavailable for?&#8221; and usually the answer would be easy&#8230; however in certain circumstances you may not know. One of these is Amazon RDS, whereby you don&#8217;t really know what happens when you reboot or change the configuration of an instance, it just sort-of happens and eventually becomes available again.</p>
<p>For Amazon RDS an example would be when you modify the DB Instance Class of your main instance, which will cause the server to be &#8220;modified&#8221; which will cause some downtime; of course a reboot will cause downtime also.</p>
<p>Therefore I needed to time how long the website would go down for, at what point connections to the database would fail, or running a query would fail, etc.</p>
<p>I wrote a PHP CLI script to record how long it will take (in seconds) for the database to recover for any given operation that will cause downtime. Start the script, and it will keep outputting &#8216;+&#8217; to the command line. Start the operation, and eventually the &#8216;+&#8217; will turn into &#8216;-&#8217;, and once they turn into &#8216;+&#8217; again it means the downtime is over and the database(s) will be available again, and it will tell you how long it took.</p>
<p>The output will look something like this&#8230;</p>
<pre class="brush: bash; gutter: true">user@server:~$ php test_upgrade.php
Starting...
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + - - - - - - - - - - - - - - - -
- +

Database down for 262 seconds</pre>
<p>The script is as follows&#8230;</p>
<pre class="brush: php; gutter: true">&lt;?php

error_reporting(0);

$host = 'myhost.us-east-1.rds.amazonaws.com';
$port = 3306;
$database = 'mydb';
$username = 'user';
$password = 'supersecretpassword';

$sql = "SELECT count(*) FROM users";

echo "Starting...\n";

$disconnectTime = 0;
$reconnectTime = 0;
$reconnected = null;

while ($reconnected !== true) {

	$link = mysql_connect($host.':'.$port, $username, $password);
	if (! $link) {
		flagConnection(false);
		$reconnected = false;
		continue;
	}

	$db_selected = mysql_select_db($database, $link);
	if (! $db_selected) {
    	flagConnection(false);
		$reconnected = false;
		continue;
	}

	$result = mysql_query($sql);
	if (! $result) {
		flagConnection(false);
		$reconnected = false;
		continue;
	}
	$row = mysql_fetch_row($result);
	if (! $row) {
		flagConnection(false);
		$reconnected = false;
		continue;
	}

	// If everything works, flag as connected
	flagConnection(true);

	// If was previously disconnected, exit the loop
	if ($reconnected === false) {
		$reconnected = true;
	}

	mysql_close($link);

}

$outageTime = $reconnectedTime - $disconnectedTime;

echo "\n\nDatabase down for $outageTime seconds\n";

function flagConnection($flag)
{
	global $disconnectedTime;
	global $reconnectedTime;
	global $reconnected;

	echo ($flag ? '+' : '-').' ';
	$log[] = $flag;

	if ($flag == false &amp;&amp; is_null($reconnected)) {
		$disconnectedTime = time();
	}

	if ($flag == true &amp;&amp; $reconnected === false) {
		$reconnectedTime = time();
	}

	sleep(1);

}

?&gt;</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.andrew-kirkpatrick.com/2011/10/testing-and-timing-rdsmysql-scheduled-downtime-with-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Google Geocoding API with PHP</title>
		<link>http://www.andrew-kirkpatrick.com/2011/10/google-geocoding-api-with-php/</link>
		<comments>http://www.andrew-kirkpatrick.com/2011/10/google-geocoding-api-with-php/#comments</comments>
		<pubDate>Thu, 13 Oct 2011 14:58:11 +0000</pubDate>
		<dc:creator>Andrew Kirkpatrick</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.andrew-kirkpatrick.com/?p=464</guid>
		<description><![CDATA[If you want to know where a particular address is by latitude and longitude, but only have the normal address details like street, city, zip, country, etc. then the Google [...]]]></description>
			<content:encoded><![CDATA[<p>If you want to know where a particular address is by latitude and longitude, but only have the normal address details like street, city, zip, country, etc. then the Google Geocoding API should be able to help. By passing it an address string it will try to work out (just like Google Maps) whereabouts the address is, and return you a JSON or XML response with what it managed to figure out.</p>
<p>Below is a basic PHP example using cURL (based on an <a href="http://stackoverflow.com/questions/5525561/using-php-curl-to-pull-data-from-json-google-maps-api">example from Stack Overflow by Jack W</a>)</p>
<pre class="brush: php; gutter: true">&lt;pre&gt;
&lt;?php

function lookup($string){

   $string = str_replace (" ", "+", urlencode($string));
   $details_url = "http://maps.googleapis.com/maps/api/geocode/json?address=".$string."&amp;sensor=false";

   $ch = curl_init();
   curl_setopt($ch, CURLOPT_URL, $details_url);
   curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
   $response = json_decode(curl_exec($ch), true);

   // If Status Code is ZERO_RESULTS, OVER_QUERY_LIMIT, REQUEST_DENIED or INVALID_REQUEST
   if ($response['status'] != 'OK') {
   	return null;
   }

   print_r($response);
   $geometry = $response['results'][0]['geometry'];

	$longitude = $geometry['location']['lng'];
	$latitude = $geometry['location']['lat'];

	$array = array(
		'latitude' =&gt; $geometry['location']['lng'],
		'longitude' =&gt; $geometry['location']['lat'],
		'location_type' =&gt; $geometry['location_type'],
	);

	return $array;

}

$city = 'San Francisco, USA';

$array = lookup($city);
print_r($array);

?&gt;
&lt;/pre&gt;</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.andrew-kirkpatrick.com/2011/10/google-geocoding-api-with-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Samba share path incorrect even though it&#8217;s mounted in the Finder</title>
		<link>http://www.andrew-kirkpatrick.com/2011/10/samba-share-path-incorrect-even-though-its-mounted-in-the-finder/</link>
		<comments>http://www.andrew-kirkpatrick.com/2011/10/samba-share-path-incorrect-even-though-its-mounted-in-the-finder/#comments</comments>
		<pubDate>Wed, 05 Oct 2011 08:56:01 +0000</pubDate>
		<dc:creator>Andrew Kirkpatrick</dc:creator>
				<category><![CDATA[Mac]]></category>

		<guid isPermaLink="false">http://www.andrew-kirkpatrick.com/?p=457</guid>
		<description><![CDATA[Sometimes if a Samba share (Windows share or a Samba share from Unix) does not disconnect cleanly in Mac OS X, you may end up with a broken symlink in [...]]]></description>
			<content:encoded><![CDATA[<p>Sometimes if a Samba share (Windows share or a Samba share from Unix) does not disconnect cleanly in Mac OS X, you may end up with a broken symlink in /Volumes/</p>
<p>This means that even if you re-mount the same share, and it will be named the same in the Finder, the actual symlink path won&#8217;t be the same. For example if you&#8217;re using a Workspace in Eclipse that points to that share, you won&#8217;t be able to use it because /Volumes/ will look like this:</p>
<pre class="brush: bash; gutter: true">Andrew:Volumes andrew$ pwd
/Volumes
Andrew:Volumes andrew$ ls
Macintosh HD    share    share-1</pre>
<p>The old symlink will still be there, and it will create another one with a number appended. If this does happen, disconnect the Samba share from the Finder, then delete the remaining share from /Volumes/ and then re-mount it in the Finder.</p>
<p>The share should then mount with the correct path!</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.andrew-kirkpatrick.com/2011/10/samba-share-path-incorrect-even-though-its-mounted-in-the-finder/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

