Как сделать рандом из массива с указанной вероятностью для элементов?
Сложить все веса. Их сумма это 100%, «единица».
Взять случайное число от 0 до 1.
Спроецировать на ваш диапазон, посмотреть, куда попали.$sum = array_sum($a);
$rnd = rand() / getrandmax(); // от 0 до 1
$runningSum = 0;
foreach($a as $k => $v) {
  $runningSum += $v / $sum;
  if ($runningSum >= $rnd) {
    $key = $k;
    break;
  }
}
if (!$key) $key = $k;

echo "Выпало: " . $key . PHP_EOL;
Приводим коэффициенты к целым числам пропорционально так, чтобы минимальный коэффициент равнялся единице, остальные округляем до единиц. Таким образом получаем на выходе массив с целыми числами, где отношения в пропорции элементов друг к другу будут близкими к изначальным. Далее на основе этого промежуточного массива генерируем новый, с диапазонами, для первого элемента от 0 до его значения, для каждого последующего от суммы всех предыдущих значений до сумма + текущее значение. Таким образом весь массив диапазонами покрывает значения от 0 до суммы всех величин из первого промежуточного массива, которую обозначим как S. Далее используем только второй массив с диапазонами, для каждого элемента выборки генерим рандомное число R от 0 до S, и находим ключ согласно тому диапазону, куда в каждой итерации попадает R.
По идее данный алгоритм идентичен варианту Дмитрия, но эффективен по части использования памяти. Опять же, его тоже можно оптимизировать. :)
ЗЫ: Те же яйца, но в профиль предложил Сергей Соколов