By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
437,751 Members | 1,216 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 437,751 IT Pros & Developers. It's quick & easy.

Incorrect array pseudo-random filling with for loop - strange for me

P: 5
Hi, this is my code that should produce something like a timetable for a few days with each day divided into 30 minute pieces. It makes query from MySQL and then creates a 2d $array[$time][$date] which then is to be echoed like a table into html.
Almost everything goes well except for one entry going for an hour longer and one disappearing if shorter than 1hour (e.g. 30mins)
Expand|Select|Wrap|Line Numbers
  1. <?php 
  2.  
  3. for($i=0; $i<$numRows; $i++) { 
  4.     $result = mysql_fetch_array($response);
  5.     $headerArray[] = $result[meetingDate]; // this is for table header cells
  6.  
  7.     // this loop fill the array $schedule[$time][$date] from data queried from DB
  8.     // $time is taken from the "for loop" with analogy to 10 = 10:00, 10,5 = 10:30
  9.     // each DB entry has "startTime" and "endTime" (which is excluded from duration of the entry
  10.     // it's supposed to fill each array cell within given time-space between start and end with the <a...>
  11.     // * * * the loop below is referred futher in the text
  12.     for ($time=$result[startTime]; $time < $result[endTime]; $time += 0.5) {
  13.       $schedule[$time][$result[meetingDate]] = 
  14.       "<a href=\"detail.php?meetingDate=" . $result[meetingDate] . "&amp;startTime=" . $result[startTime] . "\">" . $result[clientName] . "</a>";
  15.     }
  16.   }
  17.  
  18.   //the creation of header array made some duplicate entries, so I'm now removing them and sorting the array by date
  19.   $headerArray = array_unique($headerArray);
  20.   sort($headerArray);
  21.  
  22.   //this creates the header row of the html table
  23.   echo "<table class=\"scheduleTable\">\n";
  24.   echo "  <tr><td>&nbsp;</td>"; //top-left corner cell should remain blank
  25.   foreach ($headerArray as $index => $date) {
  26.     echo "<td>$date</td>";
  27.   }
  28.   echo "</tr>";
  29.  
  30.   // now I manualy (e.g. not by "foreach") cycle through times and write-out the entry for given date if any
  31.   for ($time=10; $time<24.5; $time += 0.5) {
  32.     if (!stripos($time, ".")) {      //this is for changing 10,5 form to 10:30 etc.
  33.       echo "\n  <tr><td>$time:00</td>";
  34.     }
  35.     else {
  36.       $floorTime=floor($time);
  37.       echo "\n  <tr><td>$floorTime:30</td>";
  38.     }
  39.  
  40.     // this loop scans throug each specific time by dates, thus finding and writing-out entries for that specific time and date
  41.     foreach ($headerArray as $index => $date) {
  42.       if (isSet($schedule[$time][$date])) {
  43.         echo "<td class=\"scheduleClient\">";
  44.         echo $schedule[$time][$date];
  45.       }
  46.       else {   // if it doesn't find any entry, it put "Available" instead
  47.         echo "<td class=\"scheduleAvailable\">Available";
  48.       }
  49.       echo "</td>";
  50.     }
  51.     echo "</tr>";
  52.   }    
  53.   echo "</table>";
  54.  
  55. ?>
By some echos I worked out that DB query si absolutely correct and I can access all the data(which are also correct = the entry that get longer is fine and correct so far)

* * * Also when I put an echo into this loop that echoed an auxiliary iterated variable (which is not shown in the posted code) and also echoed the very own iterator of the loop - $time, I found out everything just to be OK. That means the entry which got longer (= more occupied cells in the html table) was shown in correct length by echoed variables.(which imho means that the loop runs for the right amount of cycles) And also the entry that disappeared from the table was shown correctly by echoes. (Also meaning the loop _should_ be ok) And therefore these data should be correctly written into the array, beacause these echoes were in close touch with the line that is stuffing data into the array.

I just don't get it :-(

My personal impression is that it might be something like those cells that are displayed incorrectly as occupied by the entry are somehow touched in the array and therefore they are by isSet( ) evaluated as beiing set. But:
1) I'm not able to find out why, how and where
2) If they were just mistakenly touched, they wouldn't contain the entry that they are (incorrectly) prolonging, making that entry look longer. (occupiing more table cells). They would contain just "something", not the preceding entry

Just for better imagination:
Assume I have an entry - start=10, end=13.5, date=whatever(this doesnt make the difference imho)
Therefore the entry duration should occupy cells: 10:00, 10:30 ... 12:30, 13:00 (13:30 is excluded)
The number of loop iterations should be 7 and the final $time should be 13.0
What the debugging echoes show is as above - auxiliary iterated var prints 7 and $time prints 13.
But in the table the entry occupies also the 13:30 cell.

And about the disappearing entry:
start=15.5, end=16
aux iterator shows 1 and $time shows 15.5 -- which is correct (but this is printed by echoes)
In the end this entry is not present in the html table

If anyone would bother himself with reviewing my code, I would appreciate.

Luke
Aug 26 '08 #1
Share this Question
Share on Google+
6 Replies


P: 5
UPDATE:

Tried to adjust data in DB and found out following:

When entry is shorter than 1hour (the obly possibility is 30 minutes) it disappears from the html table. When this same DB row is modified to be 1hour long, it appears. When the same entry is 1.5hour AND endTime is .5 it gets 30minutes longer than it should be. When it is 1hour AND endTime is .5 (thus startTime is also .5) it has correct length, but is shifted 30minutes later. (= first 30mins disappears, last 30mins are false and shouldn't be there)

Every entry which begins with .0 and ends with .5 is 30mins longer

Luke
Aug 27 '08 #2

Dormilich
Expert Mod 5K+
P: 8,639
Could you compare the $schedule array with var_dump($schedule); before and after the table creation (e.g. line 15/51)? this should give you/us a hint whether $schedule has been altered by isset() (or anything else) or not.
This is indeed very tricky...

idea: maybe !empty() instead of isset() is better?
Aug 27 '08 #3

P: 5
So after comparison by var_dump($schedule) (thx for showing me this function, I haven't known it before) I found both dump to be identical. However both beiing really strange - .0 keys were ok, but .5 keys were shown as Strings and some of them were even missing. With var_dump( ) now I'm able to compare it to the DB.

Say we have an entry "entry1" startTime=11.5 endTime=13.5

In $schedule it should reside betwen 11.5 and 13.0, both limits included
But key 11.5 in $schedule is shown to be String! (the others are not) -- So, as this is startTime value, it explains why the first cell in html table is missing when entry's startTime is x.5 (I am using for loop to scan through $schedule's time-key, not foreach. And for loop generates integers (or what?) but 11.5 is String)
Then there is key 12, which is integer = correct. 12.5 is missing (it's not there even as an String - it's not there at all) and the last value is 13 as integer = correct.
I think that there is some shift due to the "11.5" beiing string and thus the last cell is not added (as I thought before), but rather it is the last correct cell, just shifted.

Alright, I give up :-( -- I tried to add $time interator next to clientName for the loop that is filling $schedule to see which array cell belongs to which table cell and got nothing but chaos:
//following is info from var_dump( )
["11.5"] => "entry1 11.5"
[12]=> "entry1 12.5"
[13]=> "entry1 13"

//and this data resulted in following table-part:
[ TIME ] [ CLIENT ]
[12:00] [entry1 12.5]
[12:30] [entry1 12.5]
[13:00] [entry1 13]
[13:30] [entry1 13]

EDIT: Now I think I should just use some "time/date" <strike>datatype</strike> instead of integer 10 - 10.5 -- I found date/time object... Hope this will help
EDIT_END

I anyone of you guys see a simple solution without need of you to think hard, please tell me. Otherwise, don't bother solving this sh*t.

Thanks for the "var_dump( )" tip - this helped to move things towards the solution. If I don't find a way to use date/time instead of integer, this function will help me solving the mystery of intergers beiing strings and shifting and all the other stuff.
Aug 27 '08 #4

P: 5

EDIT: Now I think <strike>I should just use some "time/date"</strike> datatype instead of integer 10 - 10.5 -- PHP doesn't have a time/date datatype. I found some date/time funcions though... Hope those will help
EDIT_END
Seems like date_add( ) and "while loop" might be of use for me in connection with foreach.
Aug 27 '08 #5

Dormilich
Expert Mod 5K+
P: 8,639
You can force a string to become float/integer:
Expand|Select|Wrap|Line Numbers
  1. $time = 0 + $time;
  2. # or
  3. settype($time, "float");
maybe this can help, but I have to think a bit more about the examples. maybe a good night's sleep can bring up some ideas...

what do you get with var_dump($result)? are there missing data too?
Aug 27 '08 #6

P: 5
You can force a string to become float/integer:
Thanks, but it should work without this "work-around"


what do you get with var_dump($result)? are there missing data too?
Thank you for your efforts, but I switched the code to use timestamp instead.

Now I do it like this:
Expand|Select|Wrap|Line Numbers
  1. <?php 
  2.    putenv("GMT"); 
  3.  
  4.   for($i=0; $i<$numRows; $i++) { 
  5.     $result = mysql_fetch_array($response);
  6.     $headerArray[] = $result[meetingDate]; // header cells for html table
  7.  
  8.  
  9.     //preparing timestamps from startTime and endTime
  10.     $tsStartTime = strToTime("1970-01-01 " . $result[startTime]);
  11.     $tsEndTime = strToTime("1970-01-01 " . $result[endTime]);
  12.     $time = $tsStartTime;
  13.  
  14.     echo "<br />startTime: $result[startTime]";
  15.     echo "<br />stamp: $tsStartTime";
  16.  
  17.     while ($time < $tsEndTime) {
  18.       $schedule[$time][$result[meetingDate]] = 
  19.       "<a href=\"detail.php?meetingDate=" . $result[meetingDate] . "&amp;startTime=" . $result[startTime] . "\">" . $result[clientName] . "</a>";
  20.       //DEBUG
  21.       $strTime = date("H:i", $time);
  22.       echo "<br />Time: $strTime";
  23.  
  24.       $time += 1800; //adding 30minutes
  25.     }
  26.   }
  27.  
  28.  
  29.   echo "<br />";
  30.   var_dump($schedule);
  31.  
  32.  
  33.   //processing header data
  34.   $headerArray = array_unique($headerArray);
  35.   sort($headerArray);
  36.  
  37.  
  38.   //creating header cells of the html table
  39.   echo "<table class=\"scheduleTable\">\n";
  40.   echo "  <tr><td>&nbsp;</td>"; //pocatecni prazdna bunka
  41.   foreach ($headerArray as $index => $date) {
  42.     echo "<td>$date</td>";
  43.   }
  44.   echo "</tr>";
  45.  
  46.   //preparing timestamps
  47.   $time = strToTime("1970-01-01 10:00");
  48.   $strTime = date("H:i", $time);
  49.   echo "<br />Ten oclock: $strTime";
  50.   echo "<br />stamp: $time";
  51.   $pastMidnight = strToTime("1970-01-02");
  52.   $strTime = date("H:i", $pastMidnight);
  53.   echo "<br />Midnight: $strTime";
  54.   echo "<br />stamp: $pastMidnight";
  55.  
  56.   while ($time < $pastMidnight) {
  57.     $strTime = date("H:i", $time);
  58.     echo "\n  <tr><td>$strTime</td>";
  59.  
  60.     foreach ($headerArray as $index => $date) {
  61.       if (isSet($schedule[$time][$date])) {
  62.         echo "<td class=\"scheduleClient\">";
  63.         echo $schedule[$time][$date];
  64.       }
  65.       else {
  66.         echo "<td class=\"scheduleAvailable\">Available";
  67.       }
  68.       echo "</td>";
  69.     }
  70.     echo "</tr>";
  71.     $time += 1800;
  72.   }    
  73.  
  74.   echo "</table>";
  75. ?>

I was about to write I am experiencing difficulties with timestamp beiing shifted probably by timezone and php.ini not helping out. But as I were writing this post and thinking about what would people reply to that, I sorted that out - I used " putenv("GMT"); " to set timezone so that it's not shifted.
If anyone has a clue why php.ini didn't work, please tell me. ( I tried php.ini both in root dir and in the same dir as the script)

So now the code seems to be working (at least for the first brief sight)
Aug 27 '08 #7

Post your reply

Sign in to post your reply or Sign up for a free account.