开发者

PHP: execute script 5 minutes after first script is run

开发者 https://www.devze.com 2023-02-06 01:32 出处:网络
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 scrip开发者_StackOverflow

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 scrip开发者_StackOverflow社区t 5 minutes later. Maybe it's not difficult, but it's hard to google stuff like this.


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.


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?


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.


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.


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!


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.


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.


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.


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.


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.


Are you looking for that?

sleep php.net

0

精彩评论

暂无评论...
验证码 换一张
取 消