I have an script for getting a table from a DB which is written in PHP.
I am trying to add name for each column to be in the first row:
A part of the Code is:
$rows = [];
foreach (range(1, 4) as $row) {
$rows[$row] = "";
}
$rows["Name"] = $order->user->aFirstName;
$rows["Last Name"] = $alumn->aLastName;
$rows["Age"] = $alumn->aAge;
$rows["Gender"] = $alumn->aGender;
$string = "";
foreach ($rows as $r) {
$string .= $r . "\t";
}
what I want to get is
1 | Name | Last Name | Age | Gender
2 | John | Des | 45 | Male.
What I get now is the data in 1st row.
1 | John | Des | 45 | Male.
Any suggestion? Thanks
You can create a new first element in $rows using https://www.php.net/manual/de/function.array-unshift.php
$labels = ["Name" => "NameLabel", "Last Name" => "Last NameLabel" ...];
array_unshift($rows, $labels);
So the first element of the $rows array are the labels. Now when the table is generated is will display the labels at the top.
You are loading the arrays incorrectly.
I assume you dont want to get the column names from the meta data available to you, and are happy to add the column names manually, if not let me know
$rows = [];
// add labels
$rows[] = ["Name", "Last Name", "Age", "Gender"];
#$rows[] = [$order->user->aFirstName, $alumn->aLastName, $alumn->aAge, $alumn->aGender];
// I dont have your data, so this is to simulate the above line
$rows[] = ['John', 'Des', 45, 'Male'];
$string = '';
foreach ($rows as $i => $row) {
$n = $i+1;
$string .= "$n\t";
foreach ($row as $col){
$string .= $col . "\t";
}
$string .= '<br>'. PHP_EOL;
}
print_r($string);
RESULTS, as you can see a Tab is not really enough to correctly format the table
1 Name Last Name Age Gender <br>
2 John Des 45 Male <br>
Related
This question already has answers here:
Transpose 2d array, join second level with commas, and join first level with pipes
(5 answers)
Closed 7 months ago.
i am using form to insert multiple passenger list using implode
form passenger list
view passenger list
In controller
$passname=''.implode("*",$this->input->post("passangernm")).'';
$passage=''.implode("*",$this->input->post("psgage")).'';
$passgender=''.implode("*",$this->input->post("psggender")).'';
$passpref=''.implode("*",$this->input->post("psgpref")).'';
In View
<td>".implode(explode('*',$rec->passangerName)," | ")." ".implode(explode('*',$rec->passangerAge)," | ")." ".implode(explode('*',$rec->passangerGender)," | ")."</td>
Result show like
Roshan | Gyan | manish 23 | 23 | 23 male | male | male lower | middle | upper
But I need like this format
Roshan 23 male lower | Gyan 23 male middle | manish 23 male upper|
You can first count the total number of values in any one of them then use for loop to show all the data as you want, like so -
$passangerNameArr = explode('*', $rec->passangerName);
$passangerAgeArr = explode('*', $rec->passangerAge);
$passangerGenderArr = explode('*', $rec->passangerGender);
$passangerBerthArr = explode('*', $rec->your_varialbe); // Name not provided in your code(change here)
// All the other value count should be equal to this one ↓↓ ie if 2 passengers then 2 ages and gender
$total = count($passangerNameArr);
for($i = 0; $i < $total; $i++){
echo "<td>";
// notice the spaces and double quotes ↓↓ (You can also use for space)
echo "{$passangerNameArr[$i]} {$passangerAgeArr[$i]} {$passangerGenderArr[$i]} {$passangerBerthArr[$i]}";
echo " | ";
echo "</td>
}
Also, keep in mind that this is assuming you always have more than one data in your column, so you should first check if the returned variable is an array only then you should apply this code.
Hope this helps you.
I would definitely recommend not storing passenger details in a delimited format. Each value should be it's own column (ideally on another table that you can join).
You can store it as JSON which is easier to work with, but either way it makes that data difficult to search on.
Based on this scenario and assuming there are values for every field that match up correctly, I think it might make more sense to create an array of strings in the Controller and use that to display the data in the View.
Get the POST data in the Controller:
list($passnames) = $this->input->post("passangernm");
list($passages) = $this->input->post("psgage");
list($passgenders) = $this->input->post("psggender");
list($passprefs) = $this->input->post("psgpref");
Loop through the data in the Controller to build strings:
$passengersArray = [];
foreach($passnames as $key => $name) {
$passengersArray[] = $name . " " . $passages[$key] . " " . $passgenders[$key] . " " . $passprefs[$key];
}
$passengersArray should now be an array of strings where each array item is a different passenger, so in the View you can implode them with | delimiter:
"<td>" . implode("|", $passengersArray) . "</td>"
You can use array_column like so. This will still work even if the names/ages/genders/preferences don't have the same number of items in them:
$names = ["Roshan", "Gyan", "manish"];
$ages = ["23", "23", "23"];
$genders = ["male", "male", "male"];
$preferences = ["lower", "middle", "upper"];
$data = [$names, $ages, $genders, $preferences];
$max_len = count(max($data));
$combined = [];
for($i=0; $i<$max_len; $i++){
$combined[] = implode(" ", array_column( $data, $i ) );
}
echo '<td>' . implode(" | ", $combined) . '</td>';
If you can change the way the passenger details are stored in the database, I agree with Spudly that are better ways of storing the data.
Alternative answer
The following also works:
$combined = [];
array_map(function(...$params) use (&$combined){
$combined[] = implode(" ", $params);
}, $names, $ages, $genders, $preferences);
echo '<td>' . implode(" | ", $combined) . '</td>';
Here's the CSV table:
-------------------------
| Name | Age | Favorite |
-------------------------
| John | 30 | Apple |
-------------------------
| Bill | 25 | Grape |
-------------------------
| Ann | 40 | Orange |
-------------------------
Now, using strictly PHP, is there anyway to sort only the "Favorite" by ascending order of "Age"? An expected output would be something like this:
25 Grape
30 Apple
40 Orange
I've been using fgetcsv to echo them onto the document, but they are not not sorted by ascending age, of course. Is there anyway to throw these in an array or something, sort by age, and then echo?
To open up your CSV file:
function readCSV($file)
{
$row = 0;
$csvArray = array();
if( ( $handle = fopen($file, "r") ) !== FALSE ) {
while( ( $data = fgetcsv($handle, 0, ";") ) !== FALSE ) {
$num = count($data);
for( $c = 0; $c < $num; $c++ ) {
$csvArray[$row][] = $data[$c];
}
$row++;
}
}
if( !empty( $csvArray ) ) {
return array_splice($csvArray, 1); //cut off the first row (names of the fields)
} else {
return false;
}
}
$csvData = readCSV($csvPath); //This is your array with the data
Then you could use array_multisort() to sort it on a value.
<?php
// Obtain a list of columns
foreach ($csvData as $key => $row) {
$age[$key] = $row['volume'];
$favorite[$key] = $row['edition'];
}
// Sort the data with age first, then favorite
// Add $csvData as the last parameter, to sort by the common key
array_multisort($age, SORT_ASC, $favorite, SORT_ASC, $csvData);
?>
I have view cart session like this
ID NAME DISC QTY
-- ---- ------ ------
1 AAAA D1 2
1 AAAA D5 1
2 BBBB D1 1
1 AAAA D1 1
What I want is, showing a query session with result like this
NAME TOTAL
---- ------
AAAA 4
BBBB 1
How can I do this?
I have a query like this for show cart:
<?php
if(count($_SESSION[data1][ID])>0)
for($i=0;$i<count($_SESSION[data1][ID]);$i++)
{
if($_SESSION[data1][ID][$i]!='')
{ ?>
<td ><?=$_SESSION[data1][ID][$i]?></td>
<td ><?=$_SESSION[data1][NAME][$i]?></td>
<td ><?=$_SESSION[data1][DISC][$i]?></td>
<td ><?=$_SESSION[data1][QTY][$i]?></td>
<?php } } ?>
You can simply loop through the data adding the quantities to an array indexed by the name.
Quick'n'dirty example
<?php
$names = array("AAA", "BBB", "AAA", "BBB");
$qts = array(1, 2, 3, 4);
for ($i=0; $i<count($names); $i++)
{
$res[$names[$i]] += $qts[$i];
}
$k = array_keys($res);
for ($i=0; $i<count($k); $i++)
{
echo $k[$i] . ":" . $res[$k[$i]] . "<br/>";
}
?>
AAA:4
BBB:6
You can create a new array $resultArray and take $_SESSION['data1'] in foreach loop, and check if ID does exists in $resultArray, if yes, append it, other wise create it.
<?php
$resultArray = array();
if(count($_SESSION['data1'])>0){
foreach($_SESSION['data1'] as $data){
if(isset($resultArray[$data['ID']])){
$resultArray[$data['ID']] += $data['QTY'];
} else {
$resultArray[$data['ID']] = $data['QTY'];
}
}
}
print_r($resultArray); //check out result
?>
I am trying to retrive data from database using FECH_ASSOC in order the output will took like this
last1 first1 last2 first2 & last3 first3
last4 first4 & last4 first4
this is the database i have:
ID index first last
--------------------------
1 1 first1 last1
2 1 first2 last2
3 1 first3 last3
4 2 first4 last4
5 2 first5 last5
Each output row shoud defined by the index value.
as you can see in the output example I need the organ before the last one in any array to be separetad because i need to put the & before it.
this is the code i came up with:
//HERE I RETRIVE ALL THE DATA FROM THE DATABASE.
$sql = "SELECT COUNT( * ) FROM table WHERE index= $index";
$result = $dbh->prepare($sql);
$result->execute();
$number_of_rows = $result->fetchColumn();
//ASSOC DEFINITION
$sth = $dbh->prepare("SELECT * FROM table WHERE index= $index);
$sth->execute();
$value = $sth->fetch(PDO::FETCH_ASSOC);
//THIS IS WHERE I CALL ALL THE ROWS BY THEIR VALUE
$return = "";
$fname = $value['fname'];
$lname = $value['lname'];
$numRow = $number_of_rows-2; // THE ITEM BEFORE THE LAST ONE IN THE ARRAY
$lastItem = $number_of_rows - 1; //LAST INDEX IN THE ARRAY
for($counter = 0; $counter <= $numRow; $counter++){
$value = $sth->fetch(PDO::FETCH_ASSOC);
$fname[$counter] = !empty($fname[$counter]) ? $fname[$counter] : '';
$return .= $lname. ', ' . $fname;
}
$fname[$counter] = !empty($fname[$lastItem]) ? $fname[$lastItem] : '';
$return .= "&" . $fname. ', ' . $lname;
$return .= ' ';
return $return;
this is the output i get:
last3 first1 last1 first1 & last2 first1
last5 first4 & last4 first4
I cant figure out what i am doing wrong.
I tryied using foreach but i didnt manage to separete the last pair of values here.
I am stuck with this this for a few days.
any help would be great.
This is a follow-up question for my earlier question here:
Some help "syncing" two loops in PHP
I want to take a list of dates and show them as ranges if their date is the same or max 1 day apart.
This is the output of my database:
+-----+------------+
| uid | date |
+-----+------------+
| 39 | 2014-09-17 |
| 46 | 2014-09-18 |
| 40 | 2014-09-19 |
| 48 | 2014-09-19 |
| 45 | 2014-09-20 |
| 47 | 2014-12-05 |
+-----+------------+
This is the HTML I want to generate:
Contract from 17/09/2014 to 20/09/2014
UIDS: 39-46-40-48-45
Contract from 05/12/2014
UIDS: 47
This is my sourcecode
<?php
$output = '';
$list = array();
$lastitem = $lastdate = null;
$query = 'SELECT * FROM project_dates';
$sth = $dbh->prepare($query);
$sth->execute();
if($sth->rowCount() > 0) {
$i = 0;
while($row = $sth->fetch()) {
// CURRENT DATE
$date = new DateTime($row['date']);
// STORAGE
$item = array(
'date' => array(),
'var' => $row['uid'], // A '-' delimited variable of all the uids in the range (40-41-...)
'uids' => array() // An array of all the uids in the range
);
// IF THE DATE DIFF IS LESS THAN OR EQUAL TO ONE DAY
if ($item['date'] === $lastitem['date'] && $date->diff($lastdate)->days <= 1) {
// Problem here: looking for last date in set!
$list[$i-1]['date']['end'] = $date;
//Add current uid to the '-' delimited variable of uids of this range
$list[$i-1]['uid'] = $list[$i-1]['uid'].'-'.$item['uid'];
// Add current uid to the array of uids of this range
array_push($list[$i-1]['uids'],$item['uid']);
} else {
// Next range
$list[$i] = $item;
$list[$i]['date']['start'] = $date;
$lastitem = $item;
$lastdate = $date;
array_push($list[$i]['uids'],$item['uid']);
$i++;
}
}
}
if(count($list)){
// Show text with first date and last date of the range
$output .= 'Contract from '.$item['date']['start']->format('d/m/Y');
$output .= isset($item['date']['end']) ? ' to ' . $item['date']['end']->format('d/m/Y') : '';
$output .= '<br />Uids: '.$item['var'];
}
foreach ($list AS $item) {
// Loop over the dates in this range
$output .= $item['date'].'<br />';
}
if(count($list)) {
// Line under this range
$output .= '<hr />';
}
echo $output;
?>
For some reason, my code returns 4 ranges instead of 2. I've been trying to figure out for hours why. Can someone help me? This is the faulty HTML:
Contract from 17/09/2014 to 18/09/2014
UIDS: 39-46
Contract from 19/09/2014
UIDS: 40
Contract from 19/09/2014 tot 20/09/2014
UIDS: 48-45
Contract van 05/12/2014
UIDS: 47
Can anyone be of assistance?