Баг при чтении/записи файла

Статус
В этой теме нельзя размещать новые ответы.

Aizen

Создатель
Регистрация
18 Мар 2016
Сообщения
17
Реакции
4
Здравствуйте.
Набросал маленький модуль для подсчета кликов по кнопке. массив со статистикой кодирую в json и записываю в файл.

Код:
$button = $_GET['button'];

if( !$button ) exit();

$stats = get_vars("button_stats");

$date = date('Y-m-d');

$count = intval($stats[$date][$button]);
$count++;

$stats[$date][$button] = $count;

set_vars( "button_stats", $stats );

Для записи и чтения файла использую функции движка DLE
Код:
function set_vars($file, $data) {
   
    $file = totranslit($file, true, false);
   
    if ( is_array($data) OR is_int($data) ) {
       
        file_put_contents (ENGINE_DIR . '/cache/system/' . $file . '.php', json_encode( $data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ), LOCK_EX);
        @chmod( ENGINE_DIR . '/cache/system/' . $file . '.php', 0666 );
       
    }
}

function get_vars($file) {
    $file = totranslit($file, true, false);

    $data = @file_get_contents( ENGINE_DIR . '/cache/system/' . $file . '.php' );

    if ( $data !== false ) {

        $data = json_decode( $data, true );
        if ( is_array($data) OR is_int($data) ) return $data;

    }

    return false;   
}

В итоге получается что каждые пару часов содержимое файла сбрасывается.
Предпологаю что проблема в функции записи или чтения с файла. Но не могу понять где именно.
 
С DLE не сильно знаком, но в вашей функции есть такое -
file_put_contents (ENGINE_DIR . '/cache/system/' . $file . '.php', json_encode( $data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ), LOCK_EX);

Как видите вы кладете информацию в папку cache, есть подозрения что при сбросе кеша вы просто удаляете свой файл, и он обнуляется :)
 
При чтении файла нет блокировки, в итоге может возникнуть коллизия.
Второй момент, с которым сталкивался, чтение делал где-то в начале скрипта, а запись через несколько секунд, после выполнения. В итоге подсчёт был неправильный.

Вообще для этого дела лучше бд использовать, пусть даже SqlLite, с методами типа update ... set counter += 1.

Либо разбирайтесь как работают блокировки и как вписать их в свою логику:
Для себя дёргал вот отсюда функции Для просмотра ссылки Войди или Зарегистрируйся getValue($key) и setValue($key, $value) удалив ненужную логику работы с кешем.
 
Проблема скорее всего в том, что 2 скрипта одновременно пытаются писать в 1 файл.
Подобное решал либо блокировкой записи путем создания временного файла, либо использованием БД.
 
Просто очищается кэш. Нужно изменить папки для сохранения данных и не использовать папки кэша
 
Делайте запись/чтение значений в папку /engine/data/ и не будет пропадать
 
я бы проверял результат json_encode, коварная функция:
Passing a non UTF-8 string to json_encode() will make the function return false in PHP > 5.5

То есть если в неё передали не-UTF8 строку, файл запишется пустой.
 
Статус
В этой теме нельзя размещать новые ответы.
Назад
Сверху