问题
So, on my arcade, howlingdoggames.com. I have a points system that gives you a point every time you visit a page with a game on, now, to reduce abuse of this, I would like to make some sort of delay, so its only awarded after 45 seconds. Here's what i've tried.
...
if ($_SESSION['lastgame'] != $gameid);{
sleep(45);
$points = $points + $game_points;
$_SESSION['lastgame'] = $gameid;
}
...
But, this just seems to halt my whole website for 45 seconds, because this is in the index.php file, as with alot of the other code to my site.
Is there anyway I can isolate that bit of code, so it only makes the function
$points = $points + $game_points;
wait for 45 seconds?
回答1:
There is (mostly) no multithreading in PHP. You can sort of do this with forking processes on Unix systems but that's irrelevant because multithreading isn't really what you're after. You just want simple logic like this:
$now = time();
session_start();
$last = $_SESSION['lastvisit'];
if (!isset($last) || $now - $last > 45) {
$points = $_SESSION['points'];
if (!isset($points)) {
$points = 0;
}
$_SESSION['points'] = $points + 10;
$_SESSION['lastvisit'] = $now;
}
Basically only give the points if the increment between the last time you gave points is greater than 45 seconds.
回答2:
It is session block your script. not "There is no multithreading in PHP". session_write_close() before sleep() will solve block your whole script. but may not fit in your problem.
so you had to save the bonus using settimeout of js and AJAX.
from comment of sleep() in php.net: http://www.php.net/manual/en/function.sleep.php#96592
Notice that sleep() delays execution for the current session, not just the script. Consider the following sample, where two computers invoke the same script from a browser, which doesn't do anything but sleep.
回答3:
No, not directly. You need to take a different approach, like remembering the timestamp of last visit and only add points if sufficient amount of time has passed since that.
回答4:
There is no multithreading in PHP, so sleep()
is always going to block your whole script.
The way you should solve this is to record the the time of the last game, and only award points if it is more than 45 seconds later than that.
<?php
session_start();
if (!isset($_SESSION['last_game_time'])
|| (time() - $_SESSION['last_game_time']) > 45) {
// code to award points here
$_SESSION['last_game_time'] = time();
}
Bear in mind that users could still abuse this if they disable cookies (thus they will have no session data). So if that really worries you, check that they have cookies enabled before allowing them to use the feature (there are probably several questions that cover this).
回答5:
Instead of blocking the script, save the current time in the session, don't add the points and let the page render. Then on later page views if you see that the saved time in session is older than 45 seconds, add the points, store them wherever you need, and clear the time.
回答6:
You cannot, but you can make this code a javascript one, and save the bonus using AJAX.
来源:https://stackoverflow.com/questions/1617412/how-can-i-stop-php-sleep-affecting-my-whole-php-code