<?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>kill the radio &#187; php</title>
	<atom:link href="http://blog.killtheradio.net/tag/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.killtheradio.net</link>
	<description>or die trying</description>
	<lastBuildDate>Thu, 15 Dec 2011 20:21:43 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>PHP finally has anonymous functions??</title>
		<link>http://blog.killtheradio.net/technology/php-finally-has-anonymous-functions/</link>
		<comments>http://blog.killtheradio.net/technology/php-finally-has-anonymous-functions/#comments</comments>
		<pubDate>Fri, 15 Apr 2011 18:30:37 +0000</pubDate>
		<dc:creator>Andrew Lyon</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[features]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[tricks]]></category>

		<guid isPermaLink="false">http://blog.killtheradio.net/?p=679</guid>
		<description><![CDATA[Wow, I can&#8217;t believe I missed this&#8230;nobody seems to be talking about it at all. Ever since PHP 5.3, I can finally do non-generic callbacks. UPDATE: Check out this description of PHP lambdas (much better than what I&#8217;ve done in the following). function do_something($value) { // used &#62;= 2 times, but only in this function, [...]]]></description>
			<content:encoded><![CDATA[<p>Wow, I can&#8217;t believe I missed this&#8230;nobody seems to be talking about it at all. Ever since PHP 5.3, <a href="http://php.net/manual/en/functions.anonymous.php">I can finally do non-generic callbacks</a>.</p>
<p>UPDATE: <a href="http://www.ibm.com/developerworks/opensource/library/os-php-5.3new2/index.html">Check out this description of PHP lambdas</a> (much better than what I&#8217;ve done in the following).</p>
<pre>function do_something($value)
{
    // used &gt;= 2 times, but only in this function, so no need for a global
    $local_function = function($value) { ... };

    // use our wonderful anonymous function
    $result = $local_function($value);
    ...
    // and again
    $result = $local_function($result);
    return $result;
}</pre>
<p>There&#8217;s also some other great stuff you can do:</p>
<pre>$favorite_songs = array(
    array('name' =&gt; 'hit me baby one more time', 'artist' =&gt; 'britney'),
    array('name' =&gt; 'genie in a bottle', 'artist' =&gt; 'xtina'),
    array('name' =&gt; 'last resort', 'artist' =&gt; 'papa roach')
);
$song_names = array_map(function($item) { return $item['name']; }, $favorite_songs);</pre>
<p>GnArLy bra. If PHP was 20 miles behind Lisp, it just caught up by about 30 feet. This has wonderful implications because there are a lot of functions that take a callback, and the only way to use them was to define a global function and send in an array() callback. Terrible. Inexcusable. Vomit-inducing.</p>
<p>Not only can you now use anonymous functions for things like array_map() and preg_replace_callback(), you can define your own functions that take functions as arguments:</p>
<pre>function do_something_binary($fn_success, $fn_failed)
{
    $success = ...
    if($success)
    {
        return $fn_success();
    }
    return $fn_failed();
}

do_something_binary(
    function() { echo "I successfully fucked a goat!"; },
    function() { echo "The goat got away..."; }
);</pre>
<p>Sure, you could just return $success and call whichever function you need after that, but this is just a simple example. It can be very useful to encapsulate code and send it somewhere, this is just a demonstration of the beautiful new world that just opened for PHP.</p>
<p>So drop your crap shared host (unless it has &gt;= 5.3.0), get a VPS, and start using this wonderful new feature.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.killtheradio.net/technology/php-finally-has-anonymous-functions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP&#8217;s preg functions don&#8217;t release memory??</title>
		<link>http://blog.killtheradio.net/tricks-hacks/phps-preg-functions-dont-release-memory/</link>
		<comments>http://blog.killtheradio.net/tricks-hacks/phps-preg-functions-dont-release-memory/#comments</comments>
		<pubDate>Tue, 17 Aug 2010 23:37:11 +0000</pubDate>
		<dc:creator>Andrew Lyon</dc:creator>
				<category><![CDATA[Tricks/Hacks]]></category>
		<category><![CDATA[bugs]]></category>
		<category><![CDATA[memory]]></category>
		<category><![CDATA[memory leak]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://blog.killtheradio.net/?p=612</guid>
		<description><![CDATA[We were writing some parsing code for a client today. It takes a long string (html) and parses it out into array items. It loops over the string recursively and running a few preg_replaces on it every pass. We got &#8220;out of memory&#8221; errors when running it. After putting in some general stats, we found [...]]]></description>
			<content:encoded><![CDATA[<p>We were writing some parsing code for a client today. It takes a long string (html) and parses it out into array items. It loops over the string recursively and running a few preg_replaces on it every pass. We got &#8220;out of memory&#8221; errors when running it. After putting in some general stats, we found that memory usage was climbing 400k after each block of preg_replaces, which was being added on each loop (there were around 600 loops or so). This memory just grew and grew, even though the recursion at most got 6 levels deep. It was never being released.</p>
<p>I did some reading and found that the preg* functions cache up to 4096 regex results in a request. This is the problem&#8230;a pretty stupid one too. It would be nice if they made this a configurable option or at <em>least</em> let you turn it off when, say, you are running a regex on a different string every time (why the hell would I run the same regex on the same string twice&#8230;isn&#8217;t that what variables are for?) Unless I&#8217;m misunderstanding and PHP caches the compiled regex (but not its values)&#8230;but either way, memory was climbing based on the length of the string.</p>
<p>Since the regex was only looking at the beginning of the string and disregarding the rest (thank god), the fix was easy (although a bit of a hack):</p>
<pre>$val = preg_replace('/.../', '', $long_string);</pre>
<p>Becomes:</p>
<pre>$short_string = substr($long_string, 0, 128);
$val = preg_replace('/.../', '', $short_string);</pre>
<p>PHP guys: how about an option to make preg* NOT have memory leaks =).</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.killtheradio.net/tricks-hacks/phps-preg-functions-dont-release-memory/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Strange problems with hosts resolving in PHP (and some other linux weirdness)</title>
		<link>http://blog.killtheradio.net/technology/strange-problems-with-hosts-resolving-in-php-and-some-other-linux-weirdness/</link>
		<comments>http://blog.killtheradio.net/technology/strange-problems-with-hosts-resolving-in-php-and-some-other-linux-weirdness/#comments</comments>
		<pubDate>Mon, 07 Jun 2010 18:51:31 +0000</pubDate>
		<dc:creator>Andrew Lyon</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[configuration]]></category>
		<category><![CDATA[fixes]]></category>
		<category><![CDATA[hosts]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[problems]]></category>
		<category><![CDATA[sudo]]></category>

		<guid isPermaLink="false">http://blog.killtheradio.net/?p=565</guid>
		<description><![CDATA[This weekend I wen&#8217;t on a frenzy. I turned beeets.com from a single VPS enterprise to 4 VPSs: 2 web (haproxy, nginx, php-fpm, sphinx, memcached, ndb_mgmd) and 2 database servers (ndmtd). There&#8217;s still some work to do, but the entire setup seems to be functioning well. I had a few problems though. In PHP (just [...]]]></description>
			<content:encoded><![CDATA[<p>This weekend I wen&#8217;t on a frenzy. I turned beeets.com from a single VPS enterprise to <a href="http://www.linode.com/?r=15d5d2323910d69794b93ed02cd7d43b2f68d8c5">4 VPSs</a>: 2 web (<a href="http://haproxy.1wt.eu/">haproxy</a>, <a href="http://nginx.org/">nginx</a>, <a href="http://php-fpm.org/">php-fpm</a>, <a href="http://www.sphinxsearch.com/">sphinx</a>, <a href="http://memcached.org/">memcached</a>, <a href="http://dev.mysql.com/doc/refman/5.0/en/mysql-cluster.html">ndb_mgmd</a>) and 2 database servers (<a href="http://dev.mysql.com/doc/refman/5.0/en/mysql-cluster.html">ndmtd</a>). There&#8217;s still some work to do, but the entire setup seems to be functioning well.</p>
<p>I had a few problems though. In PHP (just PHP, and nothing else) hosts were not resolving. The linux OS was resolving hosts just fine, but PHP couldn&#8217;t. It was frustrating. Also, I was unable to sudo. I kept checking permissions on all my files in /etc, rebooting, checking again, etc.</p>
<h2>The fix</h2>
<p>Then I looked again. /etc itself was owned by andrew:users. Huh? I changed permissions back root:root, chmod 755. <em>Everything works</em>. Now some background.</p>
<p>A while back, I wrote some software (bash + php) that makes it insanely easy to install software to several servers at once, and sync configurations for different sets of servers. It&#8217;s called &#8220;ssync.&#8221; It&#8217;s not ready for release yet, but I can say without it, I&#8217;d have about 10% of the work done that I&#8217;d finished already. Ssync is a command-line utility that lets you set up servers (host, internal ip, external ip) and create groups. Each group has a set of install scripts and configuration files that can be synced to /etc. The configuration files are PHP scriptable, so instead of, say, adding all my hosts by hand to the /etc/hosts file, I can just loop over all servers in the group and add them automatically. Same with my www group, I can add a server to the &#8220;www&#8221; group in ssync, and all of a sudden the HAproxy config knows about the server.</p>
<p>Here&#8217;s the problem. When ssync was sending configuration files to /etc on remote servers, it was also setting permissions on those files (and folders) by default. This was because I was using -vaz, which attempts to preserve ownership, groupship, and permissions from the source (not good). I added some new params (so now it&#8217;s &#8220;-vaz &#8211;no-p &#8211;no-g &#8211;no-o&#8221;). Completely fixed it.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.killtheradio.net/technology/strange-problems-with-hosts-resolving-in-php-and-some-other-linux-weirdness/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Arrays: Some PHP tricks I never knew</title>
		<link>http://blog.killtheradio.net/tricks-hacks/arrays-some-php-tricks-i-never-knew/</link>
		<comments>http://blog.killtheradio.net/tricks-hacks/arrays-some-php-tricks-i-never-knew/#comments</comments>
		<pubDate>Fri, 27 Nov 2009 22:56:02 +0000</pubDate>
		<dc:creator>Andrew Lyon</dc:creator>
				<category><![CDATA[Tricks/Hacks]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://blog.killtheradio.net/?p=337</guid>
		<description><![CDATA[This will be a short post, but pretty cool. You can add arrays together: $test1 = array('name' =&#62; 'andrew'); $test2 = array('status' =&#62; 'totally gnar, dude'); print_r($test1 + $test2); --------------------------- Array ( [name] =&#62; andrew [status] =&#62; totally gnar, dude ) Wow&#8230;who would have thought. And my most recent favorite, converting objects to events. It&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>This will be a short post, but pretty cool.</p>
<p>You can add arrays together:</p>
<pre>	$test1	=	array('name' =&gt; 'andrew');
	$test2	=	array('status' =&gt; 'totally gnar, dude');

	print_r($test1 + $test2);
	---------------------------
	Array
	(
	    [name] =&gt; andrew
	    [status] =&gt; totally gnar, dude
	)</pre>
<p>Wow&#8230;who would have thought. And my most recent favorite, converting objects to events. It&#8217;s a simple foreach($object as $key =&gt; $val) and putting each element into a separate array right? WRONG:</p>
<pre>	$array	=	(array)$object;</pre>
<p>No fucking way. Casting actually works in this case. Why does nobody tell me anything?! This is great for parsing XML because any parser normally returns an object, and quite honestly, I hate dealing with objects. All database data is by default returned as an array usually,  and it&#8217;s a pain having some data sources being objects while others are arrays. Now it doesn&#8217;t matter&#8230;if you like objects, cast an associative array as an (object), if you like arrays cast with (array). I love PHP&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.killtheradio.net/tricks-hacks/arrays-some-php-tricks-i-never-knew/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to convert HTML named entities to numbered entities in PHP</title>
		<link>http://blog.killtheradio.net/how-tos/how-to-convert-html-named-entities-to-numbered-entities-in-php/</link>
		<comments>http://blog.killtheradio.net/how-tos/how-to-convert-html-named-entities-to-numbered-entities-in-php/#comments</comments>
		<pubDate>Wed, 04 Nov 2009 05:40:12 +0000</pubDate>
		<dc:creator>Andrew Lyon</dc:creator>
				<category><![CDATA[How to's]]></category>
		<category><![CDATA[encoding]]></category>
		<category><![CDATA[how-to]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://blog.killtheradio.net/?p=294</guid>
		<description><![CDATA[I recently (read: today) had an obnoxious problem: I&#8217;m writing some code for creating an ATOM feed, and kept getting errors about entity-escaped values. Namely, things like &#38;rsquo;, &#38;bull;, etc. Even written as entities, Opera and IE7 did not recognize them. I read somewhere that it was necessary to convert the named entities to numbered [...]]]></description>
			<content:encoded><![CDATA[<p>I recently (read: today) had an obnoxious problem: I&#8217;m writing some code for creating an ATOM feed, and kept getting errors about entity-escaped values. Namely, things like &amp;rsquo;, &amp;bull;, etc. Even written as entities, Opera and IE7 did not recognize them. I read somewhere that it was necessary to convert the named entities to numbered entities. Great.</p>
<p>Well, PHP doesn&#8217;t have a native function for this. Why, I do not know&#8230;there seems to be functions for many other things, and adding an argument to htmlentities that returns numbered entities would seem easy enough. Either way, I wrote a quick function that takes the htmlentities translation table, adds any <span style="text-decoration: underline;">missing values</span> that are not in the translation table, and runs the conversion to numbered entities. Check it:</p>
<pre>
function htmlentities_numbered($string)
{
	$table	=	get_html_translation_table(HTML_ENTITIES);
	$trans	=	array();
	foreach($table as $char => $ent)
	{
		$trans[$ent]	=	'&#'. ord($char) .';';
	}

	$trans['&amp;euro;']	=	'&amp;#8364;';
	$trans['&amp;sbquo;']	=	'&amp;#8218;';
	$trans['&amp;fnof;']	=	'&amp;#402;';
	$trans['&amp;bdquo;']	=	'&amp;#8222;';
	$trans['&amp;hellip;']	=	'&amp;#8230;';
	$trans['&amp;dagger;']	=	'&amp;#8224;';
	$trans['&amp;Dagger;']	=	'&amp;#8225;';
	$trans['&amp;circ;']	=	'&amp;#710;';
	$trans['&amp;permil;']	=	'&amp;#8240;';
	$trans['&amp;Scaron;']	=	'&amp;#352;';
	$trans['&amp;lsaquo;']	=	'&amp;#8249;';
	$trans['&amp;OElig;']	=	'&amp;#338;';
	$trans['&amp;lsquo;']	=	'&amp;#8216;';
	$trans['&amp;rsquo;']	=	'&amp;#8217;';
	$trans['&amp;ldquo;']	=	'&amp;#8220;';
	$trans['&amp;rdquo;']	=	'&amp;#8221;';
	$trans['&amp;bull;']	=	'&amp;#8226;';
	$trans['&amp;ndash;']	=	'&amp;#8211;';
	$trans['&amp;mdash;']	=	'&amp;#8212;';
	$trans['&amp;tilde;']	=	'&amp;#732;';
	$trans['&amp;trade;']	=	'&amp;#8482;';
	$trans['&amp;scaron;']	=	'&amp;#353;';
	$trans['&amp;rsaquo;']	=	'&amp;#8250;';
	$trans['&amp;oelig;']	=	'&amp;#339;';
	$trans['&amp;Yuml;']	=	'&amp;#376;';

	$string	=	strtr($string, $trans);
	return $string;
}
</pre>
<p>
Hope it&#8217;s helpful.
</p>
<p>
UPDATE &#8211; apparently, even the numbered entities are not valid XML. Fair enough, I&#8217;ve converted them all to <a href="http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1252.TXT" target="_blank" rel="nofollow">unicode (0&#215;80 &#8211; 0x9F)</a>. All my ATOM feeds validate now (through <a href="http://feedvalidator.org" target="_blank" rel="nofollow">feedvalidator.org</a>).</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.killtheradio.net/how-tos/how-to-convert-html-named-entities-to-numbered-entities-in-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP culture &#8211; a scourge on good programming</title>
		<link>http://blog.killtheradio.net/technology/php-culture-a-scourge-on-good-programming/</link>
		<comments>http://blog.killtheradio.net/technology/php-culture-a-scourge-on-good-programming/#comments</comments>
		<pubDate>Tue, 27 Oct 2009 08:16:14 +0000</pubDate>
		<dc:creator>Andrew Lyon</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[rants]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://blog.killtheradio.net/?p=270</guid>
		<description><![CDATA[Having taken my programming roots in QBASIC (shut up), C, C++, and a very healthy self-administered dose of x86 assembly, I can say that for the most part I have a good sense of what programming is. All of what I&#8217;ve learned up until now has helped me develop my sense for good code, and [...]]]></description>
			<content:encoded><![CDATA[<p>Having taken my programming roots in QBASIC (shut up), C, C++, and a very healthy self-administered dose of x86 assembly, I can say that for the most part I have a good sense of what programming is. All of what I&#8217;ve learned up until now has helped me develop my sense for good code, and helped me to write programs and applications that I can sit back and be proud of. I&#8217;ve been working with PHP for over 4 years now, and I have to say it&#8217;s the most ugly language I&#8217;ve ever used.</p>
<p>Let me explain. PHP itself is wonderfully loosely-typed, C-like syntactically, and all around easy to write code for. The syntax is familiar because of my background. The integration with web is apparent down to its core, and it&#8217;s a hell of a lot easier than assembly to write. When perusing through a project filled to the brim with C source code, I&#8217;m usually left thinking about how it works, why the developer did what they did, and why that makes sense for that particular application. I&#8217;m usually able to figure out these questions and there&#8217;s one main reason: the code isn&#8217;t shit. With PHP, I&#8217;m usually left wondering what the developer was thinking, the 100s of ways I could have done it more efficiently, and why this person is actually making money doing this.</p>
<p>With roughly 90% of open-source PHP projects, everything works great. I love it, clients love it, everyone kisses eachother&#8217;s ass. But then one day you get that inevitable change request&#8230;I want it to do THIS. A quick look at the source code reveals that, omg, it&#8217;s been written by a team of highly trained ape-like creatures! It surprises me that WordPress plugins that get 100s of downloads a day throw errors (unless you disable error output, which I never do on my dev machines). Whole architectures are written with random indentation, or indentation with spaces (sorry Rubyers, but space-indentation is an evil scourge on humanity). No effort is put into separating pieces of code that could so easily be modularized if only they were given a second thought.</p>
<p>Do I hate PHP? No, I love PHP. I think it&#8217;s a well-written, high-level web development language. It&#8217;s fast, portable, and scalable. It allows me to focus on the problems I face, not the syntax of what I&#8217;m trying to do. Paired with an excellent editor like Eclipse (w/ PHPeclipse) I&#8217;m unstoppable. But why can&#8217;t any other PHP developers share my love of well-written code? It&#8217;s the #1 critique of PHP, and rightly so. I&#8217;m pretty sure that all programming languages, save Python, allow you to write awful, unreadable code&#8230;but PHP&#8217;s culture seems to be built around shitty code, amateurish hacks, and lack of elegance. PHP isn&#8217;t the problem, it&#8217;s the people writing it who suck!</p>
<p>So I do love the language, but hate most of the implementations. I have to say though, nothing is worse than Coldfusion.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.killtheradio.net/technology/php-culture-a-scourge-on-good-programming/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why I hate smarty</title>
		<link>http://blog.killtheradio.net/technology/why-i-hate-smarty/</link>
		<comments>http://blog.killtheradio.net/technology/why-i-hate-smarty/#comments</comments>
		<pubDate>Mon, 21 Sep 2009 21:03:20 +0000</pubDate>
		<dc:creator>Andrew Lyon</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[rants]]></category>
		<category><![CDATA[templating]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://blog.killtheradio.net/?p=187</guid>
		<description><![CDATA[Smarty is everyone&#8217;s favorite templating language for PHP. It&#8217;s great in many ways, one of the main features being that it can display things on a website. It also promotes separation of display code and logic, which many PHP programmers seem to have trouble with: oscommerce, PHPList, etc etc. So why do I hate it? [...]]]></description>
			<content:encoded><![CDATA[<p><a rel="nofollow" href="http://www.smarty.net/" target="_blank">Smarty</a> is everyone&#8217;s favorite templating language for PHP. It&#8217;s great in many ways, one of the main features being that it can display things on a website. It also promotes separation of display code and logic, which many PHP programmers seem to have trouble with: oscommerce, PHPList, etc etc.</p>
<p>So why do I hate it?</p>
<p><em>&lt;rant&gt;</em><br />
There&#8217;s <em>no fucking point!</em> All bad programmers write bad code. Why create a language within a language just to force bad programmers to do one thing right? I realize that Smarty does enforce separation of logic from display very well. I&#8217;ve used it in several projects. But if its capabilities are so strikingly similar to PHP that for most things there is a 1-1 reference, why bother? Why not just use PHP code?</p>
<p>Also, the plugins (and {php} tag) allow you to make logical decisions, run mysql queries, <em>send rockets to the moon</em>&#8230;there&#8217;s nothing you can do in PHP that you cannot do in Smarty&#8230;which makes Smarty completely worthless for what it&#8217;s trying to do.</p>
<p>If you want to promote good programming, you don&#8217;t need Smarty. You can rewrite Smarty as a PHP object that sets variables and includes a template. I&#8217;ve written this a dozen times over&#8230;and it does the exact same thing, except templates are in PHP so <em>everyone </em>can understand them, there is no caching trickery going on, and best of all you don&#8217;t need to reference some stupid guide on how to display something in a strange language which you <em>already know how to do in PHP</em>.<br />
<em>&lt;/rant&gt;</em></p>
<p>So, in summation, please don&#8217;t stop using Smarty. It&#8217;s a good piece of code for people who don&#8217;t understand the basics of separation of logic from display&#8230;but realize that Smarty is a hack, a patch, a band-aid. The REAL problem is bad programming, not something inherently wrong with PHP that needs to be rewritten.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.killtheradio.net/technology/why-i-hate-smarty/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>aframe with replication</title>
		<link>http://blog.killtheradio.net/technology/aframe-with-replication/</link>
		<comments>http://blog.killtheradio.net/technology/aframe-with-replication/#comments</comments>
		<pubDate>Tue, 11 Aug 2009 20:02:14 +0000</pubDate>
		<dc:creator>Andrew Lyon</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[aframe]]></category>
		<category><![CDATA[frameworks]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[replication]]></category>

		<guid isPermaLink="false">http://www.killtheradio.net/?p=89</guid>
		<description><![CDATA[A while ago, I wrote a snippet about MySQL replication. Well, I finally started playing with it not long ago, and was very successful. Apparently it works well, even for someone who hasn&#8217;t set it up before. Nice. I haven&#8217;t actually set this up on beeets because we don&#8217;t need it yet, and also I [...]]]></description>
			<content:encoded><![CDATA[<p>A while ago, I wrote a snippet about MySQL replication. Well, I finally started playing with it not long ago, and was very successful. Apparently it works well, even for someone who hasn&#8217;t set it up before. Nice. I haven&#8217;t actually set this up on beeets because we don&#8217;t need it yet, and also I haven&#8217;t played with it enough to feel confident using it on a production basis.</p>
<p>That said, our <a href="http://www.lyonbros.com" target="_blank">Lyon Bros</a> aframe framework now supports replication. It sends selects to the slave, writes to master, last_id to master, transactions to master, etc. Basically the only thing that slaves get are dumb selects (which are most of the queries anyway). I had the opportunity to test this out with the play MySQL replcation setup, and it works perfectly. It was nice to see something that complicated actually working.</p>
<p>Right now, it only supports connecting to two servers: master and slave (it holds off on connecting to those servers until one of them actually gets a request to save time on request startup). Basically, aframe doesn&#8217;t support load balancing. This means that if you have more than one master or slave, to use replication effectively, you&#8217;ll have to use a MySQL replication load balancer (either software or hardware). This will give you a single IP address to send requests to, but distribute the requests automatically to improve load times.</p>
<p>Hopefully we&#8217;ll need to set this up soon, but for now, just the one MySQL server will do =). Sometime within the next few months, we plan on releasing aframe as open source. It&#8217;s licensed and ready to go, but we have no documentation&#8230;and just saying &#8220;check out CakePHP and hope it works the same&#8221; won&#8217;t fly&#8230;especially since aframe is 23,148,855,308,184,500x better than Cake.</p>
<p>One thing I&#8217;d like to check out on round two of replication tinkering is <a href="http://www.maatkit.org/" target="_blank">Maatkit</a>. From what I hear, it automates a lot of stuff I would be writing scripts for and checking every day. I looked at it a while ago and it seemed overly complicated, but that was even before I tried to get a server replicated. Maybe nowadays it would be easier.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.killtheradio.net/technology/aframe-with-replication/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Is a good Windows-based S3 tool too much to ask?</title>
		<link>http://blog.killtheradio.net/technology/is-a-good-windows-based-s3-tool-too-much-to-ask/</link>
		<comments>http://blog.killtheradio.net/technology/is-a-good-windows-based-s3-tool-too-much-to-ask/#comments</comments>
		<pubDate>Tue, 11 Aug 2009 19:20:08 +0000</pubDate>
		<dc:creator>Andrew Lyon</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[amazon]]></category>
		<category><![CDATA[caching]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[s3]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[soap]]></category>
		<category><![CDATA[upload]]></category>

		<guid isPermaLink="false">http://www.killtheradio.net/?p=77</guid>
		<description><![CDATA[With Amazon S3 being as good and cheap as it is, it&#8217;s almost essential for what I need it for&#8230;storing images and large static files. The problem is there is no interface besides SOAP, and if you don&#8217;t know how I feel about SOAP, let me tell you: it makes my head want to fucking [...]]]></description>
			<content:encoded><![CDATA[<p>With Amazon S3 being as good and cheap as it is, it&#8217;s almost essential for what I need it for&#8230;storing images and large static files. The problem is there is no interface besides SOAP, and if you don&#8217;t know how I feel about SOAP, let me tell you: it makes my head want to fucking explode. It&#8217;s insanely complicated for what it does. It tries to standardize so many things that it&#8217;s completely bloated&#8230;sending the message &#8220;hello&#8221; from one computer to another in SOAP takes oh about 10 years&#8230;5 years for a team of 50 supercomputers working in tandem to build the header and message body (which will total about 400 mb when finally complete), .02ms to send, and 5 years in decoding. Use JSON, you crackheads. Sure you&#8217;ll actually have to document it, but nothing is worse than SOAP, not even documenting.</p>
<p>That&#8217;s besides the point though. S3 chose to use SOAP, so I refuse to write my own client for it. This means that, as of late, the world is without a <span style="text-decoration: underline;">good</span> free S3 uploading client. S3Fox, the firefox extension, is ok&#8230;it can&#8217;t handle SSL connections though, so expect to lose your private key to a sniffer about 10 seconds after your first request. JungleDisk is now a completely paid service (I already pay for S3, I&#8217;m not paying those guys to fucking USE it). Linux has some great <em>command line</em> tools for S3 (yay&#8230;), but that leaves windows with either S3fox, JD ($$$), or a handful of shitty S3 clients.</p>
<p>Right now, I have to use a PHP script I built around the <a href="http://undesigned.org.za/2007/10/22/amazon-s3-php-class" target="_blank">S3 PHP Class</a> to do any uploading that doesn&#8217;t make me vomit. The S3 class works REALLY well&#8230;it lets you assign ACL while uploading, change headers for images (for browser-side caching, mmm) and best of all, doesn&#8217;t completely suck. Let&#8217;s all thank Donovan Schönknecht for writing something that actually works well and communicates with S3.</p>
<p>Here&#8217;s a piece of code I wrote that wraps around the S3 uploader. It uploads images, sets Cache-Control headers, and removes the images. What you want to do is copy your images into a folder, run this file one directory up (change $start_folder to == the name of the folder your images are in), and sit back. It will upload all your images, directory structure preserved, publicly viewable and with cache-control headers.</p>
<pre>&lt; ?
	// quick config
	$bucket			=	'your.bucket.com';
	$start_folder	=	'images';

	// settings
	error_reporting(E_ALL);
	ini_set('display_errors', 1);
	ini_set('max_execution_time', 3600);

	// include S3 class
	include 'S3.php';
	$s3	=	new S3('[your key]', '[your secret]', false);

	// get list of files. if you don't want a subdirectory, just change this line to not need one. hopefully you know PHP...
	$files	=	recurse(array(), $start_folder);

	// loop over files and upload
	for($i = 0, $n = count($files); $i &lt; $n; $i++)
	{
		$ext	=	preg_replace('/.*\./', '', $files[$i]);
		$type	=	'image/jpeg';
		if($ext == 'jpg')
		{
			$type	=	'image/jpeg';
		}
		else if($ext == 'gif')
		{
			$type	=	'image/gif';
		}
		else if($ext == 'png')
		{
			$type	=	'image/png';
		}

		if(
			!$s3-&gt;putObject(
				$s3-&gt;inputFile($files[$i]),
				$bucket,
				$files[$i],
				S3::ACL_PUBLIC_READ,
				array(),
				array('Cache-Control' =&gt; 'max-age=31536000', 'Content-Type' =&gt; $type)
			)
		)
		{
			echo '&lt;span style="color:green;"&gt;Failed: upload of '. $files[$i] . '';
		}
		else
		{
			echo '&lt;span style="color:green;"&gt;Succeeded: upload of '. $files[$i] .'';
			unlink($files[$i]);
		}
	}

	function recurse($files, $dir)
	{
		$d	=	scandir($dir);

		for($i = 0, $n = count($d); $i &lt; $n; $i++)
		{
			if(!preg_match('/^\./', $d[$i]))
			{
				if(is_dir($dir . '/' . $d[$i]))
				{
					$files	=	recurse($files, $dir . '/' . $d[$i]);
				}
				else
				{
					$files[]	=	$dir . '/' . $d[$i];
				}
			}
		}

		return $files;
	}
?&gt;</pre>
<p>Feel free to modify, copy, blah blah&#8230;but give credit where it&#8217;s due. Let it be a light to you when all other lights go out. Hopefully it helps someone, because it sure helps me out.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.killtheradio.net/technology/is-a-good-windows-based-s3-tool-too-much-to-ask/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Throw apache to the wind?</title>
		<link>http://blog.killtheradio.net/technology/throw-apache-to-the-wind/</link>
		<comments>http://blog.killtheradio.net/technology/throw-apache-to-the-wind/#comments</comments>
		<pubDate>Sun, 18 Jan 2009 20:24:51 +0000</pubDate>
		<dc:creator>Andrew Lyon</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[fastcgi]]></category>
		<category><![CDATA[hosting]]></category>
		<category><![CDATA[lighttpd]]></category>
		<category><![CDATA[modproxy]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://killtheradio.dev/?p=26</guid>
		<description><![CDATA[So after hours of searching and tweaking, I finally got the answer I never wanted: it&#8217;s not possible to have apache serve mod_fastcgi requests through it&#8217;s own reverse proxy (ie load-balance mod_fastcgi). I know this is incorrect. But it had taken me so long and wasted so much time getting to the point where I [...]]]></description>
			<content:encoded><![CDATA[<p>So after hours of searching and tweaking, I finally got the answer I never wanted: it&#8217;s not possible to have apache serve mod_fastcgi requests through it&#8217;s own reverse proxy (ie load-balance mod_fastcgi). I know this is incorrect. But it had taken me so long and wasted so much time getting to the point where I was almost as clueless as when I started, that I took drastic action.</p>
<p>I installed <a href="http://www.lighttpd.net/" target="_blank">lighttpd</a>. I already had the FastCGI setup running, not to mention I got a new Linode for testing remote PHP. The only problem was that I couldn&#8217;t load balance between my slack box (web server) and my new linode (debian app server). BTW I chose <a href="http://www.debian.org/" target="_blank">Debian</a> because the image was smaller and from what I know, it&#8217;s essentially the same as Slack. I really haven&#8217;t had ANY problems moving to it yet, and let&#8217;s face it, Deb is a lot more standard. Installing PHP was a bitch, but that&#8217;s what apt-get is for (no, I compiled PHP&#8230;but I&#8217;ll be damned if I&#8217;m going to hand compile all the stupid dependencies).</p>
<p>Anyway, within 20 minutes, lighttpd had PHP running through FastCGI load balanced between two servers. Needless to say, I fell in love. Not to mention all the information I was inundated with along the way about how small and lean lighttpd is swayed this choice a little.</p>
<p>So as far as I know, <a href="http://www.beeets.com" target="_blank">beeets</a> is running great on both of its &#8220;new&#8221; servers and loving it.</p>
<p>There was a bit of trouble getting used to the new URL rewriting scheme, but generally instead of doing apache&#8217;s</p>
<p>RewriteCond blahblah !-f</p>
<p>You can just do url-rewrite(&#8216;(images|css|js)&#8217; =&gt; &#8216;$0&#8242;)</p>
<p>(this is a horrible oversimplification, but you get the idea)&#8230;you write the URLs you DON&#8217;T want to be rewritten to $0. Works wonders.</p>
<p>All that&#8217;s left is some cache-control headers (I&#8217;m crazy about them, if you can&#8217;t tell yet), and some speed testing. I&#8217;m excited to see if lighttpd is actually faster than apache under ab.</p>
<p>Next up, <a href="http://www.capify.org/" target="_blank">Capistrano</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.killtheradio.net/technology/throw-apache-to-the-wind/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Amazon S3</title>
		<link>http://blog.killtheradio.net/technology/amazon-s3/</link>
		<comments>http://blog.killtheradio.net/technology/amazon-s3/#comments</comments>
		<pubDate>Fri, 16 Jan 2009 20:22:59 +0000</pubDate>
		<dc:creator>Andrew Lyon</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[amazon]]></category>
		<category><![CDATA[beeets]]></category>
		<category><![CDATA[caching]]></category>
		<category><![CDATA[hosting]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[storage]]></category>

		<guid isPermaLink="false">http://killtheradio.dev/?p=24</guid>
		<description><![CDATA[Very cool service. I updated beeets to pull all images from images.beeets.com, an S3 bucket. Also, all css files now go through /css/css.php/file.css &#8230;which rewrites url(/images/&#8230;) to url(http://images.beeets.com/images/&#8230;) And guess what, it all works. I had some bad experiences with the S3Fox firefox plugin in the past, but it&#8217;s since been updated and I&#8217;ve been [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://aws.amazon.com/" target="_blank">Very cool service</a>. I updated <a href="http://www.beeets.com" target="_blank">beeets</a> to pull all images from images.beeets.com, an S3 bucket. Also, all css files now go through</p>
<p>/css/css.php/file.css &#8230;which rewrites</p>
<p>url(/images/&#8230;) to</p>
<p>url(http://images.beeets.com/images/&#8230;)</p>
<p>And guess what, it all works. I had some bad experiences with the <a href="https://addons.mozilla.org/en-US/firefox/addon/3247" target="_blank">S3Fox</a> firefox plugin in the past, but it&#8217;s since been updated and I&#8217;ve been using it regularly.</p>
<p>Also, using <a href="http://undesigned.org.za/2007/10/22/amazon-s3-php-class" target="_blank">S3.php</a>, all profile images now go directly onto images.beeets.com. Wicked.</p>
<p>So what does this mean? A few things:</p>
<p>1. Less bandwidth &amp; work &#8211; beeets will spend more time serving HTML, CSS, and JS than images.</p>
<p>2. Safer &#8211; We were backing up profile images to S3 indirectly before, but the chances of S3 going down VS our hosting are slim.</p>
<p>3. Worse image caching &#8211; Before, I had .htaccess controlling all the caching for static files. I liked it that way. S3 doesn&#8217;t do this very well at all. Apparently it&#8217;s configurable, but I don&#8217;t know how&#8230;any ideas?</p>
<p>All in all, it should be better for beeets. Maybe we&#8217;ll actually let users have images bigger than 10&#215;10 now ;)</p>
<p>Thumbs up to S3 (and probably all other Amazon web services).</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.killtheradio.net/technology/amazon-s3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Apache, PHP, FastCGI &#8211; The two day crucible</title>
		<link>http://blog.killtheradio.net/technology/apache-php-fastcgi-the-two-day-crucible/</link>
		<comments>http://blog.killtheradio.net/technology/apache-php-fastcgi-the-two-day-crucible/#comments</comments>
		<pubDate>Fri, 16 Jan 2009 20:14:19 +0000</pubDate>
		<dc:creator>Andrew Lyon</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[fastcgi]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[servers]]></category>

		<guid isPermaLink="false">http://killtheradio.dev/?p=19</guid>
		<description><![CDATA[Wow. You&#8217;d think it would be easy. In fact, it should have been. Compile a module, load it from apache. Recompile PHP with &#8211;enable-fastcgi&#8230;oh wait, I already had it in there (always thinking ahead!!). Change some apache settings. Right? Yeah, right. It took two days. I can&#8217;t even really remember why. The biggest problem was [...]]]></description>
			<content:encoded><![CDATA[<p>Wow. You&#8217;d think it would be easy. In fact, it should have been. Compile a module, load it from apache. Recompile PHP with &#8211;enable-fastcgi&#8230;oh wait, I already had it in there (always thinking ahead!!). Change some apache settings.</p>
<p>Right? Yeah, right. It took two days. I can&#8217;t even really remember why. The biggest problem was that running make &amp;&amp; make install in the mod_fastcgi source was NOT yielding a &#8216;mod_fastcgi.so&#8217; as the documentation PROMISED! In fact, it installed mod_fastcgi.la instead, a highly useless file.</p>
<p>So how did the master get out of this bind? Beats me, try asking him. As for me, I had to run &#8216;ld -Bshareable *.o -o mod_fastcgi.so&#8217; which is mentioned in some document from a long time ago in a galaxy far, far away.</p>
<p>Let me interject and say that the information on the <a href="http://www.fastcgi.com" target="_blank">FastCGI website</a> is &#8220;not very well documented.&#8221;</p>
<p>Day 2. I figured, what&#8217;s the point of FastCGI if it&#8217;s not set up to connect to a remote App server? Maybe I don&#8217;t HAVE an external server set up, but we can pretend. Well that&#8217;s another nightmare. There&#8217;s a good <a href="http://www.cyberciti.biz/tips/rhel-fedora-centos-apache2-external-php-spawn.html" target="_blank">external FastCGI</a> guide written about it, and guess what it worked. Not really a nightmare at all, come to think of it. Quite pleasant.</p>
<p>All in all, shouldn&#8217;t have taken 2 days =P (I&#8217;m a tinkerer)&#8230;but fuck it, I have FastCGI now, ready to connect to all those App servers I have churning away in the background (one day).</p>
<p>In all the excitement, I also compiled and installed the <a href="http://httpd.apache.org/docs/2.0/mod/worker.html" target="_blank">apache worker-MPM</a>. A few tests with ab didn&#8217;t really show any noticeable difference. But threads are cool, right?</p>
<p>Next up: figure out how to configure Apache to pass all requests ending in .php (whether the file exists on the web server or not) to our &#8220;app&#8221; server. Is this possible?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.killtheradio.net/technology/apache-php-fastcgi-the-two-day-crucible/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>IIS and PHP</title>
		<link>http://blog.killtheradio.net/technology/iis-and-php/</link>
		<comments>http://blog.killtheradio.net/technology/iis-and-php/#comments</comments>
		<pubDate>Wed, 14 Jan 2009 20:13:59 +0000</pubDate>
		<dc:creator>Andrew Lyon</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[fastcgi]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[servers]]></category>

		<guid isPermaLink="false">http://killtheradio.dev/?p=16</guid>
		<description><![CDATA[So tonight I helped a client set up PHP5 on IIS 7 using MSSQL 2005. These things always work great in theory but judging my my use of the word &#8220;theory&#8221; in italics, you can probably guess that things weren&#8217;t so smooth in practice. The client was smart enough to get FastCGI working through IIS&#8230;something [...]]]></description>
			<content:encoded><![CDATA[<p>So tonight I helped a client set up PHP5 on IIS 7 using MSSQL 2005. These things always work great in <em>theory</em> but judging my my use of the word &#8220;theory&#8221; in italics, you can probably guess that things weren&#8217;t so smooth in <em>practice</em>.</p>
<p>The client was smart enough to get FastCGI working through IIS&#8230;something I would have probably rolled over on. From then on, it was an upward battle getting a simple PHP prototype project going.</p>
<p>In the later versions of PHP 5, it would seem that all mssql_* functions have&#8230;been&#8230; removed? There is an ntwdblib.dll that needs to be replaced to play nicely with mssql 2005&#8230;but it doesn&#8217;t exist in the latest releases. How strange. I ended up reverting to 5.2.5, making me a not-so-bleeding-edge pushover :&#8217;(. It&#8217;s cool though.</p>
<p>Then MSSQL doesn&#8217;t accept normal logins, only windows ones, and it&#8217;s bloomin&#8217; impossible finding out how to change that.</p>
<p>One thing Microsoft seems to have actually done right is release a rewrite module (much like mod_rewrite) that you don&#8217;t have to frickin&#8217; pay for, which is nice. On a side note, I really hated Windows Server 2008. It&#8217;s like Vista in every way, except that the design is slightly different, somewhat. Sorry, MS, but get your shit together plz, kkthxbai.</p>
<p>Anyway, we got everything going. What a pain in the ass though!</p>
<p>If you&#8217;re wondering, I&#8217;m more of a Unix guy ;). And yes, I <em>have</em> used a computer before.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.killtheradio.net/technology/iis-and-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

