8

I'm making a PHP site, and I would like to have a script (when you click a button) which adds some info to my MySQL database (I can do this part by myself) and it executes a script 5 minutes later. Maybe it's not difficult, but it's hard to google stuff like this.

3
  • 1
    What is the purpose of this time-displaced action? What information is added that requires this displacement? Commented Jan 23, 2011 at 15:08
  • 1
    I'm making a browser-based game and I want it to if someone wants to build a building it takes * minutes and then finishes. Commented Jan 23, 2011 at 15:18
  • that comment helps a lot with our understanding of what you're trying to achieve, and how to help you. I'd suggest that a lot of the answers already given are trying to achieve something quite different. Commented Jan 23, 2011 at 16:41

11 Answers 11

6

Sleep is a VERY bad idea. Client browser would have to wait 5 minutes to finish request!!!

In my opinion it's not possible to do it like you want to.

You should create another script which queries database and checks if there is new data (and on successful fetch does the job). This script should be run by cron every N minutes.

Sign up to request clarification or add additional context in comments.

Comments

6

Pretty tough one. I'd go for something like this:

  1. your original script adds a record to the database, containing its time of execution,
  2. another script contains the action that needs to be taken 5 minutes later - but launches it only if the db record mentioned above contains a timestamp of at least 5 minues ago (hope that's clear enough, I'm having trouble phrasing this)
  3. set crontab to execute the second script every X minutes (perhaps 2).

It won't be 5 minutes EXACTLY, but rather something between 5 and 7 (in case you choose to launch the script every 2 minutes). Would that do?

2 Comments

This looks like a good idea, but how can I calculate if the time of 1 of the entries was 5 mins ago?
In the first script, you put executiontime = NOW() in the database. In the second, you check for executiontime < UNIX_TIMESTAMP()-300 or something similar. There are a couple ways to do it, I think.
4

You could implement a queue in your database, where you add "commands" to be executed, and also store when to execute this command. Then have a cron job that runs every minute and checks said queue to see if it's time to execute a certain command.

Comments

4

If you're on a unix box:

exec("echo 'php script.php' | at now +5 minutes");

Which will schedule the php script.php command to run after 5 minutes.

1 Comment

This gets pretty unwieldy with lots of users, though.
1

I'm making a browser-based game and I want it to if someone wants to build a building it takes * minutes and then finishes.

Considering this is your actual goal, I recommend just saving the original building with a timestamp.

I know you tagged your question with PHP, but I don't want to include all the overhead of handling mysql queries in PHP, especially since I don't know how you prefer to execute the queries or what framework you're suing, so here's some pseudocode to handle this "building buildings" task:

build.php

building_type_id = sanitize(POST['id'])
user_id = current_user['id']

query('INSERT INTO buildings (user_id, building_type_id, created_at) 
       VALUES (' + user_id + ', ' + building_type_id + ', CURRENT_TIME)');

my_buildings.php

user_id = current_user['id']

completed_buildings = query('SELECT * FROM buildings b
  LEFT OUTER JOIN building_types t ON b.building_type_id = t.id
  WHERE DATE_ADD(b.created_at, INTERVAL t.construction_time SECOND) < NOW();')
under_construction = query('SELECT * FROM buildings b
  LEFT OUTER JOIN building_types t ON b.building_type_id = t.id
  WHERE DATE_ADD(b.created_at, INTERVAL t.construction_time SECOND) > NOW();')

Hope this helps!

2 Comments

This is a great piece of code, exactly what I'm trying to achieve! next time I will add the thing I want to achieve in the first post. Thanks!
If you like it, feel free to contribute a vote and/or click the checkmark on the left of this answer so that others in the future can more easily find it!
0

IMHO the best way is: On button click save the job to run in the db with the time it should run. Write a small daemon, fetches every 10/5/2 seconds new jobs which should be executed and executes them.

EDIT: Btw the idea using cron for checking for new jobs to execute, is better, but only if you have a small website and you don't need to do load balancing for the jobs.

Comments

0

The way I would do this is to run a cron job between the two scripts.

  1. the first script sets a value in a database table.
  2. the cron job executes the second script. every minute or what not.
  3. the second script checks for the database value set by script 1 to decide whether to run entirely or not.

Comments

0

I would suggest doing the timer in Javascript rather than PHP.

Put a timestamp in the user's $_SESSION to indicate when they started the event, and then have Javascript call back to the browser after five minutes.

PHP would still need to know the start time (to prevent the user from hacking the game by tweaking the Javascript time-out), but it wouldn't need to actually do any count-down timing or sleeping or anything like that itself.

Comments

0

You could fork the process and in the child fork, do a sleep for 5 minutes before executing your second script. I've tested this and it appears the child process will still execute even after the parent has finished. Something like

//initial code
$pid = pcntl_fork(); //fork the process
if ($pid==0) // if in the child
{
    exec("sleep 300; php second_process.php"); //sleep for 5 minutes and execute second script
    return; // or exit
}
// rest of initial script...

The "return;" is important as the rest of the script will execute a 2nd time (i.e. in the child) unless it's there.

Comments

0

Someone asked about the purpose of this and your answer was: "I'm making a browser-based game and I want it to if someone wants to build a building it takes * minutes and then finishes"

You don't actually need to time an execution for this. You can do it all in one run by storing buildStartedAt and buildFinishedAt as part of the building-schema.

Now maybe you want the building to have a nice animation when it finishes, then you just do all of that on the frontend but make sure nothing meaningful can be done with the building if the timestamp is before the buildFinishedAt time in order to a void cheating by potential hackers.

Comments

-3

Are you looking for that?

sleep php.net

3 Comments

sleep will block; The OP didn't mention it explicitly, but it sounds more like a question for an non-blocking solution.
Not really, I want it to execute another script. EG. the button calls process.php and process.php has to execute other.php 5 minutes later.
A little of imagination... Of course you cant do that in the same script of the webpage. But you can call from the scriptOfWebBrowser.php to another script actionAfter5Minutes.php in the server running background with the sleep function so you dont need any cron or whatever and is not a problem for the user...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.