Можно ли запланировать запуск PHP-скрипта в определенное время или по истечении определенного времени?

Я пишу социальную облачную игру для Android и использую PHP на сервере. Почти все аспекты игры будут управляться пользователем или пользователем-устройством, поэтому большую часть времени устройство отправляет запрос на сервер, а сервер, в свою очередь, отправляет ответ на устройство. Иногда сервер также отправляет push-сообщения на устройства, но обычно в ответ на обращение устройства одного пользователя к серверу.

Однако есть один особый случай, когда пользователь может установить «таймер», и по истечении заданного времени сервер должен отправить push-сообщения на все устройства. Один из способов сделать это — оставить таймер локальным для устройства пользователя и, как только он сработает, отправить сигнал на сервер для отправки push-сообщений. Однако было несколько причин, по которым я не хотел делать это таким образом. Например, если пользователь решает больше не играть или проигрывает игру, технически таймер должен оставаться в игре.

Я искал метод в PHP, который позволил бы мне сделать что-то подобное, но все, что я придумал, это будильники, которые не мне нужны. Я также подумал о задачах cron, и действительно, они были рекомендованы для подобных ситуаций на этом и других форумах, но, поскольку это не повторяющееся событие, а, скорее, однократное событие, которое происходит в произвольный момент времени, я не знал, что работа cron - это то, что я хочу.

Мое текущее лучшее решение включает задание cron, которое запускается раз в секунду и проверяет, произойдет ли одно из этих событий в следующую секунду, и, если это так, отправляет push-сообщения. Это правильный способ справиться с этой ситуацией, или есть лучший инструмент, который я еще не нашел?


person William    schedule 16.08.2011    source источник
comment
задание cron или демон, или более подходящий язык, чем php   -  person    schedule 17.08.2011
comment
более подходящий язык, чем php? вы можете установить задание cron с PHP, так что вряд ли это неподходящий метод   -  person Doug Molineux    schedule 17.08.2011
comment
Минимальные интервалы запуска cronjob — минута, каждую секунду что-то выполнять нельзя. Я не думаю, что это хорошая идея запускать его каждую секунду, но если вы найдете это решение, которое вам подходит, вам придется создать еще один скрипт, который просто while(true){system('php /path/to/file &'); sleep(1);}   -  person shesek    schedule 17.08.2011
comment
@Dagon: ну, я лучше разбираюсь в C/C++, чем во всем остальном, поэтому демон может быть тем, что я искал. В этом случае я мог бы иметь очередь этих таймеров в отсортированном порядке и ждать запуска какого-либо события в течение времени до первого элемента в очереди. Если бы новый элемент был добавлен в начало очереди, сумматор мог бы установить мое событие, чтобы я мог установить новый тайм-аут своего сна. Возможно, я так и пойду, если не смогу придумать лучший вариант. Я просто не хочу просыпаться каждую секунду и проверять, не пора ли.   -  person William    schedule 18.08.2011


Ответы (3)


cron отлично подходит для скриптов, запускаемых на регулярной основе, но если вы хотите, чтобы одноразовый (или двукратный) скрипт запускался в определенное время, вы должны использовать команду unix 'at', и вы можете сделать это прямо из php используя такой код:

/****
 * Schedule a command using the AT command
 *
 * To do this you need to ensure that the www-data user is allowed to
 * use the 'at' command - check this in /etc/at.deny
 *
 *
 * EXAMPLE USAGE ::
 *
 * scriptat( '/usr/bin/command-to-execute', 'time-to-run');
 * The time-to-run shoud be in this format: strftime("%Y%m%d%H%M", $unixtime)
 *
 **/

function scriptat( $cmd = null, $time = null ) {
    // Both parameters are required
    if (!$cmd) {
        error_log("******* ScriptAt: cmd not specified");
        return false;
    }
    if (!$time) {
        error_log("******* ScriptAt: time not specified");
        return false;
    }

    // We need to locate php (executable)
    if (!file_exists("/usr/bin/php")) {
        error_log("~ ScriptAt: Could not locate /usr/bin/php");
        return false;
    }

    $fullcmd = "/usr/bin/php -f $cmd";

    $r = popen("/usr/bin/at $time", "w");
    if (!$r) {
        error_log("~ ScriptAt: unable to open pipe for AT command");
        return false;
    }
    fwrite($r, $fullcmd);
    pclose($r);

    error_log("~ ScriptAt: cmd=${cmd} time=${time}");

    return true;
}
person muz the axe    schedule 11.08.2014

решение 1: ваш php-файл может включать конечный цикл

$con = true;
 while($con)
   {
   //do sample operation
   if($end)
      $con = false;
   else
   sleep(5); // 5 seconds for example
   }

Решение 2: используйте задания cron. В зависимости от вашего CP вы можете следовать инструкциям и вызывать программу php в определенное время
ограничение: в задании cron минимальное время между двумя вызовами составляет 1 минуту
решение 3: использовать сценарий оболочки и вызовите свою программу php, когда захотите

person Shahrokhian    schedule 16.08.2011
comment
Я бы сделал комбинацию обоих - держать PHP-скрипт вечно работающим - не очень хорошая идея. Запускайте скрипт из cronjob каждые 10 минут, каждый раз на 10 минут. Скрипт будет иметь цикл, который делает что-то вроде $start=time(); while (time()-$start < 600) { ... sleep(1); }, и cronjob будет запускать его каждые 10 минут, */10 * * * * php /path/to/file - person shesek; 17.08.2011
comment
Вы правы, это необязательно, даже мы можем проверить загрузку процессора, если загрузка процессора превысила ожидаемую, закройте программу и дождитесь нового вызова (используя cronjobs или сценарии оболочки) - person Shahrokhian; 17.08.2011
comment
@shesek: я думаю, что я выберу комбинированный подход. План состоит в том, чтобы ограничить минимальное количество времени в будущем, на которое может быть установлен один из этих таймеров. Скажем, десять минут. Затем создайте задание cron, которое просыпается каждые две минуты или около того и проверяет, не истечет ли таймер в течение следующих двух минут. Если это так, он спит до истечения времени, просыпается и запускает таймер. В противном случае он может просто выйти из сценария, зная, что нет возможности внедрения нового таймера. - person William; 18.08.2011
comment
Навскидку, я знаю, многие люди говорят, что PHP может использовать много ресурсов, когда он просто спит, или что нехорошо держать скрипт PHP работающим вечно (например, демон). Кто-нибудь знает, сколько или каких ресурсов это связывает или где может быть порог для разрешения запуска PHP-скрипта? - person William; 18.08.2011
comment
@William, это интересный вопрос. Я бы открыл это как новый вопрос. - person shesek; 20.08.2011

Вы можете перевести PHP в сон на определенное время — после этого он возобновит выполнение кода, но это серьезно не так. рекомендуется, потому что, когда скрипт спит, он все еще использует ресурсы процессора, и если у вас есть несколько скриптов, которые спят в течение длительного периода времени, это приведет к невозможной нагрузке на ваш сервер.

Единственный известный мне вариант — это Cron. Как говорит @Pete, вы можете управлять заданиями Cron из PHP, например:
http://net.tutsplus.com/tutorials/php/managing-cron-jobs-with-php-2/

Это потребует немало кодирования, но я думаю, что это ваш лучший вариант.

Другой вариант — заставить браузер вашего пользователя вызывать функцию PHP с использованием запроса Ajax и setTimeout JavaScript, как это предлагается в принятом ответе на этот вопрос:
как вызвать функцию в PHP после 10 секунд загрузки страницы (не с помощью HTML)

person Robin Winslow    schedule 16.08.2011