1

I'm trying to accomplish something using an associative array as suggested somewhere else here on Stackoverflow, but I've never used arrays so I'm struggling. I've looked it up but only to be left more confused than I was!

Here's the deal: I want to display a random image as the background of a Worpdress site, AND show the name of the photographer who took the image as well. So I've created a function that includes an associative array that associates the image with the photographer, and a little script to retrieve both the photo and the photographer's name. This is my function:

function bg_image_info() {

$creditsList = array(
    "1" => "Photographer 1",
    "2" => "Photographer 2",
    "3" => "Photographer 3",
    ...
    ...
    "74" => "Photographer 74"
);

$root = get_stylesheet_directory_uri();
$dir = $root . "/images/bgs/";
$random = mt_rand(1,74); 

$path = $root . "/images/bgs/bg_" . $random . ".jpg";
$credits = $creditsList["" . $random . ""];

return array($path, $credits);

}

It works pretty well, but there's one catch. I need to use the two values $path and $credits in two different places ($path as a "src" attribute, $credits in a "p" tag), so what I tried to do after some research was write these two more functions:

function bg_image_path() {
    list($bgPath, $bgCredits) = bg_image_info($path, $credits);
    echo $bgPath;
}

function bg_image_credits() {
    list($bgPath, $bgCredits) = bg_image_info($path, $credits);
    if($bgCredits) {
        echo "Photo " . $bgCredits . "";
    }
}

and then call each one where I need to value to be. But it looks like the two functions use a different $random value because the photo and the credits don't match (they do if I replace mt_rand() with a fixed value for test purposes).

So how do I echo the two values returned by the first function so that the same $random value is used?

I would really really appreciate any help, thank you!

Bankitalia
  • 21
  • 4

2 Answers2

0

Associative arrays uses named keys for values and we can create them in similar way like indexed arrays. foreach is used to loop through an associative array.

<?php
$colors = array("0"=>"Red","1"=>"Green","2"=>"Blue");
echo "0th element of array is " . $colors["0"];
echo "<br>";
//looping
foreach ($colors as $key=>$value){
    echo "Key=".$key." value=".$value;
    echo "<br>";
}
?> 

Output:

0th element of array is Red
Key=0 value=Red
Key=1 value=Green
Key=2 value=Blue
Naresh Kumar P
  • 4,127
  • 2
  • 16
  • 33
0

Of course that happens because you are calling the function twice, each time you want either the path or credits, thus generating two different random values.

I don't see the need for these two last functions (bg_image_path() and bg_image_credits()). A simple fix is to call your main function at some point in your page (before first use) and just keep those variables to use when needed.

list($bgPath, $bgCredits) = bg_image_info($path, $credits); 
# [...]
<img src="<?= $bgPath ?>" />
# [...]
<p>Credits: <?= $bgCredits ?></p>

Answering your comment, I completely understand that you want to keep it tidy and don't repeat yourself, but really, in this case you're just using a function. Nothing wrong repeating a line that calls a function in two or more places. That's how it is supposed to be used after all :)

Anyways, if you want to echo your values by means of different functions, you have to share the random number between them so you get the same thing. First way that comes to my mind is you generate the number yourself and them use two functions to echo the correct thing by passing them this number. But since you want to keep it all in function calls, I think you will prefer to do it similar to your current setup of 3 functions. What could be done is a complete rewrite to just generate the value in the main function and keep the data in the other ones:

function
bg_image_info()
{
    # note the global to avoid it being local only
    global $bg_random = mt_rand(1,74);
}

function
bg_image_path()
{
    echo get_stylesheet_directory_uri() .
            "/images/bgs/bg_$bg_random.jpg";
}

function
bg_image_credits()
{
    $creditsList = [
        'none',
        "Photographer 1",
        "Photographer 2",
        "Photographer 3",
        # ...
        "Photographer 74"
    ];

    echo $creditsList[$bg_random];
}

<?php bg_image_info(); ?>
<img src="<? bg_image_path() ?>" />
<p>Credits: <? bg_image_credits() ?></p>

Or go with an object oriented approach!

class RandomImage
{
    public $path;
    public $credits;

    public function
    __construct()
    {
        $r = mt_rand(1,74);

        $creditsList = [
            'none',
            "Photographer 1",
            "Photographer 2",
            "Photographer 3",
            # ...
            "Photographer 74"
        ];

        $path = get_stylesheet_directory_uri() .
                    "/images/bgs/bg_$r.jpg";

        $credits = $creditsList[$r];
    }
}

<?php $img = new RandomImage; ?>
<img src="<?= $img->path ?>" />
<p>Credits: <?= $img->credits ?></p>
sidyll
  • 57,726
  • 14
  • 108
  • 151
  • Hi @sidyll, thank you for your answer, I love how simple it looks! I'm a bit confused though as to where I should move the "list($bgPath, $bgCredits) = bg_image_info($path, $credits);" bit — should it go into my main function, after the return statement? Or should I create a new function? (I actually tried both right now and it's not working, not sure what I'm doing wrong...) – Bankitalia Sep 16 '16 at 13:22
  • Hi @Bankitalia No need for another function, just use it directly in your destination page (inside your first `` for example). How does your page work? Let me know if you still have any doubts I will write a full example. – sidyll Sep 16 '16 at 13:29
  • Hi @sidyll, yes, I realized that just a minute ago, and got it working on my site. Thanks! :) However I'd love to hear if you had any ideas about incorporating the list() bit in the main function or maybe create an extra function, so that I don't have to add extra code directly in the page... I use this in several different pages, so that would help keeping things tidy ;) – Bankitalia Sep 16 '16 at 13:33
  • @Bankitalia I edited with other examples. Of course they are just suggestions and can be written in many different ways. The last one specially, I'm not echoing but could do just like the functions. Anyway, I just wanted to include differences (specially in syntax!) to give you another perspective and hopefully some new tricks :D – sidyll Sep 16 '16 at 14:08
  • Hey @sidyll, thank you so much for taking the time to write those examples! The second one is a bit too advanced for me but the first one looks good. I have another challenge for you if you had more time to put into this — I have one page with a carousel where each slide should have its own random background. I just realized that using the solutions we already have, the same image would come up for each slide... How could we change the $random value for the different slides? Anyway, thank you again for your help so far! – Bankitalia Sep 16 '16 at 14:30
  • Nevermind, I got it. Just have to repeat the bit for each slide. Again, thank you for your help! – Bankitalia Sep 16 '16 at 14:48
  • @Bankitalia yes, exactly. Or call the function that sets the random again if you're using the example I gave. Happy to help, best wishes! – sidyll Sep 16 '16 at 16:05