Is this code protected against SQL injection attacks?
Looks O.K. to me as well, as far as the SQL injection goes.

However, I'd suggest checking the return value of $sth-&gt;execute();, so you capture possible errors (i.e., DB being down).

You might also consider doing a case insensitive search for the existing usernames and e-mails, since "person@gmail.com" is the same address as "Person@GMail.com" and users "Person" and "person" are hard to distinguish.

I think empty($string) is more advisable than strlen($string) == 0.

Last, but not least, adding a "retype your password" field would be a good security against user mistyping what he wants for a password and then ending with a useless account (or having to use "I forgot my password" before the very first login).