user7491692
user7491692

Reputation:

Using time() inside a while loop

For a school assignment we need to write a PHP script that counts for 1 second.

The following code I wrote should do exactly that was my thought:

$startTijd = time();
$teller = 0;
while($startTijd == time()){
    echo 'Iteratie: ' . $teller . '<br>';
    $teller++;
}

However, every time I run this or any PHP script similar to it that uses the time() function inside a while loop I get a 502 bad request from the server when I try to visit the page.

Upvotes: 0

Views: 1551

Answers (2)

LSerni
LSerni

Reputation: 57388

Your code as it is would not work (would not count one second exactly), because time() has a granularity of one second, and you have no guarantees that you landed on your page exactly at the tick of a second. So you need to synchronize.

To be clear, imagine calling time() several times, and let's suppose time() outputs in HH:MM:SS instead of Unix timestamps for legibility's sake:

Code
print time()
print time()
print time()
...

Output:
01:15:17
01:15:17
01:15:17
...
01:15:18
01:15:18
01:15:18
...

Your program probably currently does not work correctly because even in the little time that the loop runs, it generates a fantastic quantity of output (as can be seen above, time() remains "valid" for up to a whole second, and in that time a loop can execute lots of times). If there's some sort of resource limit on the PHP process, it's possible that this drives the process over its quota, resulting in the 502 error. You can check that by removing the echo from the loop, and just adding echo "Done." at the end.

You want to count between the instant in time in which time() transitions from 01:15:17 to 01:15:18, up to the instant when it again transitions to 01:15:19. Those instants will be separated by exactly one second.

What you would need to do is:

$startTijd = time()+1; // It is now maybe 01:15:17.93. We want to start
                       // counting at 01:15:18, so we need to wait for it.
while($startTijd !== time()) {
    // Do nothing except maybe a very brief sleep to save CPU
    usleep(5); // this is optional anyway.
}
// It is now 01:15:18.000003 and $startTijd is 01:15:18
$teller = 0;
// time() will remain equal to 01:15:18 for one second,
// while wall clock time increases from 01:15:18.000003 to 01:15:18.999999
while ($startTijd == time()) {
    // Don't output anything here
    $teller++;
}
// New transition detected.
// It is now e.g. 01:15:19.000137 and time() says 01:15:19.
echo 'Iteratie: ' . $teller . '<br>';

Alternately you can use microtime(true):

$teller = 0;
$endTijd = microtime(true) + 1.0;
while ($endTijd >= microtime(true)) {
    // Don't output anything here
    $teller++;
}
echo 'Iteratie: ' . $teller . '<br>';

Upvotes: 2

Ren&#233; H&#246;hle
Ren&#233; H&#246;hle

Reputation: 27295

Your code makes no sense... your while statment is only true if you computer is fast enough.

$startTijd = 100; # you set here the time represented by a number

while(100 == time() #101) { # here time is some milliseconds or seconds in the future

so after a second your while stops so that make not so much sense. Then use

while(true) {

and stop the while with a condition insight the while loop.

Upvotes: 1

Related Questions