PHP
小ネタ

array_rand関数の結果を日付ごとに一意に固定する

More than 3 years have passed since last update.


毎日 00:00 のタイミングで更新する

array_rand 関数は srand 関数で設定されるシードをそのまま利用しているので、ここに当該日の00:00ごとに更新される固有な値を与えれば、日付ごとに結果を固定して取得することが出来ます。また、それ以降の処理に影響を及ぼさないように、再度シードをランダムに初期化しています。


関数定義(日付形式文字列を整数変換したものを利用する場合)

function daily_array_rand(array $array, $num = 1) {

$datetime = new DateTime('now', new DateTimeZone('Asia/Tokyo'));
srand($datetime->format('Ymd'));
$retval = array_rand($array, $num);
srand();
return $retval;
}


関数定義(タイムスタンプを利用する場合)

function daily_array_rand(array $array, $num = 1) {

$datetime = new DateTime('today', new DateTimeZone('Asia/Tokyo'));
srand($datetime->getTimestamp());
$retval = array_rand($array, $num);
srand();
return $retval;
}

ここでは 0.png 1.png ... 9.png からランダムに1つ選択してみます。同日中であれば何度リロードしても同じ結果が得られるはずです。


使い方

$range = range(0, 9);

printf('<img src="%1$d.png" alt="%1$d番の画像">', $range[daily_array_rand($range)]);


更新されるタイミングを 00:00 以外の時刻に指定する

もし 00:00 以外のタイミングで更新したい場合は、以下のように関数を拡張しましょう。


関数定義(日付形式文字列を整数変換したものを利用する場合)

function daily_array_rand(array $array, $num = 1, $at = '00:00') {

$timezone = new DateTimeZone('Asia/Tokyo');
$interval = new DateInterval((new DateTime($at, $timezone))->format('\P\TH\Hi\Ms\S'));
$datetime = new DateTime('now', $timezone);
srand($datetime->sub($interval)->format('Ymd'));
$retval = array_rand($array, $num);
srand();
return $retval;
}

最初に示した例を朝7時のタイミングで更新するように変更してみます。


使い方

$range = range(0, 9);

printf('<img src="%1$d.png" alt="%1$d番の画像">', $range[daily_array_rand($range, 1, '07:00')]);