<?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>Hello, I am Sean Murphy &#187; php</title>
	<atom:link href="http://iamseanmurphy.com/tag/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://iamseanmurphy.com</link>
	<description>Thoughts, news, code by Sean Murphy</description>
	<lastBuildDate>Thu, 26 Jan 2012 02:37: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>A Better HAProxy Health Check For Dynamic Websites</title>
		<link>http://iamseanmurphy.com/2009/04/22/a-better-haproxy-health-check-for-dynamic-websites/</link>
		<comments>http://iamseanmurphy.com/2009/04/22/a-better-haproxy-health-check-for-dynamic-websites/#comments</comments>
		<pubDate>Wed, 22 Apr 2009 16:14:50 +0000</pubDate>
		<dc:creator>Sean Murphy</dc:creator>
				<category><![CDATA[Scalability]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[fastcgi]]></category>
		<category><![CDATA[fcgi]]></category>
		<category><![CDATA[haproxy]]></category>
		<category><![CDATA[high availablity]]></category>
		<category><![CDATA[load balancing]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[web server]]></category>

		<guid isPermaLink="false">http://iamseanmurphy.com/2009/04/22/a-better-haproxy-health-check-for-dynamic-websites/</guid>
		<description><![CDATA[Nobody wants their website to go down, or worse, for users to notice the site is down. Because of this most larger websites will run on multiple servers to provide some level of high availability. In a multi-server architecture there is typically a load balancer (or cluster of load balancers) to distribute the load among [...]]]></description>
			<content:encoded><![CDATA[<p>Nobody wants their website to go down, or worse, for users to <em>notice</em> the site is down. Because of this most larger websites will run on multiple servers to provide some level of high availability. In a multi-server architecture there is typically a load balancer (or cluster of load balancers) to distribute the load among a pool of web servers. When a server goes down it&#8217;s taken out of the pool until it is once again ready to handle requests. HAProxy (a software load balancer) has the ability to perform this task by doing periodic health checks on all the servers in a cluster. The default settings, though, could give false positives in some cases, and thus create a bad user experience by allowing ill application servers to continue receiving requests.</p>
<p><span id="more-33"></span><br />
When in HTTP mode HAProxy&#8217;s default health check is a simple OPTIONS request. This has the advantage of being a very lightweight request, and is easy to identify and filter from server logs. Consider this scenario though: HAProxy balances the load between several web servers running nginx and PHP-FastCGI. If nginx is up but PHP-FastCGI goes down, nginx will still properly handle the OPTIONS request from HAProxy, giving the impression that all is well. HAProxy continues sending requests to the ill server which in turn get a 504 Gateway Timeout (or similar) response. Not a very good situation.</p>
<p>A solution would be to use a deeper health check, one that goes beyond nginx to the PHP-FastCGI process. That way if PHP-FastCGI goes down, the whole server is presumed &#8216;down&#8217;.</p>
<pre>
backend appservers

 mode http

 option httpchk HEAD /health_check.php HTTP/1.1\r\nHost:\ example.com

 server web1 x.x.x.x:80 weight 5 check inter 2000

 server web2 x.x.x.x:80 weight 5 check inter 2000

 server web3 x.x.x.x:80 weight 5 check inter 2000</pre>
<p>In the above example I&#8217;m using a custom health check request which will be processed by PHP-FastCGI. health_check.php is a lightweight script that contains simply <code>&lt;?php echo "I'm healthy"; ?&gt;</code>. I also added a host header so that the health check will be handled by a specific nginx virtual host. The nginx vhost config has this in it:</p>
<pre>
location = /health_check.php {

 access_log		off;

 fastcgi_pass	127.0.0.1:9000;

 fastcgi_index	index.php;

 include	/etc/nginx/fastcgi_params;

}</pre>
<p>And there you have it&#8211;a better HAProxy health check for dynamic websites.</p>
]]></content:encoded>
			<wfw:commentRss>http://iamseanmurphy.com/2009/04/22/a-better-haproxy-health-check-for-dynamic-websites/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>.htaccess File Causes 500 Internal Server Error on Network Solutions</title>
		<link>http://iamseanmurphy.com/2009/02/21/htaccess-file-causes-500-internal-server-error-on-network-solutions/</link>
		<comments>http://iamseanmurphy.com/2009/02/21/htaccess-file-causes-500-internal-server-error-on-network-solutions/#comments</comments>
		<pubDate>Sat, 21 Feb 2009 20:16:19 +0000</pubDate>
		<dc:creator>Sean Murphy</dc:creator>
				<category><![CDATA[Work]]></category>
		<category><![CDATA[500]]></category>
		<category><![CDATA[cgi]]></category>
		<category><![CDATA[htaccess]]></category>
		<category><![CDATA[mod_php]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://iamseanmurphy.com/2009/02/21/htaccess-file-causes-500-internal-server-error-on-network-solutions/</guid>
		<description><![CDATA[How&#8217;s that for a search engine friendly title, eh? This is just a quick note for anyone who has to deal with Network Solutions hosting (for clients or otherwise). Apperantly Network Solutions doesn&#8217;t run PHP with Apache&#8217;s mod_php, but rather as a CGI application. That means if you try to put PHP configuration directives in [...]]]></description>
			<content:encoded><![CDATA[<p>How&#8217;s that for a search engine friendly title, eh?</p>
<p>This is just a quick note for anyone who has to deal with Network Solutions hosting (for clients or otherwise). Apperantly Network Solutions doesn&#8217;t run PHP with Apache&#8217;s mod_php, but rather as a CGI application. That means if you try to put PHP configuration directives in a .htaccess file it will cause a 500 Internal Server Error. My helpful reference: <a href="http://www.nerdliness.com/article/2008/07/29/because-network-solutions-sucks#comment-4925">Because Network Solutions Sucks</a>.</p>
<p>You have been warned.</p>
]]></content:encoded>
			<wfw:commentRss>http://iamseanmurphy.com/2009/02/21/htaccess-file-causes-500-internal-server-error-on-network-solutions/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Auto-Linking URLs with PHP</title>
		<link>http://iamseanmurphy.com/2008/12/01/auto-linking-urls-with-php/</link>
		<comments>http://iamseanmurphy.com/2008/12/01/auto-linking-urls-with-php/#comments</comments>
		<pubDate>Mon, 01 Dec 2008 23:54:30 +0000</pubDate>
		<dc:creator>Sean Murphy</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[auto-linking]]></category>
		<category><![CDATA[laconica]]></category>
		<category><![CDATA[links]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[regex]]></category>
		<category><![CDATA[urls]]></category>

		<guid isPermaLink="false">http://iamseanmurphy.com/2008/12/01/auto-linking-urls-with-php/</guid>
		<description><![CDATA[A week or so ago I was working on a bug in the auto-linking code for Laconica, the software that powers Indenti.ca. Squashing that particular bug wasn&#8217;t too hard, but I wanted to take the functionality a step further (closer to the calibre of Gmail) and it turns out, writing robust auto-linking code is more [...]]]></description>
			<content:encoded><![CDATA[<p>A week or so ago I was working on a bug in the auto-linking code for <a href="http://laconi.ca">Laconica</a>, the software that powers <a href="http://identi.ca">Indenti.ca</a>. Squashing that particular bug wasn&#8217;t too hard, but I wanted to take the functionality a step further (closer to the calibre of Gmail) and it turns out, writing robust auto-linking code is more difficult than it initially seems. So I played with it a little at a time here and there, testing as many edge cases as I could think of. The result is a function that&#8217;s more robust than most URL auto-linking code I&#8217;ve come across.</p>
<p>I still need to add support of internationalized TLDs and HTML. So, although it only works with plain text for now, I think it&#8217;s off to a good start. Check out the <a href="http://iamseanmurphy.com/autolinking/demo.php">demo</a> or <a href="http://iamseanmurphy.com/autolinking/demo.php?download">download the source</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://iamseanmurphy.com/2008/12/01/auto-linking-urls-with-php/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>MySQL SELECT Entries Before NOW()</title>
		<link>http://iamseanmurphy.com/2008/02/19/mysql-select-entries-before-now/</link>
		<comments>http://iamseanmurphy.com/2008/02/19/mysql-select-entries-before-now/#comments</comments>
		<pubDate>Tue, 19 Feb 2008 22:57:22 +0000</pubDate>
		<dc:creator>Sean Murphy</dc:creator>
				<category><![CDATA[Databases]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[now]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[query cache]]></category>
		<category><![CDATA[rounded time]]></category>

		<guid isPermaLink="false">http://iamseanmurphy.com/2008/02/19/mysql-select-entries-before-now/</guid>
		<description><![CDATA[I’m in the business of making things faster. Using NOW() in a SQL query is something I’m going to complain about. Here’s a familiar scenario from the online publishing industry where future dating articles is a commonality: You have a news site. You need to display only articles that have been published, and one of [...]]]></description>
			<content:encoded><![CDATA[<p>I’m in the business of making things faster. Using NOW() in a SQL query is something I’m going to complain about. Here’s a familiar scenario from the online publishing industry where future dating articles is a commonality:</p>
<p>You have a news site. You need to display only articles that have been published, and one of the criteria is that they need to have a publish_date before now. Easy, peasy, lemon squeezy.</p>
<p><span id="more-3"></span>
<pre name="code" class="sql">SELECT author, title, body FROM articles WHERE publish_date &lt;= NOW();</pre>
<p>That works, right? Yeeeeah, it works, but it isn’t <em>optimal</em>. The problem is that MySQL can’t use the query cache on any query that has NOW() in it (or CURRENT_TIME() or any of <a href="http://dev.mysql.com/doc/refman/5.0/en/query-cache-how.html" title="How MySQL Query Cache Works">these other functions</a> for that matter).  The solution I like to use is have PHP generate the timestamp. Even better is to have PHP round the timestamp, like so:</p>
<pre name="code" class="php">// Calculate time to nearest 15 minutes
$roundness = 60 * 15;
$rounded_now = (round(time() / $roundness) * $roundness);
$sql = "SELECT author, title, body FROM articles WHERE publish_date &lt;= $rounded_now";</pre>
<p>Of course, depending on how time sensitive your application is, you may need to change the code from rounding to 15 minutes to something like 5 minutes, or 1 minute. Hey, even rounding to 30 seconds would be better than using NOW() because you can use query cache!</p>
]]></content:encoded>
			<wfw:commentRss>http://iamseanmurphy.com/2008/02/19/mysql-select-entries-before-now/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

