PHP Multidimensional Array to Two Column HTML Table - php

I have an array called $data and I would like to display a two column html table,
tableHeader on the left hand column.
tableData on the right hand column.
A print_r($data) displays the following
Array
(
[0] => Array
(
[tableHeader] => ID
[tableData] => 104
)
[1] => Array
(
[tableHeader] => Member Number
[tableData] => not available
)
[2] => Array
(
[tableHeader] => First Name
[tableData] => Peter
)
[3] => Array
(
[tableHeader] => Last Name
[tableData] => Keys
)
[4] => Array
(
[tableHeader] => Address
[tableData] => 17 main road
)
[5] => Array
(
[tableHeader] => Email
[tableData] => P3TER#HOTMAIL.CO.UK
)
[6] => Array
(
[tableHeader] => Post Code
[tableData] => LDN 1
)
[7] => Array
(
[tableHeader] => City
[tableData] => London
)
[8] => Array
(
[tableHeader] => Year Graduated
[tableData] => 0000-00-00
)
[9] => Array
(
[tableHeader] => Subject Studied
[tableData] => Comp
)
[10] => Array
(
[tableHeader] => Telephone Number
[tableData] => 123123
)
)
I have tried the following foreach loop but I keep receiving an error message;
Message: Undefined variable: value
<table class="table">
<thead>
<? foreach ($data as $value): ?>
<tr>
<th scope="col"><?php echo $value['tableHeader']; ?></th>
</tr>
<? endforeach; ?>
</thead>
<tbody>
<? foreach ($data as $value): ?>
<tr>
<th scope="col"><?php echo $value['tableData']; ?></th>
</tr>
<? endforeach; ?>
</tbody>
</table>
What am I doing wrong?

It looks like the short tags are not working, because when the php code inside of the foreach loop is executed, it does not recognise the $value variable, because it was never parsed by php.

Related

Reconstruct PHP array to fit data into html table correctly

I'm trying to display data that shows the count for each month for locations in Jan-December.
I wrote the query to get the necessary data from the server but when I display it in the view in my table the layout for the data, doesn't look the way I want it to look like in my table. I believe I have to reconstruct the array that I wrote in the query for the right format first and then I can display it in my table?
Right now, the data that comes back from the server looks like so
<table id="registeredTable" class="table table-striped table-bordered table-hover">
<thead>
<tr>
<th>Locations</th>
<th>January</th>
<th>Feburary</th>
<th>March</th>
<th>April</th>
<th>May</th>
<th>June</th>
<th>July</th>
<th>August</th>
<th>September</th>
<th>October</th>
<th>November</th>
<th>December</th>
</tr>
</thead>
<tbody>
<?php
foreach($selectAllmonthlylocations as $item) {
echo '
<tr>
<td>'.$item["locations"].'</td>
<td>'.$item["Total"].'</td>
</tr>
';
}
?>
</tbody>
</table>
So my question is how can I format my array properly to display it in my table how I want?
Array
(
[0] => Array
(
[usergroup] => Austin_Domestic
[DateAdded] => 2018-01-03
[Total] => 15
)
[1] => Array
(
[usergroup] => Austin_International
[DateAdded] => 2018-01-25
[Total] => 2
)
[2] => Array
(
[usergroup] => BayArea_Domestic
[DateAdded] => 2018-01-16
[Total] => 192
)
[3] => Array
(
[usergroup] => BayArea_International
[DateAdded] => 2018-01-05
[Total] => 28
)
[4] => Array
(
[usergroup] => Bengaluru_Domestic
[DateAdded] => 2018-01-10
[Total] => 2
)
[5] => Array
(
[usergroup] => Bengaluru_International
[DateAdded] => 2018-01-05
[Total] => 1
)
[6] => Array
(
[usergroup] => Cork
[DateAdded] => 2018-01-02
[Total] => 31
)
[7] => Array
(
[usergroup] => CulverCity
[DateAdded] => 2018-01-10
[Total] => 3
)
[8] => Array
(
[usergroup] => Denver
[DateAdded] => 2018-01-10
[Total] => 1
)
[9] => Array
(
[usergroup] => Hyderabad
[DateAdded] => 2018-01-05
[Total] => 3
)
[10] => Array
(
[usergroup] => London
[DateAdded] => 2018-01-02
[Total] => 10
)
[11] => Array
(
[usergroup] => Macau
[DateAdded] => 2018-01-17
[Total] => 1
)
[12] => Array
(
[usergroup] => Munich
[DateAdded] => 2018-01-02
[Total] => 6
)
[13] => Array
(
[usergroup] => Sacramento_Domestic
[DateAdded] => 2018-01-04
[Total] => 1
)
[14] => Array
(
[usergroup] => Shanghai
[DateAdded] => 2018-01-12
[Total] => 2
)
[15] => Array
(
[usergroup] => Singapore
[DateAdded] => 2018-01-03
[Total] => 8
)
[16] => Array
(
[usergroup] => Sydney
[DateAdded] => 2018-01-21
[Total] => 1
)
[17] => Array
(
[usergroup] => Tokyo
[DateAdded] => 2018-01-04
[Total] => 3
)
[18] => Array
(
[usergroup] => Austin_Domestic
[DateAdded] => 2018-02-01
[Total] => 31
)
[19] => Array
(
[usergroup] => Austin_International
[DateAdded] => 2018-02-19
[Total] => 2
)
[20] => Array
(
[usergroup] => Bangkok
[DateAdded] => 2018-02-07
[Total] => 1
)
[21] => Array
(
[usergroup] => BayArea_Domestic
[DateAdded] => 2018-02-08
[Total] => 165
)
[22] => Array
(
[usergroup] => BayArea_International
[DateAdded] => 2018-02-12
[Total] => 29
)
Here is my code:
$selectallmonthlysql = 'SELECT locations, DateAdded, COUNT(*) as Total
FROM testserverdataSignup
WHERE DateAdded > "2017-12-31"
GROUP BY month(DateAdded), locations';
$selectAllmonthlystmt = $dbo->prepare($selectallmonthlysql);
$selectAllmonthlystmt->execute();
$selectAllmonthlylocations = $selectAllmonthlystmt->fetchAll(PDO::FETCH_ASSOC);
Screenshot of what the table currently looks like: I want the individual count for each location to correlate to the month and go across instead of down
First change your query
$selectallmonthlysql = '
SELECT
locations,
MONTHNAME(DateAdded) AS month,
COUNT(*) AS total
FROM
testserverdataSignup
WHERE
DateAdded > "2017-12-31"
GROUP BY month(DateAdded),locations';
I lowercased Total to total, its something that was irritating me.
With PDO then you can do
$results = $selectAllmonthlystmt->fetchAll(PDO::FETCH_GROUP);
foreach($results AS $location => $row ){
FETCH_GROUP is poorly documented but this will organize your data with the first column as the Key of the nested array, in this case the location, which is exactly what we want. One of the reasons I use PDO instead of that other DB library I won't mention by name but it starts with MySql and ends with i.
MONTHNAME (click for documentation) will return the full name of the month like "February" which although is not necessary (just a number would do) its much easier to read when outputting the array for debugging.
You'll wind up with something like this
//canned example data, notice one month is out of order and the big gap
// between February to October, this is to show it properly orders and
//fills those in. Always best to test this situations.
$result = array(
"Austin_Domestic" => array(
0 => Array(
"month" => "February",
"total" => 5
),
1 => Array(
"month" => "January",
"total" => 15
),
2 => Array(
"month" => "October",
"total" => 8
),
),
);
//$results = $selectAllmonthlystmt->fetchAll(PDO::FETCH_GROUP);
//then putting it all together
//we'll need the months in an array anyway so we can saves some space with them in the HTML too.
$months = array(
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
)
?>
<table id="registeredTable" class="table table-striped table-bordered table-hover">
<thead>
<tr>
<th>Locations</th>
<?php foreach($months as $month){
//Output the names of the months
echo "<th>{$month}</th>\n";
} ?>
</tr>
</thead>
<tbody>
<?php
foreach( $result as $location => $rows ){
echo "<tr>\n";
echo "<td>{$location}</td>\n";
//simplifies lookup by month (indexes are correlated)
//it returns column 'month' from $rows as a flat array.
//we can save ourselves an external loop by doing this "trick"
$m = array_column($rows, 'month');
//for example, in the case: [0=>February,1=>January,2=>October]
//because this is created from $rows, with a natural number index
//we can simply do array_search on $m to get the index we need in $rows (see below)
foreach($months as $month){
$index = array_search($month, $m);
if(false === $index){
echo "<td>0</td>\n";
}else{
echo "<td>{$rows[$index]['total']}</td>\n";
}
}
echo "</tr>\n";
}
?>
</tbody>
</table>
Output (I did format it to look a bit nicer):
<table id="registeredTable" class="table table-striped table-bordered table-hover">
<thead>
<tr>
<th>Locations</th>
<th>January</th>
<th>February</th>
<th>March</th>
<th>April</th>
<th>May</th>
<th>June</th>
<th>July</th>
<th>August</th>
<th>September</th>
<th>October</th>
<th>November</th>
<th>December</th>
</tr>
</thead>
<tbody>
<tr>
<td>Austin_Domestic</td>
<td>15</td>
<td>5</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>8</td>
<td>0</td>
<td>0</td>
</tr>
</tbody>
</table>
Sandbox
One note and benefit of using an array for the months is you spelled Feburary wrong it should be February something I've been guilty of many many times.
The only real downside to this, is the month name has to match the month name returned from the DB, which shouldn't be an issue if they are spelled correctly (which is how I found the mistake). Otherwise this can applied to the month as a number just as easily, same idea.
Cheers!
First, you should change the query to return MONTH(DateAdded) instead of the whole date, since that's how your output table is organized:
$selectallmonthlysql = 'SELECT locations, MONTH(DateAdded) AS month, COUNT(*) as Total
FROM testserverdataSignup
WHERE DateAdded > "2017-12-31"
GROUP BY month, locations';
Then you should reorganize the array into nested arrays:
array(location1 => array(month1 => total1, month2 => total2, ...),
location2 => array(month1 => total1, month2 => total2, ...),
...)
This code will do that:
$groupedData = array();
while ($selectAllmonthlystmt->fetch(PDO::FETCH_ASSOC) {
$groupedData[$row['locations']][$row['month']] = $row['Total'];
}
Then you can use nested loops when creating the table. The outer loop creates the rows, the inner loop is for the cells in the row.
foreach ($groupedData as $location => $locationData) {
echo "<tr><td>$location</td>";
for ($month = 1; $month <= 12; $month++) {
echo "<td>";
echo isset($locationData[$month]) ? $locaitonData[$month] : 0;
echo "</td>";
}
echo "</tr>";
}

Create spec HTML Table using PHP stdClass Object

I have an array of date, something like below
Array
(
[0] => stdClass Object
(
[question_id] => 64
[title] => Question1
[question_type_id] => 1
[settings] =>
[poll_id] => 5
[answer] => Array
(
[0] => stdClass Object
(
[answer_id] => 1
[poll_id] => 5
[question_id] => 64
[answer] => Answer1-1
[created_at] => 2018-07-08 17:36:15
)
[1] => stdClass Object
(
[answer_id] => 5
[poll_id] => 5
[question_id] => 64
[answer] => Answer1-2
[created_at] => 2018-07-08 19:27:33
)
)
)
[1] => stdClass Object
(
[question_id] => 65
[title] => Question2
[question_type_id] => 6
[settings] => ["više od 2km","manje od 2km"]
[poll_id] => 5
[answer] => Array
(
[0] => stdClass Object
(
[answer_id] => 2
[poll_id] => 5
[question_id] => 65
[answer] => Answer2-1
[created_at] => 2018-07-08 17:36:47
)
[1] => stdClass Object
(
[answer_id] => 6
[poll_id] => 5
[question_id] => 65
[answer] => Answer2-2
[created_at] => 2018-07-09 23:31:31
)
)
)
I need a table in browser to look like
enter image description here
Question1 Question2 Question3
Answer1-1 Answer2-1 Answer3-1
Answer1-2 Answer2-2 Answer3-2
This is my code:
<table class="table">
<thead>
<tr>
<?php foreach ($DATA['question'] as $question): ?>
<th><?php echo htmlspecialchars($question->title); ?></th>
<?php endforeach; ?>
</tr>
</thead>
<tbody>
<tr>
<?php foreach ($DATA['question'] as $question): ?>
<td><?php for ($i=0,$j=count((array)$question->answer);$i<$j;$i++) {
echo htmlspecialchars($question->answer[$i]->answer);
}?></td>
<?php endforeach; ?>
</tr>
</tbody>
My problem is that I can not place Answer1-2 in the next row of table.
Any idea?
Thanks a lot
There are a few options how you can do this.
Generate each of your intended columns as a single element and place that in a cell.
Populate an array in the way you wish to display them
Create a for(i=0;i<maxAmountOfAnswers;i++) wrapping another foreach (questions) and populate the table row by row.
Use DataTables or other libraries that can read a json.
Think about why you want this though; semantically tables are intended to display one kind of data. Is there a good reason why you wouldn't just show 1 table per question, or tables at all?
Thanks a lot for your answer! It is my solutionn.
<table class="table">
<thead>
<tr>
<?php foreach ($DATA['question'] as $question): ?>
<th><?php echo htmlspecialchars($question->title); ?></th>
<?php endforeach; ?>
</tr>
</thead>
<tbody>
<tr>
<?php foreach ($DATA['question'] as $question): ?>
<td><?php for ($i=0,$j=count((array)$question->answer);$i<$j;$i++) {
echo htmlspecialchars($question->answer[$i]->answer);
echo "<br />";
}?></td>
<?php endforeach; ?>
</tr>
</tbody>
</table>
And what is looks like.
enter image description here

How do I correct my arrays to create my desired table output?

I have two arrays, one for creating the first column (service) in a table like structure and the second for every other column (day) after that. First column array has the structure:
Array
(
[0] => DPW
[1] => PNS
[2] => WS1
[3] => WS2
)
This is a dynamic array so there could be more values than this, but it will always be unique and sorted alphabetically.
My second array for the other columns has the structure:
Array
(
[0] => Array
(
[Monday] => Array
(
[0] => Array
(
[date] => 42016
[message] => 07:00 START
[service] => DPW
)
[1] => Array
(
[date] => 42016
[message] => 16:30 START
[service] => PNS
)
[2] => Array
(
[date] => 42016
[message] =>
[service] => WS1
)
// etc ...
[3] => Array
(
[Thursday] => Array
(
[0] => Array
(
[date] => 42017
[message] =>
[service] => DPW
)
[1] => Array
(
[date] => 42017
[message] => 16:00 CUT OFF
[service] => DPW
)
[2] => Array
(
[date] => 42017
[message] =>
[service] => PNS
)
)
)
)
So basically each day is the next column. My problem is I initially thought that the service key in the second array was always in the same order for each day, but its not. You can see from the Thursday that DPW is twice in a row, whereas Monday isn't. I can change the format of these arrays, so this is where my questions lie.
View desired output
My thoughts are for starters the day should contain the same number of keys as the services array, so should I add a blank value to make up the same number of keys? To cater for the same service in a row should I add a further level to cater for multiple values look like so:
Array
(
// etc ...
[3] => Array
(
[Thursday] => Array
(
[0] => Array
(
[0] => Array
(
[date] => 42017
[message] =>
[service] => DPW
)
[1] => Array
(
[date] => 42017
[message] =>
[service] => DPW
)
)
[2] => Array
(
[0] => Array
(
[date] => 42017
[message] =>
[service] => PNS
)
)
[3] => Array
(
)
[4] => Array
(
)
)
)
)
I have also added in the blank values. Finally how would I print these values in the same order as the first (services) array so they aren't under the wrong service?
If is difficult to explain this and I could be going about it the wrong way, but that's why I am asking the questions.
EDIT:
Almost there with this, my only issue now is I need to show the Start and Cut Off date as being the same item spread out across multiple days. For instance the array might have these values at some point:
[1] => Array
(
[date] => 42016
[message] => 16:30 START
[service] => DPM
)
// etc...
[3] => Array
(
[date] => 42021
[message] => 16:30 CUT OFF
[service] => DPM
)
So I need a way to have these on their own row with a background colour or something to show they are the one item, like the graphic above. Not sure if this is possible?
Thanks
Robert!
I'm not sure this is exactly what you want, but it might help :
$services = array('DPW', 'PNS', 'WS1', 'WS2');
$days = array(
array(
'Monday' => array(
array(
'date' => 42016,
'message' => '07:00 START',
'service' => 'DPW'
),
array(
'date' => 42016,
'message' => '16:30 START',
'service' => 'PNS'
),
array(
'date' => 42016,
'message' => '',
'service' => 'WS1'
),
),
),
array(
'Thursday' => array(
array(
'date' => 42017,
'message' => '',
'service' => 'DPW'
),
array(
'date' => 42017,
'message' => '16:00 CUT OFF',
'service' => 'DPW'
),
array(
'date' => 42017,
'message' => '',
'service' => 'PNS'
)
)
)
);
And here is the HTML Table:
<?php $service_days = []; ?>
<table cellpadding="10" width="100%" align="left">
<thead>
<td style="background:#333;color:#FFF">Service</td>
<?php foreach($days as $day): ?>
<td style="background:#666;color:#FFF"><?php echo array_keys($day)[0]; ?></td>
<?php
foreach(array_values($day)[0] as $d)
$service_days[array_keys($day)[0]][$d['service']][] = $d;
?>
<?php endforeach; ?>
</thead>
<?php foreach($services as $service): ?>
<tr>
<td><?php echo $service ?></td>
<?php foreach($service_days as $day => $srv): ?>
<td>
<?php foreach($srv as $_service => $periode): ?>
<?php if($_service == $service): ?>
<?php foreach($periode as $p): ?>
<p style="background:#DDD"><?php echo $p['date'], '<br>', $p['message']; ?></p>
<?php endforeach; ?>
<?php endif; ?>
<?php endforeach; ?>
</td>
<?php endforeach; ?>
</tr>
<?php endforeach; ?>
</table>

Parsing Multidimensional Array in PHP

Apologies if this is a duplication of another answer, I have spent a considerable amount of time looking through this and other forums without finding an explanation that makes sense to my very small brain.
I have a multi-dimensional array that I need to parse through using PHP:
Array
(
[dataSetOut] => Array
(
[diffgram] => Array
(
[anonymous] => Array
(
[maindb_productionhistory] => Array
(
[0] => Array
(
[z_internal_sequence] => 1
[z_internal_groupid] => 0
[z_internal_colorbg] => 15461355
[z_internal_colorfg] => 0
[maindb_productionhistory_operation] => 0402D04
[maindb_productionhistory_date] => 2014-02-19T00:00:00+00:00
[maindb_productionhistory_shift] => 1
[maindb_productionhistory_transcode] => 33
[maindb_productionhistory_qty] => 153
[!diffgr:id] => maindb_productionhistory1
[!msdata:rowOrder] => 0
)
[1] => Array
(
[z_internal_sequence] => 2
[z_internal_groupid] => 0
[z_internal_colorbg] => 16777215
[z_internal_colorfg] => 0
[maindb_productionhistory_operation] => 0402D04
[maindb_productionhistory_date] => 2014-02-19T00:00:00+00:00
[maindb_productionhistory_shift] => 1
[maindb_productionhistory_transcode] => 34
[maindb_productionhistory_qty] => 6
[!diffgr:id] => maindb_productionhistory2
[!msdata:rowOrder] => 1
)
)
)
)
)
[errorMessage] =>
)
I am looking to output a table like:
Operation | Date | Qty
0402D04 | 2014-02-19 | 153
0402D04 | 2014-02-19 | 6
<table>
<thead>
<tr>
<th>Operation</th>
<th>Date</th>
<th>Qty</th>
</tr>
</thead>
<tbody>
<?php
foreach($array['dataSetOut']['diffgram']['anonymous']['maindb_productionhistory'] as $val){
echo "<tr>";
echo "<td>".$val['maindb_productionhistory_operation']."</td>";
echo "<td>".date('Y-m-d',strtotime($val['maindb_productionhistory_date']))."</td>";
echo "<td>".$val['maindb_productionhistory_qty']."</td>";
echo "</tr>";
}
?>
</tbody>
</table>

Print two-column table from Mongo aggregation in PHP

I have the following Mongo aggregation in PHP:
$results = $collection1 -> aggregate (array(
'$group' => array(
'_id' => '$Issue',
'total' => array('$sum' => 1 ),
)), array( '$sort' => array( 'total' => -1 ), ));
print_r($results);
It adequately produces the following output:
Array ( [result] => Array ( [0] => Array ( [_id] => Sales [total] => 51 )
[1] => Array ( [_id] => Service [total] => 41 ) [2] => Array ( [_id] =>
Marketing [total] => 31 ) [3] => Array ( [_id] =>Delivery [total] => 28 )
... etc.
Pardon my "noob" question here, but how do I format this into a simple two-column HTML format showing the name of the category in the first column (e.g., Sales, Marketing, etc.) and the total for each category on the same row?
I don't want to use print_r or var_dump and I've tried various 'foreach' and 'while' methods from this site and am just stumped at this point.
Thank you, kindly, in advance.
Hmm maybe I have missed something here but does this do it?
<table>
<thead>
<tr>
<th></th><th>Total</th>
</tr>
</thead>
<tbody>
foreach($output_var['result'] as $row){
?><tr><td><? echo $row['_id']; ?></td><td><? echo $row['total'] ?></td></tr><?
}
</tbody>
</table>

Categories