PHP - generic variable variable name of a variable - php

I am quite new on php and I got stuck with a problem..
I have an array with the day of the week call
$days = array( 'monday', 'tuesday', 'wednesday', 'thurday', 'frieday', 'sunday', 'saturday' );
also got a for loop index i=0 i<7 i++ that go along all day of the week so I dont need to repeat the code 7 times (1 for each day)
and I got open, close, hours and lots of info about each day..
so i some part I loop I need to asing a value to a generic variable called:
$ini_XXXXX_close where XXX is the day of the week so it's ($ini_$dias[$i]_close) generally speaking
when I tried to do: $ini_$dias[$i]_close=0; I got error...
So what I did is use a third variable..
$indexcloseini="ini_$dias[$i]_close";
and then
$$indexcloseini=0 which sucessfull generate the variable $ini_XXXXX_close=0;
( doble $$ read it from php manual)
But the problem is when I tried later to compare that variable with any other value inside and IF sentence..
The only way to acomplish is already to use an intermediate variable..
Is there any other easy way to do this.. I read php reference manual and tried using {!} and lots of thing but cant get it work..
Is there any function to transform this "$ini_$dias[$i]_close" to string so I could then make
$*STRING CONVERSION FUNCTION of $ini_$dias[$i]_close*
to create the variable composed by many variable values ?

Personally I would not go that route. It is complex, confusing and hardly ever a usefull solution. HJave you considered using a nested array for storing the values? Or even creating an object?
As an array, you could have:
$ini = array('monday'=>array(), 'tuesday'=>array(), //etc);
$ini[$day]['closeStatus'] = 0;

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.

Convert a little different multidimensional arrays in same multidimensional array

I'm using an API from a contributer for my hotel booking engine. Whenever i need some information from his system, i execute CURL and i get the response in XML. Then i apply json_decode(json_encode(simplexml_load_string($response)), true)
and i get the response in array. So far so good, but there is a specific problem. The returned XML for the same function doesn't have always the same format. It depends on the parameters of the request. I 'll use a specific example to make this clear.
When i need to get the availability of my room/rooms, i send a request with a range of days. There are 4 different situations here.
1 room - 1 day
1 room - multiple days
Multiple rooms - 1 day
Multiple rooms - Multiple days
In situation (1) the array is like this:
In situation (2) the array is like this:
In situation (3) the array is like this:
In situation (4) the array is like this:
As you can see, if there is 1 room, there is no 0 key as an index and the information seems like "1 level up". Same situation for days. If you request for more than 1 day, then all days have their index (0, 1, 2 etc..).
The question is: Is there a way to convert every response to the array like situation 4?
I mean if there is 1 room, place it's information under RoomAvailability['0']. If there are more, place them like RoomAvailability['1'], RoomAvailability['2'] etc...
Same thing for the DayAvailability. If there is one one day place the day's information under DayAvailability['0']. Many days? DayAvailability['1'], DayAvailability['2'] etc...
With this trouble the only thing i could do to check if there are many rooms was:
if (isset($response['RoomsAvailability']['RoomAvailability']['0'])) {
//Do staff
}
But that's pretty bad! I don't want to waste time and conditions if there is 1 room or 50, 1 day or 30!
Any1 can help?
Just do a pre-check if they're array, and if not, encapsulate it in an array.
First do that for the main array (in this case the second RoomsAvailability)
an array
if(array_key_exists('#attributes', ($response['RoomsAvailability']['RoomAvailability']))
{
$response['RoomsAvailability']['RoomAvailability'] = [$response['RoomsAvailability']['RoomAvailability']];
}
After that you need to run each room and do the same for the days
foreach($response['RoomsAvailability']['RoomAvailability'] as &$item)
{
if(array_key_exists('DayAvailability', $item))
{
$item = [$item];
}
}
Full code:
// check if the base room availability is a single room, if it is convert into an array
if(array_key_exists('#attributes', ($response['RoomsAvailability']['RoomAvailability']))
{
$response['RoomsAvailability']['RoomAvailability'] = [$response['RoomsAvailability']['RoomAvailability']];
}
// now do the same for all the days in rooms
foreach($response['RoomsAvailability']['RoomAvailability'] as &$item)
{
if(array_key_exists('DayAvailability', $item))
{
$item = [$item];
}
}
// now do you stuff
NOTICE: on the foreachI've added an & at &$item so that the changes in the foreach do have effect outside of it
I answer my own question because i found out what my problem is.
In this line json_decode(json_encode(simplexml_load_string($response)), true) if a node has children, the array is like $array[0][something], $array[1][something] etc... but if there is only one child the array goes like $array[something] without the 0 key! That was totally unexpected!
After a lot of search, it seems like there is no abstract and proper way to convert any XML to a php array, keep each node's attributes and keep the same structure as the XML was. Please correct me if i'm wrong.
I decided to use SimpleXMLElement php.net link, pretty simple and easy to use.

Accessing variables, named with variables PHP

I am very new to programming and I got a job from school to do a "forecast" weather map from random generated numbers.
I already got 7 different arrays for every day (day1 -> day7) and all the code afterwards to check the required stuff and create the weather map.
Now I have the problem that I'd like to go through all the 7 arrays in 1 for-loop. I asked a friend and I think it's a very tiny thing missing / done wrong...
As I already got all the code afterwards (currently hardcoded for 1 day) I'd be pleased if you could provide me a solution for my (I guess crappy) way, not a totally different way eventhough it's most likely much more efficent what so ever.
I tried it like this:
for($daynr = 1; $daynr < 8; $daynr++){
$dayZ = 'day'.$daynr;
print_r($$dayZ);
...
This works like a charm and gives out array 1-7. But when I try to access a part of dayZ I get stuck:
echo $$dayZ[0][0]
Gives out:
Notice: Undefined variable: in C:\xampp\htdocs\index.php
on line 139
As many stuff later like $temp = explode('/',$$dayZ[$region_nr][3])... need to access the day-array it would be cool to have a solution for that.
Btw, something like echo $day1[0][0] works without problems.
Any help very appreciated, thanks in advance
Best regards
Michael
A cleaner solution would be to place the days in another array. So instead of $day1, $day2 etc you have an array $days containing your arrays for each day.
$days[0][0][0] // monday
$days[1][0][0] // tuesday
// ...
Use
${$dayZ}[0][0]
Keep in mind that this kind of variable format does NOT improve readability or good code.

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.

PHP accessing object stored in an array

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>';
}

Categories