у меня такой вопрос, как правильно организовать запись в файл так, что-бы записей в нем было не больше чем 100.
файл будет выглядеть к примеру так:
время1 : UserNick1
время2 : UserNick2
время3 : UserNick3
время4 : UserNick4
тоесть, что при записи если в файле больше 100 строчек удалят первый сколько нужно что-бы было 99, а потом добавлять 100-ю.
Мой вариант:
Может перед записыванием нужно считать содержимое в массив, а потом обработать массив, добавить последнюю запись - новые данные, и этот массив записать поновомув заданный файл.
что то я в этой теме нифига не пойму автор общается с публикой ?
у тебя такой вопрос
и сам же отвечает на этот вопрос ?
тоесть, что при записи если в файле бо…
или я чтото не так понял ?
да, отредактировал первый пост, а только сейчас понял что не совсем нормальный текст написал
А зачем тебе это вобще нужно?
<?php
$filename = "твой_файл";
$items = file ($filename);
if (count ($items) > 99)
for ($i = 100; $i < count ($items); $i++)
unset ($items[$i]);
$items[] = "строка"; // новая строка
$f = fopen ($filename, "w");
fwrite ($f, implode ("\n\r", $items);
fclose ($f)
?>
А как ещё? больше ничего в голову не пришло
я бы считывал в массив, а после implode('\n', $content), если строчки не по сотне килобайт.
зачем нужно – организовать лог файл, только в лог файле хранить последних 100действий.
вот думаю как правильно организовать бы это.
Если важна скорость и требования к памяти (в друг больше строчек хранить захочется), то лучше выкинуть из алгоритма массивы и лишние условия из цикла.
Файл log-а нужно проинициировать нужным кол-вом пустых строк.
Читать файл пока не будет найдена вторая строка, потом начинать писать со второй строки, но в другой файл. Когда весь файл прочитан, дописать новую строку. Затем переименование, с затиранием старого файла. Операция переименования атомарная в журналируемых FS, не должно быть проблем с одновременным чтением файла другим процессом, да и целостность гарантируется при сбоях в момент записи.
Использовать функции fread, fwrite и временный буфер.
Предлагаю на повестку дня следующее извращение: создаем некое подобие базы, max_amount полей с максимальной длиной строки field_length (сколько заблагорассудится), и проходим их по кругу, затирая новым значением самое старое.
Минусы: файл лога – бинарный.
Плюсы: при записи лога все предыдущие значения не считываются, т.е., экономится время и не засоряется память.
<?php
define("field_length", "256"); // количество символов в поле
define("max_amount", "100"); // количество записей. Не более 256
define("base_filename", "base.db"); // файл лога
function log_write($str){
$thread = @fopen (base_filename, "r+");
if($thread===false){
$thread = fopen(base_filename, "w");
fwrite($thread, chr(max_amount-1));
fclose($thread);
$thread = @fopen (base_filename, "r+");
};
$offset = (ord(fread($thread, 1)) + 1) % max_amount;
fseek($thread, $offset * field_length + 1);
fwrite($thread, str_pad($str, field_length, "\x00"), field_length);
fseek($thread, 0);
fwrite($thread, chr($offset));
fclose($thread);
};
function log_read(){
$return_value = array();
$thread = fopen(base_filename, "r");
$offset = (ord(fread($thread, 1)) + 1) % max_amount;
fseek($thread, $offset * field_length + 1);
while(true) {
$chunk = rtrim(fread($thread, field_length), "\x00");
if (feof($thread)) break;
$return_value[] = $chunk;
};
fseek($thread, 1);
for ($i=0; $i<$offset; $i++){
$return_value[] = rtrim(fread($thread, field_length), "\x00");
};
return $return_value;
};
?>
Вот изврат. А зачем вооще всё хранить в одном файле? ИМХО, лучше для каждого дня чтобы свой файл создавался тобишь 'log_',data ('d-m-Y', time ()).'.log'. И удалять те которым уже больше n дней. Или принципиально именно по 100 записей хранить в одном файле?
А я сразу говорил, что изврат
а что мешает использовать возможности операционной системы? пишешь текущую запись в новый файл, потом сливаешь новый файл со старым, сохраняешь в старое имя, новый файл удаляешь, старый (который уже содержит новую строчку первой) усекаешь до 100 строк.
почти уверен
не знаю точно какими командами можно сделать, но если man'ы поворошить, думаю найдется что нить
to Виктор yumaa Диденко далеко не всегда разрешено выполнять команды операционной системы…
// при добавлении строк в файл делаешь:
// $stringsToAdd – массив строк, которые сейчас надо добавить
define('STRINGS_AMOUNT', 100);
$fileName = '/path_to_your_log_file';
$dstStrings = '';
if (file_exist($fileName) && !is_dir($fileName)) {
$strings = explode("\n", file_get_contents($fileName));
if (is_array($strings)) {
$strings += $stringsToAdd;
if ($cnt = count($strings)) {
if ($cnt > STRINGS_AMOUNT) {
$dstStrings = array_slice($strings, $cnt – STRINGS_AMOUNT);
$dstStrings = implode("\n", $dstStrings);
}
}
}
}
if (!file_put_contents($fileName, $dstStrings))
{
echo 'Cannot write to log!';
}
отладить, надеюсь, сможешь – я не проверял правильность функционирования )
to Михаил SWD Полянин
да, не всегда. но если можно, то почему бы не пользоваться. пусть автор отпишется.
а вообще я согласен с вашим #10
to Виктор yumaa Диденко
мой вариант позволяет реализовать и такую возможность, при этом выполняя функциональные требования #1
да дело не в функциональности. просто сам подход "файл -> массив -> файл" мне кажется подходом через ж..у. и вообще, лог, по смыслу, должен быть логом, а не монитором текущей деятельности. как ты по 100 последним ошибкам определишь, что не работало два дня назад в ночь с пятницы на субботу в три часа ночи, если эта ошибка уже давно стерта?
согласен
но если у заказчика такие требования – ему можно сказать о том, что такой лог малоэффективен, но реализовать можно и так, как он хочет
к тому же, возможно (тут вопрос к Игорь Яценко
), что это типа тестового задания, или по учебе 
такие задания любят давать, просто чтобы посмотреть, как человек умеет работать