Archive for May, 2009

What 255 characters looks like

“Should I use TEXT or VARCHAR field here?”

I’ve lost count of the number of times that I asked myself this question when putting together database structures. Since the maximum a VARCHAR can hold is 255, it becomes a question of whether or not the data you’re saving will be any longer than that. Sometimes that’s an easy call (phone number = VARCHAR; email body = TEXT), other times its blurry (verbose error logs, foreign-language data sets, user-submitted comments, etc).

“So what? Why not just use TEXT and be done with it?”

It’s true that in most cases it won’t make a difference. However, if you need to index and search the field, you should think carefully before blindly using TEXT. The data in TEXT type fields are stored outside the table itself, using only a few bytes for pointer information. This means that TEXT fields are not indexed, while VARCHAR fields are. This can have a tremendous effect on your SQL query speeds, as generally larger TEXT fields increase query time exponentially. Even if we take indexing out of the picture, the external storage of TEXT fields means that you’ll still see generally faster searches with VARCHAR.

Which brings us back to the original problem: when is a 255 character cap good enough? See for yourself. Below you’ll find a block of lorem ispum text that’s exactly 255 characters long (spaces count):

Lorem ipsum dolor sit amet, nonummy ligula volutpat hac integer nonummy. Suspendisse ultricies, congue etiam tellus, erat libero, nulla eleifend, mauris pellentesque. Suspendisse integer praesent vel, integer gravida mauris, fringilla vehicula lacinia non

If you’re like me, you’ll look at that and say, “That’s a lot more than I thought.”

Another way to look at it: RFC2822 says that a subject line may contain 998 total characters, with a max of 78 per line. Most mail clients don’t support multi-line subjects, so 78 characters is the practical limit you’ll find in most cases.

So if you ever find yourself doing that fuzzy-string-length-guestimation math in your head, bookmark this page to add a visual to the guesswork as well.


Go Bullets!

My brother, Patrick, plays lacrosse for Gettysburg College. Last weekend they beat Stevenson University — an upset by the stats, but they owned the game — which advanced them to the NCAA Division III Championship.

They’ll be playing Cortland at Gillette Stadium, home of the New England Patriots, on Sunday for the title. The game will be televised on CBS College Sports Network.

So yeah, my brother? Kind of a big deal.

Good luck, bud! Kick ass!


IE: You’re still doing it wrong…

While working on the file manager section of the Fwd:Vault website, I decided to do a quick check on cross-browser compatibility. The following screenshots are of the same page using the same HTML layout, CSS definitions, etc…

At this point in my career, I don’t think words can express how much I utterly loathe Microsoft’s IE team (and Microsoft in general) for their completely overt dismissal of browser standards. But that won’t stop me from trying, so listen up, you morons.

Building a website is an incredibly complex task, and that complexity increases almost daily. Today, all my sites include code written in HTML, CSS, JavaScript, SQL, and PHP (or ASP, JSP, etc). Nuance aside, that’s five languages! All intermingled to accomplish one goal: put a page in front of a user.

On top of that, I have to worry about abstract concepts like SEO, caching, file sizes/load times, traffic stats, usability, server uptime, SSL, data integrity, backups, security…I could keep going. I have enough to do without having to worry about your browser — I check the others, I only worry about your browser — mucking up my display or breaking my Javascript. Less time spent dealing with browser compatibility issues equals more time building a better browsing experience, which is good for everyone, even you.

Furthermore, I don’t like the notion of “pushing” a user toward or away from any given browser. As a web developer and webmaster, I am in the business of delivering my site content. Having to urge people to choose a better browser is a distraction at best, lost traffic at worst. From the perspective of my users, it’s better to just handle the problems quietly in the background. I think this same mindset is why you don’t see overwhelming support (yet) for movements like WeDontSupportIE.com.

However, as my example above starkly displays, there are now four solid mainstream alternatives out there, and plenty of smaller options as well. That says nothing about the inroads of Mac and Linux into the OS market. How much longer do you think “IE inertia” will carry?

In short, when it comes to HTML/CSS interpretation and display, IE should be in lock step with competitors. If you do that, you can essentially remove web developers from the browser debate, which is big for you because you’re not winning any popularity contests with us. Differentiate yourself from the competition by creating a better user experience, and let the end user decide.

Of course I’m not holding my breath, so one of these buttons my end up on Fwd:Vault before launch

I haven’t decided yet…


Translating PHP error constants

I wanted to log all the errors thrown out by Fwd:Vault processes to ensure that any bugs I don’t catch myself bubble to the top very quickly. To get started, I replaced PHP’s default error handling with a custom error handler function, which simply logs the error in a MySQL table before passing it along to the normal internal error handler.

Later, I’m going to add non-error notices to the mix, and set up an RSS feed to output these errors, allowing me real-time updates on overall system health.

If the error handling stuff sounds like Greek, read up before going further:

When PHP throws any kind of error, the error is assigned an error level, which can be expressed in two ways: an integer or a predefined constant. The constant represents the integer, making the two completely interchangeable. However if you build a custom error handler, you are only given the integer, which doesn’t automagically translate back to the constant value. It’s a heckuva lot easier to recognize E_USER_ERROR instead of the integer 256, so I want to store that error constant for reading purposes. If you find yourself looking at error numbers, and want the matching constant string, use this block of code:

switch ($errno) {
  case 1:     $e_type = 'E_ERROR'; break;
  case 2:     $e_type = 'E_WARNING'; break;
  case 4:     $e_type = 'E_PARSE'; break;
  case 8:     $e_type = 'E_NOTICE'; break;
  case 16:    $e_type = 'E_CORE_ERROR'; break;
  case 32:    $e_type = 'E_CORE_WARNING'; break;
  case 64:    $e_type = 'E_COMPILE_ERROR'; break;
  case 128:   $e_type = 'E_COMPILE_WARNING'; break;
  case 256:   $e_type = 'E_USER_ERROR'; break;
  case 512:   $e_type = 'E_USER_WARNING'; break;
  case 1024:  $e_type = 'E_USER_NOTICE'; break;
  case 2048:  $e_type = 'E_STRICT'; break;
  case 4096:  $e_type = 'E_RECOVERABLE_ERROR'; break;
  case 8192:  $e_type = 'E_DEPRECATED'; break;
  case 16384: $e_type = 'E_USER_DEPRECATED'; break;
  case 30719: $e_type = 'E_ALL'; break;
  default:    $e_type = 'E_UNKNOWN'; break;
}

This will give you a string in $e_type matching the proper constants. The switch block accounts for all the current PHP constants as of this posting, plus a catch-all E_UNKNOWN in case you’re doing something really weird.

Now let’s add some perspective to this code block. Here’s an sample custom error handler that grabs the constant string for logging purposes and outputs the error to the screen. The internal handler is bypassed in this example, since we don’t need it to do anything (note how the function kills page processing when a fatal error occurs). We’ll also set this custom function as the default error handler.

function custom_error_handler($errno, $errstr, $errfile, $errline) {
  $exit_now = false;
  switch ($errno) {
    case 1:     $e_type = 'E_ERROR'; $exit_now = true; break;
    case 2:     $e_type = 'E_WARNING'; break;
    case 4:     $e_type = 'E_PARSE'; break;
    case 8:     $e_type = 'E_NOTICE'; break;
    case 16:    $e_type = 'E_CORE_ERROR'; $exit_now = true; break;
    case 32:    $e_type = 'E_CORE_WARNING'; break;
    case 64:    $e_type = 'E_COMPILE_ERROR'; $exit_now = true; break;
    case 128:   $e_type = 'E_COMPILE_WARNING'; break;
    case 256:   $e_type = 'E_USER_ERROR'; $exit_now = true; break;
    case 512:   $e_type = 'E_USER_WARNING'; break;
    case 1024:  $e_type = 'E_USER_NOTICE'; break;
    case 2048:  $e_type = 'E_STRICT'; break;
    case 4096:  $e_type = 'E_RECOVERABLE_ERROR'; $exit_now = true; break;
    case 8192:  $e_type = 'E_DEPRECATED'; break;
    case 16384: $e_type = 'E_USER_DEPRECATED'; break;
    case 30719: $e_type = 'E_ALL'; $exit_now = true; break;
    default:    $e_type = 'E_UNKNOWN'; break;
  }
  echo "<strong>$e_type</strong> &mdash; $errstr on line $errline in file $errfile<br />n";
  //send_to_log("$e_type - $errstr on line $errline in file $errfile");
  if ($exit_now) exit(1);
  // Don't execute PHP internal error handler
  return true;
}
set_error_handler('custom_error_handler');

At this point you have all the information necessary to do whatever you want with the error. A future post will expand on that send_to_log() statement, but serves as a placeholder example.


New Gaming Want: Global Agenda

Factoid about me: PlanetSide ranks in the top 5 for my all-time favorite gaming experiences. A persistent MMO world that was essentially a massive FPS match, there was nothing like it. You’d be part of an army of literally hundreds, all working together to attack an outpost tower, a large base, a continent. Grounds troops rushing in, with actual artillery, tanks, and air support, and all human players. Mind-blowingly awesome.

Recently, a gaming buddy of mine from my PlanetSide days pointed me to an upcoming title called Global Agenda. On the surface it looks like a very similar attempt to blend an MMO environment with FPS gameplay and RPG “stat” elements. In my opinion PlanetSide was a game ahead of its time, as massive worlds (WoW), deep tactics (WoW, WAR), and strong community elements (WoW, Steam, CoD, XBL, etc etc) have only really taken hold in the past 5 years or so. A game setting out to do something similar today could be positively outstanding.

Needless to say, I am registered for the Beta, waiting with bated breath. I recommend you do the same.


Usability Fail: Xenocode

Maybe I’m just getting more cynical, but I’ve been finding a lot more sites doing really stupid things that serve only to piss off their users. As a result I’ve decided to start a new series of posts titled “Usability Fail” which will discuss just that: sites that make dumb decisions that utterly fail in the “user-friendly” and “usability” categories.

The Site
Today’s site is one that I’ve actually lauded in the past. Xenocode develops really cool sandboxing software that allows your to run a program on any platform (Windows vs Mac vs Linux), at any patch level (service pack 2 vs service pack 3), and regardless of existing software (run IE7 alongside IE8). In their own buzzwords…

Xenocode is an advanced application virtualization and streaming microkernel that emulates core OS subsystems entirely within user-mode space. Virtualized applications reside in isolated “sandboxes”, allowing software to run side-by-side without conflicts or modifications to the host device.

Our unique, patent-pending application virtualization and XStream delivery technology provide users with a highly reliable, low-latency product experience on the web, intranet, or USB storage devices.

If you squint your eyes and tilt your head, you can see some good points through that bull.

Their browser virtualizers are great for testing your site in the various flavors of Internet Exploder. Personally I think you’re okay if it looks decent in IE7 and IE8, but some are still supporting IE6, and they have a virtual install of that as well. I keep links for all 3 versions on my desktop, and find them incredibly handy.

The Failure
So with all this cool software, what’s the problem? They made them difficult to load and run from anywhere other than their site. When you click any of the run buttons, the program is downloaded to your desktop and executed, but leaves no obvious traces to rerun the program later. Interestingly, this was not the case when I originally reviewed their software. I have since updated that review with a warning, along with instructions on how you can get them to run without visiting the site (just gotta pull the downloaded executable out of their temp folder).

Obviously the intention here is to keep eyeballs on the site in hopes of creating sales conversions for their virtualization software (you can wrap your own programs). It feels like an MBA got his or her hands on the implementation reigns, and decided this was the way to drive traffic.

Obviously, I strenuously disagree. I know where I got the software, and if I ever need to virtualize a program I know exactly where to go. Forcing me to visit your site every time I want to use your extremely helpful tool only does two things: annoy me and increase the likelihood that I will jump ship to another product when it comes along (and it will). That second reason is especially nasty, because flexibility usually trumps functionality. The alternative may not even be as good as Xenocode’s software, but if they let me use it how and when I want, the difference becomes mentally negligible.

The Solution
Fortunately the fix is super-easy: just go back to what you were doing before and put the program right on the desktop. If you really want to drag your heels, present an opt-in option to make the program locally available, though that approach may only serve to further prove user opposition to you getting in the way.

Even if Xenocode doesn’t change a thing, you can still follow my instructions to achieve the same result. Here’s hoping they take the extra legwork back out of it.