PHP accessing object stored in an array - php

I am new to taking an object oriented approach with php...actually I have a lot of learning to do overall, but the only way to learn is by doing.
So I have an array that holds several DateTime objects..I know this to be true because I have ran var_dump on the array and it indeed is holding several objects.
I need to go through each date and make sure there is never a difference greater than one day.
My research would seem to indicate that we cannot access or modify an object using the subscript operator:
$foo = $neat_array[$i+1]->format('U') ; //looking to format DateTime object as unix
//this returns an error every time
Okay I am fine with that, but I simply cannot figure out the syntax to access a specific item in the array so that it is seen as an object and does not pull an error.
I have pieced together that using -> is how I need to do it, but I never get any useable result.
Here is pseudo code of what I am trying to do
foreach($date_array as $date)
{
//check to see if the difference between the next date in the array and the current date of the array is greater than one day.
//I cannot use diff because I am on php 5.2 so I am trying this
$date->format('U') and then doing the math
}

Since learning by experimenting (and failing) is IMO a great way to learn, here is something to get you started.
$date_array = array(
new DateTime("tomorrow"),
new DateTime("now"),
new DateTime("yesterday"),
new DateTime("last day of october")
);
for( $i = 0, $count = count( $date_array); $i < $count; $i += 2) {
// Get the current object AND the next one in the array
echo $date_array[ $i ]->format('U'); echo '<br />';
echo $date_array[ $i + 1 ]->format('U'); echo '<br />';
// Now that you have the UNIX timestamps, you can do the math you need in here.
}
Note that the above will fail if the array contains an odd number of elements - I'll leave that fix up to you (if you need it).
Demo
Edit: You're probably getting that error for one of two reasons:
You're referencing an element that either isn't a DateTime object
You're referencing an element that doesn't exist in the date array
Here is a demo that shows error #2.
Edit: Here is a working example based off your answer that works for even and odd array sizes. It is essentially the same, except I don't bother with saving the values to variables or subtracting and comparing to 1 (since it's unnecessary).
$session_dates = $date_array = array(
new DateTime("tomorrow"),
new DateTime("yesterday"),
new DateTime("now"),
);
for( $i = 0, $count = count( $date_array) - 1; $i < $count; $i++)
{
if( ($date_array[ $i + 1 ]->format('U') - $date_array[ $i ]->format('U')) > 86400)
{
die( 'The date array does not contain consecutive dates.');
}
}
See it in action.

Okay..first of all, I appreciate everyone's help. Nickb, thanks for the help and the demos. As I surmised earlier, your suggestion that I might be trying to access an element that doesn't exist in the array was absolutely the case. What I am trying to do here is a pretty important part of a site I am creating..this whole mess will serve as a function in a class that checks reservation dates.
This is my first shot at Stack Overflow, so forgive me but I probably should have put more information in my initial question, but I was convinced I knew why the code wasn't working..which was completely incorrect!
See, since I always needed to know the current element, plus the next element in the array, my code was always breaking on the very last run of the loop, because it was trying to access the current key, plus the next one (which didn't exist on the last try).
Now, the real frustrating part is I screwed around with the for loop for this code all night and I still could not get it to cleanly go through every item without breaking...I would always over-run on that last item of the array and pull the error. I think the problem all along was that I never needed to go through every item in the array, just up to the second to last item (plus check the next one) then quit the loop.
Here is my code that finally works, but I don't really like it...I have a feeling there are some simple fixes in syntax and other areas that will make this more efficient...if not, the so be it...this is by the way, basically my testing code full of echos to see what was actually happening, but it is finally doing everything right:
$count = (count($session_dates)-1);
//never could get that last item to not trigger error, so subtracting one from the count was the only thing to end my frustration!!!but as I write this answer I think I see why and that is because we don't need to go through each item of the array, just each but the last item
echo '<p>'.$count.' this is the count of session dates </p>';
for ($i=0; $i<$count; $i++){
$unix_one = $session_dates[$i+1]->format('U');
//make some variables that are in the date format I want to visualize for echoing
$unix_echo_one = $session_dates[$i+1]->format("n".'/'."j".'/'."Y");
$unix_two = $session_dates[$i]->format('U');
$unix_echo_two = $session_dates[$i]->format("n".'/'."j".'/'."Y");
//see if the difference is greater than one day
if(($unix_one-$unix_two)/86400>1){
echo 'these dates are absolutely not consecutive, you fail!!';
//we only need one occurrence to wreck what we are trying to do, so just exit if it happens.
exit();
}
//I needed to see if any of the loop was happening to help try and figure this out!!
echo '<p>'.$unix_echo_one.'||'.$i.'||'.$unix_echo_two.'</p>';
}

Related

PHP array_push() inside a function in a class to array outside of class

I'm struggling with my lack of operational knowledge with handling or arrays and variables within a private function that is within a class in an applciation I've "inherited" control of.
The function loops for X days, within that loop, a certain number of MySQL rows will be returned, from a range of different queries. Each row from each query issues a +1 to a counter.
Some maths is then performed on the value of the counter (not really relevant)
Once X days have been iterated through, I need to discard all days calcualted coutner value EXCEPT the value that was the highest. I had planned on using max($array); for this.
I will greatly strip down the code for the purpose of this example:
class Calendar {
public $heights;
private fucntion dayLoop($cellNumber) {
$heights = []; //array
$block_count = 0; //counter
while(mysqlrowdata) {
[code for mysql operations]
$block_count++; //increment the count
}
$day_height = ($block_count * 16) + 18; //do some math specific to my application
$this->heights[] = $day_height; //commit calc'd value to array
//array_push($heights, $day_height); //this was a previosu attempt, i dont think i should use array_push here..??
}
}
This function is called on other "front end" pages, and if I perform a var_dump($heights); at the bottom of one of those pages, the array returns empty with
Array ( )
Essentially, at that front end page, I need to be able to A) inspect the array with vlaues from each looped day from X days, and B) pull the largest calc'd counter value from any of the X days that were iterated through in the loop.
I have tried a myriad of things, like changing the function to be public, defining the start of the array on the front end pages instead of anywhere in the class or fucntion. I declared array name as a variabel in the class as I read that I needed to do that.
Overall, I just don't really understand how I'm MEANT to be handling this, or if I'm going about it in completely the wrong way? Solutions very welcome, but advice and words of wisdom also appreciated greatly. Thanks.

Nested foreach inside a while loop, array is not an array after first while

I have a while loop with a nested foreach loop, after the first while loop is run the array inside the foreach loop is being unset (or at least ceases to be an array).
Where I'm headed is an array of data for a bar chart which shows every day since a start date and the number of clicks by type (8 types) on each day. So I'm calculating the number of days from the start date to now, and for each day it checks the first array to see how many, if any, and what types of clicks there were on that day.
Here's the relevant bit of code...
$i=0;
while($i<=$numdays)
{
echo $date2->format('Y-m-d') . "<br>";
foreach($clicklist as $key => $clicklist) {
if ( $clicklist[clickdate] === $date2 ) {
echo $clicklist[clicks]." clicks on ".$clicklist[type]." on that date<br>";
}
}
$date2->modify('+1 day');
$i++;
echo is_array($clicklist) ? 'Array<br>' : 'not an Array<br>';
}
$numdays is the number of days from the startdate to now (needed for one of the chart variables, $date2 is the startdate and $clicklist is the array of clicks/dates/types from the db. All the random echos are just so I can see what's going on - or not as the case may be.
The while loop works fine is isolation, the foreach loop also works fine outside the while loop (using a static date in place of the variable), but of course that's just a one time run.
From the manual, foreach resets the pointer back to the start automatically, so that's not an issue.
I'm missing something obvious I'm sure.. any guidance much appreciated.
foreach($clicklist as $key => $clicklist)
Is where your problem is. Do not reuse the name, change it for something such as
foreach($clicklist as $key => $cl)
otherwise by the end of your loop, $clicklist will be overwritten as the last element that was iterated.
Edit: on a related note, avoid accessing your array without quotes, such as in $clicklist[clickdate]. This could later on turn into a bug if you ever encounter a constant that has been defined with that same name. Use $clicklist['clickdate'] instead.

Create a multi column array using for loop

So as the question states, im trying to create an array using a for loop, this seems as though its a simple question, but i cant find the asnwer on SO or googling. Heres what im doing:
$twelve=array("user","day");
for($i=0; $i<$value; $i++)
{
$total=$anarray[$i][value]; //get a value
$twelve[$i]=($i,$total); //insert values into array
}
this doesn't work, how should i go about getting this to work?
You may end up in a never-ending loop if $total=$anarray[$i][value]; is an increasing value. Regardless of the loop, you'll want to do as the other answerer mentioned, namely:
$twelve[$i] = array($i, $total);
I think it should be $twelve[$i] = array($i, $total);
Also, on this line;
$total=$anarray[$i][value]; //get a value
Unless value is defined as a constant, I think you want to do $anarray[$i][$value];.
PHP might not recognize value as a set variable or a constant, therefore crashes and never sets $twelve to any value.
I have found a solution that does work
in each loop simply do:
$twelve[$i]["user"]=$i;
$twelve[$i]["day"]=$total;
It would be nice if there is a way to do that in one line, but that is working.

Need a code snippet for backward paging

Hi guys I'm in a bit on a fix here. I know how easy it is to build simple pagination links for dynamic pages whereby you can navigate between partial sets of records from sql queries. However the situation I have is as below:
COnsider that I wish to paginate between records listed in a flat file - I have no problem with the retrieval and even the pagination assuming that the flat file is a csv file with the first field as an id and new reocrds on new lines.
However I need to make a pagination system which paginates backwards i.e I want the LAST entry in the file to appear as the first as so forth. Since I don't have the power of sql to help me here I'm kinda stuck - all I have is a fixed sequence which needs to be paginated, also note that the id mentioned as first field is not necessarily numeric so forget about sorting by numerics here.
I basically need a way to loop through the file but backwards and paginate it as such.
How can I do that - I'm working in php - I just need the code to loop through and paginate i.e how to tell which is the offset and which is the current page etc.
I'm assuming you have a well-formed document with delimiters.
$array = explode("<>", $source); //parse data into an array
$backward = array_reverse($array); //entire array is reversed - last elements are now first
Use this code for a jumping off point.
$records = file('filedata.csv');
$recordsInOrder = array_reverse($records);
$first = 5;
$last = 10;
for($x = $first; $x <= $last; $x++) {
$viewTheseResults[] = $recordsInOrder[$x];
}
You can use an offset to determine the starting and ending keys in the array similar to how you would if you were pulling the data from a database.

PHP Change Array Over and Over

I have any array
$num_list = array(42=>'0',44=>'0',46=>'0',48=>'0',50=>'0',52=>'0',54=>'0',56=>'0',58=>'0',60=>'0');
and I want to change specific values as I go through a loop
while(list($pq, $oin) = mysql_fetch_row($result2)) {
$num_list[$oin] = $pq;
}
So I want to change like 58 to 403 rather then 0.
However I always end up getting just the last change and non of the earlier ones. So it always ends up being something like
0,0,0,0,0,0,0,0,0,403
rather then
14,19,0,24,603,249,0,0,0,403
How can I do this so it doesn't overwrite it?
Thanks
Well, you explicititly coded that each entry should be replaced with the values from the database (even with "0").
You could replace the values on non-zero-values only:
while(list($pq, $oin) = mysql_fetch_row($result2)) {
if ($pq !== "0") $num_list[$oin] = $pq;
}
I don't get you more clear, i thought your asking this only. Check this
while(list($pq, $oin) = mysql_fetch_row($result2)) {
if($oin==58) {
$num_list[$oin] = $pq;
}
}
In my simulated tests (although You are very scarce with information), Your code works well and produces the result that You want. Check the second query parameter, that You put into array - namely $pg, thats what You should get there 0,0,0,0,0...403 OR Other thing might be that Your $oin numbers are not present in $num_list keys.
I tested Your code with mysqli driver though, but resource extraction fetch_row is the same.
Bear in mind one more thing - if Your query record number is bigger than $numlist array, and $oin numbers are not unique, Your $numlist may be easily overwritten by the folowing data, also $numlist may get a lot more additional unwanted elements.
Always try to provide the wider context of Your problem, there could be many ways to solve that and help would arrive sooner.

Categories