Posts from September 2008
Election 2008 Powered By Twitter
Twitter released a live look at the presidential election, and it’s pretty darn slick. I love the way it auto-updates, and even better is the way the updates are paused when you hover over a tweet. It’s unfortunate, as Andrew Smith mentioned, that it doesn’t include any third party candidates, but hopefully they’ll add them sometime in the near future.
Revision3 Beta
Yesterday, the second phase of Revision3 Beta, Revison3’s search for new shows, was released. I did pretty much all of the backend development, and it’s powered by Viddler’s API. There are some really great shows here, so definitely check it out. You can read Revision3’s announcement on their blog.
Reverie, Shot on the new Canon 5D
Reverie was shot completely on the new Canon 5D, and seriously, I am in complete awe. The quality of the video is absolutely breathtaking; I was shaking my head in amazement during most of the video. I guess I need to start saving up for one…
Cheap, Easy Audio Transcription With Mechanical Turk
Andy Baio explains how he used Amazon’s Mechanical Turk to have a 36-minute MP3 transcribed while he slept for only $15.40. Really great explanations, and it’s pretty cool how easy Amazon has made it to outsource menial tasks.
Thoughts on Affordable Web Hosting
I’ve created my share of websites, and in doing so, I’ve had experiences with a whole lot of web hosts, some of which I’ve loved, others I’ve really disliked. Below, I compiled a list of four of my favorite hosts, two that offer shared hosting and two VPS hosts. Being a college student, all four are affordable, and I’ve had a good experience with all of them.
Dreamhost
The Basics: Super-cheap, feature-rich shared hosting.
Pricing: $9.95/mo. for 1 domain registration, 500GB disk space, 5TB bandwidth, unlimited emails and databases. If you use the code KS50 when signing up, you’ll get $50 off your first year.
My Thoughts: I love Dreamhost. I hate Dreamhost. I’ve gone back and forth between these two emotions numerous times, but ultimately I’ve been really satisfied with my Dreamhost experience. It’s impossible not to like all the developer friendly features, like Subversion hosting and full SSH access. However, they don’t have the the greatest history of downtime, and they even accidently overcharged customers by over $7 million. All that being said, I’m still a happy customer, because, well, they’re really, really cheap, and, for the most part, I haven’t had any issues with them. I wouldn’t host anything mission critical with them, but for the average blog or personal site, they more than suffice.
- Dreamhost Plans
- Sign Up Page - Use this link to enable the KS50 promo code and get $50 off your first year of hosting.
EngineHosting
The Basics: No frills, high quality shared and dedicated hosting, aimed mostly at ExpressionEngine users.
Pricing: $10/mo. for their cheapest plan (400MB disk space, 10GB bandwidth, 100MB database, 15 emails)
My Thoughts: If you’re looking for a feature-rich host with gigabytes upon gigabytes of storage space, EngineHosting definitely isn’t it. On their lowest plan, you get 400MB diskspace, 10GB bandwidth, and only 15 email addresses, which means if you compare them solely on numbers to hosts like Dreamhost, they will likely always come out on bottom. However, their customer service and quality is excellent, especially if you’re building an ExpressionEngine site. I’ve used them for a client site for about 10 months now, and they’ve been absolutely stellar: the site hasn’t been down once, and I haven’t had to contact support once. I won’t think twice about using them for any future ExpressionEngine sites.
RailsPlayground
The Basics: Affordable VPS hosting, specializing in Ruby on Rails.
Pricing: $14.95/mo. for the cheapest VPS plan (10GB diskspace, 256MB RAM, 100GB bandwidth)
My Thoughts: Although I only used RailsPlayground for a couple months, I really enjoyed their service. I had never run a VPS (virtual private server) before, and I was able to pick it up pretty quickly, thanks to their excellent support: I would come across an issue, email them, and they would respond right immediately. Even though I no longer use them, it’s not due to a poor experience, but rather due to my desire to try out Slicehost. I wouldn’t hesitate recommending them to anyone looking for an affordable VPS.
Slicehost
The Basics: Cost-effective VPS hosting, with an amazing community.
Pricing: $20/mo. for the cheapest plan (10GB diskspace, 256MB RAM, 100GB bandwidth)
My Thoughts: Slicehost is currently hosting this site, and I couldn’t be happier. I’m no sysadmin, but following their excellent articles has helped me to build a fast, secure, and stable VPS. I was further amazed by their community when I mentioned an issue at 1AM on their IRC channel, and within 20 minutes, it was fixed. They seem to be completely focused on providing really reliable hosting, and it really shows. The result is rock-solid hosting, and I highly recommend them for anyone looking for VPS hosting.
Umbrella Today?
Umbrella Today? is a brilliant little weather app that just answers one question. You can even sign up to receive text message alerts when an Umbrella may be necessary. Nice!
Jason Fried: Things We've Learned At 37signals
This is a rough transcript from Jason Fried’s talk at Web 2.0 Expo, and there’s some really great stuff in here about project planning and development. I really like his first point about momentum and how it’s a good idea to break large projects into 2 week chunks to make it more manageable. Personally, I’ve definitely noticed this myself: the “newer” a project feels, the more excited you are about it.
Object Oriented PHP Memory Concerns
Ryan Campbell over at Particletree runs through some of the problems you can run into if you’re using object oriented PHP. I was pretty surprised at how quickly it becomes a memory issue, so it’s definitely a good read for anyone working on any size PHP site.
Canon 5D Mark II Details from Thomas Hawk
Thomas Hawk runs down the major features of the upcoming Canon 5D Mark II. This is a really exciting camera: not only does it have great upgrades to the already awesome 5D, but it now includes a full 1080 16:9 video mode.
Simple PHP Caching Using Output Buffering
I’ve worked on quite a few PHP projects recently, and all of them have required some form of caching. From working with each, I’ve come up with a pretty efficient method for caching code using PHP’s output buffering. It ends up being really quick and super flexible.
Output Buffering Basics
Output buffering is a pretty simple concept: instead of letting PHP return data to your user’s browser, you capture it and store it in a “buffer,” and you can decide what to do with it. Here’s a simple example:
ob_start();
echo "Hello! This is buffered.";
$buffer = ob_get_clean();
Let’s go through the code line-by-line. The first line calls ob_start() (docs), which starts output buffering. The next line normally would be sent to the browser. Instead, since I called ob_start(), it gets stored in our buffer. The third line takes the current buffer and assigns it to the $buffer variable and stops the current buffer, all using the ob_get_clean() function (docs). It’s really simple stuff, and it becomes very powerful when used correctly.
How Caching Will Work
For this post, I’m going to be caching a simple API, and the general process will work like this:
- A user makes an API call, something like
http://mysite.com/api/?method=myapp.search&type=people&query=Kyle - If a cache file exists for the call, and it is younger than 15 minutes, skip to #6.
- Start buffering PHP’s output.
- Run the code to process the request.
- Save the contents of the buffer to a file, with a unique filename.
- Return result to the user.
Where Cached Output Will Be Saved
To save the output, I’m going to be creating a file for each unique request. For this application, the request will be unique based on the GET parameters passed. To do this, I’ll be creating an MD5 hash of an alphabetical list of GET keys and values. Here’s the function:
function cache_key() {
$keys = array();
foreach($_GET as $key => $value) {
$keys[] = $key . "=" . $value;
}
sort($keys);
return md5(implode('&', $keys));
}
function cache_filename() {
globals $cache_dir;
return $cache_dir . '/' . cache_key() . '.cache';
}
Please note that this will have to be customized based on what exactly you’re caching. For instance, if you’re caching individual pages, you may want to create the key using the path to the page. Whatever it is you’re using, just make sure it is unique and consistent for each page.
Checking The Cache
When a request is made, it’s necessary to first check to see if it has already been cached, and, if it has, whether the cache hasn’t expired. I’ll be using the filesystem to achieve this:
$cache_time = 15*60; // 15 minutes in seconds
function cache_exists() {
globals $cache_time;
if(@file_exists(cache_filename()) && time() - $cache_time < @filemtime(cache_filename())) {
return true;
} else {
return false;
}
}
So what exactly is going on here? If you take a close look, we’re using the file_exists() (docs) and filemtime() (docs) functions to see if the cache file already exists and, if it does, whether it’s recent enough to serve (in this case, if it’s less than 15 minutes old, the function returns true). I’m placing @ signs before these two functions so that, if they fail, it doesn’t return an error. Instead, the function will just return false and the code will run as if no cache file exists.
Putting It All Together
Now, it’s time to get everything working together. First, a couple of necessary functions for saving and reading the cache:
function read_cache() {
return file_get_contents(cache_filename());
}
function save_cache($value) {
$fp = @fopen(cache_filename(), 'w');
@fwrite($fp, $value);
@fclose($fp);
}
Now, a few calls to wrap around your code:
function start_cache() {
if(cache_exists()) {
echo read_cache();
exit();
} else {
ob_start();
}
}
function stop_cache() {
$data = ob_get_clean();
save_cache($data);
echo $data;
}
And to implement it, this is all you need to do:
start_cache();
// Your code that needs to be cached
stop_cache();
And you’re done! All-in-all, it’s a very simple way to achieve a very powerful result.
Drawbacks to This Method
The first thing you want to keep in mind when using this caching method is that it caches the entire page. This can be good: if everyone visiting the page sees the same content anyways, why not cache it for everyone? However, if you’re serving a page that appears different to different users, it can be a bad idea. For instance, what if an administrator visits the page, and it gets cached? When the next non-administrator visits, they’re going to see all the administration information. Bad news.
Also, due to the simplicity of this method, there’s no way to easily expire the cache of a single page. Let’s go back to the blog entry example. If you decide to make a change to the entry, you’ll have to wait at least 15 minutes before the cache is cleared, or you have to go in and delete all the cache files (since it’s difficult to determine which file goes with which page). For many applications, this probably won’t an issue, but it’s something to keep in mind.
Download the Source
Hopefully, this was helpful. If you’d like to download the entire source, you can grab it here.
iTunes 8 Released
iTunes 8 was released today, and there’s one feature that I’ve really been enjoying so far: Genius playlists. You pick a song in your library, hit the Genius button, and it creates an entire playlist of similar songs. I’ve been finding lots of songs I haven’t listened to in a long time, and it really does a great job of creating some solid playlists. The new visualizer is pretty ridiculous, as well.
jParallax
A jQuery plugin that “turns a selected element into a ‘window’, or viewport, and all its children into absolutely positioned layers that can be seen through the viewport.” As you move your mouse, the layers move, depending on how “far away” the object is. Check out the demo, it’s pretty amazing stuff.
