I want to merge the table row if the date have an same id's. I have some array data like this :
Array
(
[0] => Array
(
[id] => 2
[date] => 05/13/2014
[content] => some contents 1
[act] => act1 act2 act3
)
[1] => Array
(
[id] => 2
[date] => 05/28/2014
[content] => some contents 1
[act] => act1 act2 act3
)
[2] => Array
(
[id] => 7
[date] => 06/04/2014
[content] => some contents 2
[act] => act1 act2 act3
)
)
Then I tried to group its data into the same id by :
if($queryx = $this->mymodel->myfunction($par)){
$datax = $queryx;
}
$i = 0;
foreach ($datax as $idx => $val) {
$dates[$val['id']][$i] = $val['date'].",".$val['id'];
$contn[$val['id']][$i] = $val['content'];
$i++;
}
then :
$j = 0; $y = 0;
echo "<table border='1'>\r\n";
foreach ($dates as $idx => $val) {
$tmpexp = explode(',', $val[$j]);
echo "<tr>\r\n";
echo "<td rowspan='".count($val)."'>".$tmpexp[0]."</td>\r\n";
foreach ($val as $idx1 => $val1) {
if($idx1 > 0)
{
echo "<tr>\r\n";
}
echo "<td>".$dates[$tmpexp[1]][$y]."</td>\r\n";
if($idx1 < 1)
{
echo "<td rowspan='".count($val)."'>".$contn[$tmpexp[1]][$y]."</td>\r\n";
echo "<td rowspan='".count($val)."'>act1 act2 act3</td>";
echo "</tr>\r\n";
}
$y++;
}
$j++;
}
echo "</table>";
There is no problem if the data have at least two child, but if the date only have one child (see data with id's 7) there is show an error because Undefined offset. So how I add some handler if there is only one child on the data. There is my desired result:
Please see this image:
I use the 'read ahead' technique for processing nested loops. It does mean that 'foreach' loops cannot be used as the next record must be read as soon as the current one has been processed. Basically, the last action you do in the loop is read the next record as you are setting it up for the next iteration. Note, you never test when to print a record as that is decided by the structure of the groups. The code loops are the same as the structure of the groups in the data
A 'group' is all the records with the same id.
I assume that the 'content' and 'act' are identical for each entry in the group.
Edited to add 'rowspan' attributes to the appropriate 'td' tags. I suspect css may be easier at this point.
The issue is that the group cannot be displayed until it is known how many entries are in it.
So, i 'buffer' all the records belonging to a group in an array. at the end of the group, it is displayed with the appropriate 'rowspan' attributes in the html.
It is tested on PHP 5.3.18. It includes test data.
<?php /* Q24028866 */
$testData = array(array('id' => 2, 'date' => '05/13/2014', 'content' => 'some contents 2', 'act' => 'act1 act2 act3'),
array('id' => 2, 'date' => '05/28/2014', 'content' => 'some contents 2', 'act' => 'act1 act2 act3'),
array('id' => 7, 'date' => '06/04/2014', 'content' => 'some contents 7', 'act' => 'act1 act2 act3'),
array('id' => 8, 'date' => '06/08/2014', 'content' => 'some contents 8', 'act' => 'act1 act2 act3'),
array('id' => 8, 'date' => '06/09/2014', 'content' => 'some contents 8', 'act' => 'act1 act2 act3'));
?>
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<table border='1'>
<thead><th>Date</th><th>Content</th><th>Act</th></thead>
<?php
// use 'read ahead' so there is always a 'previous' record to compare against...
$iterContents = new \ArrayIterator($testData);
$curEntry = $iterContents->current();
while ($iterContents->valid()) { // there are entries to process
$curId = $curEntry['id'];
// buffer the group to find out how many entries it has...
$buffer = array();
$buffer[] = $curEntry;
$iterContents->next(); // next entry - may be same or different id...
$curEntry = $iterContents->current();
while ($iterContents->valid() && $curEntry['id'] == $curId) { // process the group...
$buffer[] = $curEntry; // store all records for a group in the buffer
$iterContents->next(); // next entry - may be same or different id...
$curEntry = $iterContents->current();
}
// display the current group in the buffer...
echo '<tr>';
echo '<td>', $buffer[0]['date'], '</td>';
$rowspan = count($buffer) > 1 ? ' rowspan="'. count($buffer) .'"' : '';
echo '<td', $rowspan, '>', $buffer[0]['content'], '</td>',
'<td', $rowspan, '>', $buffer[0]['act'], '</td>';
echo '</tr>';
for($i = 1; $i < count($buffer); $i++) {
echo '<tr><td>', $buffer[$i]['date'], '</td>';
echo '</tr>';
}
} ?>
</table>
</body>
</html>
The following code will give you a clue what you should do,
$newArray = array();
$counter=0;
foreach($datax as $key=>$val){
$newArray[$val['id']][$counter]['date'] = $val['date'];
$newArray[$val['id']][$counter]['content'] = $val['content'];
$newArray[$val['id']][$counter]['act'] = $val['act'];
$counter++;
}
$newArray = array_map('array_values', $newArray);
Related
I am trying to display my data group by keyregion and then group by key_region currently it is working fine for key_region but for group by keyregion is not working headings are repeating, if headings are same it has to comes only one for keyregion see here output
Code:
Working of While loop is -
First it sort data with keyregion
After sorting with keyregion, it sort with key_region and year and group together.
var_export for $Zeile
array (
0 =>
(object) array(
'reisenr' => '2191302',
'beginn' => '2021-10-02',
'ende' => '2021-10-25',
'airline' => 'AI',
'status' => '4',
'price' => '4998',
'keywords' => 'indien24',
'keyregion' => 'Himalaya',
'key_region' => 'Indien & Himalaya',
'Shortlink' => 'die-indienreise.de/intensiv',
'keycountry' => 'India',
'tourname' => 'Indien Intensiv',
'jahr' => '2021',
'month' => '10',
'beginn_f' => 'Sa, 2. Okt',
'ende_f' => 'Mo, 25. Okt 2021',
'comment_de' => '',
'tage' => '23',
)
<?php
function ausgabe_einfach($zeile)
{
$i=0;
while(count($zeile) - 1 > $i){
global $status;
$keywords = $zeile[$i]->keywords;
$jahr = $zeile[$i]->jahr;
$key_region = $zeile[$i]->key_region;
$keyregion = $zeile[$i]->keyregion;
$beginn = $zeile[$i]->beginn;
?>
<table class="termine">
// Here is heading for $keyregion & $keycountry
<div class="date" style="color:#fc453e"><b><?php echo $keyregion; ?> <?php echo $jahr;?></b><br></div><b><caption class="date1"><?php echo $key_region; ?> </b></caption>
<?php
$j=$i+1;
//printing some values here
while((count($zeile) - 1 > $i) && (count($zeile) - 1 > $j) && ($j > $i) && ($jahr == $zeile[$j]->jahr) && (strtolower($key_region) == strtolower($zeile[$j]->key_region)) && (date("Y", strtotime($zeile[$i]->beginn)) == date("Y", strtotime($zeile[$j]->beginn))) && (strtolower($keyregion) == strtolower($zeile[$j]->keyregion))){
"";
//Printing output values here
like ReiseNR
$i++;
$j++;
}
$i++;
}
?>
<?php
}
If there any help in resolving my issue that will be much helpful for me and appreciated.
can you give me idea how to implement this idea for "dynamic" html table.
I have an array
$arr = array(
array(
'label' => 'First name',
'data' => array(
array('fname' => 'John'),
array('fname' => 'Ralph'),
),
),
array(
'label' => 'Last name',
'data' => array(
array('lname' => 'Doe'),
array('lname' => 'Loren'),
),
),
array(
'label' => 'Description',
'data' => array(
array('description' => 'Something bout John'),
array('description' => 'Something about Ralph'),
),
),
);
Now from the keys 'label' im creating the table columns
---------------------------------------
|First Name | Last Name | Description |
---------------------------------------
The problem is how to put 'fname' keys in the first column, 'lname' in the second and 'description' in the third.
With this part of code im trying to put the data in all columns
private function tableBody()
{
$data = $this->data;
$table = '<tbody>';
foreach($data as $key => $value){
foreach($value['data'] as $k => $v){
$table .= '<tr>';
foreach($v as $col => $name){
$table .= '<td>' . $name . '</td>';
}
$table .= '</tr>';
}
}
$table .= '</tbody>';
return $table;
}
Also my idea is not to hard code array keys for multiple usage(except label and data).
First I would remap the data to process it in loops.
$labels = [];
$rows = [];
foreach($arr as $column) {
$label = $column['label'];
$labels[] = $label;
foreach($column['data'] as $key => $value) {
$rows[$label][] = $value;
}
}
Now print out the labels with the headline.
echo "<table>\n";
echo "<tr>";
foreach($labels as $label) echo "<th>{$label}</th>";
echo "</tr>\n";
Iterate through the rows and create the HTML.
$labelCount = count($labels);
$rowCount = count($rows[$labels[0]]);
while($rowCount) {
echo "<tr>";
for ($i = 0; $i < $labelCount; $i++) {
$current = array_shift($rows[$labels[$i]]);
$value = reset($current);
echo "<td>{$value}</td>";
}
echo "</tr>\n";
$rowCount--;
}
echo "</table>\n";
This gives a table like below
<table>
<tr><th>First name</th><th>Last name</th><th>Description</th></tr>
<tr><td>John</td><td>Doe</td><td>Something bout John</td></tr>
<tr><td>Ralph</td><td>Loren</td><td>Something about Ralph</td></tr>
</table>
You need to manipulate the initial array to reduce it to something more manageable. You could brute force your way like so:
function reduce($data) {
$ret = [];
foreach ($data as $d1) {
// column header could have been fetched here
foreach ($d1 as $k2 => $d2) {
// keeping track of what label we need
$key = '';
// keeping the values together
$child = [];
// discarding non arrays
if (is_array($d2)) {
foreach ($d2 as $d3) {
// identifier fetch from this level
foreach ($d3 as $k4 => $d4) {
$key = $k4;
$child[] = $d4;
}
}
}
// assigning back to the main array only if we have something
if (!empty($child)) {
$ret[$key] = $child;
}
}
}
return $ret;
}
That will return the following:
Array
(
[fname] => Array
(
[0] => John
[1] => Ralph
)
[lname] => Array
(
[0] => Doe
[1] => Loren
)
[description] => Array
(
[0] => Something bout John
[1] => Something about Ralph
)
)
I have a page which shows data from a database which has a unserialized data. The unserialized data looks like that:
array (
'text-name' => 'test',
'email' => 'test#gmail.com',
'text-company' => 'test',
'tel-number' => '978456132',
'products' =>
array (
0 => 'Domains',
1 => 'Weebly',
),
'menu-country' => 'Austria',
'number' => '1001 - 10,000',
'text-current-registrar' => '5',
'notes' => 'test',
'text-current-url' => 'https://www.foo.com/boo-foo/',
'text-previous-url' => 'https://www.foo.com/boo-foo/',
'text-utm_source' => '',
'text-utm_medium' => '',
'text-utm_campaign' => '',
'gdpr-b' =>
array (
0 => 'I',
),
'gdpr-c' =>
array (
0 => 'I',
),
'gdpr-d' => NULL,
'gdpr-e' => NULL,
)
the data in the DB is in this format: 'a:18:{s:9:"text-name";s:4:"test";s:5:"email";s:14:"test#gmail.com";s:12:"text-company";s:4:"test";s:10:"tel-number";s:9:"978456132";s:8:"products";a:2:{i:0;s:7:"Domains";i:1;s:6:"Weebly";}s:12:"menu-country";s:7:"Austria";s:6:"number";s:13:"1001 - 10,000";s:22:"text-current-registrar";s:1:"5";s:5:"notes";s:4:"test";s:16:"text-current-url";s:59:"https://www.bla.com/foo-bar/";s:17:"text-previous-url";s:59:"https://www.bla.com/foo-bar/";s:15:"text-utm_source";s:0:"";s:15:"text-utm_medium";s:0:"";s:17:"text-utm_campaign";s:0:"";s:6:"gdpr-b";a:1:{i:0;s:1:"I";}s:6:"gdpr-c";a:1:{i:0;s:1:"I";}s:6:"gdpr-d";N;s:6:"gdpr-e";N;}'
the php code to display is as follows:
<?php
$no = 1;
while ($row = mysqli_fetch_array($query))
{
echo '<tr>';
echo '<td>'.$no.'</td>';
echo '<td>'.$row['form'].'</td>';
$formdata = unserialize($row['data']);
foreach ($formdata as $key => $fdata)
{
if( sizeof($fdata) !=1 )
{
if (is_array($fdata)) {
$fsofdata = array_map('unserialize', $fdata);
foreach ($fsofdata as $prod => $prodvalue)
{
if ( ($prod === 'gdpr-b') || ($prod === 'gdpr-c') || ($prod === 'gdpr-d') || ($prod === 'gdpr-d') ) {
foreach ($prodvalue as $pprod => $pprodvalue)
{
echo '<td>'.$pprod.''.($pprodvalue).'</td>';
}
}
else {
echo '<td>'.($prodvalue).'</td>';
}
}
}
else {
echo '<td>'.($fdata).'<td/>';
}
}
else {
echo '<td>'.($fdata).'<td/>';
}
}
echo '<td>'.$row['date']. '</td>';
echo '</tr>';
$no++;
}
?>
The problem here is that the data which is present inside the products array and the gdpr-b, gdpr-c variables are showing as array i tried array_map on the data but that too didnt help how do i display the values in the array in the table.
serialize() and unserialize() are dual - i.e. if you have an array and serialize it then unserialize will get you back the exact same array (including all nested sub-arrays).
However, if your original array contained elements which are the serialization of another arrays (so these elements are currently strings) - then you will have to iterate over your 1-st level array and unserialize each individual item.
The best approach is to serialize only the top-level array as a whole - not each of its items.
And if your array does not contain objects - it is much better to use json_encode and json_decode
$_REQUEST = array(
'articolo' => array(
1 => 1,
3 => 'Sostituzione sostituzioni',
4 => 'Cambio olio'
),
'specifica' => array(
1 => 2,
3 => 'Camoin',
4 => 'Furgone'
),
'quantita' => array(
1 => 3,
3 => 5,
4 => 7
)
);
i need to insert on database like this
$_REQUEST['articolo'][1]
$_REQUEST['specifica'][1]
$_REQUEST['quantita'][1]
on database row and
$_REQUEST['articolo'][3]
$_REQUEST['specifica'][3]
$_REQUEST['quantita'][3]
on another row and ...
$_REQUEST['articolo'][4]
$_REQUEST['specifica'][4]
$_REQUEST['quantita'][4]
i just want to know how to make another array row by row
i need to print
1 -> $_REQUEST['articolo'][1]
2 -> $_REQUEST['specifica'][1]
3 -> $_REQUEST['quantita'][1]
Sostituzione sostituzioni -> $_REQUEST['articolo'][3]
Camoin -> $_REQUEST['specifica'][3]
5 -> $_REQUEST['quantita'][3]
Cambio olio -> $_REQUEST['articolo'][4]
Furgone -> $_REQUEST['specifica'][4]
7 -> $_REQUEST['quantita'][4]
thank
you need something like this:
foreach ($request as $key => $value)
{
$request[$key][1] //row1
$request[$key][3] //row2
$request[$key][4] //row3
}
Edit Based on the comments:
if the array is dynamic(you do not know the keys of the sub-array), you can do this instead:
foreach ($request as $key => $value)
{
foreach ($request[$key] as $key2 => $value2)
{
$request[$key][$key2] //here are your values
}
}
Now you have an idea on how to do it right? use those values inside that foreach to add data to your database
$name = array_keys($_REQUEST);
$index = array_keys($_REQUEST['articolo']);
for($i=0; $i < count($index); $i++):
if($i + 1 % count($index)):
for($j=0; $j < count($name); $j++):
echo $name[$j].': '.$_REQUEST[$name[$j]][$index[$i]].'<br>'."\n";
endfor;
echo '<hr>';
endif;
endfor;
output it's right now
articolo: 1
specifica: 2
quantita: 3
articolo: Sostituzione sotituzioni
specifica: Camoin
quantita: 5
articolo: Cambio olio
specifica: Furgone
quantita: 7
now just need to insert the ordinate data on database
I'm sure there's a fairly easy way to do this. I have an the following data in an array:
Array
(
[ActivityDiaryEntry] => Array
(
[date] => 2011-03-03
[type] => Walking
[minutes] => 60
)
)
Array
(
[ActivityDiaryEntry] => Array
(
[date] => 2011-03-02
[type] => Walking
[minutes] => 22
)
)
Array
(
[ActivityDiaryEntry] => Array
(
[date] => 2011-03-01
[type] => Biking
[minutes] => 45
)
)
I'm not too skilled at PHP, but I know how to display this data by row to display as <tr><td>[date]</td><td>[type]</td><td>[minutes]</td></tr>. But I'd like to have the data display in columns like this:
2011-03-01 | 2011-03-02 | 2011-03-03
------------------------------------
Biking | Walking | Walking
------------------------------------
45 | 22 | 60
I didn't test this, but it should work. It should serve as an example of what needs to be done. I tried to write this to limit the number of foreach loops used. If I reordered the data first and then performed the takes, I'd of needed 4 foreach loops. The benefit to this method is that you don't need to update the code if more columns are added, so long as all records have the same number of columns.
<?php
// Your list of records
$records = array(
array( "key1" => "value", "key2" => "value", "key3" => "value" ),
array( "key1" => "value", "key2" => "value", "key3" => "value" ),
array( "key1" => "value", "key2" => "value", "key3" => "value" )
);
// Create an array to store the values of each row based on number of columns in first value
$rows = array_fill( 0, count( $records[0] ), "" );
$keys = array_keys( $records[0] );
// Create a column for each record in it's respective row.
foreach( $records as $k => $record )
for( $i=0, $max=count( $rows ); $i < $max; $i++ )
$rows[ $i ] .= "<td>".$record[ $keys[ $i ] ]."</td>";
// Turn each row in our array into an html table row.
print "<tr>".implode( "</tr><tr>", $rows )."</tr>";
Here's the code test: http://codepad.org/SSS8S2eU
A little ugly but works :')
$a[0] = array('ActivityDiaryEntry' => array("date" => "2011-03-03", "type"=> "Walking", "minutes" => 60));
$a[1] = array('ActivityDiaryEntry' => array("date" => "2011-03-03", "type"=> "Walking", "minutes" => 22));
$a[2] = array('ActivityDiaryEntry' => array("date" => "2011-03-03", "type"=> "Biking", "minutes" => 42));
$keys = array_keys($a[0]["ActivityDiaryEntry"]);
echo '<table>';
for($c = 0; $c < count($a); $c++) {
echo '<tr>';
for($i = 0; $i < count($a[$c]['ActivityDiaryEntry']); $i++) {
echo '<td>' . $a[$i]['ActivityDiaryEntry'][$keys[$c]] . '</td>';
}
echo '</tr>';
}
echo '</table>';
http://codepad.org/5Tuk8x3Q
This code works if i am not wrong defining the array, but i suggest you play with all the options provided here and find a better solution.
$data = array (
array (
'ActivityDiaryEntry' => array
(
'date' => "2011-03-03",
'type' => "Walking",
'minutes' => 60
)
),
array (
'ActivityDiaryEntry' => array
(
'date' => "2011-03-02",
'type' => Walking,
'minutes' => 22
) ),
array (
'ActivityDiaryEntry' => array
(
'date' => "2011-03-01",
'type' => Biking,
'minutes' => 45
)
)
);
echo "<table>";
$i = 0;
foreach ($data as $key => $val) {
echo "<tr>";
foreach ($data as $kk => $vv){
if ($i==0) {
echo "<td>". $vv['ActivityDiaryEntry']['date'] ."</td>";
}else if ($i == 1){
echo "<td>". $vv['ActivityDiaryEntry']['type'] ."</td>";
}else if ($i == 2){
echo "<td>". $vv['ActivityDiaryEntry']['minutes'] ."</td>";
}
}
echo "</tr>";
$i++;
}
echo "</table>";
This would be a great candidate for DataTables, which is actually Javascript that I use to display my results generated on the back end by PHP. It's a full-blown javascript grid system that adds a ton of features to standard HTML table outputs. To make it work you would:
Get your results as shown and output as a json_encoded string (i.e, echo json_encode($array) I do this in a separate file so it outputs clean text to the screen.
On the page to display the table, setup a "dummy table"
Setup Datatables in the same page as the dummy table like this:
$(document).ready(function() {
$('#replace').dataTable( {
"bProcessing": true,
"sAjaxSource": 'file.php'
} );
} );
Set values for sorting, filtering, paging, etc. per the tutorial.
Datatables gives you so much more power than just a standard HTML table, and you're already 90% of the way there with the data. It's so much more user friendly than just jamming stuff on the screen.
Before transposing your data (converting columns to rows), you must reduce the depth/complexity by removing the unusable first level and generate an indexed array of what is left.
Then iterate the first array in the new, simplified data structure and extract column data. Each column (there are three) will be displayed in its own table row using a flexible implode()ing technique.
Code: (Demo)
$subarrays = array_column($array, "ActivityDiaryEntry");
echo '<table>';
foreach ($subarrays[0] as $column => $notUsed) {
echo '<tr><td>' , implode('</td><td>', array_column($subarrays, $column)) , '</td></tr>';
}
echo '</table>';
Output:
<table>
<tr>
<td>2011-03-03</td>
<td>2011-03-03</td>
<td>2011-03-03</td>
</tr>
<tr>
<td>Walking</td>
<td>Walking</td>
<td>Biking</td>
</tr>
<tr>
<td>60</td>
<td>22</td>
<td>42</td>
</tr>
</table>
You could write a for loop for each field, displaying one row in each loop.
The Javascript answer below might be a good way to do it, but I would suggest using PHP and tables if you are not completely comfortable using Javascript in your applications. It is also good PHP practice.
If I were you, I'd use code like this, and css properties to format the table how you'd like.
echo '<table>';
echo '<tr><td>Date</td><td>Type</td><td>Minutes</td></tr>';
foreach ($array as $entry){
echo '<tr>';
echo '<td>'.$entry['date'].'</td>';
echo '<td>'.$entry['type'].'</td>';
echo '<td>'.$entry['minutes'].'</td>';
echo '</tr>';
}
echo '</table>';
You can use stuff like this to edit your tables display, also check out http://www.w3schools.com/css/css_table.asp
echo '<tr style="border-bottom: 1px solid black;"></tr>';
cheers