Перезаписать строку в файле с помощью PHP

каков наилучший способ перезаписи определенной строки в файле? Я в основном хочу найти файл для строки "@parsethis " и перезаписать остальную часть этой строки чем-то другим.

5 ответов


Если файл не слишком большой, лучшим способом, вероятно, было бы прочитать файл в массив строк с file () поиск по массиву строк для строки и редактировать эту линию, затем implode () массив и fwrite() он возвращается в файл.


Если файл действительно большой (файлы журналов или что-то вроде этого), и вы готовы пожертвовать скоростью для потребления памяти, вы можете открыть два файла и по существу сделать трюк Джереми Рутен предложено использовать файлы вместо системной памяти.

$source='in.txt';
$target='out.txt';

// copy operation
$sh=fopen($source, 'r');
$th=fopen($target, 'w');
while (!feof($sh)) {
    $line=fgets($sh);
    if (strpos($line, '@parsethis')!==false) {
        $line='new line to be inserted' . PHP_EOL;
    }
    fwrite($th, $line);
}

fclose($sh);
fclose($th);

// delete old source file
unlink($source);
// rename target file to source file
rename($target, $source);

ваша главная проблема заключается в том, что новая строка может быть не такой же длины, как старая. Если вам нужно изменить длину строки, нет никакого способа переписать хотя бы весь файл после измененной строки. Самый простой способ-создать новый, измененный файл, а затем переместить его поверх оригинала. Это есть полный файл доступен для читателей. Используйте блокировку, чтобы убедиться, что только один скрипт изменяет файл сразу, и так как вы собираетесь замените файл, сделайте блокировку на другом файле. Проверьте flock().

если вы уверены, что новая строка будет такой же длины, как и старая, вы можете открыть файл в режиме чтения/записи (используйте r+ в качестве второго аргумента fopen()) и вызов ftell() сохранить позицию линия начинается каждый раз перед вызовом fgets() читать линию. Как только вы найдете строку, которую хотите перезаписать, вы можете использовать fseek() вернуться к началу строки и fwrite() новые данные. Один из способов заставить линию всегда быть одинаковой длины-это разместить ее на максимально возможной длине.


или если ваш файл не слишком большой:

$sample = file_get_contents('sample');
$parsed =preg_replace('#@parsethis.*#', 'REPLACE TO END OF LINE', $sample);

вам нужно будет выбрать разделители'#', которых нет в файле.


Я бы, скорее всего, сделал то, что предложил Джереми, но только для альтернативного способа сделать это здесь другое решение. Это не было протестировано или использовано и предназначено для систем *nix.

$cmd = "grep '@parsethis' " . $filename;
$output = system($cmd, $result);
$lines = explode("\n", $result);
// Read the entire file as a string
// Do a str_repalce for each item in $lines with ""