生成唯一盐(给出未经验证的示例)

I am redesigning my application where I need to have an unique salt.

I provide the way it is and I look forward to hear if this does not work the correct way or other ways I can improve it.

public function generatesalt($x=0)
{
    $x++;

    $string = md5(uniqid(rand(), true));
    $salt = substr($string, 0, 12);

    $stored = array();
    $qw = $this->registry->dbi->query("SELECT `salt` FROM `".PRE."membership`")->results();
    foreach ($qw as $k => $v)
        $stored[] = $v['salt'];


    if (in_array($salt,$stored))
        return $this->generatesalt($x);

    return $salt." /// ".$x;
}   

Thanks. Again, my question is if this looks to work the correct way and you can't see serious disadvantages.

Doesn't storing salts in a database that also contains the password hashes defeat the purpose of having an unknown string added to your pre-hashed string?

If a hacker gets database access, and only database access, they'll have the salts and hashes. If you have a static salt declared in a PHP define, they'll need server access as well as database access to get the same information.

Also relevant, you should remove the Output privilege from your SQL user if possible, so that a hacker can't put shells on your server with just database access and get your PHP-defined salt.

Well, theoretically, salts only need to be unique in the sense that no other password should be hashed using that salt. The idea is to make it infeasible for bad guys to crack the hashes. If you use a salt, and you hash the password correctly (i.e. using something like bcrypt, scrypt, pbkdf2, etc.), then it will take a long time to crack just a handful of passwords -- let alone an entire database.

In practice randomly generated salts that are sufficiently long are not likely to occur more than once, so they should be more than fine.

In PHP a simple way of generating salts is to use mcrypt_create_iv(). It generates random bits from the system, which can be encoded for easier storage:

function randomSalt($length = 16) {
    $bits = mcrypt_create_iv($length);
    $encoded = base64_encode($bits);
    return substr($encoded, 0, $length);
}
echo randomSalt(); // Something like: "Yt5iX/LvdxOyxCiX"

Finally, salts do not have to be a secret. That is not why salts are used. Imagine you want to walk over to the corner shop. It takes 5 minutes. Now, imagine that you are forced to take a 24-hour detour. That is the salt. It is a huge road-bump that bad guys need to get over every time they crack a new hashed password. (Note: the 24 hours are just an example -- how long it takes depends on a few things, but you get the idea.)