Jump to content

foreach loop overwriting all values with last key value


Go to solution Solved by AdRock,

Recommended Posts

I have got an array from a database and I want to change some of the values like using ucwords() etc.

 

The problem is when i run the array through a foreach loop, it overwrites all the values in the array with the values of the last row in the array.

 

I've been racking my brains all afternoon and can't figure out what's going wrong.

foreach($rows as $key => $row) {

    //$rows['datetime'] = Forum::change_date(strtotime($row['postdate']));
    $rows[$key]['board'] = strtolower(str_replace(array(' ','\''), array('-',''),$row['boardname']));
    $rows[$key]['boardid'] = $row['boardno'];
    $rows[$key]['boardname'] = ucwords($row['boardname']);
    $rows[$key]['topicname'] = Words::shortenText($row['topicname'],30);
}

I end up with the 6 rows in the array all the same.

 

Any ideas what I'm doing wrong?

Edited by AdRock

Don't try and modify the $rows array directly in the loop.  Reference $row.  Try this:

foreach($rows as &$row) {
    $row['board'] = strtolower(str_replace(array(' ','\''), array('-',''),$row['boardname']));
    $row['boardid'] = $row['boardno'];
    $row['boardname'] = ucwords($row['boardname']);
    $row['topicname'] = Words::shortenText($row['topicname'],30);
}
I end up with the 6 rows in the array all the same.

 

 

how do you know that? perhaps your code putting the original data into the array is putting in all the same data (or retrieving all the same data in the query statement) or your code displaying the results after the code you posted above is displaying all the same result but the data in the array is correct.

 

also, why not do the processing you show above when you put the original data into the array. your current scheme has you looping over the data three times.

And, I agree with mac_gyver.  Do this formatting either when you loop to get results from the DB or better when you display them.  Maybe put it in a function that is called in the display loop.

I just looked and the array is the PDP query.  With teh old mysql_query() way I would just do a while loop and do all the processing in there but while loops don't work with PDO so i need a foreach loop

PDO works fine with while loop look at example #2 on PDO fetch method. What is your implementation of PDO?

Edited by Ch0cu3r

you can directly iterate over the PDOStatement instance, format, and display your data, using just one foreach() loop.

 

if you are getting 6 same rows, it's likely your query is returning 6 same rows. what is your code, from your query statement through to the point where you are displaying and seeing the 6 same rows?

 

the snippet of code you posted isn't where the problem lies.

This is the code all in the same place where i execute my query and do the foreach()

$sql = "SELECT  b.boardid as boardno, b.*, t.topicname, m.*,
        (SELECT  COUNT(*) FROM topics ti
        WHERE ti.boardid = b.boardid) AS topiccount,
        (SELECT COUNT(*) FROM topics ti, messages mi
        WHERE ti.boardid = b.boardid AND mi.topicid = ti.topicid) AS messagecount
        FROM boards b LEFT JOIN messages m ON m.messageid =
        (SELECT  mii.messageid FROM topics tii, messages mii
        WHERE tii.boardid = b.boardid AND mii.topicid = tii.topicid
        ORDER BY mii.postdate DESC LIMIT 1) LEFT JOIN topics t ON t.topicid = m.topicid ORDER BY boardname ASC LIMIT $offset, $entries_per_page";

$rows = $this->db->clean($sql);

foreach($rows as $row) {

    $rows['postdate'] = Forum::change_date(strtotime($row['postdate']));
    $rows['boardname'] = ucwords($row['boardname']);
    $rows['topicname'] = Words::shortenText($row['topicname'],30);
    $rows['board'] = strtolower(str_replace(array(' ','\''), array('-',''), $row['boardname']));
}

and this is the bit of the database class

public function clean($sql, $fetchMode = PDO::FETCH_ASSOC)
    {
        $sth = $this->query($sql);
            
        $sth->execute();
        return $sth->fetchAll();
    }

Hope you can helkp with this as it's driving me nuts

 

What I posted will work for this scenario, but to go along with mac_gyver, use it in the loop that displays the rows:

function customize_row($row) {
    $row['postdate'] = Forum::change_date(strtotime($row['postdate']));
    $row['boardname'] = ucwords($row['boardname']);
    $row['topicname'] = Words::shortenText($row['topicname'],30);
    $row['board'] = strtolower(str_replace(array(' ','\''), array('-',''), $row['boardname']));
    
    return $row;
}

// your display code
foreach($rows as &$row) {
    $row = customize_row($row);
    // output $row stuff   
}
  • Solution

Many thanks to all of you for your help.

 

I looked this morning as I wasn't convinced my foreach loop was wrong like Ch0cu3r said and I done a var_dump on the query result and saw my database array was fine and was what I expected.

 

I knew if the query was correct and the foreach was correct it must be to do with where it's being output so I looked at my foreach loop on the display page and noticed I had

 

<?php foreach($this->forum as $forumitem):?>
<div class="eW">
<div class="e1 col_1">
<h5><a href="<?php echo URL;?>forum/board/<?php echo $this->forum[0]['boardname']; ?>"><?php echo $this->forum[0]['boardname']; ?></a></h5><p><?php echo $this->forum[0]['boarddesc']; ?></p>
</div>
<div class="e2 col_2">
<p><?php echo $this->forum[0]['messagecount']; ?> Posts</p><p><?php echo $this->forum[0]['topiccount']; ?> Topics</p>
</div>
<div class="e3 col_3"> 
<?php if (!empty($forumitem[0]['topicname'])):?>
<p><b>Last post</b> by <?php echo $this->forum[0]['author']; ?></p><p>in <?php echo $this->forum[0]['topicname']; ?></p><p>on <?php echo $this->forum[0]['datetime']; ?></p>
<?php endif; ?>
</div>
</div>

It turned out and i could see that straight away from my var_dump that I needed to replace the 0 in the key value with $key and change the foreach to

<?php foreach($this->forum as $key => $forumitem):?>

As soon as I did this it worked.

 

Again many thanks for pointing me in the right direction as it would have taken me ages to figure this out not knowing if my foreach was right.

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.