PHP Найти известную строку в файле, а затем добавить строку перед ней

Мне нужно найти известную строку внутри файла конфигурации, а затем добавить некоторый контент (другую строку) до этого.

Каков наиболее эффективный способ сделать это?

Пример:

$findString = "Find Me";
$newString = "String To Add";

файлtomodify.config

aaaaaaaaaaaaaaaa
bbbbbbbb
Find Me
cccccccccccccc
ddddddddddd
eeeeeeeeeeeeeeeee

Желаемый результат:

aaaaaaaaaaaaaaaa
bbbbbbbb
String To Add
Find Me
cccccccccccccc
ddddddddddd
eeeeeeeeeeeeeeeee

Я использовал fopen для доступа к файлу, но это позволяет только добавлять или добавлять содержимое по умолчанию с помощью fwrite. В настоящее время я не могу придумать эффективный способ удовлетворить мои требования, поэтому любая помощь будет оценена по достоинству.


person Phill Healey    schedule 08.12.2015    source источник
comment
В общем, при файловом вводе-выводе вам придется перезаписывать конец файла после вставки. Вы можете читать/записывать блоки одновременно, чтобы сделать это быстрее. (опция r+ должна позволить вам использовать seek() и писать в середине файла, только перезаписывать)   -  person ebyrob    schedule 08.12.2015


Ответы (2)


Этот вопрос по существу требует двух ответов:

  • Один для случая, когда размер файла гарантированно достаточен для чтения в память.
  • Один для противоположного случая

Первая версия легко реализуется

$s=file_get_contents('/path/to/file');
$s=str_replace("\nFind Me\n", "\nString To Add\nFind Me\n", $s);
file_put_contents('/path/to/file', $s);

Вторая версия нуждается в дополнительной доработке, в соответствии с

$in=fopen('/path/to/file', 'rb');
$out=fopen('/path/to/file.tmp', 'wb');
while (($s = fgets($in)) !== false) {
  if ($s == "Find Me") $s="String To Add\nFind Me";
  fputs($out, $s);
}
fclose($in);
fclose($out);
unlink('/path/to/file');
rename('/path/to/file.tmp', '/path/to/file');
person Eugen Rieck    schedule 08.12.2015
comment
Это всего лишь несколько килобайт, так что все нормально для загрузки в память. - person Phill Healey; 08.12.2015
comment
@PhillHealey - тогда версия 1 должна быть довольно быстрой и надежной - person Eugen Rieck; 08.12.2015
comment
Большой! Я знал, что это будет просто. Еще один не тот случай, когда за деревьями не видно леса. Спасибо за два варианта. - person Phill Healey; 09.12.2015

Если файлы маленькие, вы можете прочитать весь файл с помощью file_get_contents и использовать функцию preg_replace().

Например;

$new = preg_replace( "/$findString/", "$newString\n$findString", $originalContentAsString );
person ALchEmiXt    schedule 08.12.2015
comment
@AbraCadaver Да, замена строки, вероятно, лучший вариант в этом случае. - person Phill Healey; 14.12.2015