I want to show one value from my array until a certain time is reached (every morning at 5:00 am). If this time is reached the next value from my array should be shown.
After the last value of the array was reached the script should start (automatically) with the first array value, again.
Example:
My array
$eventschedule = array("apple", "banana", "mango", "peach");
Loop should work like that:
**Schedule** | **Shown array value**
27.12. 5:00 am - 28.12. 4:59 am | apple
28.12. 5:00 am - 29.12. 4:59 am | banana
29.12. 5:00 am - 30.12. 4:59 am | mango
30.12. 5:00 am - 31.12. 4:59 am | peach
31.12. 5:00 am - 01.01. 4:59 am | apple | **loop should start again**
I think this could be achieved within a loop (maybe there is a better solution), but I don't know how to express the condition, that the script should get the next arrays' value every day at 5:00 am.
$eventschedule = array("apple", "banana", "mango", "peach");
$currenttime = date('Y-m-d H:i:s');
$nextevent = date('Y-m-d 5:00', strtotime(' +1 day'));
$i = 0;
while ($i <= 3) {
if ($currenttime < $nextevent) {
echo $eventschedule[$i];
$i++;
}
}
I'll deal mostly with the logic side of things, but I'd like to add that maybe your problem could be solved in other ways, or at least improve in some ways. For example: There's no sleep in your code? If the time did not arrive yet, it should check for the next one?
There's 2 solutions that I see, although they have the same basis: loop the array indefinitely. But, there are some little changes in implementation details:
Nested Loops: Use while (true) and a second loop internally (a while like you use, or a for/foreach).
Flattened Loop with modulo: Use while (true) { $i = ($i + 1) % count($eventschedule); } with your logic after the $i.
I'll show only the loop part of the code, assume that $eventschedule, $currenttime and $nextevent are already defined.
Nested Loops
I'll use nested while just because that's what you used, but otherwise I'd recommend using foreach.
while (true) {
$i = 0;
while ($i <= 3) { // could be generalized to $i <= count($eventschedule)
// or even better: changed to foreach
if ($currenttime < $nextevent) {
echo $eventschedule[$i];
$i++;
}
}
}
Flattened Loop with modulo
The idea is that when $i = 4, it'll loop back to 0.
$i = 0;
while (true) {
if ($currenttime < $nextevent) {
echo $eventschedule[$i];
$i = ($i + 1) % 4; // or % count($eventschedule);
// this is equivalent to:
/*
$i++;
if ($i == 4) {
$i = 0;
}
*/
}
}
Related
the title may be pretty confusing. Here's a script which requires a start-end and step value to add numbers to the start value:
function addieren($start, $ende, $schritt = 1) {
if ($start < $ende) {
$erg = 0;
for ($i = $start; $i <= $ende; $i += $schritt) {
$erg += $i;
yield $erg;
}
}
}
foreach (addieren(2, 10, 2) as $erg) {
echo $erg . "<br>";
}
So the start value is 2, the end value is 10 (but it's not ending at 10 as the result shows), and it should add 2 to the $i every step.
Here's the output:
2
6
12
20
30
The first output is clear to me, since the $erg was 0 and it added the 2 because of 2 steps.
But the next output is 6 and I don't get why. In the second loop, $i is 2 and and the script says: $i += $schritt so when $i is 2 and the $schritt value is also 2, why doesn't that output 4 as the second output? Hope you get what I mean.. I guess it's a pure logic error in my head.
i have a homework like this
Imaginative Tree
An imaginative tree grows in a garden. The tree only grows 1 m long in autumn and 2 times the height of the tree in spring. Make a program that determines the highest tree after Y years with the initial height X m.
in 1 year spring come first
i've tried to put multiple symbol inside the loop,
<?php
$holddata =0;
$length =0
function randomtree($year,$firstlength){
for ($i=0; $i < $year ; $i++) {
$holddata= $firstlength* 2;
$length= $holddata+1;
}
echo $length;
}
echo randomtree(2,3);
but the value not increasing ,i expected the $firstlength*2 and add 1 on it then loop them 2 times so the result will be 15 ,( 3*2+1=7 ,7*2+1=15)
You need to use the value of $firstlength as the basis of the start of each calculation and assign the result to it for the next iteration. This code also returns the result rather than echoing out out.
So to simplify your code you can use...
function randomtree($year,$firstlength){
for ($i=0; $i < $year ; $i++) {
$firstlength = ($firstlength* 2)+1;
}
return $firstlength;
}
echo randomtree(2,3);
I have been working for a while to combine a "foreach loop" and a "while loop". I would like my foreach to run 30 times. This is indicated by $counter. Now the problem is that my "while" again starts the "foreach" every time. But it hears 30 times turning the "while" each time again.
If I get the while part away and use static code, it will work completely. But I need to link my DB for the information. Perhaps an option is to make a "foreach" a "for" or a whole different option. But I have no idea how to set him up.
$counter = days in a month
$index = foreach time for running. Max $counter
$NUM = unique number of 1 people
The $ index together with $ cut_startday together indicate when a box is to be red or green.
Here's the code for the none working foreach:
foreach(range(1,$counter) as $index) {/*open foreach*/
$get_data = "
SELECT *
FROM core";
$result1 = $conn->query($get_data) or die($conn ->error);
//Start query 1
if($result1) {
while($row = $result1->fetch_assoc()) {
// Get NUM, START DATE and END DATE
$NUM = ($row['c_m_num']);
$startdate = ($row['e_date_s']);
$enddate = ($row['e_date_e']);
// Cut strings for date
$sort_year = substr($startdate, 6, 4); // START YEAR -> 2017
$sort_month = substr($startdate, 0, 2); // START MONTH -> 09
$cut_startday = substr($startdate, 3, 2); // START DAY -> 17
$cut_endday = substr($enddate, 3, 2); // END DAY -> 19
if($load_m_NUM == "$NUM" and $index >= $cut_startday && $index <= $cut_endday ){
echo"<td style='background-color:red;'>x</td>";
}
else{
echo"<td style='background-color:green;'></td>";
}
}
}
/*end foreach*/ }
What the idea is of the code. I want a calendar with a top row de days of a month and on the left side al the people. If the core find a match between days and 1 men, color the td red if not color green.
Any help greatly appreciated!
You could change the foreach statement to for ($index = 0; $index < 30; $index++). To improve your code I suggest putting the for loop inside the while loop instead. That way you only query the database once instead of 30 times.
Ive managed to loop through a table and get the difference in days between 2 dates adjacent to each other in the table.
Multiple entries have the same date, i have it now that when that date changes, it displays an image however i want it to display the image as many times as the difference in date
$sql = mysql_query("SELECT * FROM Films_Info")
or die(mysql_error());
$last_value = null;
while ($row = mysql_fetch_assoc($sql)) {
if (!is_null($last_value)) {
$a = new DateTime($row['FilmRelease']);
echo "<p>".$row['FilmName']."</p>";
$interval = $a->diff(new DateTime($last_value));
//echo $interval->format('%d days');
$i = 0;
}
$howManydays = $interval->days;
for ( $i; $howManydays; $i++) {
echo "<img src=\"day.jpg\" />";
$howManydays = 0;
}
$last_value = $row['FilmRelease'];
}
for ( $i = 0; $i < $howManydays; $i++) The second is a conditional statement telling when the loop should stop.
The first section in the for loop where it says $i = 0 initialized the variable $i to 0 and then tests the condition $i < $howManydays.
Let's say $howManydays equals 1. That means 0 < 1, so the loop will perform.
At the end of the loop, the third section is called ($i++), so $i is incremented and now equals 1. The second section is called again to test conditions $i < $howManydays which is asking if 1<1 which it's not, so the loop will exit.
So if $howManydays is greater than 0, the loop should happen the integer amount that is in $howManydays.
You will want to remove $howManydays = 0; within the for loop, if you don't want it to only fire once.
The for loop
for ( $i = 0; $i < $howManydays; $i++){
// ...
}
is somewhat equivalent to the while loop:
$i = 0;
while ( $i < $howManydays ){
// ...
$i++;
}
http://php.net/manual/en/control-structures.for.php for more information
In your code above, you should also check if interval was set. You should probably just do an if rather than a while, if only need one interval.
you could just do a simple division on the interval and print out the image that many times
$last_value_u = $last_value->format('U');
$a_u = $a->format('U');
$interval = $a_u - $last_value_u;
$image_count = intval($interval/86400);
for($i=0;$i<$image_count;$i++)
echo "<p><img src=\"day.jpg\" /></p>";
Update
An alternative option would be to loop through the interval:
for($i=$last_value_u;$i<$a_u;)
{
if(intval(($a_u - $i)/86400) == X)
{
// run special code for specific day
}
else
{
// run code for every other day
}
$i+=86400;
}
I have a code that generates total posts from a database per hour for the latest 10 hours. Now, the problem is that only hours with posts are displayed, but that won't work for me because i want to display the whole thing as a chart.
Example of the current array:
array("12"=>"20403",
"15"=>"17017",
"17"=>"84013");
The keys represent the hour in a 24 format. So what i need is a function that fills in the empty hours with 0 value.
Example:
$currenthour=date('H'); // i think it may be based on the latest hour.
array("11"="0",
"12"=>"20403",
"13"=>"0",
"14"=>"0",
"15"=>"17017",
"16"=>"0",
"17"=>"84013",
"18"=>"0",
"19"=>"0",
"20"=>"0");
Thanks!
foreach(range(0, 23) as $hour)
if(!isset($ary[$hour]))
$ary[$hour] = 0;
ksort($ary);
to fill in only last hours you may need something like
function last_hours($hour, $cnt) {
return $hour < $cnt - 1 ?
array_merge(range($hour, 0), range(23, 25 - $cnt + $hour)) :
range($hour, $hour - $cnt + 1);
}
and then
$now = date("G");
$new_array = array();
foreach(last_hours($now, 10) as $hour)
$new_array[$hour] = isset($ary[$hour]) ? $ary[$hour] : 0;
Use array_fill OR do it with a loop (assuming $hours is your array:
$currenthour=date('H');
for($i = $currenthour; $i < 23; $i++)
if(!isset($hours[$i]))
$hours[$i] = 0;
You can simply iterate through the array, and see if the value at the index is set. Like this:
Edit with your the last 10 hours:
$currenthour=date('H')
$beginrange = $currenthour - 10
if ($beginrange =< 0)
$beginrange = 23 + $beginrange
$endrange = $currenthour
//set up the for loop
foreach(range($beginrange, $endrange) as $i)
//check if the element is set
if(!isset($array[$i]))
// set it
$array[$i] = 0;