Your approach is fairly common, since array_rand only returns an array of randomized keys of the supplied array, or returns a single random key from the array when supplying 1 as the amount, you will be forced to use a for loop to retrieve the desired amount, and leads to reduced performance when a very large amount is requested.
An alternative to array_rand is using shuffle. To resolve a desired amount larger than the source array, use array_merge to fill the array until the desired amount is reached. Then use array_slice to reduce the shuffled array to exactly the desired amount.
Example: https://3v4l.org/LDSj4
//create an array of 8 values - for this example
$a = range('A', 'H');
//specify a larger amount of values to retrieve
$amount = 20;
//this only occurs when the array is smaller than the amount
while (count($a) < $amount) {
//fill the array exponentially with the same values until amount is reached
$a = array_merge($a, $a);
}
//randomize the array order
shuffle($a);
//reduce the array to the desired amount
$a = array_slice($a, 0, $amount);
var_dump($a);
Example Results (results vary as seen in the example link);
array(20) {
[0]=>
string(1) "F"
[1]=>
string(1) "B"
[2]=>
string(1) "E"
[3]=>
string(1) "B"
[4]=>
string(1) "H"
[5]=>
string(1) "A"
[6]=>
string(1) "C"
[7]=>
string(1) "C"
[8]=>
string(1) "C"
[9]=>
string(1) "G"
[10]=>
string(1) "G"
[11]=>
string(1) "H"
[12]=>
string(1) "D"
[13]=>
string(1) "F"
[14]=>
string(1) "A"
[15]=>
string(1) "G"
[16]=>
string(1) "E"
[17]=>
string(1) "C"
[18]=>
string(1) "E"
[19]=>
string(1) "D"
}