Выполнять скрипт php только один раз на живом сайте

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

Проблема в том, что, когда есть много трафика, это не совсем работает, потому что он использует некоторые случайные и взвешенные числа, поэтому, если он попал в кучу раз, результаты не то, что мы хотим.

Итак, вопрос. Есть ли способ узнать, сколько раз к конкретному сценарию обращаются? И ограничивать его только один раз за раз?

Спасибо!

Вы можете сделать что-то вроде этого (требуется PHP 5):

if(file_get_contents("lock.txt") == "unlocked"){ // no lock present, so place one file_put_contents("lock.txt", "locked"); // do your processing ... // remove the lock file_put_contents("lock.txt", "unlocked", LOCK_EX); } 

file_put_contents () по умолчанию перезаписывает файл (в отличие от добавления), поэтому содержимое файла должно быть только «заблокировано» или ничего. Вы хотите указать флаг LOCK_EX, чтобы убедиться, что этот файл в настоящее время не открыт другим экземпляром скрипта, когда вы пытаетесь его написать.

Очевидно, что, как отметил в своем ответе @Pekka, это может вызвать проблемы, если возникает фатальная ошибка (или сбой в работе PHP или сбои сервера и т. Д.) Между установкой блокировки и ее удалением, так как файл просто останется заблокированным.

Техника, которую вы ищете, называется блокировкой.

Самый простой способ сделать это – создать временный файл и удалить его, когда операция завершена. Другие процессы будут искать этот временный файл, видеть, что он уже существует и уходит.

Однако вам также необходимо позаботиться о сбое процесса владельца замка и не удалять блокировку. Здесь сложная задача кажется сложной.

Решения для блокировки файлов

PHP имеет встроенную функцию flock() которая обещает независимую от ОС функцию блокировки на основе файлов. У этого вопроса есть некоторые практические советы о том, как его использовать. Однако на странице руководства предупреждается, что при некоторых обстоятельствах у flock() возникают проблемы с несколькими экземплярами скриптов PHP, пытающихся получить блокировку одновременно. Этот вопрос, похоже, содержит более сложные ответы на эту проблему, но все они не являются тривиальными для реализации.

Блокировка базы данных

Автор этого вопроса, вероятно, испугался осложнениями, связанными с flock() – запрашивает другие методы, не связанные с файловыми GET_LOCK() и использует GET_LOCK() MySQL. Я никогда с ним не работал, но это выглядит довольно просто – если вы все равно используете mySQL, это может стоить того.

Черт, эта проблема сложна, если вы хотите сделать это правильно! Заинтересованы в том, появится ли что-нибудь более элегантное.

Запустите скрипт с SQL-запросом, который проверяет, если поле метки времени из базы данных превышает 1 день назад. Если да – записать текущую временную метку и выполнить скрипт.

псевдо-sql, чтобы показать идею:

 UPDATE runs SET lastrun=NOW() WHERE lastrun<NOW()-1DAY 

(для разных серверов sql потребуются разные изменения выше)

Проверьте, сколько строк было обновлено, чтобы убедиться, что этот скрипт запущен. Не делайте это с двумя запросами – SELECT и UPDATE, потому что это больше не будет атомным.