atpnifb Posted February 4, 2022 Share Posted February 4, 2022 Hello! New to PHP and this forum! I am trying to get a mySQL database of videos listed into my HTML page in four equal columns. I have done this successfully, however they are being listed in order left to right then down and so. Basically vid01 is in column one then vid02 is in column two same for 3 then 4 then the next row down starts at vid05. I want them in order vertically, i.e. in my test list i have 94 vids ... column one should list vid01 thru vid24...column two should list vid25 thru vid49...column three should list vid50 thru vid74...column four should list vid75 thru vid94 Below is the code I am using so far. Also please see attached images showing the database and the way the HTML looks using the current code. Any help is greatly appreciated! Thank you all so much in advance! <div class="row"> <?php $countQuery = "SELECT COUNT(*) AS count FROM `videos`"; $countResult = mysqli_query($conn, $countQuery); while ($row = mysqli_fetch_assoc($countResult)) { $countOutput = $row['count']; } // echo $countOutput; $codeQuery = $mysqli->query("SELECT * FROM videos WHERE vid_category = 'one' ORDER BY vid_title ASC"); $codes = $codeQuery->fetch_all(MYSQLI_ASSOC); $codes = array_chunk($codes, 4); ?> <div class="col-md-3"> <ul class="simple"> <?php foreach (array_column($codes, 0) as $code): ?> <?php echo $code['vid_code']; ?> <?php endforeach; ?> </ul> </div> <div class="col-md-3"> <ul class="simple"> <?php foreach (array_column($codes, 1) as $code): ?> <?php echo $code['vid_code']; ?> <?php endforeach; ?> </ul> </div> <div class="col-md-3"> <ul class="simple"> <?php foreach (array_column($codes, 2) as $code): ?> <?php echo $code['vid_code']; ?> <?php endforeach; ?> </ul> </div> <div class="col-md-3"> <ul class="simple"> <?php foreach (array_column($codes, 3) as $code): ?> <?php echo $code['vid_code']; ?> <?php endforeach; ?> </ul> <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> </div> </div> Quote Link to comment Share on other sites More sharing options...
requinix Posted February 4, 2022 Share Posted February 4, 2022 What you currently do is chunk it into groups of 4 (so it goes 1,2,3,4; 5,6,7,8; 9,10,11,12) and then use array_column to get the Nth member of each group into the Nth column (column 1 has 1,5,9; column 2 has 2,6,10, etc). What you want to do is chunk it so there are 4 groups, and then put the contents of the Nth group into the Nth column. Now here's a question. If you have 10 items to put into those four columns, do you want 1 | 4 | 7 | 10 2 | 5 | 8 | 3 | 6 | 9 | where the last "column" is incomplete, or 1 | 4 | 7 | 9 2 | 5 | 8 | 10 3 | 6 | | where the last "row" is incomplete? The normal answer here, with the values going column-by-column, would be the first. That means there are ceil(10 items / 4 columns) = 3 items per column, except the last which has (10 items - 3 items per column * 3 columns not counting the last) = 1 item remaining. Fortunately you only need to figure out how many items you want in each of the 4 chunks - that is, ceil(number of items / number of columns). Then PHP will give you an array with four elements and each column can foreach over its respective chunk, just like you're doing now except you're asking it to chunk with the wrong number. 1 Quote Link to comment Share on other sites More sharing options...
atpnifb Posted February 4, 2022 Author Share Posted February 4, 2022 Thank you so much for your answer! I would prefer the columns be as even as possible, referring to your second example, where the last "row" is incomplete. The first example is totally acceptable though if that is easier to implement. However, being new to all this I am not sure exactly how to write that into my code. I will try to figure it out now but if you can respond with the best way to actually write it in the code I would greatly appreciate that as well! Quote Link to comment Share on other sites More sharing options...
Solution requinix Posted February 4, 2022 Solution Share Posted February 4, 2022 Then array_chunk won't be quite as helpful: it'll create 3 chunks of the same size and 1 of a remainder. I can't think of an easier way of doing this than creating your own chunks: <?php const COLUMNS = 4; $items = range(1, 98); $count = count($items); $base = floor($count / COLUMNS); // 24 $remainder = $count % COLUMNS; // 2 // so $base * COLUMNS + $remainder == $count $chunks = []; for ($start = 0; $start < $count; ) { // the base amount, plus one if there are any remainder to include $length = $base + ($remainder-- > 0 ? 1 : 0); $chunks[] = array_slice($items, $start, $length); $start += $length; } print_r($chunks); // [1-25, 26-50, 51-74, 75-98] 1 Quote Link to comment Share on other sites More sharing options...
atpnifb Posted February 4, 2022 Author Share Posted February 4, 2022 Got it. I will try this now and see if I can make it work. I will respond back with the results shortly. Thank you! Quote Link to comment Share on other sites More sharing options...
atpnifb Posted February 5, 2022 Author Share Posted February 5, 2022 OK so it is working and going in order as expected, but it is showing the full array element in the HTML. How do I get it to only show one thing for each line in the column? It should only show the vid_name or vid_code rather. It should look like the first HTML view image I attached in the original post. I am stuck trying to figure out how to get it to do something like: <?php echo $chunks[0]['vid_code']; ?> But when I try that I get this error: Warning: Undefined array key "vid_code". There are no errors with your original code of: <?php print_r ($chunks[0]); ?>. I attached the Updated HTML view to this post along with the code I just added. Thank you again for your help! <div class="row"> <?php $countQuery = "SELECT COUNT(*) AS count FROM `videos`"; $countResult = mysqli_query($conn, $countQuery); while ($row = mysqli_fetch_assoc($countResult)) { $countOutput = $row['count']; } // echo $countOutput; $codeQuery = $mysqli->query("SELECT * FROM videos WHERE vid_category = 'one' ORDER BY vid_title ASC"); $codes = $codeQuery->fetch_all(MYSQLI_ASSOC); // print_r ($codes); $codeCount = count($codes); // echo $codeCount; // $codes = array_chunk($codes, 4); const COLUMNS = 4; $items = $codes; $count = $codeCount; $base = floor($count / COLUMNS); // 24 $remainder = $count % COLUMNS; // 2 // so $base * COLUMNS + $remainder == $count $chunks = []; for ($start = 0; $start < $count; ) { // the base amount, plus one if there are any remainder to include $length = $base + ($remainder-- > 0 ? 1 : 0); $chunks[] = array_slice($items, $start, $length); $start += $length; } ?> <div class="col-md-3"> <ul class="simple"> <?php print_r ($chunks[0]); ?> </ul> </div> <div class="col-md-3"> <ul class="simple"> <?php print_r ($chunks[1]); ?> </ul> </div> <div class="col-md-3"> <ul class="simple"> <?php print_r ($chunks[2]); ?> </ul> </div> <div class="col-md-3"> <ul class="simple"> <?php print_r ($chunks[3]); ?> </ul> <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> </div> </div> Quote Link to comment Share on other sites More sharing options...
requinix Posted February 5, 2022 Share Posted February 5, 2022 2 hours ago, atpnifb said: OK so it is working and going in order as expected, but it is showing the full array element in the HTML. How do I get it to only show one thing for each line in the column? It should only show the vid_name or vid_code rather. The code I posted was a sample of how the process can work. You should spend some time to read through it, maybe look up what unfamiliar parts are doing (or ask), then adapt it to suit your own specific needs. The end result should be something that is part what I wrote and part what you had before. Quote Link to comment Share on other sites More sharing options...
atpnifb Posted February 5, 2022 Author Share Posted February 5, 2022 Yes that is what I have been doing for hours since your last post. Your code did not show how to split it into the columns so I figured that out. I have also looked up the things I do not understand but I have not been able to get it to work 100 percent yet. I have spent countless hours on learning PHP in the last two weeks. I have been really stuck this past couple days. So I created this account and asked for help. I am not just looking for you to do the work for me, just point me in the right direction. I literally knew nothing about PHP 3 weeks ago, so I still have a long way to go. So far I have only gotten it to show the entire list in each column, instead of equal-ish parts. I have been researching reading searching and trying, but I cannot figure out how to get the values to split between the four columns. I really appreciate your help so far and cannot help if you think I am not doing anything on my end. I am trying really hard whether you believe me or not. If you can continue to help it is greatly appreciated if not I understand and will go elsewhere for advice, not for someone to just give me the exact answer. Here is the current code and attached is the updated HTML view. <div class="row"> <?php function print_r2($val){ echo '<pre>'; print_r($val); echo '</pre>'; } $countQuery = "SELECT COUNT(*) AS count FROM `videos`"; $countResult = mysqli_query($conn, $countQuery); while ($row = mysqli_fetch_assoc($countResult)) { $countOutput = $row['count']; } // echo $countOutput; $codeQuery = $mysqli->query("SELECT * FROM videos WHERE vid_category = 'one' ORDER BY vid_title ASC"); $codes = $codeQuery->fetch_all(MYSQLI_ASSOC); // print_r ($codes); $codeCount = count($codes); // echo $codeCount; // $codes = array_chunk($codes, 4); const COLUMNS = 4; $items = $codes; $count = $codeCount; $base = floor($count / COLUMNS); // 24 $remainder = $count % COLUMNS; // 2 // so $base * COLUMNS + $remainder == $count $chunks = []; for ($start = 0; $start < $count; ) { // the base amount, plus one if there are any remainder to include $length = $base + ($remainder-- > 0 ? 1 : 0); $chunks[] = array_slice($items, $start, $length); $start += $length; } ?> <div class="col-md-3"> <ul class="simple"> <?php foreach ($chunks as $chunk) { foreach ($chunk as $data) { echo $data['vid_code']; } } ?> </ul> </div> <div class="col-md-3"> <ul class="simple"> <?php foreach ($chunks as $chunk) { foreach ($chunk as $data) { echo $data['vid_code']; } } ?> </ul> </div> <div class="col-md-3"> <ul class="simple"> <?php foreach ($chunks as $chunk) { foreach ($chunk as $data) { echo $data['vid_code']; } } ?> </ul> </div> <div class="col-md-3"> <ul class="simple"> <?php foreach ($chunks as $chunk) { foreach ($chunk as $data) { echo $data['vid_code']; } } ?> </ul> <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> </div> </div> Quote Link to comment Share on other sites More sharing options...
requinix Posted February 5, 2022 Share Posted February 5, 2022 22 minutes ago, atpnifb said: Yes that is what I have been doing for hours since your last post. My reply was a bit late so I did assume you were still working on it. Not everyone does, when they're waiting for replies, but you seemed more responsible than that. 22 minutes ago, atpnifb said: Your code did not show how to split it into the columns so I figured that out. You're much closer. $chunks will be an array with a chunk for each column: $chunk[0] for the first, $chunk[1] for the second, and so on. That means each column doesn't need an additional foreach on $chunks itself. You only need the one foreach, and you run it on the appropriate $chunk[X] directly. 22 minutes ago, atpnifb said: I really appreciate your help so far and cannot help if you think I am not doing anything on my end. I am trying really hard whether you believe me or not. No worries. I've been doing this long enough that I'm pretty good at spotting which people want help to work through the problem and which people want help so they don't have to do the work at all. 1 Quote Link to comment Share on other sites More sharing options...
atpnifb Posted February 5, 2022 Author Share Posted February 5, 2022 10 minutes ago, requinix said: My reply was a bit late so I did assume you were still working on it. Not everyone does, when they're waiting for replies, but you seemed more responsible than that. I truly enjoy learning all types of coding and I have been teaching myself everything throughout the years off and on. I rarely post my own topics for help unless I really do not understand. Most topics are already posted about and answered very well but sometimes you get into something specific and it can be hard to figure out without being able to ask about it directly. 10 minutes ago, requinix said: You're much closer. $chunks will be an array with a chunk for each column: $chunk[0] for the first, $chunk[1] for the second, and so on. That means each column doesn't need an additional foreach on $chunks itself. You only need the one foreach, and you run it on the appropriate $chunk[X] directly. This is very encouraging and helpful! I will continue to work on this and post my progress once I get some results. Hints and tips like this is really what I am looking for. I need to think about it and work on my creative and logical problem solving. Copying and pasting an answer does me no good. Even though I used most of your exact code from earlier, I still spent time researching things like "array_slice". That way I can understand WHY you used it and start to see the logic in the code you gave me as an example to start from. Thank you very much again for your time and sharing some of your knowledge on the subject. Quote Link to comment Share on other sites More sharing options...
atpnifb Posted February 5, 2022 Author Share Posted February 5, 2022 (edited) I am so close. I have columns 2, 3, and 4 working perfectly fine. Column 1 is correct but is repeating itself 4 times vertically. Every change I have tried so far throws an error. I tried putting the same code in the first column as the other columns and it everything and says that "$chunk" is undefined. Here is the code when all the columns are "working": (See the first image below with the red checkmarks on it, showing the result of this code where all the columns are "working".) <div class="row"> <?php $countQuery = "SELECT COUNT(*) AS count FROM `videos`"; $countResult = mysqli_query($conn, $countQuery); while ($row = mysqli_fetch_assoc($countResult)) { $countOutput = $row['count']; } $codeQuery = $mysqli->query("SELECT * FROM videos WHERE vid_category = 'one' ORDER BY vid_title ASC"); $codes = $codeQuery->fetch_all(MYSQLI_ASSOC); $codeCount = count($codes); const COLUMNS = 4; $items = $codes; $count = $codeCount; $base = floor($count / COLUMNS); $remainder = $count % COLUMNS; $chunks = []; for ($start = 0; $start < $count; ) { $length = $base + ($remainder-- > 0 ? 1 : 0); $chunks[] = array_slice($items, $start, $length); $start += $length; } ?> <!-- COLUMN 1 --> <div class="col-md-3"> <ul class="simple"> <?php foreach ($chunks as $chunk[]) { foreach ($chunk[0] as $data) { echo $data['vid_code']; } } ?> </ul> </div> <!-- COLUMN 2 --> <div class="col-md-3"> <ul class="simple"> <?php foreach ($chunk[1] as $data) { echo $data['vid_code']; } ?> </ul> </div> <!-- COLUMN 3 --> <div class="col-md-3"> <ul class="simple"> <?php foreach ($chunk[2] as $data) { echo $data['vid_code']; } ?> </ul> </div> <!-- COLUMN 4 --> <div class="col-md-3"> <ul class="simple"> <?php foreach ($chunk[3] as $data) { echo $data['vid_code']; } ?> </ul> <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> </div> </div> ==================================================================================== Here is the code when I make the first column match the other three that work, and it breaks everything: (See the second image below, showing the result of this code where all the columns are broken.) <div class="row"> <?php $countQuery = "SELECT COUNT(*) AS count FROM `videos`"; $countResult = mysqli_query($conn, $countQuery); while ($row = mysqli_fetch_assoc($countResult)) { $countOutput = $row['count']; } $codeQuery = $mysqli->query("SELECT * FROM videos WHERE vid_category = 'one' ORDER BY vid_title ASC"); $codes = $codeQuery->fetch_all(MYSQLI_ASSOC); $codeCount = count($codes); const COLUMNS = 4; $items = $codes; $count = $codeCount; $base = floor($count / COLUMNS); $remainder = $count % COLUMNS; $chunks = []; for ($start = 0; $start < $count; ) { $length = $base + ($remainder-- > 0 ? 1 : 0); $chunks[] = array_slice($items, $start, $length); $start += $length; } ?> <!-- COLUMN 1 --> <div class="col-md-3"> <ul class="simple"> <?php foreach ($chunk[0] as $data) { echo $data['vid_code']; } ?> </ul> </div> <!-- COLUMN 2 --> <div class="col-md-3"> <ul class="simple"> <?php foreach ($chunk[1] as $data) { echo $data['vid_code']; } ?> </ul> </div> <!-- COLUMN 3 --> <div class="col-md-3"> <ul class="simple"> <?php foreach ($chunk[2] as $data) { echo $data['vid_code']; } ?> </ul> </div> <!-- COLUMN 4 --> <div class="col-md-3"> <ul class="simple"> <?php foreach ($chunk[3] as $data) { echo $data['vid_code']; } ?> </ul> <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> </div> </div> I am going to bed now but I will resume my research and trial and error method tomorrow. Let me know your thoughts when you have a chance. Thank you! Edited February 5, 2022 by atpnifb Corrected information in post. Quote Link to comment Share on other sites More sharing options...
requinix Posted February 5, 2022 Share Posted February 5, 2022 Looks like you're kinda throwing syntax at the problem and hoping it goes away. That very, very rarely ever works. I will say that I wrote the wrong variable name a couple times in my previous post. $chunks is the one that has the chunks of the array, not $chunk. If you fix that with columns 2-4 then they should work equally correctly, but the only reason they work at all now is because you stumbled into some code that is wrong but accidentally makes the other parts do what you want. With the three columns working, compare your code for those with the code for the first one. Quote Link to comment Share on other sites More sharing options...
kinzer Posted February 5, 2022 Share Posted February 5, 2022 <?php $end = count($data); $id = array_column($data, 'id'); $option = array_column($data, 'option'); $start = array_column($data, 'start'); ?> <table class="table"> <thead> <tr> <th scope="col">Header ID</th> <th scope="col">Header</th> <th scope="col">Header Option</th> <th scope="col">Header</th> <th scope="col">Header</th> <th scope="col">Actions</th> </tr> </thead> <tbody> <?php for ($i = 0; $i < $end; ++$i){ ?> <tr> <?php echo "<td>".$id[$i]."</td>";?> <?php echo "<td>".$status[$i]."</td>";?> <?php echo "<td>".$option[$i]."</td>";?> <?php echo "<td>".$start[$i]."</td>";?> <?php echo "<td><a href=" . "edit_data.php?id=$id[$i]" . "><ion-icon name='create-outline'></ion-icon> </span></a></td>";?> </tr> <?php } ?> </tbody> </table> Quote Link to comment Share on other sites More sharing options...
atpnifb Posted February 5, 2022 Author Share Posted February 5, 2022 12 hours ago, requinix said: Looks like you're kinda throwing syntax at the problem and hoping it goes away. That very, very rarely ever works. I will say that I wrote the wrong variable name a couple times in my previous post. $chunks is the one that has the chunks of the array, not $chunk. If you fix that with columns 2-4 then they should work equally correctly, but the only reason they work at all now is because you stumbled into some code that is wrong but accidentally makes the other parts do what you want. With the three columns working, compare your code for those with the code for the first one. Apologies for using the wrong code. I am trying to learn the right way. I have never been taught any of this so I do not know exactly what to do. I have changed $chunk to $chunks in each of the columns and they are all working properly now. Here is the code now: <div class="row"> <?php $countQuery = "SELECT COUNT(*) AS count FROM `videos`"; $countResult = mysqli_query($conn, $countQuery); while ($row = mysqli_fetch_assoc($countResult)) { $countOutput = $row['count']; } $codeQuery = $mysqli->query("SELECT * FROM videos WHERE vid_category = 'one' ORDER BY vid_title ASC"); $codes = $codeQuery->fetch_all(MYSQLI_ASSOC); $codeCount = count($codes); const COLUMNS = 4; $items = $codes; $count = $codeCount; $base = floor($count / COLUMNS); $remainder = $count % COLUMNS; $chunks = []; for ($start = 0; $start < $count; ) { $length = $base + ($remainder-- > 0 ? 1 : 0); $chunks[] = array_slice($items, $start, $length); $start += $length; } ?> <!-- COLUMN 1 --> <div class="col-md-3"> <ul class="simple"> <?php foreach ($chunks[0] as $data) { echo $data['vid_code']; } ?> </ul> </div> <!-- COLUMN 2 --> <div class="col-md-3"> <ul class="simple"> <?php foreach ($chunks[1] as $data) { echo $data['vid_code']; } ?> </ul> </div> <!-- COLUMN 3 --> <div class="col-md-3"> <ul class="simple"> <?php foreach ($chunks[2] as $data) { echo $data['vid_code']; } ?> </ul> </div> <!-- COLUMN 4 --> <div class="col-md-3"> <ul class="simple"> <?php foreach ($chunks[3] as $data) { echo $data['vid_code']; } ?> </ul> <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> </div> </div> If you have any advice of what I can look into to change the code to be better or more proper or correct, then I would love to research that. Thank you! Quote Link to comment Share on other sites More sharing options...
requinix Posted February 5, 2022 Share Posted February 5, 2022 20 minutes ago, atpnifb said: Apologies for using the wrong code. I am trying to learn the right way. I have never been taught any of this so I do not know exactly what to do. Don't worry about whether you have the "right" code. Everyone can arrive at the right code eventually. What's more important is the process you use to arrive at that code. There's a lot to PHP, and all programming languages, but ultimately they all act like a recipe: you use particular ingredients in a particular sequence to achieve a particular result. Sometimes you can substitute one ingredient for another, and sometimes you can adjust the sequence to work better, but most of the time you can't throw things into a pot and expect something edible. Being a good cook is about understanding each part and combining them successfully. Here we have a few ingredients to work with, such as databases, math, arrays, for loops, and foreach loops. Each of those is made up even more ingredients, such as the mysqli library, SQL queries, integer division, array brackets, and ternary expressions. It's a lot of moving parts but understanding what each does and means is crucial to being able to use them correctly. And when you understand them, it's easier to arrange them in an order to achieve the result you want. 20 minutes ago, atpnifb said: If you have any advice of what I can look into to change the code to be better or more proper or correct, then I would love to research that. The best piece of advice is something I said earlier: don't always copy and paste code but spend some time to learn what it represents so that you can extract the relevant parts and apply them to your own code. On the more factual side of things, I'll pick the one that stands out: $items = $codes; $count = $codeCount; You start with the $codes and $codeCount variables and then copy them into the $items and $count variables. So you now have two pairs of variables that mean the same things. There's no need to have duplicates like that, so you could keep the two you started with and forget the two new ones - all you have to do then is adjust the later code to use the correct variables. Quote Link to comment Share on other sites More sharing options...
atpnifb Posted February 5, 2022 Author Share Posted February 5, 2022 Thanks so much for the advice. You are absolutely right about all that. Quote Link to comment 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.