Just thought I would throw in my opinion regarding salt as well.
I do disagree with some of kromey's comments.
You add a salt to make the hash difficult to brute force, and that does not only include rainbow tables.
As other has mentioned storing the salt together with the hash will make it much easier for the attacker to brute force it, compared to if he only had the hash.
It is also wrong to assume that if the attacker gain access to the user table he will have access to the rest of the database as well. A properly constructed script will use database users with specific access, just to make sure that if one db user is breached, they will only have limit access. The database user who operate the login page, should only have read access to the tables needed etc.
If the hacker "breach" the server, then you have already lost. And there would be no need for him to break your hashes, all he need to do is listen as your users log in. Which leaves server security your top priority.
In my opinion the salt should help prevent any case of offsite brute force attemts (Of course you need to have onsite protection against brute force attempts as well). Either by the use of a global salt, or better by a algorythm creating the salt out of the unique information from each user as well as shifting the location of the salt/password based on the same algorythm.
Also to make the hash almost impossible to break, use chr to include uncommon characters into the hash. Most "brute force" software can not handle uncommon characters. http://no2.php.net/chr
Note: Using a "unique" salt which is stored in the database per user will give you a worse security than using a global stored salt. Due to it will be difficult for the hacker to get access to the global salt without taking over the server.
And even if the hacker get ahold of the salt, it would give exact the same protection as the "unique" salt.
In regards to what hash function you use, there is not really a major difference as long as your salt process is good.
I would personally not suggest using anything over sha1 due to the time the function require to run. Even a md5 hash is still secure as long as you use a good salt and a proper login functionality.
People seem to believe that md5 is weak due to the collision possibilities, while in reality that is not true. What will it help me to find a collision? I will not be able to use it at all! The collision value will with the salt added create a different hash, i.e. I got nowhere. And consider that I need to figure out what the salt is I will need to try every possibility of the "collisions" as well (i.e. keep trying to login while removing characters) it will be a extreamly time consuming process. Please note that if the attacker knows the salt then a collision will allow him to login (another reason why you should not store the salt easily located in the database).
In regards of hashing the value several times, I would not recommend it as it does not add any added value. You just increase the processing power your script require to run. A proper brute force software will already rehash the results several times to check if the "script" does it.