tags:

views:

412

answers:

5

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  A: 

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.

Anti Veeranna
+1  A: 

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.

Lukáš Lalinský
+2  A: 

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).

Ben James
+5  A: 

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.

cletus
Oddly random downvote on this. Just curious if there was a reason or it was a failed tactical downvoting attempt?
cletus
It wasn't me, but the code example doesn't actually answer the question, as this should happen only after you visit a new game + you have a typo in `$_SESSION['last']`.
Lukáš Lalinský
@Lukas: thanks for pointing that out. Fixed.
cletus
A: 

You cannot, but you can make this code a javascript one, and save the bonus using AJAX.

e-satis
this seems quite unsecure...
Hippo
How so ? You validate the AJAX call in the server anyway.
e-satis