<?php

/**
 * Input can be specified as basic array or array of arrays:
 * - array = [key1 => weight1, key2 => weight2, ...]
 * - array = [[..., weightKey => weight], [..., weightKey2 => weight2], ...]
 *
 * @param array         $array Array to shuffle
 * @param string|null   $weight_key Optional weight key if input is array of arrays 
 */
function weighted_shuffle(array &$array, $weight_key = null)
{
    if($weight_key === null) {
        $arr = $array;
    } else {
        $arr = array_combine(array_keys($array), array_column($array, $weight_key));
    }
    $max = 1.0 / getrandmax();
    array_walk($arr, function (&$v, $k) use($max) {
        $v = pow(rand()*$max, 1.0/$v);
    });
    arsort($arr);
    array_walk($arr, function (&$v, $k) use($array) {
       $v = $array[$k];
    });
    $array = $arr;
}