[Solved] Array object starting at second row problem

Hi all

When I print my results the first item is skipped besides the venue names, everything else starts from the second item.

Example:

Venue 1 has no photo or url
Venue 2 has Venue 1’s photo and url
Venue 3 has Venue 2’s photo and url

$result = $mysqli->query($query);

$categoryArray = array();
while ($item = mysqli_fetch_object($result)) {
  $categoryArray[$item->venue][] = $item;
}

And on the page further down:

foreach ($categoryArray as $venue => $items) { 
  $photo = $item->photo;
  $url = str_replace(" ", "-", (strtolower($item->venue)));
  
    print "<li><a href='{$url}'>";
    print "<img src='{$photo}'>";
    print "<span>{$venue}</span>";

    print "<div>";

          foreach ($items as $item) { 
            $cat = $item->category;
            print "<span>{$cat}</span>";
          }
    print "</div></a>";
    print "</li>";
}

Can anybody spot what I’m doing wrong, something to do with the for each order?

If it helps, after a var_dump($categoryArray) each venue looks like the below with the amount of objects varying depending on how many categories associated with each venue:

{ 
["venue one"]=> array(3) { 
  [0]=> object(stdClass)#39 (3) { 
    ["venue"]=> string(12) "venue one" 
    ["photo"]=> string(20) "venue_one.gif" 
    ["category"]=> string(10) "category one" 
  } 
  [1]=> object(stdClass)#40 (3) { 
    ["venue"]=> string(12) "venue one" 
    ["photo"]=> string(20) "venue_one.gif" 
    ["category"]=> string(7) "category two" 
  } 
  [2]=> object(stdClass)#41 (3) { 
    ["venue"]=> string(12) "venue one" 
    ["photo"]=> string(20) "venue_one.gif" 
    ["category"]=> string(13) "category three" 
  } 
}

Thanks,
Barry

Is this the problem?

foreach ($categoryArray as $venue => $items) { 
  $photo = $item->photo;

On your second line, you reference $item, but the loop doesn’t create a variable called $item. There is a variable of that name in your earlier code where you retrieve the query results:

while ($item = mysqli_fetch_object($result)) {

but that will be blank in the first iteration of your loop because the end of the results were reached.

Thats the thing, the photos show, likewise for the urls attached to the venues, it’s just that they are not calculating correctly, skipping/jumping one resulting in the wrong photos and urls.

The venue names are all in order, as are the categories - it’s the photo and url that are misplaced.

I realised this and tried adding the the photo and url variables into the second foreach, though everything repeats multiple photos and positioned in the wrong place.

Just can’t figure out what I’m doing wrong?

The query itself is based on a three table join, hence the json above I’m pulling the single venue name and looping over the categories below the name.

Example:

Venue 1
Photo
Cat1, Cat 2, Cat 3

Any further ideas?

To recap, the venue name and categories display ok and in order - Its photo and url that are not working correctly.

Thanks, Barry

Ah, I see what you’re doing, I hadn’t read it correctly at the start. At the point where you assign values to the photo and url, I don’t think $item will have a value.

While I’m sure there are better ways, could you do something like:

foreach ($categoryArray as $venue => $items) { 
  $first = true;
  foreach ($items as $item) { 
    if ($first) { 
      $photo = $item->photo;
      $url = str_replace(" ", "-", (strtolower($item->venue)));
  
      print "<li><a href='{$url}'>";
      print "<img src='{$photo}'>";
      print "<span>{$venue}</span>";

      print "<div>";
          $first = false;
          }
      $cat = $item->category;
      print "<span>{$cat}</span>";
      }
 print "</div></a>";
 print "</li>";
}

So you iterate each category for each venue, but only output the venue details the first time through the loop.

Maybe this was the problem, though again, the photos and url where showing, just not syncing up.

I was under the impression that
while ($item = mysqli_fetch_object($result))
is where
$photo = $item->photo;
retrieved the values

Will have to track back on things if I need to use this snippet again.


Moving forward, what you have suggested works great droopsnoot :smiley:

I’ve just changed things with your updated code, working good! I see what you’ve do.

I think this is a little easier now as all the venue details are in one place, I’ll be including more rows of data for each venue further down the line, address and so on.

So you iterate each category for each venue, but only output the venue details the first time through the loop.

The is exactly what I was trying to do in the first place ha. It’s only the categories we need to iterate at this point :sunglasses:

Cool, and thanks for the examples.

Barry

It was, but you showed that you’d closed the while loop that retrieves the results into $item before you got to the foreach() loop to display the information. Hence, the only thing in $item is either the last result from the query, or maybe nothing at all, I can’t remember quite how that bit works. It would work if you were displaying it as part of the same loop that retrieves the results.

Glad it’s working now.

Yes that explains why in one instance the last venue and photo was repeating for every item. Nice to know, might try and keep the while open as a test case see what results I can get.

Thanks again!

Barry

Well, if the only thing you’re doing is displaying the items as in your later loop, there’s no reason to build an array in one loop then iterate through it in a separate loop, unless you’re doing something with the array contents between reading them and displaying them. You could just as easily loop through the results, check to see in the venue changed (to display that information only the first time it changes) and display the rest each time.

I did sometime back, though forgotten what I used it for - which resulted in me building lots of queries this way, ever since :upside_down:

I’m already running into issues trying to add single value variables at the same level as the $cat, repeating over and over.

Sounds good, how would we code this?

Little example to get started :sunglasses:

Barry

pseudo-code

$lastvenue = ""
while ($result = whatever) {
  if $result['venue'] != $lastvenue {
    // display venue details
    }
  // display other details
  $lastvenue = $result['venue']
  }
1 Like

Right on!

Thanks droopsnoot give some ideas, do some testing.

Barry

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.