PHPで配列の要素をランダムに取得する方法|array_rand・shuffle・mt_randの使い分け

PHPで配列からランダムに要素を選ぶ方法はいくつかあります。「1つだけ選ぶ」「複数選ぶ」「配列ごとシャッフルする」で適した関数が変わり、元の配列を変えてしまうかどうかも重要なポイントです。この記事では代表的な方法と、その違い・注意点を解説します。

この記事の結論:1つ選ぶなら array_rand()(キーを返す。元配列はそのまま)。配列ごと並べ替えるなら shuffle()元配列を変更する点に注意)。パスワードやトークンなどセキュリティ用途には random_int() を使います。
スポンサーリンク

array_rand()で1つ(または複数)選ぶ

array_rand() はランダムなキーを返します。元の配列は変更されないため、もっとも扱いやすい方法です。連想配列でもそのまま使えます。

array_randで1つ選ぶ
<?php
$fruits = ["Apple", "Banana", "Cherry", "Date", "Elderberry"];

$key = array_rand($fruits); // ランダムなキー
echo $fruits[$key];         // そのキーの値

第2引数に個数を渡すと、複数のキーを配列で取得できます。(同じ要素は重複しません)。

array_randで複数選ぶ
<?php
$fruits = ["Apple", "Banana", "Cherry", "Date", "Elderberry"];

$keys = array_rand($fruits, 2); // キーが2つの配列
foreach ($keys as $k) {
    echo $fruits[$k] . "\n";
}

shuffle()で配列ごとシャッフルする

shuffle() は配列の要素をランダムに並べ替えます。並べ替えた先頭を取ればランダムな1件になります。

shuffleで並べ替え
<?php
$fruits = ["Apple", "Banana", "Cherry", "Date", "Elderberry"];

shuffle($fruits);   // 元の配列の並び順が変わる
echo $fruits[0];    // ランダムな1件
shuffle() は元の配列を直接書き換えます(破壊的)。「元の順序を保ったままランダムに1つ取りたい」だけなら shuffle() は不向きで、array_rand() を使ってください。また shuffle() はキーを振り直すため、連想配列のキーは失われます

mt_rand()でインデックスを指定する

mt_rand()0〜要素数-1 の乱数を作り、そのインデックスの要素を取る方法もあります。ただしこれはキーが 0,1,2… の連番配列でしか正しく動きません

mt_randでインデックス指定(連番配列限定)
<?php
$fruits = ["Apple", "Banana", "Cherry", "Date", "Elderberry"];

$index = mt_rand(0, count($fruits) - 1);
echo $fruits[$index];
連想配列やキーが飛んでいる配列でこの方法を使うなら、先に array_values() でキーを0からの連番に振り直してください。そのまま $arr[$index] とすると存在しないキーを参照してしまいます。要素数の取得は配列の要素数をカウントする方法を参照。

セキュリティ用途はrandom_intを使う

mt_rand()array_rand()暗号学的に安全ではありません。くじ・抽選・パスワード・トークンなど予測されては困る用途では、random_int()(PHP 7.0+)を使います。

random_intで安全に選ぶ
<?php
$items = ["A", "B", "C", "D"];

$index = random_int(0, count($items) - 1);
echo $items[$index];

方法の使い分け

方法 用途 元配列
array_rand() 1つ/複数のキーを取得 変更しない
shuffle() 配列ごと並べ替え 変更する
mt_rand() 連番配列のインデックス指定 変更しない
random_int() セキュリティ用途 変更しない

よくある質問(FAQ)

Q元の配列を変えずにランダムな1件がほしいです。
Aarray_rand() を使います。ランダムなキーを返すだけで元の配列は変更されません。shuffle() は元配列を並べ替えてしまうので、この用途には不向きです。
Qshuffleを使ったら配列の順番が変わってしまいました。
Ashuffle()元の配列を直接並べ替える関数だからです(仕様)。順序を保ちたいなら、コピーをシャッフルするか、array_rand() を使ってください。
Q連想配列でmt_randを使うとうまくいきません。
Amt_rand(0, count-1)0始まりの連番キーが前提だからです。連想配列では、先に array_values() でキーを振り直すか、array_rand()(キーをそのまま扱える)を使ってください。
Q抽選やトークン生成にmt_randを使ってよいですか?
Aおすすめしません。mt_rand()array_rand()予測される可能性があり、暗号学的に安全ではありません。セキュリティが関わる用途では random_int() を使ってください。

まとめ

PHPで配列からランダムに取得する方法を整理します。

  • 1つ/複数選ぶなら array_rand()(元配列はそのまま)
  • shuffle() は元配列を破壊的に並べ替える(キーも失われる)
  • mt_rand() のインデックス指定は連番配列限定
  • セキュリティ用途は random_int()
  • 連想配列でインデックス方式を使うなら array_values() で振り直す

関連として、array_valuesでキーを振り直す方法配列の最初と最後の要素を取得する方法配列の要素数をカウントする方法もあわせて読むと、PHPの配列操作に強くなれます。