随机字符串生成器返回相同的值

$list_ar = array();
for($x = 0;$x < 500; $x++){
    $val = generateRandomString(20);
    if(!in_array($val,$list_ar)){
        echo $x.'=='.$val.'<br>';
        array_push($list_ar,$val);
    } else {
        echo $x.'== IN ARRAY<br>';
    }
}

function generateRandomString($length){
    $characterlist = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789';
    $characterlist_array = str_split($characterlist);
    $id = '';
    for($a = 0;$a<$length;$a++){
        shuffle($characterlist_array);
        $position = array_rand($characterlist_array, 1);
        $id .= $characterlist_array[$position];
    }
    return $id; 
}

When I run the code above it gives in array false up to 360 lines after that it returns in array true. I'm expecting it to return in array false up to 500 lines I've been running the code more than 20 times and it gives the same result of exactly 360 lines in array false. Any ideas?

Based on what Marc said what happens if you change your function to:

function generateRandomString($length){
    $characterlist = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789';
    $characterlist_count = strlen($characterlist)-1;

    $id = '';
    for($a = 0;$a<$length;$a++){
        $id .= $characterlist[rand(0,$characterlist_count)];
    }
    return $id; 
}

Does it still fail?

Since we are answering with alternatives:

function generateRandomString($length) {
    $characterlist = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789';
    $characterlist_array = str_split($characterlist);
    shuffle($characterlist_array);

    return implode(array_slice($characterlist_array, 0, $length));
}