I need to output the response from the database in XML. So far I have gotten it to output this:
The outermost tag needs to match the name of the action query, it'll either be <courses> or <students>.
Here is my code:
<?php
require_once('./database.php');
if (isset($_GET['format'])) {
$format = filter_var($_GET['format']);
}
if (isset($_GET['action'])) {
$action = filter_var($_GET['action'], FILTER_SANITIZE_STRING);
$tableName = "sk_$action";
}
$query = "SELECT * FROM $tableName";
if (isset($_GET['course'])) {
$course = filter_input(INPUT_GET, 'course');
$query .= " WHERE courseID = :course";
}
function arrayToXml($arr, $i = 1, $flag = false)
{
$sp = "";
for ($j = 0; $j <= $i; $j++) {
$sp .= " ";
}
foreach ($arr as $key => $val) {
echo "$sp<" . $key . ">";
if ($i == 1) echo "\n";
if (is_array($val)) {
if (!$flag) {
echo "\n";
}
arrayToXml($val, $i + 5);
echo "$sp</" . $key . ">\n";
} else {
echo "$val" . "</" . $key . ">\n";
}
}
}
$statement = $db->prepare($query);
$statement->bindValue(':course', $course);
$statement->execute();
$response = $statement->fetchAll(PDO::FETCH_ASSOC);
$statement->closeCursor();
if ($format == 'json') {
echo json_encode($response);
}
if ($format == 'xml') {
arrayToXml($response, 1, true);
}
I'm pretty new to PHP and have never worked with XML. All help is appreciated. Thanks.
function arrayToXml($arr, $collectionTag, $singleTag) {
$collection = new SimpleXMLElement("<$collectionTag/>");
foreach ($arr as $row) {
$element = $root->addChild($singleTag);
foreach ($row as $tag => $value) {
$element->addChild($tag, $value);
}
}
return $collection;
}
$courses = arrayToXml($response, 'courses', 'course');
echo $courses->asXML();
Tested with PHP 7.1.23. Output:
<?xml version="1.0"?>
<courses>
<course><courseID>cs601</courseID><courseName>Web Application Development</courseName></course>
<course><courseId>cs602</courseId><courseName>Server-Side Application Development</courseName></course>
<course><courseId>cs701</courseId><courseName>Rich Internet Application Development</courseName></course>
</courses>
(I added newlines because by default it doesn't add any.)
How to get data in different section like today, upcoming, and overdue date with the help of foreach loop.
foreach($list as $index=>$row) {
$dueDt = new DateTime($row->due_timeDate);
$todayDt = new DateTime('now');
$due = $dueDt->format('Y-m-d');
$today = $todayDt->format('Y-m-d');
if($due == $today) {
echo $due.' Today' ;
echo '<br>';
$task['today'][]=$row;
} elseif($due>$today) {
echo $due.' Upcoming';
echo '<br>';
$task['today'][]=$row;
} elseif($due<$today) {
echo $due.' Overdue';;
echo '<br>';
$task['overdue'][]=$row;
}
}
My data is coming like this:
2015-10-30 Upcoming
2015-10-29 Today
2015-10-28 Overdue
2015-10-28 Overdue
2015-10-27 Overdue
2015-10-27 Overdue
2015-10-15 Overdue
But I want the data like this from foreach loop:
Upcoming
2015-10-30
Today
2015-10-29
Overdue
2015-10-28
2015-10-28
2015-10-27
2015-10-27
2015-10-15
$task['today'] = array();
$task['Upcoming'] = array();
$task['Overdue'] = array();
foreach ($list as $index => $row)
{
$dueDt = new DateTime($row->due_timeDate);
$todayDt = new DateTime('now');
$due = $dueDt->format('Y-m-d');
$today = $todayDt->format('Y-m-d');
if ($due == $today)
{
$task['today'][] = $row;
}
elseif ($due > $today)
{
$task['Upcoming'][] = $row;
}
elseif ($due < $today)
{
$task['Overdue'][] = $row;
}
}
foreach ($tasks as $dueDate => $task)
{
if (!empty($task))
{
echo $dueDate . "<br />";
foreach ($task as $date)
{
echo " " . $date . "<br />";
}
}
}
You need to use key value pairs of your array.
Take key as time (Today, Tomorrow, Overdue).
This should be a multi-dimensional array.
Print in loop like following:
<?php
$tasks = array();
foreach($list as $index=>$row) {
$dueDt = new DateTime($row->due_timeDate);
$todayDt = new DateTime('now');
$due=$dueDt->format('Y-m-d');
$today=$todayDt->format('Y-m-d');
if($due==$today) {
$tasks['today'][] = $due;
}
else if($due>$today) {
$tasks['upcoming'][]=$due;
}
else if($due<$today) {
$tasks['overdue'][]=$due;
}
}
if (! empty($tasks)) {
foreach ($tasks as $dueDate => $task) {
echo ucwords($dueDate);
if (! empty($task)) {
foreach ($task as $title) {
echo "<br/>--> " . $title;;
}
}
}
}
?>
Try this
foreach($list as $index=>$row) {
$dueDt = new DateTime($row->due_timeDate);
$todayDt = new DateTime('now');
$due=$dueDt->format('Y-m-d');
$today=$todayDt->format('Y-m-d');
if($due==$today){
$up['upcome']=$row;
}elseif($due>$today){
$to['Today']=$row;
}elseif($due<$today){
$over['overdue']=$row;
}
if (!empty($up)) {
echo "Upcoming";
foreach ($up as $new_up) {
echo " " . $new_up['upcome']."<br>";
}
}
if (!empty($to)) {
echo "Today";
foreach ($to as $new_to) {
echo " " . $new_to['Today']."<br>";
}
}
if (!empty($over)) {
echo "Overdue";
foreach ($over as $new_over) {
echo " " . $new_over['overdue']."<br>";
}
}
}
Output will be
Upcoming
2015-10-30
Today
2015-10-29
Overdue
2015-10-28
2015-10-28
2015-10-27
2015-10-27
2015-10-15
According to your data-structure:
$data = ['2015-10-25','2015-10-26','2015-10-27','2015-10-28','2015-10-29','2015-10-30'];
$current = '2015-10-27';
// Saving Array Keys for future work
$rows = array('overdue','today','upcomming');
foreach($data as $date) {
// Compare each date to find our $rows array
$curt = strtotime($current);
$d = strtotime($date);
if($d < $curt) {
$rows['overdue'][] = $date;
} else if($d > $curt) {
$rows['upcomming'][] = $date;
} else if($d == $curt) {
$rows['today'][] = $date;
}
}
//Now Print each $rows:
echo 'Overdue: <br>'. implode('<br>', $rows['overdue']) .'<br><br>';
echo 'Today: <br>'. implode('<br>', $rows['today']) .'<br><br>';
echo 'Upcomming: <br>'. implode('<br>', $rows['upcomming']);
Prints:
Overdue:
2015-10-25
2015-10-26
Today:
2015-10-27
Upcomming:
2015-10-28
2015-10-29
2015-10-30
I'm calculating the average,min,max for each column.
The 16th column value is coming wrong for max and min. Average is working perfectly fine, but wrong only for the last column with large arrays -- I also get a notice error.
My code:
mysql_connect("localhost", "root", "") or
die("Could not connect: " . mysql_error());
mysql_select_db("db");
$qry = mysql_query("select blob_field from table where id=1");
$arr = mysql_fetch_row($qry) ;
$rt = explode("\n",$arr[0]);
$header_arr1 = explode(',',$rt[0]);
$header1 = array();
$channels = count($header_arr1)-2 ;
$header1[] = join(',', array_slice($header_arr1, 2));
//Only Header
$arr_values = array_values($rt);
$array_slice = array_slice($arr_values, 1);
echo "<pre>";
//print_r($array_slice);
$result_array = array();
for($i=0;$i<count($array_slice);$i++)
{
//echo $i;
$result_array[] = join(',',array_slice(explode(',', $array_slice[$i]), 2));
}
//print_r($result_array);
//$array_combined = array_merge($header1,$result_array);
$token = array( 'Average', 'Max', 'Min');
foreach($result_array as $key=>$val)
{
$res_arr[] = explode(",",$val);
}
$avArray = array();
$res_arr= array(
0=>array(1,2,3,6,7,8,9,11,33,44,55,66,77,88,16,18),
1=>array(17,52,38,666,79,8,9,15,33,44,55,66,76,88,16,18),
2=>array(17,562,538,7666,579,688,9,15,933,44,55,660,76,808,106,108),
);
foreach ($res_arr as $k=>$subArray)
{
foreach ($subArray as $id=>$value)
{
//print_r($id);
$avArray[$id] += $value/count($res_arr); //Notice: Undefined offset: 3
}
}
$token = array( 'Average', 'Max', 'Min');
$num = $avArray;
$tc=16;
?>
<table border="1" style="border-collapse: collapse;">
<thead>
<tr>
<th>Channels</th>
<?php for($j=0;$j<=$tc-1;$j++):?>
<th>CH<?= $j+1;?></th>
<?php endfor;?>
</tr>
</thead>
<tbody>
<?php
echo "<tr><td>Average</td>";
for($i=0; $i<=$tc-1;$i++)
{
echo "<td>" .round($num[$i],2). "</td>";
}
echo "<tr><td>Max</td>";
$arr_max = array();
foreach($res_arr as $subArray)
{
foreach($subArray as $k=>$v) {
$arr_max[$k][] = $v;
}
}
$max_array = array_map('max', $arr_max);
for($i=0; $i<=$tc-1;$i++)
{
echo "<td>" .$max_array[$i]. "</td>";
}
echo "<tr><td>Min</td>";
$arr_min = array();
foreach($res_arr as $subArray)
{
foreach($subArray as $k=>$v1) {
$arr_min[$k][] = $v1;
}
}
$min_array = array_map('min', $arr_min);
for($g=0; $g<= $tc-1;$g++)
{
echo "<td>" .$min_array[$g]. "</td>";
}
?>
</tbody>
</table>
See inline comments for explanation.
$avArray = array();
$res_arr= array(
0=>array(1,2,3,6,7,8,9,11,33,44,55,66,77,88,16,18),
1=>array(17,52,38,666,79,8,9,15,33,44,55,66,76,88,16,18),
2=>array(17,562,538,7666,579,688,9,15,933,44,55,660,76,808,106,108),
);
/*
foreach ($res_arr as $k=>$subArray){
foreach ($subArray as $id=>$value){
// this causes "Notice: Undefined offset: 0...15" because you can't add to an undeclared value
$avArray[$id] += $value/count($res_arr);
}
}
*/
$res_count=count($res_arr); // declare this outside of the loop for efficiency
foreach ($res_arr as $k=>$subArray){
foreach ($subArray as $id=>$value){
if($k==0){
$avArray[$id]=$value; // declare first round of values
}else{
$avArray[$id]+=$value; // add to existing values
if($k==2){
$avArray[$id]=$avArray[$id]/$res_count; // only divide on the last iteration
}
}
}
}
print_r($avArray);
No matter how you want to present it, you are going to have to loop over the data set more than one. Once to calculate and once to display.
Here is another snippet: (Demo)
$array = [
[1,2,3,6,7,8,9,11,33,44,55,66,77,88,16,18],
[17,52,38,666,79,8,9,15,33,44,55,66,76,88,16,18],
[17,562,538,7666,579,688,9,15,933,44,55,660,76,808,106,108],
];
$count = count($array);
$mins = [];
$maxs = [];
$avgs = [];
foreach ($array as $i => $row) {
foreach ($row as $col => $value) {
$ch = $col + 1;
if (!$i) {
$mins[$ch] = $value;
$maxs[$ch] = $value;
$avgs[$ch] = $value;
} else {
if ($value < $mins[$ch]) {
$mins[$ch] = $value;
}
if ($value > $maxs[$ch]) {
$maxs[$ch] = $value;
}
$avgs[$ch] += $value;
if ($i === $count - 1) {
$avgs[$ch] = number_format($avgs[$ch] / $count, 2);
}
}
}
}
echo '<table border=1>';
printf(
'<tr><th>Channels</th><th>CH%s</th></tr>',
implode('</th><th>CH', array_keys($avgs))
);
printf(
'<tr><th>Average</th><td>%s</td></tr>',
implode('</td><td>', $avgs)
);
printf(
'<tr><th>Max</th><th>%s</td></tr>',
implode('</td><td>', $maxs)
);
printf(
'<tr><th>Min</th><td>%s</td></tr>',
implode('</td><td>', $mins)
);
echo '</table>';
I have a mysql table with data like (name, address, sex, city state, zip, country, timezone) When a user fills in the form to add this data, i would like the relevant time-zone to be added based on state and country, how can i do this?
Thanks,
Why not have the following select box in your form?
$list = DateTimeZone::listAbbreviations();
$idents = DateTimeZone::listIdentifiers();
$data = $offset = $added = array();
foreach ($list as $abbr => $info) {
foreach ($info as $zone) {
if ( ! empty($zone['timezone_id'])
AND
! in_array($zone['timezone_id'], $added)
AND
in_array($zone['timezone_id'], $idents)) {
$z = new DateTimeZone($zone['timezone_id']);
$c = new DateTime(null, $z);
$zone['time'] = $c->format('H:i a');
$data[] = $zone;
$offset[] = $z->getOffset($c);
$added[] = $zone['timezone_id'];
}
}
}
array_multisort($added, SORT_ASC, $data);
$options = array();
foreach ($data as $key => $row) {
$options[$row['timezone_id']] = $row['time'] . ' - '
. formatOffset($row['offset'])
. ' ' . $row['timezone_id'];
$values[$row['timezone_id']] = $row['time'] . '/'
. formatOffset($row['offset'])
. '/' . $row['timezone_id'];
}
function formatOffset($offset) {
$hours = $offset / 3600;
$remainder = $offset % 3600;
$sign = $hours > 0 ? '+' : '-';
$hour = (int) abs($hours);
$minutes = (int) abs($remainder / 60);
if ($hour == 0 AND $minutes == 0) {
$sign = ' ';
}
return 'GMT' . $sign . str_pad($hour, 2, '0', STR_PAD_LEFT)
.':'. str_pad($minutes,2, '0');
}
echo "<select name='locale'>";
foreach($options as $key=>$value){
echo "<option value='".$values[$key]."'>".$value."</option>";
}
echo "</select>";
This would handle the fact there are states with multiple timezones. When you then get the result of this form submission, you can explode the value of the field on '/', where $_POST['locale'] is the handler for the chosen select option, then you can extract timezone, country and state from a single field.
$locale=explode("/",$_POST['locale']);
// $locale[0] = timezone
// $locale[1] = country
// $locale[2-n] = state(s)