1

I made this piece of code, and it echo's out 5 random rows of data from the array every time you run it.

What I really want it to be is that it takes 5 random values of the array and echo out the same values for 5 minutes before it randomizes again.

I know it's possible with MySQL by just storing the information there, but I would prefer a maybe easier / simpler way. If it would be possible with PHP only, that'd be great.

$random = $id; // make a copy of the multi-dimensional array

for($i = 0; $i < 5; $i++) {
    shuffle($random); // randomize order
    $results = array_pop($random); // return last value and remove from array

    echo $result[0][0], " ", $result[0][1], "<br>\n";
}

Anybody who has an idea or suggestions?

Kid Diamond
  • 2,232
  • 8
  • 37
  • 79

5 Answers5

3

Here's an implementation using mt_srand(), mt_rand() and array_multisort(). With array_multisort() you can sort an array against another array's values.

Using a seed that changes every 5 minutes you can use mt_rand() to create an 'order' array that stays the same for a specified time, with which you can sort your target values consistently until the 'order' array changes

The current implementation of the seed time is based on minutes alone, you might want to increase the randomness of this based on hour/date etc.

// mocking an array of ids
$ids = range(0, 5);

// create and assign a 'seed' value that changes 
// every $duration and assign to mt_srand
// credited: http://stackoverflow.com/a/2480681/312962
$duration = 5;
$mins = date('i', strtotime('now'));
$seed = $mins - ($mins % $duration);

mt_srand($seed);

// use mt_rand to build an 'order by'
// array that will change every $duration
$orderBy = array_map(function() {
    return mt_rand();
}, range(1, count($ids)));

// sort $ids against $orderBy
array_multisort($orderBy, $ids);

// This will yield
var_dump($ids);

This might yield something like the following, the order of which should only change when the value passed to mt_srand() changes.

array (size=6)
  0 => int 4
  1 => int 1
  2 => int 0
  3 => int 3
  4 => int 2
  5 => int 5

Hope this helps :)

Darragh Enright
  • 13,676
  • 7
  • 41
  • 48
  • 1
    I like your answer. However, one issue with your code is, despite having the duration set to 5, it still updates every 1 minute. Can you fix that? – Kid Diamond Mar 08 '14 at 12:48
  • Silly me! In my haste I make a mistake - I wasn't seeding `mt_srand()` with the correct value. Updated, sorry about that. – Darragh Enright Mar 08 '14 at 13:32
0

You could use a cache (with Pear::Cache_Lite):

<?php
require_once('Cache/Lite.php');
define("YOUR_ID", "Something identifying the cache");

$options = array(
    'cacheDir' => '/tmp/',
    'lifeTime' => 5 * 60 // 5 min
);

$cache = new Cache_Lite($options);

if ($data = $cache->get(YOUR_ID)) {
    echo $data
} else {
    $random = $id; // make a copy of the multi-dimensional array
    $data = "";
    for($i = 0; $i < 5; $i++) {
        shuffle($random); // randomize order
        $results = array_pop($random); // return last value and remove from array

        $data .= $result[0][0], " ", $result[0][1], "<br>\n";
    }
    echo $data;
    $cache->save($data, YOUR_ID);
}

(not tested)

0

You could drop your present code into another loop and use the php sleep() function to make the script pause for five minutes.

$random = $id; // make a copy of the multi-dimensional array

$number_of_times_to_run_code = 10;

for($a = 0; $a < $number_of_times_to_run_code; $a++) {


   for($i = 0; $i < 5; $i++) {
   shuffle($random); // randomize order
   $results = array_pop($random); // return last value and remove from array

   echo $result[0][0], " ", $result[0][1], "<br>\n";
   }

// sleep five minutes (240 seconds)
sleep(240);

}

if you don't want it to stop you can use a while loop instead of a for loop.

RoJG
  • 49
  • 3
0

Instead of using a datastore you could use a file-based cache. This checks when the file was last modified and if it was greater than 5 minutes ago, it randomizes it.

if( ! file_exists("array.txt")) {
    touch("array.txt");

    $array = [];

    // generate some random data for the array
    for($i = 0; $i != 10; $i++) {
        for($n = 0; $n != 10; $n++) {
            for($m = 0; $m != 10; $m++) {
                $array[$i][$n][$m] = mt_rand();
            }
        }
    }

    file_put_contents("array.txt", serialize($array));
}

// checks when the file was last modified
if(filemtime("array.txt") <= strtotime('5 minutes ago')) {
    $array = unserialize(file_get_contents("array.txt"));
    shuffle($array);
    file_put_contents("array.txt", serialize($array));
}

$array = unserialize(file_get_contents("array.txt"));

for($i = 0; $i < 5; $i++) {
    $result = array_pop($array);
    echo "{$result[0][0]} {$result[0][1]}<br>\n";
}
Jordan Doyle
  • 2,976
  • 4
  • 22
  • 38
0

Another way is to store the time the script ran last in a SESSION variable. Then work out the elapsed time. I provide some sample test code. The purpose is that the script always runs. You just decide what to do on each run. It doesn't run every 5 minutes but that is not important in this case. You just what someone to see it randomised if they visit every few minutes.

session_start();

$timeLastRandom = 0; // if no session variable yet.
$timeNow = time();

if (isset($_SESSION['random_last_run'])) {
  $timeLastRandom = $_SESSION['random_last_run'];
}

// check that the interval has elapsed...
if ($timeNow - $timeLastRandom > (5 * 60)) { // run the new code

  $_SESSION['random_last_run'] = $timeNow; // record time last ran...
  echo 'Time elaspsed -- run your code...' . ($timeNow - $timeLastRandom);
}
else {

  echo 'Time elaspsed -- run your old code...' . ($timeNow - $timeLastRandom);
}
Ryan Vincent
  • 4,483
  • 7
  • 22
  • 31