TechnoDiver Posted November 10, 2021 Share Posted November 10, 2021 Hi, Freaks, I hope all are well. I'm trying to make a while loop and there's a common manner used that I've seen in many, many example of code -> <?php while($row = mysqli_fetch_array($data_query)) { ... } and this manner of doing it auto-stops when it's to the end of the mysqli array. Using this exact way is not compatible with the syntax that I can use as I use a database wrapper that is highly abstracted. for example, this would be the typical layout of a DB query for a user post -> <?php $table = "un_posts"; $field = "deleted"; $value = "no"; $rule = "ORDER BY id DESC"; $query = $this->_db->get($table, array($field, "=", $value), $rule); $this->_data = $query->all(); // $this->_data is an array of objects and this would be my typical way of assigning the data -> <?php foreach ($this->data() as $obj) { $post_data = array( "id" => $obj->id, "content" => $obj->content, "added_by" => $obj->add_by, "date_added" => date("F d, Y H:i:s", strtotime($obj->date_added)), "user_to" => $obj->user_to, ); for project specific reasons I'd like to change this from a foreach loop to a while loop. What I found out is that the auto-stop of the while loop using the $row = mysqli..... does not work if I do something like this -> <?php while($obj = $this->data()) { $post_data = array( "id" => $obj->id, "content" => $obj->content, "added_by" => $obj->add_by, "date_added" => date("F d, 20y H:i:s", strtotime($obj->date_added)), "user_to" => $obj->user_to, ); and it creates an infinite loop. Keeping in mind that $this->data() (I have a class method data() that returns $this->_data if anyone noticed the difference) is an array of objects why am I not getting the same result as <?php while($row = mysqli_fetch_array($data_query)) { ... } I don't understand. They're both arrays being looped through. What's the difference where mine isn't breaking the loop at the end but the mysqli array breaks the loop at the end of it? Quote Link to comment https://forums.phpfreaks.com/topic/314201-messing-around-with-while-loops/ Share on other sites More sharing options...
Barand Posted November 10, 2021 Share Posted November 10, 2021 A while() loop stops when the condition returns false (mysqli_fetch_array() returns false when there are no more records to fetch) A foreach() loops iterates through the elements of an array Quote Link to comment https://forums.phpfreaks.com/topic/314201-messing-around-with-while-loops/#findComment-1591932 Share on other sites More sharing options...
mac_gyver Posted November 10, 2021 Share Posted November 10, 2021 10 minutes ago, TechnoDiver said: They're both arrays being looped through no. the code using mysqli_fetch_xxxx statement is fetching a row of data from the result of the query, as an associative, a numeric array, or both (default is both), assigning the fetched row of data to the $row variable, then the while() conditional/loop statement is testing the true/false result from that fetch/assignment. this stops because when there is no more data to fetch, a false value is returned by the fetch statement. the while loop code works because the condition being tested changes from true to false when the end of the data is reached. the while loop code you proposed is assigning the whole array in $this->data() to $obj, each pass through the loop, which is always a true value for a non-empty array, so, the loop becomes a forever-loop. while (pun intended) you can make a while() loop loop over an array, the php function needed to do so has been removed in php8, i.e. there's no good reason to change from using a foreach() loop to loop over an array of data. what problem are you having by using a foeach loop that you are trying to solve? Quote Link to comment https://forums.phpfreaks.com/topic/314201-messing-around-with-while-loops/#findComment-1591933 Share on other sites More sharing options...
ginerjm Posted November 10, 2021 Share Posted November 10, 2021 Where in the code does it cause "$this->data" to change? Looks you just keep loading up the same data over and over. And - shouldn't you have a set of square brackets on $post_data when you assign a new array to it? If you WERE doing a loop on some new data each time thru your current code is only going to save one set of data that being the last one. Quote Link to comment https://forums.phpfreaks.com/topic/314201-messing-around-with-while-loops/#findComment-1591934 Share on other sites More sharing options...
TechnoDiver Posted November 10, 2021 Author Share Posted November 10, 2021 (edited) Ok, thanks all. I didn't realize that the false return was built into the mysqli function. I guess I thought that breaking at the end was automatic by the while loop functionality. Knowing that, it's an easy fix -> <?php $cnt = 0; while($cnt < count($this->data())) { $post_data = array( "id" => $this->data()[$cnt]->id, "content" => $this->data()[$cnt]->content, "added_by" => $this->data()[$cnt]->add_by, "date_added" => date("F d, 20y H:i:s", strtotime($this->data()[$cnt]->date_added)), "user_to" => $this->data()[$cnt]->user_to, ); 22 minutes ago, mac_gyver said: what problem are you having by using a foeach loop that you are trying to solve? Not a problem, but I had a few if statements within the loop that seemed would work best if I could use 'break' and 'continue' if certain conditions weren't met, which I couldn't with the foreach() 21 minutes ago, ginerjm said: Where in the code does it cause "$this->data" to change? $this->_data is a private attribute of the class. I have a separate public function data() that returns $this->_data. All's good now though, my misunderstanding was in the functionality of the mysqli function and the while loop function. You folks explained it perfectly, thanks to you all Edited November 10, 2021 by TechnoDiver Quote Link to comment https://forums.phpfreaks.com/topic/314201-messing-around-with-while-loops/#findComment-1591935 Share on other sites More sharing options...
ginerjm Posted November 10, 2021 Share Posted November 10, 2021 (edited) The use of a while in your last is not wise. You should use the foreach on $this->data. Or get the count value ahead of the loop and then use a for using $i=0;$i<$cnt;$i++ and then use $i as the index into your array of query results. OR stick with the foreach that you already showed. Edited November 10, 2021 by ginerjm Quote Link to comment https://forums.phpfreaks.com/topic/314201-messing-around-with-while-loops/#findComment-1591936 Share on other sites More sharing options...
mac_gyver Posted November 10, 2021 Share Posted November 10, 2021 37 minutes ago, TechnoDiver said: $cnt = 0; while($cnt < count($this->data())) { $post_data = array( "id" => $this->data()[$cnt]->id, "content" => $this->data()[$cnt]->content, "added_by" => $this->data()[$cnt]->add_by, "date_added" => date("F d, 20y H:i:s", strtotime($this->data()[$cnt]->date_added)), "user_to" => $this->data()[$cnt]->user_to, ); this is a lot of unnecessary typing, processing, and evaluating the count() inside the loop statement is the slowest way to do this, just to convert an array of objects to an array of arrays (presumably you are doing something with $post_data on each pass through the loop) and to format the date/time. just originally fetch the data as an array of arrays, not of objects, and either format the date/time in the query or as a one-time operation on the fetched data. Quote Link to comment https://forums.phpfreaks.com/topic/314201-messing-around-with-while-loops/#findComment-1591939 Share on other sites More sharing options...
Psycho Posted November 10, 2021 Share Posted November 10, 2021 (edited) 1 hour ago, TechnoDiver said: Not a problem, but I had a few if statements within the loop that seemed would work best if I could use 'break' and 'continue' if certain conditions weren't met, which I couldn't with the foreach() Why are you unable to use break and continue within a foreach() loop? From the manual Quote break ¶ (PHP 4, PHP 5, PHP 7, PHP 8 ) break ends execution of the current for, foreach, while, do-while or switch structure. Quote continue ¶ (PHP 4, PHP 5, PHP 7, PHP 8 ) continue is used within looping structures to skip the rest of the current loop iteration and continue execution at the condition evaluation and then the beginning of the next iteration. Note: While the description for continue doesn't explicitly state it works for foreach() loops, the examples show that it clearly does. Edited November 10, 2021 by Psycho Quote Link to comment https://forums.phpfreaks.com/topic/314201-messing-around-with-while-loops/#findComment-1591940 Share on other sites More sharing options...
TechnoDiver Posted November 12, 2021 Author Share Posted November 12, 2021 OK, thank you all for your responses. I'm not done with this issue yet but it seems more appropriate to continue it in a new thread, which is what I'll do Quote Link to comment https://forums.phpfreaks.com/topic/314201-messing-around-with-while-loops/#findComment-1591976 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.