AdRock Posted September 25, 2013 Share Posted September 25, 2013 (edited) 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 September 25, 2013 by AdRock Quote Link to comment https://forums.phpfreaks.com/topic/282435-foreach-loop-overwriting-all-values-with-last-key-value/ Share on other sites More sharing options...
AbraCadaver Posted September 25, 2013 Share Posted September 25, 2013 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); } Quote Link to comment https://forums.phpfreaks.com/topic/282435-foreach-loop-overwriting-all-values-with-last-key-value/#findComment-1451171 Share on other sites More sharing options...
mac_gyver Posted September 25, 2013 Share Posted September 25, 2013 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. Quote Link to comment https://forums.phpfreaks.com/topic/282435-foreach-loop-overwriting-all-values-with-last-key-value/#findComment-1451172 Share on other sites More sharing options...
Ch0cu3r Posted September 25, 2013 Share Posted September 25, 2013 Can't see why in that code that is happening as I have tested but cannot reproduce the results. Wouldn't it be better to format the text when you get the data out from the database. How is $rows defined? Quote Link to comment https://forums.phpfreaks.com/topic/282435-foreach-loop-overwriting-all-values-with-last-key-value/#findComment-1451173 Share on other sites More sharing options...
AbraCadaver Posted September 25, 2013 Share Posted September 25, 2013 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. Quote Link to comment https://forums.phpfreaks.com/topic/282435-foreach-loop-overwriting-all-values-with-last-key-value/#findComment-1451174 Share on other sites More sharing options...
AdRock Posted September 25, 2013 Author Share Posted September 25, 2013 I'm using a PDO class that queries the database and I'm trying do build an MVC. I will look at how to the database is queries and see if i can put it in there. Quote Link to comment https://forums.phpfreaks.com/topic/282435-foreach-loop-overwriting-all-values-with-last-key-value/#findComment-1451175 Share on other sites More sharing options...
AdRock Posted September 25, 2013 Author Share Posted September 25, 2013 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 Quote Link to comment https://forums.phpfreaks.com/topic/282435-foreach-loop-overwriting-all-values-with-last-key-value/#findComment-1451176 Share on other sites More sharing options...
Ch0cu3r Posted September 25, 2013 Share Posted September 25, 2013 (edited) 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 September 25, 2013 by Ch0cu3r Quote Link to comment https://forums.phpfreaks.com/topic/282435-foreach-loop-overwriting-all-values-with-last-key-value/#findComment-1451177 Share on other sites More sharing options...
mac_gyver Posted September 25, 2013 Share Posted September 25, 2013 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. Quote Link to comment https://forums.phpfreaks.com/topic/282435-foreach-loop-overwriting-all-values-with-last-key-value/#findComment-1451180 Share on other sites More sharing options...
AdRock Posted September 25, 2013 Author Share Posted September 25, 2013 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 Quote Link to comment https://forums.phpfreaks.com/topic/282435-foreach-loop-overwriting-all-values-with-last-key-value/#findComment-1451183 Share on other sites More sharing options...
AbraCadaver Posted September 25, 2013 Share Posted September 25, 2013 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 } Quote Link to comment https://forums.phpfreaks.com/topic/282435-foreach-loop-overwriting-all-values-with-last-key-value/#findComment-1451185 Share on other sites More sharing options...
Solution AdRock Posted September 26, 2013 Author Solution Share Posted September 26, 2013 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. Quote Link to comment https://forums.phpfreaks.com/topic/282435-foreach-loop-overwriting-all-values-with-last-key-value/#findComment-1451261 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.