I have a set of 4 HTML list items and I'd like to shuffle the order they appear in once a week. I have found the following which could be used - but at the moment, it only returns one list item - how could I modify it to show the four required?

Any ideas would be gratefully received :)

function RandomList($TimeBase, $QuotesArray){

    $TimeBase = intval($TimeBase);

    $ItemCount = count($QuotesArray);

    $RandomIndexPos = ($TimeBase % $ItemCount);

    return $QuotesArray[$RandomIndexPos];

}

$WeekOfTheYear = date('W'); 

$RandomItems = array(
    "<li><a href=\"#northern-germany\" title=\"Northern Germany\">North</a></li>","<li><a href=\"#southern-germany\" title=\"Southern Germany\">South</a></li>","<li><a href=\"#western-germany\" title=\"Western Germany\">West</a></li>","<li><a href=\"#eastern-germany\" title=\"Eastern Germany\">East</a></li>");

print RandomList($WeekOfTheYear, $RandomItems);

Dani AI

Generated

wanted a stable, once-a-week shuffle of four list items. is on the right track: randomizing on each request is trivial, but preserving a single order for the whole week requires persistence or a deterministic procedure. The file-based example from will work, but it needs locking/cleanup and feels heavyweight for a small, predictable list.

A simpler, stateless approach is to derive a week-specific seed (include the ISO week-based year so the seed does not collide at year boundaries) and produce a deterministic permutation from that seed. This avoids writing files or changing global RNG state. One safe technique is to compute a short hash per item (using the seed plus the item index) and sort by that hash; the same seed yields the same ordering for the whole week.

Example (illustrative):

$items = [ /* your 4 li strings */ ];
$seed  = date('oW'); // ISO week-year + week number
$keys  = array_map(function($i) use ($seed) {
    return hash('sha256', $seed . '|' . $i);
}, array_keys($items));
array_multisort($keys, SORT_STRING, $items);
// $items is now in the deterministic weekly order
echo implode("\n", $items);

Notes and cautions: use date('o') (ISO year) with the week number to avoid negative/duplicate weeks around January; be explicit about server timezone if consistency matters. Avoid globally seeding the RNG (srand/mt_srand) in shared code. If you prefer persistence, use a cache (APCu/Redis) or DB rather than raw files, and always use file locking (flock) when writing. See the PHP docs for date() and hash() for details: date() and hash().

Recommended Answers

All 2 Replies

You need a foreach loop, and the code can be more simple:

$RandomItems = array(
    "<li><a href=\"#northern-germany\" title=\"Northern Germany\">North</a></li>","<li><a href=\"#southern-germany\" title=\"Southern Germany\">South</a></li>","<li><a href=\"#western-germany\" title=\"Western Germany\">West</a></li>","<li><a href=\"#eastern-germany\" title=\"Eastern Germany\">East</a></li>");

shuffle($RandomItems);
foreach($RandomItems as $r)
{
    echo $r;
}

But you still need to save the new order for a week otherwise at next refresh the order will change, you can save it into a database or into a file, here's an example with a file, after the file is generated the script, simply includes it into the page:

<?php

$week = date('W');
$file = $week.'.txt';

$previous = date('W')-1;
$oldfile = $previous.'.txt';

$rand = array(
	array('#northern-germany','Northern Germany','North'),
	array('#southern-germany','Southern Germany','South'),
	array('#western-germany','Western Germany','West'),
	array('#eastern-germany','Eastern Germany','East')
);

function RandomList($el)
{
	shuffle($el);
	$list = '';
	foreach($el as $key => $value)
	{
	    $list .= '<li><a href="'.$value[0].'" title="'.$value[1].'">'.$value[2].'</a></li>' . "\n";
	}
	return $list;
}


if(file_exists($file))
{
	if(file_exists($oldfile))
	{
		unlink($oldfile); # delete old file
	}

	include($file); # display new order for a week

}

# create file and save new order
else
{
	$myFile = $file;
	$fh = fopen($myFile, 'w') or die("can't open file");
	$stringData = RandomList($rand);
	fwrite($fh, $stringData);
	fclose($fh);
}


?>

bye :)

Or, just add this to your script:

print RandomList($WeekOfTheYear, $RandomItems);
print RandomList($WeekOfTheYear-1, $RandomItems);
print RandomList($WeekOfTheYear-2, $RandomItems);
print RandomList($WeekOfTheYear-3, $RandomItems);

You will have the same result without saving files. But this should be run directly on 3 different date('W') or you could get 0 or negatives numbers on January:

print RandomList($WeekOfTheYear, $RandomItems);
print RandomList(date('W')-1, $RandomItems);
print RandomList(date('W')-2, $RandomItems);
print RandomList(date('W')-3, $RandomItems);

Bye :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.