Обращение к файлу по очереди

140
22 июня 2019, 14:00

Есть функция проверяющая нового пользователя, она сверяет его ID, заменяет старый ник на новый (если требуется) или записывает нового пользователя (если такого нету в списке). Все данные храню в json. По скольку в функции выполняется много действий, нужно запретить к ней доступ, до тех пор, пока она не завершится. Суть проблемы, что если несколько пользователей стучатся одновременно в эту функцию, то файл json форматируется под ноль.

Вот пример функции:

function checknewuser($currentname, $id) { 
 
  $json = file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . 'users.json'); 
  $data = json_decode($json, true); 
 
  // действия над пользователем 
 
  file_put_contents('users.json', 
  json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), LOCK_EX); 
 
}

Answer 1

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

Для вашей задачи вам потребуется заблокировать файл для параллельной записи

function checknewuser($currentname, $id)
{
    // открываем файл
    $fp = fopen("users.json", "r+");
    if (flock($fp, LOCK_EX)) { // выполняем эксклюзивную блокировку
        // читаем файл
        $user = fread($fp, filesize('users.json'));
        // действия над пользователем ........
        // записываем новые данные
        fwrite($fp, $user);
        // очищаем вывод перед отменой блокировки
        fflush($fp);
        // снимаем блокировку
        flock($fp, LOCK_UN);
    } else {
        echo "Не удалось получить блокировку!";
    }
    // закрываем файл
    fclose($fp);
}

http://php.net/manual/ru/ref.filesystem.php здесь документация по всех методах работы сфайлами

Answer 2

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

Answer 3

Перед запуском $json = file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . 'users.json'); переименуйте файл под другим именем, считайте переименованный файл, измените данные, запишите их в файл и переименуйте его назад. Если первичное переименование завершится любой ошибкой - выведите сообщение, что файл заблокирован на запись или подождите какой-то интервал времени и попробуйте снова.

Но обратите внимание на совет @Arendach и попробуйте хранить данные о пользователях в БД.

READ ALSO
MYSQL Выборка с указанием даты

MYSQL Выборка с указанием даты

Подскажите пожалуйста как сделать выборку из базы по дате, есть столбец created в котором дата записи, как например вывести записи с 1010

122
Как справиться с ошибкой функии protected??Laravel? [закрыт]

Как справиться с ошибкой функии protected??Laravel? [закрыт]

вообщем осваиваю laravelПытаюсь сделать форму регистрации на блог, при обьявлении функции вылетает такая ошибка :

104
Создание проекта на Symfony

Создание проекта на Symfony

Пытался создать проект на Symfony, введя в консоли:

115
проблемы с настройкой ноды bitcoin

проблемы с настройкой ноды bitcoin

Коллеги буду очень благодарен за помощь в подключению ноды биткоин провозился уже несколько дней но так и не поборол

124