Archive for February 2010

Hello World Nightmare

Traditionally, when someone is introduced to programming, the first block of code they write is the infamous “Hello World” program. Unless you’re dealing with some esoteric language this program usually consists of just a few or even a single line. There is one popular language out there where, in comparison, Hello World is a monster: Java. If you’re a Java coder you may not see it, especially if Java wasn’t your first language. Try to look at it from the perspective of a first timer:

public class HelloWorld {

	public static void main(String[] args)
	{
		System.out.println("Hello World");
	}
}

In addition to a huge dose of OOP some of the concepts bundled into this small block of code are: visibility and scope, arrays, return types, and data types. How do you explain static to someone who has no concept of an object? I explicitly recall, when taking my first Java course, my professor referring to static as “Voodoo Magic”. Compare this to something like C++:

int main()
{
	cout << "Hello World";
	return 0;
}

Granted the whole << thing might seem a bit strange, but overall this is much easier to explain. Don't even get me started on PHP:

echo ‘Hello World’;

Don't get me wrong. I think Java is a great language for beginners. It's balance between ease of use and structure keeps new comers from punching their monitors while at the same time adhering to a fairly strict set of rules.

RosettaCodex

As someone who is already experienced with a few programming languages, learning new languages, frameworks, and platforms is a much different process from someone who has no background in programming. Obviously having written a ton of code make learning how to write different code much easier. Much of the documentation out there however does not seem to take advantage of this fact. Documentation for someone who is completely new to programming is the same as documentation for someone with years of experience. It might be easier for the experienced programmer to understand and utilize that documentation, but it is still the same documentation.

The problem here, for an experienced programmer, is that all of this documentation exists in a bubble. It does not assume any prior experience and it does not use other languages and frameworks for reference. Clearly the reason for this is because any reference to alternative approaches would be wasted on an unexperienced coder, and might even be confusing or distracting.

My solution is to create an encyclopedia of problems with solutions in as many languages, frameworks, and platforms as possible. By now, if you’ve read the title, you know I’m calling this solution RosettaCodex. The concept is the same as the Rosetta Stone. If the same thing is written in multiple languages and you know at least one, you can figure out the meaning of the others.

RosettaCodex is a cross-language reference created specifically for those with programming experience. If you think this is a good idea feel free to contribute.

Check it out: RosettaCodex

PHP Confirmation Emails

If you are implementing your own user management system you may want to ensure that emails associated with users’ accounts are valid. The most straightforward way of doing this is to send an email to this account and verify that the user received it. Obviously we don’t want to do this manually so the solution is to write a script that automates the process.

High Level Concept
What we will need to do is:

  1. Generate a confirmation code for our users are registration time
  2. Store that code and track which users are not yet confirmed
  3. Send an email containing the confirmation code to the user
  4. Facilitate the user in using the code to activate their account

Confirmation Codes

The easiest way to generate a confirmation code is to take a piece of information about the user and hash it. What we don’t want to do however, is reveal how this hash is generated or make it easy for a user to generate this hash on their own. I find that the easiest way to approach this problem is to use the current timestamp in the hash; unless the user knew the time that their hash was generated down to the second they could not generated one on their own. Here is the code:

$hash = md5( $username . time() );

Notice that I assume you already have the username.

Storing Your Confirmation Code

In order to confirm a user, both the user and the server need to know the code. This means you’ll have to store the code once it is generated. You’ll also need to track which users are confirmed and which aren’t. Fortunately we can do both these things at once. You’ll need to either add another column to your `users` table or use another method to associate the code with the user. I’ll assume that you have a column called `status` in your `users` table.

Once you’ve generated your confirmation code store it in the database. We’ll worry about determining which users are confirmed later.

Sending the Email

Now that we have generated our code we will need to send it to the user. The easiest way for a user to confirm their account is to just click a link that has the code encoded into the url:

//the link
$link = "http://yoursite.com/confirm.php?user=$username&code=$hash";

Notice that I use the page confirm.php. We will write the script in the next step, you may call it something different if you like. Also notice that I include the username and hash in the url.

Now we need to create the rest of the email and send it. One thing you’ll want to do is keep things simple. Some email clients filter out any html so it is best to use plain text when possible.

$link = 'http://yoursite.com/confirm.php?code=' . $hash;
ob_start();
?>
Confirmation Required:
Please copy and paste the following link into your browser to confirm your account
<?php echo $link; ?>
If you did not register an account just ignore this message
<?php
$message = ob_get_clean();
$headers = 'From: you@yoursite.com' . "\r\n" .
    'Reply-To: you@yoursite.com' . "\r\n" .
    'X-Mailer: PHP/' . phpversion();

mail($userEmail, 'Confirmation Required', $message, $headers);

I used an output buffer to write the message, if you are not familiar with this approach you may want the read the output buffering section Here. Notice the $headers variable. It is important that you include the From header whenever sending email. Even though the headers parameter is optional, the from header is not. I highly recommend that you take a close look at the mail documentation.

Confirming Users

Now that the user has their confirmation url we need to write the confirm.php script I mentioned earlier. I will leave comments whenever a database transaction is needed:

$userCode = $_GET['code'];
$user = $_GET['username'];

/* get the code stored in the database
if the user does not exist, or has already been
confirmed display an error message */
$serverCode;

if($serverCode == $userCode)
{
	//change the value of the status field in the database to 'confirmed' or something else if you prefer
}
else
{
	//Invalid code. Display an error message
}

In short, all we need to do is compare the user’s code with the one stored in the database. If the match change the value of the user’s status field in the database to some value that will indicated the user is confirmed. Anytime you need to check if a user is confirmed just use that field.

Additional Concerns

There are some additional concerns that I did not address that you may want to.

A user may need to have their confirmation email resent. This is just a matter of pulling the confirmation code out of the database and sending it again.

Some users or bots may register accounts that they never confirm. You may want to setup a crontab or some other means of periodically clearing out these accounts (ie if an account hasn’t been confirmed after a week, delete it).

Protect yourself from SQL Injections whenever sending user data to the database!!!