2

I am trying to make a simple roster which will rotate alphabetically.

I have a database with a list of 10 users sorted by column called First_Name. I am using PHP to retrieve all the names of people from the database and put them into an array alphabetically.

What I need to be able to do is create a further 4 arrays to list say 3 people in each array. I can get all the users in a single array by doing: $query = "SELECT * FROM carpark";

The arrays should always be filled with 3 people and when the number of people run out it should add people from the start of the loop to fill the gaps.

The way I have it right now, is to return the next 3 names from the database table which is probably not going to work if i want to rotate them.

I hope what I am asking for makes some sense..

Here is what I have so far:

<?php

include_once 'connect.php';

dbconnect("roster");

//=============================================
$w1_query = "SELECT * FROM carpark ORDER BY First_Name LIMIT 0,3";
$w1_result = mysqli_query($conn, $w1_query) or die("error getting data");

$w1_arr = array();
while ($w1_data = mysqli_fetch_array($w1_result, MYSQLI_ASSOC)) {
    array_push($w1_arr, $w1_data['First_Name']);
}
sort($w1_arr);
print_r($w1_arr);
//=============================================
//=============================================
$w2_query = "SELECT * FROM carpark ORDER BY First_Name LIMIT 3,5";
$w2_result = mysqli_query($conn, $w2_query) or die("error getting data");

$w2_arr = array();
while ($w2_data = mysqli_fetch_array($w2_result, MYSQLI_ASSOC)) {
    array_push($w2_arr, $w2_data['First_Name']);
}
sort($w2_arr);
//print_r($w2_arr);
//=============================================
//=============================================
$w3_query = "SELECT * FROM carpark ORDER BY First_Name LIMIT 6,8";
$w3_result = mysqli_query($conn, $w3_query) or die("error getting data");

$w3_arr = array();
while ($w3_data = mysqli_fetch_array($w3_result, MYSQLI_ASSOC)) {
    array_push($w3_arr, $w3_data['First_Name']);
}
sort($w3_arr);
//print_r($w3_arr);
//=============================================
//=============================================
$w4_query = "SELECT * FROM carpark ORDER BY First_Name LIMIT 9,11";
$w4_result = mysqli_query($conn, $w4_query) or die("error getting data");

$w4_arr = array();
while ($w4_data = mysqli_fetch_array($w4_result, MYSQLI_ASSOC)) {
    array_push($w4_arr, $w4_data['First_Name']);
}
sort($w4_arr);
//print_r($w4_arr);
//=============================================

//print_r($week1_arr);

echo '<table border=1><tr><th></th><th>week 1</th><th>week 2</th><th>week 3</th><th>week 4</th></tr>';

for ($x = 0; $x <= 2; $x++) {
echo '<tr><td>Bay '.$x.'</td><td>'.$w1_arr[$x].'</td><td>'.$w2_arr[$x].'</td><td>'.$w3_arr[$x].'</td><td>'.$w4_arr[$x].'</td></tr>';
}

echo '</table>';

?>

Here is the output of the above, as you can see the last two boxes should be filled with Chris, Eric.

enter image description here

3 Answers 3

3

Perhaps something like this, assuming you have all the names in a $names array, with numeric keys (required for desired functionality of array_merge).

$numBays = 3;
$numWeeks = 4;
$weeks = [];
$pool = [];
do {
    // Fill pool of names to a point where we have at least $numBays names
    while (count($pool) < $numBays) {
        $pool = array_merge($pool, $names);
    }
    // Extract an array containing $numBays names from the name pool
    $weeks[] = array_splice($pool, 0, $numBays);
} while(count($weeks) < $numWeeks);

This should leave you with a $weeks array, containing $numWeeks arrays, each with $numBays names, which you can then loop much like you currently do to produce your output.

for ($bay = 0; $bay < $numBays; $bay++) {
    echo '<tr><td>Bay '.$bay.'</td>';
    for ($week = 0; $week < $numWeeks; $week++) {
        echo '<td>'.$weeks[$week][$bay].'</td>';
    }
    echo '</tr>';
}
Sign up to request clarification or add additional context in comments.

2 Comments

this works rather perfectly sound.. i need to study your answer to make sure i understand all aspects of it but i am grateful for this elegant solution. thanks kindly!
You can combine it with Jon C's answer to make it prettier still. array_chunk could replace the outer do ... while loop and the array_splice, as long as you initially make the $pool have enough names, at least $numBays * $numWeeks. These things are always compromises, but I doubt you will run into any actual memory constraints, etc, in your use case.
3

Depending on the complexity of the system, you could merge http://php.net/manual/en/function.array-merge.php the result with itself then split it out with array_chunk http://php.net/manual/en/function.array-chunk.php.

$query = "SELECT * FROM carpark ORDER BY First_Name";
$result = mysqli_query($mysqli, $query) or die("error getting data");

$arr = array();
while ($data = mysqli_fetch_array($result, MYSQLI_ASSOC)) {
    array_push($arr, $data['First_Name']);
}
sort($arr);

$combined=array_merge($arr,$arr);
$output=array_chunk($combined,3);

echo '<table border=1><tr><th></th><th>week 1</th><th>week 2</th><th>week 3</th><th>week 4</th></tr>';

for ($x = 0; $x <= 2; $x++) {
    echo '<tr><td>Bay '.$x.'</td><td>'.$output[0][$x].'</td>   <td>'.$output[1][$x].'</td><td>'.$output[2][$x].'</td><td>'.$output[3][$x].'</td></tr>';
}

echo '</table>';

Comments

1

it will be easy if creating a array as needed. Hope this will work. Array will generate according to the values assigning for $NoOfRows & $NoOfWeeks

$NoOfRows  = 3;
$NoOfWeeks = 4;
$totalLots = $NoOfRows * $NoOfWeeks;
$dataArr = array();

//fetch all persons
$query = "SELECT * FROM carpark ORDER BY First_Name";
$result = mysqli_query($conn, $query) or die("error getting data");
while ($row = mysqli_fetch_array($result, MYSQLI_ASSOC)) {
    array_push($dataArr, $row['First_Name']);
}
$noOfPersons = count($dataArr);

//Create a new array with filling all lots
while ($noOfPersons < $totalLots) {
    $dataArr = array_merge($dataArr, $dataArr);
    $noOfPersons = count($dataArr);
}
$weekArr = array_chunk($dataArr , $NoOfRows);
//print the table
echo "<table border=1>";
for ($row = 0; $row < $NoOfRows; $row++) {
    if ($row == 0) {
        echo "<tr><td></td>";
        for ($col = 1; $col <= $NoOfWeeks; $col++) {
            echo "<td>Week $col</td>";
        }
        echo "</tr>";
    }
    for ($col = 0; $col < $NoOfWeeks; $col++) {
        if ($col == 0) {
            echo "<tr><td>Bay $row</td>";
        }
        echo "<td>";
        echo $weekArr[$col][$row];
        echo "</td>";
    }
    echo "</tr>";
}
echo "</table>";

1 Comment

Yes, this works nicely and love the flexibility you have built in to account for extra bays and weeks. Thanks very much!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.