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.
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>';
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.
Related
I cannot understand why the result of subtracting the current time from the variable of $_session['now'] that has included the previous time is zero.
I expected outputting the difference between the current time and the time when i have created the variable $student->now. Explain me please.
class Student
{
public function __set($key, $value)
{
$_SESSION[$key] = $value ;
}
public function __get($key)
{
return $_SESSION[$key];
}
}
session_start();
$student = new Student() ;
//__set function will be called ;
$student->now = time();
//__get function will be called ;
echo time() - $_SESSION["now"]; // output is zero ?!
The $_session['now'] variable is set in the line before the echo.
In the echo line the current time is compared to the time set in the line before.
Because both lines are executed directly after each other, both are executed within the same second. There will be a difference of milliseconds but time() function is measured in seconds, refer to: https://www.php.net/manual/en/function.time.php.
That's why both timestamps are the same and there is no difference between these when comparing them.
time() has a precision of ONE second, you are basically doing:
$now = time(); // e.g. 1627385278
echo time() - $now; // 1627385278 - 1627385278
This happens very fast, so the output is (almost always) zero.
The fact that your example code involves a "session" hints that you want to measure time between different HTTP requests. If that is the case, some logic is needed to ONLY set the stored value for the first time, but not thereafter.
Here is my pseudo code
For loop repeat 30 times
Call and execute API script which takes less than 1 second
I want the system to sleep for some moment(less than 1 second)
Loop end
I want the above script should finish execution in minimum of 30 seconds (2-3 seconds longer is not a problem but must not less).
Can you write a sample code for me(only time related)
Here's a little program that implements the essence of what I believe you are looking for:
$minTime = 30;
$perSec = 10000;
$start = microtime(TRUE)*$perSec;
print("This must take $minTime seconds.\n");
// Replace this loop with what you actually need done
for ($i=0; $i<10; $i++) { print("Doing stuff #{$i}... "); sleep(1); }
// Check difference in timestamps to calculate remaining time
$remain=($minTime*$perSec-(microtime(TRUE)*$perSec-$start))/$perSec;
var_dump(['remain' => $remain]);
if ($remain > 0) {
print("\n$remain seconds remaining... ");
sleep($remain);
}
print("DONE\n");
This code has been updated to use microtime() instead of time(), which only permitted intervals of integer seconds. On systems that support gettimeofday() we can work with microseconds, instead.
I have PHP array which I use to draw a graph
Json format:
{"y":24.1,"x":"2017-12-04 11:21:25"},
{"y":24.1,"x":"2017-12-04 11:32:25"},
{"y":24.3,"x":"2017-12-04 11:33:30"},
{"y":24.1,"x":"2017-12-04 11:34:25"},
{"y":24.2,"x":"2017-12-04 11:35:35"},.........
{"y":26.2,"x":"2017-12-04 11:36:35"}, ->goes up for about a minute
{"y":26.3,"x":"2017-12-04 11:37:35"},.........
{"y":24.1,"x":"2017-12-04 11:38:25"},
{"y":24.3,"x":"2017-12-04 11:39:30"}
y=is temperature and x value is date time,
as you can see temperature doesn't change so often even if, it change only for max 0.4. But sometimes after a long period of similar values it change for more than 0.4.
I would like to join those similar values, so graph would not have 200k of similar values but only those that are "important".
I would need an advice, how to make or which algorithm would be perfect to create optimized array like i would like.
perfect output:
{"y":24.1,"x":"2017-12-04 11:21:25"},.........
{"y":24.1,"x":"2017-12-04 11:34:25"},
{"y":24.2,"x":"2017-12-04 11:35:35"},.........
{"y":26.2,"x":"2017-12-04 11:36:35"}, ->goes up for about a minute
{"y":26.3,"x":"2017-12-04 11:37:35"},.........
{"y":24.1,"x":"2017-12-04 11:38:25"}
Any help?
As you specified php I'm going to assume you can handle this on the output side.
Basically, you want logic like "if the absolute value of the temperature exceeds the last temperature by so much, or the time is greater than the last time by x minutes, then let's output a point on the graph". If that's the case you can get the result by the following:
$temps = array(); //your data in the question
$temp = 0;
$time = 0;
$time_max = 120; //two minutes
$temp_important = .4; //max you'll tolerate
$output = [];
foreach($temps as $point){
if(strtotime($point['x']) - $time > $time_max || abs($point['y'] - $temp) >= $temp_important){
// add it to output
$output[] = $point;
}
//update our data points
if(strtotime($point['x']) - $time > $time_max){
$time = strtotime($point['x']);
}
if(abs($point['y'] - $temp) >= $temp_important){
$temp = $point['y'];
}
}
// and out we go..
echo json_encode($output);
Hmm, that's not exactly what you're asking for, as if the temp spiked in a short time and then went down immediately, you'd need to change your logic - but think of it in terms of requirements.
If you're RECEIVING data on the output side I'd write something in javascript to store these points in/out and use the same logic. You might need to buffer 2-3 points to make your decision. Your logic here is performing an important task so you'd want to encapsulate it and make sure you could specify the parameters easily.
I have 6 nested loops in a PHP program, however, the calculation time for the script is extremely slow. I would like to ask if there is a better way of implementing the 6 loops and increasing computation time, even if it means switching to another language. The nature of the algorithm I'm implementing requires iteration, so I don't know how I can better implement it.
Here's the code.
<?php
$time1 = microtime(true);
$res = 16;
$imageres = 128;
for($x=0;$x<$imageres;++$x){
for($y=0;$y<$imageres;++$y){
$pixels[$x][$y]=1;
}};
$quantizermatrix = 1;
$scalingcoefficient = 1/($res/2);
for($currentimagex=0;$currentimagex<($res*($imageres/$res-1)+1);$currentimagex = $currentimagex +$res){
for($currentimagey=0;$currentimagey<($res*($imageres/$res-1)+1);$currentimagey = $currentimagey +$res){
for($u=0;$u<$res;++$u){
for($v=0;$v<$res;++$v){
for($x=0;$x<$res;++$x){
for($y=0;$y<$res;++$y){
if($u == 0) {$a = 1/(sqrt(2));} else{$a = 1;};
if($v == 0){$b = 1/(sqrt(2));}else{$b = 1;};
$xes[$y] = $pixels[$x+$currentimagex][$y+$currentimagey]*cos((M_PI/$res)*($x+0.5)*$u)*cos( M_PI/$res*($y+0.5)*$v);
}
$xes1[$x] = array_sum($xes);
}
$xes2= array_sum($xes1)*$scalingcoefficient*$a*$b;
$dctarray[$u+$currentimagex][$v+$currentimagey] = round($xes2/$quantizermatrix)*$quantizermatrix;
}}}};
foreach($dctarray as $dct){
foreach($dct as $dc){
echo $dc." ";
}
echo "<br>";}
$time2 = microtime(true);echo 'script execution time: ' . ($time2 - $time1);
?>
I've removed a large portion of the code that's irrelevant, since this is the section of the code that's problematic
Essentially the code iterates through every pixel in a PNG image and outputs a computed matrix (2d array). This code takes around 2 seconds for a 128x128 image. This makes this program impractical for normal images greater than 128x128
There is a function available in Imagick library
Imagick::exportImagePixels
Refer the below link it might help you out
http://www.php.net/manual/en/imagick.exportimagepixels.php
Is there a PHP equivalent to setting timeouts in JavaScript?
In JavaScript you can execute code after certain time has elapsed using the set time out function.
Would it be possible to do this in PHP?
PHP is single-threaded, and in general PHP is focused on the HTTP request cycle, so this would be tricky to allow a timeout to run code, potentially after the request is done.
I can suggest you look into Gearman as a solution to delegate work to other PHP processes.
You can use the sleep() function:
int sleep ( int $seconds )
// Delays the program execution for the given number of seconds.
Example:
public function sleep(){
sleep(1);
return 'slept for 1 second';
}
This is ugly, but basically works:
<?php
declare(ticks=1);
function setInterval($callback, $ms, $max = 0)
{
$last = microtime(true);
$seconds = $ms / 1000;
register_tick_function(function() use (&$last, $callback, $seconds, $max)
{
static $busy = false;
static $n = 0;
if ($busy) return;
$busy = true;
$now = microtime(true);
while ($now - $last > $seconds)
{
if ($max && $n == $max) break;
++$n;
$last += $seconds;
$callback();
}
$busy = false;
});
}
function setTimeout($callback, $ms)
{
setInterval($callback, $ms, 1);
}
// user code:
setInterval(function() {
echo microtime(true), "\n";
}, 100); // every 10th of a second
while (true) usleep(1);
The interval callback function will only be called after a tickable PHP statement. So if you try to call a function 10 times per second, but you call sleep(10), you'll get 100 executions of your tick function in a batch after the sleep has finished.
Note that there is an additional parameter to setInterval that limits the number of times it is called. setTimeout just calls setInterval with a limit of one.
It would be better if unregister_tick_function was called after it expired, but I'm not sure if that would even be possible unless there was a master tick function that monitored and unregistered them.
I didn't attempt to implement anything like that because this is not how PHP is designed to be used. It's likely that there's a much better way to do whatever it is you want to do.
Without knowing a use-case for your question it's hard to answer it:
If you want to send additional data to the client a bit later you can do a JS timeout on the client side with a handler that will make a new HTTP request to PHP.
If you want to schedule some task for a later time you can store that in a database and poll the DB in regular intervalls. It's not the best peforming solution but relatively easy to implement.
if ($currenturl != $urlto)
exit( wp_redirect( $urlto ) );
You can replace above two line with below code inside your function
if ($currenturl != $urlto)
header( "refresh:10;url=$urlto" );