Why isn't this PHP parsing XML correctly? - php

I am attempting to parse Yahoo's weather XML feed via this script. The parsing itself works: I am just struggling with getting the days to correspond with today, tomorrow and the day after.
The final HTML output looks like this:
Which can be seen here: http://www.wdmadvertising.com.au/preview/cfs/index.shtml
todayMon______________19
todayTue______________26
Tue______________26
It is supposed to look like this:
Today______________(temp)
(tomrrow)______________(temp)
(day after tomorrow)______________(temp)
The PHP and HTML:
<div class="latest-weather">
<h1 class="latest-weather">Latest weather</h1>
include("class.xml.parser.php");
include("class.weather.php");
$weather_adelaide = new weather("ASXX0001", 3600, "c", $cachedir);
$weather_adelaide->parsecached();
// TODAY 1
for ($day=0; isset($weather_adelaide->forecast[$day]); $day++) {
print "<h2>today".$weather_adelaide->forecast[$day]['DAY']."</h2>";
print "<p />".$weather_adelaide->forecast[$day]['HIGH']."<br>"; }
// FORECAST 2
for ($day=1; isset($weather_adelaide->forecast[$day]); $day++) {
print "<h2>".$weather_adelaide->forecast[$day]['DAY']."</h2>";
print "<p />".$weather_adelaide->forecast[$day]['HIGH']."<br>"; }
// FORECAST 3
for ($day=2; isset($weather_adelaide->forecast[$day]); $day++) {
print "<h2>".$weather_adelaide->forecast[$day]['DAY']."</h2>";
print "<p />".$weather_adelaide->forecast[$day]['HIGH']."<br>"; }
?>
</div><!--/latest-weather-->

Either you're not very clear on how for loops work or you've just made a really silly error.
In case of the former, remember that
for($x=0; isset(blah); $x++) {
...
}
is equivalent to
$x = 0;
while(isset(blah)) {
...
$x++;
}
It looks like you are only getting forecasts for today and tomorrow; your first loop produces:
todayMon______________19
todayTue______________26
Your second loop produces:
Tue______________26
And your third loop produces nothing.
You should probably change your code to something like this:
// TODAY 1
if (isset($weather_adelaide->forecast[0])) {
print "<h2>today</h2>";
print "<p />".$weather_adelaide->forecast[0]['HIGH']."<br>";
}
// More days
for ($day=1; $day < 3 && isset($weather_adelaide->forecast[$day]); $day++) {
print "<h2>".$weather_adelaide->forecast[$day]['DAY']."</h2>";
print "<p />".$weather_adelaide->forecast[$day]['HIGH']."<br>";
}
Another comment: I see you using <p /> however you also use <br>, this is puzzling. <br> is not valid XHTML.

I assume $weather_adelaide->forecast[0] and $weather_adelaide->forecast[1] are set so you get your first for to print 2 times and your second to print one. I think you need if and not for: (not tested)
// TODAY 1
$day = 0;
if(isset($weather_adelaide->forecast[$day])) {
print "<h2>today".$weather_adelaide->forecast[$day]['DAY']."</h2>";
print "<p />".$weather_adelaide->forecast[$day]['HIGH']."<br>";
}
// FORECAST 2
++$day;
if (isset($weather_adelaide->forecast[$day])) {
print "<h2>".$weather_adelaide->forecast[$day]['DAY']."</h2>";
print "<p />".$weather_adelaide->forecast[$day]['HIGH']."<br>";
}
// FORECAST 3
++$day;
if (isset($weather_adelaide->forecast[$day])) {
print "<h2>".$weather_adelaide->forecast[$day]['DAY']."</h2>";
print "<p />".$weather_adelaide->forecast[$day]['HIGH']."<br>";
}
But I would go with a foreach(range(0, 2) as $i) and handle the special today case with a if

Related

Get the last data from if inside for loop

What I'm looking for is looking for logic that allows you to print horizontal rulers between content, except for the last content block, which you do NOT want to close with a horizontal ruler.
I have this code to loop the number from 1 to 10 and I have this if inside to check if number is stored in database.
for($i=1;$i<=10;$i++){
if($i == $class->Check($i)){
echo $i;
echo "<hr>"; // if not the last!
}
}
I want to check here if it is the last data with the if condition not the loop, so if we got from if and the loop the numbers 2,3,4,7, I want to check with another if condition if it is the last number and print something.
Notice -> the for loop numbers isn't the same it's a variable this is just an example.
What is the code for (I have this loop and when if condition is true it print something then a hr tag, but I don't want the lase print to print a hr tag so I want to check if it is the last print with if condition to stop it from printing the tag).
In your condition, you can save your output in an array, instead of displaying it immediatly, and then, you can use it later, by checking if you are at the last value :
$MyOutput = [];
for($i=1;$i<=10;$i++) {
if($i == $class->Check($i)){
$MyOutput[] = $i;
}
}
for($i = 0, $len = count($MyOutput); $i < $len; $i++)
{
echo $MyOutput[$i];
if ($i == $len - 1) // are we at the last element ?
{
// your special message for the last element
}
}

PHP: detect end of duplicate column results (calendar day)

I've been putting together a simple linear weekly event calendar script, which calls entries from a MYSQL database. It displays a sort of "8 day week" (Sunday to Sunday inclusive)
My MYSQL query is like so:
$results = $dbh->query('SELECT * FROM calendar WHERE YEARWEEK(event_date) = YEARWEEK(NOW()) OR (WEEKDAY(event_date) = 6 AND YEARWEEK(event_date) = YEARWEEK(NOW()) + 1) ORDER BY event_date ASC');
When a given day has multiple event entries, I keep the day/date heading from repeating:
$currentday = '';
$showday = true;
foreach($results as $row) {
$weekday = date("l", strtotime($row['event_date'])); {
if ($currentday != $row['event_date']) {
$showday = true;
$currentday = $row['event_date'];
}
if ($showday) {
$weekday = date("l", strtotime($row['event_date']));
if($weekday == "Sunday") {
echo "<h3 class='sunday'>";
echo $weekday;
}
else {
echo "<h3>";
echo $weekday;
}
echo date("F j", strtotime($row['event_date']));
$showday = false;
}
}
... followed by the remaining details.
All that works great.
What I'm trying to accomplish now is to group each day's results visually by means of an HTML hook.
To accomplish that, I'm trying to group each day's events within a div with a class of "daybox". I can create/open the div with this, just after the first if clause:
if ($showday) { ?><div class="daybox">
That successfully opens/create a new div for each distinct day of the foreach loop.
The problem is closing it. I tried a corresponding if $showday closing code at the end of my foreach, but in retrospect, that wasn't what I was looking for, and obviously it didn't work.
What I think I need is a way to determine whether I've reached the last entry for a given day (i.e. event_date in my database), and base my if clause off that. But so far I'm stumped how I need to articulate that.
Am I on the right track, and how would I formulate my final if clause?
Thanks!
Well, this isn't a real PHP solution, but I found a workaround that I can live with.
I changed this line:
if ($showday) { ?><div class="daybox">
to this:
if ($showday) { echo "</div><div class='daybox'>"; }
That gives me an anomalous closing div tag before the first day of the calendar, but I reconciled my HTML by placing an opening div tag outside of my foreach loop. (In my case, I already had an h2 for a "This Week" title, so now I've got the heading wrapped in a div.)
This works for this particular use case, but if somebody has the proper PHP answer, please feel free to provide.
My friend Anthony, who is a hardcore programmer, although not really a PHP guy, provided the actual code to accomplish this properly.
Below the $weekday = date ... line, the code above has been replaced with this:
if ($currentDay != $weekday) {
if ($currentDay != '') {
echo "</div>";
}
$currentDay = $weekday;
$showday = true;
echo "<div class='daybox'>";
}
?>
<section class="calendar-item">
<?php
if ($showday) {
if ($weekday == "Sunday") {
echo "<h3 class='sunday'>";
} else {
echo "<h3>";
}
echo $weekday;?>
</h3><p class="date-detail"><?php
echo date("F j", strtotime($row['event_date'])); ?></p><?php
$showday = false;
}
Works a treat. Now I need to study it in order to fully grasp how he did it.

PHP: Loop Logic

I realize this is extremely simple but I feel I'm over-looking something.
What I want to screen to display is
RED This is 0.
or
GREEN This is 1.
And for it to alternate back and forth between the displayed text. My logic if fine for alternating between Red and Green, but the "This is 0" and "This is 1" text is not displaying.
Here is my code so far:
<?php
$array = array(0=>"RED",1=>"GREEN");
$a_count = 0;
$count = 0;
while($count<10)
// DO 9 TIMES
{
echo $array[$a_count] . ' ';
//SUDO FOR IMAGE BEING DISPLAYED
while($array[$a_count] == 0)
{
echo "This is 0.<br>";
}
while($array[$a_count] == 1)
{
echo "This is 1<br>";
}
//<----SWITCH BACK AND FORTH---->
if($a_count == 1)
{
$a_count = 0;
}
else
{
$a_count++;
}
//<----------------------------->
$count++;
}
?>
I realize the easiest way to get what I would like is:
<?php
$array = array(0=>"RED",1=>"GREEN");
$a_count = 0;
$count = 0;
while($count<10)
// DO 9 TIMES
{
echo $array[$a_count] . ' ';
//SUDO FOR IMAGE BEING DISPLAYED
//<----SWITCH BACK AND FORTH---->
if($a_count == 1)
{
echo "This is 1<br>";
$a_count = 0;
}
else
{
echo "This is 0.<br>";
$a_count++;
}
//<----------------------------->
$count++;
}
?>
But this code does not contain the logic I need for the continuation of this project.
I would greatly appreciate an answer as to why my first code is not printing "This is 0."
Thank you!
What you are looking for is a mod count.
Change your loop for:
for($i=0;$i<10;$i++){
echo $array[$i%2].' This is '.($i%2);
}
The modulo operator returns the remainder of a division.
See: What are the practical uses of modulus (%) in programming?
Why not something like this:
$colors = array(0 => 'Red', 1 => 'Green');
$idx = 0;
$count = 0;
while($count < 10) {
echo "The color is {$colors['$idx']}<br />";
$count = 1 - $count; // if $count is 1, it becomes 0. if it's 0, it becomes 1
}
Your while() loops are basically totally useless. You're trying to compare the RED and GREEN strings again 0. If either evaluation happens to be true, you'll end up with an infinite loop.
Ignoring the inefficiency of this script, your while loops are comparing against the array's values, not its keys. But fixing this problem will actually expose another - an infinite loop.
You aren't changing the value of $a_count in your while loops, so there is no way for them to end.
The problem is here:
while($array[$a_count] == 0)
{
echo "This is 0.<br>";
}
while($array[$a_count] == 1)
{
echo "This is 1<br>";
}
Once it enters the first loop, it will just keep echoing "This is 0.<br>", as $a_count is unchanging.
It looks like you could change these whiles to ifs to make your code work the way you want. You also probably want to check that $a_count is 0 or 1, rather than $array[$a_count]
Well, in your first example before the while($count<10), have you initilize your values?
If you do, you must have a display like that :
RED This is 0.0
This is 0.0
This is 0.0
This is 0.0
This is 0.0
...
"This is 0.0" is display in a infinite loop.
while($array[$a_count] == 0)
{
echo "This is 0.$count<br>";
}
while($array[$a_count] == 1)
{
echo "This is 1<br>";
}
You must change the value in a while loop.
Other tips, I think you mush take a look at "foreach" php loop. Can be useful for what you want to do. modulos can also help you.
I think probably the easiest way to do this is to just use a switch statement. I feel really silly for not thinking of it before.
while($count<10)
{
echo $array[$a_count] . ' ';
//PSUEDO FOR IMAGE BEING DISPLAYED
switch($a_count):
{
case 1:
echo "This is RED.<br>";
$a_count = 0;
break;
case 0:
echo "This is GREEN.<br>";
$a_count++;
break;
}
$count++;
}

taking the latest content from a dynamic array

A small background of myself is that I'm fairly new to php. I work as an IT assistant and have been asked to edit one of the pages our designers use for samples. I cannot point you to the page as it is an internally hosted page.
I'm honestly not even sure if the question is asked correctly but please bear with me.
The page has a 'request completion date' field within a table that outputs 6 dates in a list, the designers only want it to output the latest date from that list instead of all 6, usually these will be empty so it's no use having them printed.
The code to put them is as follows;
if ($database_data['request_confirmed_comp_date'] > "0")
{ $request_confirmed_completion_date = date("d/m/Y", $database_data['request_confirmed_comp_date']); }
else
{ $request_confirmed_completion_date = " -"; }
if $database_data['request_confirmed_comp_date2'] > "0")
{
$request_confirmed_completion_date2 = date("d/m/Y", $database_data['request_confirmed_comp_date2']);
}
else
{
$request_confirmed_completion_date2 = " -";
}
if ($database_data['request_confirmed_comp_date3'] > "0")
{
$request_confirmed_completion_date3 = date("d/m/Y", $database_data['request_confirmed_comp_date3']);
}
else
{
$request_confirmed_completion_date3 = " -";
}
if ($database_data['request_confirmed_comp_date4'] > "0")
{
$request_confirmed_completion_date4 = date("d/m/Y", $database_data['request_confirmed_comp_date4']);
}
else
{
$request_confirmed_completion_date4 = " -";
}
if ($database_data['request_confirmed_comp_date5'] > "0")
{
$request_confirmed_completion_date5 = date("d/m/Y", $database_data['request_confirmed_comp_date5']);
}
else
{
$request_confirmed_completion_date5 = " -";
}
if ($database_data['request_confirmed_comp_date6'] > "0")
{
$request_confirmed_completion_date6 = date("d/m/Y", $database_data['request_confirmed_comp_date6']);
}
else
{
$request_confirmed_completion_date6 = " -";
}
if ($database_data['request_date_required'] > "0")
{
$request_date_required = date("d/m/Y", $database_data['request_date_required']);
}
else
{
$request_date_required = "-";
}
if ($database_data['request_date'] > "0")
{
$request_date = date("d/m/Y", $database_data['request_date']);
}
else
{
$request_date = "-";
}
It is then called into play using;
echo '<td><b>1.</b>'.$request_confirmed_completion_date.'<br /><b>2.</b>'.$request_confirmed_completion_date2.'<br /><b>3.</b>'.$request_confirmed_completion_date3.'<br /><b>4.</b>'.$request_confirmed_completion_date4.'<br /><b>5.</b>'.$request_confirmed_completion_date5.'<br /><b>6.</b>'.$request_confirmed_completion_date6.'</td>';
Now I may not have much php knowledge, but I know that's a horribly long way of doing that. Is there anyway that I could pull the latest date out of an array, created by the the first block of code, and then output them into the table.
Thanks for any help or advice, even if you could just point me in the right direction as to what loop to use would be helpful.
Edit: I've uploaded the full file online here, hopefully that will clear up some confusion.
You want to use the php function asort. Since all of your values look to be numeric, you should be able to do a standard sort and pull off the last item with array_pop.
It might look something like this:
asort($database_data);
$latest = array_pop($database_data);
echo date('m/d/Y', $latest);
Create an array with the variable names, like if the variables are $A, $B and $C, then
$vars = array("A","B","C");
foreach($vars as $var_name){
if($database_data[$var_name] > "0")
$$var_name = $database_data[$var_name];
else
$$var_name = "-";
}
Note: A, B and C are dummy variable names, as the variable names are too long in your code :-)
Firstly there is a problem with your if conditions, you can't say $x > "0" because with using double-quotes you are using 0 as a string. You should use integer $x > 0.
Now here my answer :
I couldn't understand your system very well, so i'm assuming always there will be 6 dates.
for($q = 0;$q < 6; $q++)
{
if($database_data[...][$q] > 0)
$dates[] = date("d/m/Y", $database_data['...'][$q]);
else
$dates[] = " - ";
}
As you see, you have to fetch your database datas as an array $database_data['...'][].
If you can tweak the original SQL statement, which probably looks something like this:
select request_confirmed_comp_date, request_confirmed_comp_date2, request_confirmed_comp_date3, request_confirmed_comp_date4, request_confirmed_comp_date5, request_confirmed_comp_date6
from sometablename
where somefield='something'
You can tweak it to use shorter (and consistent) field names
select request_confirmed_comp_date as date1, request_confirmed_comp_date2 as date2, request_confirmed_comp_date3 as date3, request_confirmed_comp_date4 as date4, request_confirmed_comp_date5 as date5, request_confirmed_comp_date6 as date6
from sometablename
where somefield='something'
And then in PHP use an array to iterate over the field names like so:
<?php
$lastCompletionDate=""; //start by assuming there was no completion date
for($i=1;$i<=6;$i++) { //check to see if any field is after the last known completion date
if ($database_data['date'.$i] && (date("d/m/Y", $database_data['date'.$i]) > $lastCompletionDate)) {
//if so, store the new date
$lastCompletionDate=date("d/m/Y", $database_data['date'.$i]);
}
}
if($lastCompletionDate) {
echo "The last completion date was $lastCompletionDate\n";
}else {
echo "There was no completion date.\n";
}
?>
An alternative solution would be to use the SQL engine's own internal functions to find the highest date like so:
select greatest(request_confirmed_comp_date,
request_confirmed_comp_date2,
request_confirmed_comp_date3,
request_confirmed_comp_date4,
request_confirmed_comp_date5,
request_confirmed_comp_date6) as greatestcompdate
from sometablename etc...
and then refer to that in PHP like
<?php
if($database_data['greatestcompdate']) {
echo "There was a greatest completion date and it was $database_data[greatestcompdate]";
}
?>

php drop down detect selection

I have a date of birth, and when the user is over Feb (02), the days should go only to 29. As you can see I'm using $month="1" just to test it. I'm supposed to use PHP only, no JavaScript or anything else. How would i go about making that?
<?php
$month="1"; // <-- currently using this to make it 29,30 or 31 days
print "<select name='day'>";
if ($month==1){
for ($i=0; $i<=28; $i++)
{
$day = 1 + $i;
print "<option value = $day>" . $day ."</option>";
}
}
if ($month==2){
for ($i=0; $i<=29; $i++)
{
$day = 1 + $i;
print "<option value = $day>" . $day ."</option>";
}
}
print "</select>";
print "<select name='month'>";
for ($i=0; $i<=11; $i++)
{
$month = 1 + $i;
print "<option value = $month>" .$month ."</option>";
}
print "</select>";
?>
Once PHP sends stuff to the browser, it is done. It cannot affect the page in any way.
JavaScript, on the other hand, takes over when the browser gets the page. It CAN change the page, and it can even ask the server to do something (in which case PHP may get involved).
In other words, you cannot do what you are asking without JavaScript.
Without Javascript it is just impossible to do.

Categories