1

I have a script PHP which do requests on MYSQL server, and I want to execute itself once a day!

The first time, I execute the script myself. And I want the script, at the end of the execution, choose a random time in the day, between 8:30AM and 7:30PM, and reexecute itself automatically the day after, at this time. Is it possible?

To choose a time randomly I have coded like this:

$tomorrow = new DateTime(date('Y-m-d H:m:s', time()+86400));
$tomorrow1 = $tomorrow -> setTime(8,30,0);
$tomorrow2 = $tomorrow -> setTime(19,30,0);

$min_time = strtotime($tomorrow1->format('Y-m-d H:m:s'));
$max_time = strtotime($tomorrow2->format('Y-m-d H:m:s'));
$rand_time = rand($min_time, $max_time);

But then I don't know how to do an automatic execution for the script at this time. Maybe I can pause like this:

sleep ($rand_time - time());

But I don't know how to reexecute the script after that. And I don't think sleep is the best solution. Do you if there is a way and how to do this?

dam
  • 53
  • 1
  • 9
  • 1
    You can use cron for this task. Run script once and before finish script should test crontab if current script already present it list and remove script if need. And after it add script again into cron with new execute time. – Vladimir Gilevich Aug 26 '15 at 08:50
  • 1
    Using linux? http://stackoverflow.com/questions/9049460/cron-jobs-and-random-times-within-giving-hours – rlanvin Aug 26 '15 at 08:50
  • Or start it via cron at 7:30, let it sleep for random time between zero and one hour and execute task then. – syck Aug 26 '15 at 08:53
  • FYI incrementing time using `+86400` can be problematic when the declared timezone has DST. Your actual output may be 1 hour +/- depending on the date. – mickmackusa Mar 23 '17 at 04:27
  • Also, you should probably change your second `m` (2-digit month) to `i` (2-digit minute) ... that could likely foul things up for you. [three instances to edit] – mickmackusa Mar 23 '17 at 04:30

2 Answers2

0

Allright, I can use cron, but the issue still remains: I need to be able to modify the task scheduler for the day after everyday by the php file itself!

dam
  • 53
  • 1
  • 9
0

The approach taken by e.g. APT::Periodic is to start the job at a fixed time (in your case 08:30) and sleep for a random period of time as the first command in your job (in your case for $(($RANDOM % 39600)) seconds, assuming your shell is Bash).

This avoids the need to write anything to the crontab.

I don't know PHP, but I think it would look something like:

#/usr/bin/php
// Wait 0-11 hours before starting (invoked by cron at 0830)
sleep(rand(0, 39600));
// It's now a time between 0830 and 1930

// rest of your code here

and your crontab would be simply

30 8 * * * /path/to/my/script

Alternatively, don't sleep at all in your script, but do the sleep in the crontab command:

SHELL=/bin/bash
30 8 * * * sleep $(($RANDOM % 39600)) && /path/to/my/script

This may be preferable if you ever need to execute the script by hand (and not want to wait up to 11h for it to start).

Toby Speight
  • 27,591
  • 48
  • 66
  • 103
  • Thank you for the answer! WHat do you mean by APT::Periodic? Is it also a cron job, starting at 8h30 and sleeping? – dam Aug 27 '15 at 08:27
  • `APT::Periodic` is a feature of the `aptitude` package manager that does daily downloads of updated packages. To prevent the archive servers being overloaded, installations shouldn't all use the same time of day to do their updates. So they start at the same time (for a given system time zone) but wait a random time between 0 and 30 minutes before starting. It's not essential to know in order to understand my answer, which is why I left out the details. See [Unattended Upgrades](https://wiki.debian.org/UnattendedUpgrades) on the Debian Wiki for more information if you want. – Toby Speight Aug 27 '15 at 18:02