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" );
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.
You have a function that always inputs an interval (natural numbers in this case), this function returns a result, but is quite expensive on the processor, simulated by sleep in this example:
function calculate($start, $end) {
$result = 0;
for($x=$start;$x<=$end;$x++) {
$result++;
usleep(250000);
}
return $result;
}
In order to be more efficient there is an array of old results, that contains the interval used an the result of the function for that interval:
$oldResults = [
['s'=>1, 'e'=>2, 'r' => 1],
['s'=>2, 'e'=>6, 'r' => 4],
['s'=>4, 'e'=>7, 'r' => 3]
];
If I call calculate(1,10) the function should be able to calculate new intervals based on old results and accumulate them, In this particular case it should take the old result from 1 to 2 add that to the old result from 2 to 6 and do a new calculate(6,10) and add that too. Take in consideration that the function ignores the old saved interval from 4 to 7 since it was more convenient to use 2-6.
This is a visual representation of the problem:
Of course in this example, calculate() is quite simple and you can just find particular ways to solve this problem around it, but in the real code calculate() is complex and the only thing I know is that calculate(n0,n3)==calculate(n0,n1)+calculate(n1,n2)+calculate(n2,n3).
I cannot find a way to solve the reuse of the old data without using a bunch of IF and foreach, I'm sure there is a more elegant approach to solve this.
You can play with the code here.
Note: I'm using PHP but I can read JS, Pyton, C and similar languages.
if you are certain that calculate(n0,n3)==calculate(n0,n1)+calculate(n1,n2)+calculate(n2,n3), then it seems to me that one approach might simply be to establish a database cache.
you can pre-calculate each discrete interval, and store its result in a record.
$start = 0;
$end = 1000;
for($i=1;$i<=$end;$i++) {
$result = calculate($start, $i);
$sql = "INSERT INTO calculated_cache (start, end, result) VALUES ($start,$i,$result)";
// execute statement via whatever dbms api
$start++;
}
now whenever new requests come in, a database lookup should be significantly faster. note you may need to tinker with my boundary cases in this rough example.
function fetch_calculated_cache($start, $end) {
$sql = "
SELECT SUM(result)
FROM calculated_cache
WHERE (start BETWEEN $start AND $end)
AND (end BETWEEN $start AND $end)
";
$result = // whatever dbms api you chose
return $result;
}
there are a couple obvious considerations such as:
cache invalidation. how often will the results of your calculate function change? you'll need to repopulate the database then.
how many intervals do you want to store? in my example, I arbitrarily picked 1000
will you ever need to retrieve non-sequential interval results? you'll need to apply the above procedure in chunks.
i wrote this:
function findFittingFromCache($from, $to, $cache){
//length for measuring usefulnes of chunk from cache (now 0.1 means 10% percent of total length)
$totalLength = abs($to - $from);
$candidates = array_filter($cache, function($val) use ($from, $to, $totalLength){
$chunkLength = abs($val['e'] - $val['s']);
if($from <= $val['s'] && $to >= $val['e'] && ($chunkLength/$totalLength > 0.1)){
return true;
}
return false;
});
//sorting to have non-decremental values of $x['s']
usort($candidates, function($a, $b){ return $a['s'] - $b['s']; });
$flowCheck = $from;
$needToCompute = array();
foreach($candidates as $key => $val){
if($val['s'] < $flowCheck){
//already using something with this interval
unset($candidates[$key]);
} else {
if($val['s'] > $flowCheck){
//save what will be needed to compute
$needToCompute[] = array('s'=>$flowCheck, 'e'=>$val['s']);
}
//increase starting position for next loop
$flowCheck = $val['e'];
}
}
//rest needs to be computed as well
if($flowCheck < $to){
$needToCompute[] = array('s'=>$flowCheck, 'e'=>$to);
}
return array("computed"=>$candidates, "missing"=>$needToCompute);
}
It is function which returns you two arrays, one "computed" holds found already computed pieces, second "missing" holds gaps between them which must be computed yet.
inside function there is 0.1 threshold, which disqualifies chunks shorter than 10% of total searched length, you can rewrite function to send threshold as parameter, or ommit it completely.
i presume results will be stored and after computing added into cache ($oldResults), which might be of any form (for example database as Jeff Puckett suggested). Do not forget to add all computed chunks and whole seeked length into cache.
I am sorry but i can't find a way without cycles and ifs
Working demo:
link
Can any body explain me what is the difference among sleep() and usleep() in PHP.
I have directed to use following scripts to do chat application for long pulling but in this script I am getting same effect using usleep(25000); or without usleep(25000);
page1.php
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"
type="text/javascript"></script>
<script>
var lpOnComplete = function(response) {
console.log(response);
// do more processing
lpStart();
};
var lpStart = function() {
$.post('page2.php', {}, lpOnComplete, 'json');
};
$(document).ready(lpStart);
</script>
page2.php
<?php
$time = time();
while((time() - $time) < 30) {
// query memcache, database, etc. for new data
$data = getLatest();
// if we have new data return it
if(!empty($data)) {
echo json_encode($data);
break;
}
usleep(25000);
}
function getLatest() {
sleep(2);
return "Test Data";
}
?>
The argument to sleep is seconds, the argument to usleep is microseconds. Other than that, I think they're identical.
sleep($n) == usleep($n * 1000000)
usleep(25000) only sleeps for 0.025 seconds.
sleep() allows your code to sleep in seconds.
sleep(5); // sleeps for 5 seconds
usleep() allows your code with respect to microseconds.
usleep(2500000); // sleeps for 2.5 seconds
usleep() is used to delay execution in "microseconds" while sleep() is used to delay execution in seconds.
So usleep(25000) is 0.025 seconds.
Is there any difference between the two?
One other difference is sleep returns 0 on success, false on error. usleep doesn't return anything.
Simply
usleep uses CPU Cycles while sleep does not.
sleep takes seconds as argument
while usleep takes microseconds as argument
Everyone knows that function calls in PHP hit the performance badly. This script demonstats the problem:
// Plain variable assignment.
$time = microtime(true);
$i = 100000;
while ($i--)
{
$x = 'a';
}
echo microtime(true) - $time."\n\n";
// 0.017973899841309
$time = microtime(true);
function f() { $a = "a"; return $a; }
$i = 100000;
while ($i--)
{
$x = f();
}
echo microtime(true) - $time."\n\n";
//0.18558096885681
By the way anonymous functions are the worst. thy are 10 times slower.
Is there a PHP-Script-Optimizer that reduces the amount of function calls and minifies the script?
There is also this post: Why are PHP function calls *so* expensive? related to this article
You only really call functions that you need at any given time, therefore no.
The thing you could do to optimize your code is using as minimal anonymous functions, reducing the amount of spaces (e.g. use a php minifier) and rename your functions to 1 letter names,
this would atleast tokenize your script which would allow for faster reading of the functions.
But in terms of optimalisation you are better off not doing so due to the readability being completely gone down the drain.
please tell me how to make a delay function to delay functions!
DelayCommand(functionToDelay, Delaytime);
..? in php 5.3+
thanks for any help
function delayCommand($callback, $delayTime) {
sleep($delayTime);
$callback();
}
This should work, consider switching out sleep() to usleep().
function DelayCommand($functionToDelay, $delayTimeInSeconds) {
sleep($delayTimeInSeconds);
$functionToDelay();
}
DelayCommand(function() { echo "yes"; }, 5);
(Code is untested)
function delayCommay($function, $nano){
usleep($nano);
$function();
}
Will do the trick however it is synchronous. So if you make a call to delayCommand it will delay your whole script until it has run the command.
If you want it done asynchronously, see my answer here: Scheduling php scripts
For your information, here's a list of related functions:
sleep() / usleep() - Sleep for an amount of (micro)seconds.
time_sleep_until() - Sleep until a timestamp.
time_nanosleep() - Sleep for an amount of seconds and nanoseconds.
Here is what I have for delaying a function in MS, Sleep and Usleep pause the execution of the whole script, this seems to work pretty well
public function DelayTime($ms){
$now = microtime();
$finishtime = ($now + $ms);
while($now < $finishtime){
$now = time();
if($now >= $finishtime){ break; }
}
return true;
}