Any PHP experts here?

I want to make the home page mf my website a little more interesting by displaying links and thumbnails for five random articles, instead of five that I have hardcoded in the page.

I found an excellent little PHP script that reads any specified number of random lines from a text file - lines which can be whole chunks of X/HTML code - so far so good.

Trouble is, there’s no safeguard against it picking the same line twice - which looks really dumb on the page.

So I know what I want - I need to modify the script so that it keeps track of the lines (or their index numbers) it has already picked and if the random function happens to point at one of those again, it retries until it gets a fresh one.

(obviously the potential pitfall there is that if I ask for 5 unique lines and the file only contains 4, it will run forever trying to find a fifth unique record, but I can simply avoid letting that happen)

I just don’t know quite enough PHP to be able to make the mod myself.

Here’s the code as it stands:


 <?php
// Function to display random ads from a list 
function showRandomAD($ADnumber = 1){
    // Loading the ad list into an array
    $adList = file('includes/adlist.txt');
    
    // Check the total number of ads
    $numberOfADs = sizeof($adList);
   
    // Initialize the random generator
    list($usec, $sec) = explode(' ', microtime());
    srand((float) $sec + ((float) $usec * 100000));
   
    // Initialize the ads counter
    $adCount = 0;
    
    // Loop to display the requested number of ads
    while ($adCount++ < $ADnumber) {
        // Generate random ad id
        $actAD = rand(0, $numberOfADs-1);
        // Display the above generated ad from the array
        echo $adList[$actAD].'<br/>';
    }
}
?> 

Are there any kindly PHP experts here who might be able to help (that is, help with this specific problem, and in so doing, help me learn a bit more).

You can use a hash table to keep track of items you’ve seen already, so you don’t show them twice. Here’s a simple example (untested):



 <?php
// Function to display random ads from a list 
function showRandomAD($ADnumber = 1){
    // Loading the ad list into an array
    $adList = file('includes/adlist.txt');
    
    // Check the total number of ads
    $numberOfADs = sizeof($adList);
   
    // Initialize the random generator
    list($usec, $sec) = explode(' ', microtime());
    srand((float) $sec + ((float) $usec * 100000));
   
    // Initialize the ads counter
    $adCount = 0;
    
    // Initialize table to keep track of dupes
    $seen = array( );

    // Loop to display the requested number of ads
    while ($adCount < $ADnumber) {
        // Generate random ad id
        $actAD = rand(0, $numberOfADs-1);
        if( $seen[$actAd] ) { 
            continue;
        } else { 
            // Display the above generated ad from the array
            echo $adList[$actAD].'<br/>';
            $seen[$actAd] = 1;
            $adCount++;
         }
    }
}
?> 


This uses the array $seen as a hash table. When you echo a particular item, it gets set as a key in $seen with a value of 1 and $adCount is incremented. The next time through the loop, if the random function picks one we’ve already seen, it executes the continue statement which goes back to the beginning of the loop and $adCount is not incremented.

Thanks for that, but I can’t get it to work.

There’s a ten second delay or so, then a 500 Internal Server Error - it looks like it might never be breaking out of the loop (but I don’t know enough to work out why).

The line it’s choking on is:

$seen[$actAd] = 1;

  • If I comment out that line, it runs (although of course it produces duplicates, because that’s the line that would be assigning the value in the hash table).

Variable names are case sensitive.
$actAd is not the same as $actAD.

Make them the same case.
i.e. make $actAd the same case as $actAD

:smack: How many times did I look for that?

Thanks.

Yay! It works - now in operation in the main column of my home page.

I had been worrying that it was looking a bit stagnant, but this works quite well, I think.