Как удалить строку из файла?

3 ноября 2014 г. Просмотров: 1019
При работе с небольшими объёмами данных на языке PHP иногда бывает проще хранить их в файлах, чем создавать базу данных и организовать взаимодействие с ней скриптов. В таких случаях задача по удалению заданных строк из текстового файла возникает не редко. Разберём в подробностях по возможности наиболее простой способ сделать это.

Вам понадобится

  • Начальные знания языка PHP

Инструкция

  • Исходные данные:
  • - имеем текстовый файл allStrings.txt, который содержит некоторое количество строк данных

    - требуется удалить из файла строку №44

    Алгоритм решения поставленной задачи будет таким: нужно открыть файл, прочесть содержащиеся в нём строки в массив строк и переписать существующий файл содержимым массива, пропустив строку, предназначенную к удалению.

  • Для реализации этого алгоритма в скрипте сначала присвоим значения переменным, которые будут содержать имя исходного файла и номер строки, приговорённой к удалению:$fileName = "allStrings.txt";
  • $lineToKill = 44;Затем прочтём файл в массив строк:$stringsArray = file($fileName);Проверим есть ли в файле нужная нам строка. Весь дальнейший код будет выполняться только если выполнено условие $lineToKill не больше, чем количество строк в массиве $stringsArray:if($lineToKill // здесь будет основной цикл программы

    }Если условие не выполнено, то удалять нам нечего. Пусть скрипт напечатает информационное сообщение об этом:else echo "Количество строк в файле меньше ".$lineToKill." !";Если же условие выполнено, следует очистить исходный файл для новой записи:$fileHandle = fopen($fileName, "w");Теперь нам следует организовать цикл, перебирающий все элементы массива строк. Но поскольку индексация массива начинается с нуля, а номер строки для удаления мы отсчитывали от единицы, то ещё до начала цикла уменьшим значение $lineToKill на единицу, чтобы не повторять эту операцию на каждом шагу:$lineToKill--;Поря организовать цикл:foreach($stringsArray as $key => $value) {

    // здесь код каждого шага цикла

    }Переменная $key будет содержать индекс текущей строки в массиве, а переменная $value - значение этой строки. В каждом шаге цикла будем сравнивать индекс строки в массиве с номером, предназначенным на удаление и если они не совпадают, то будем записывать значение этой строки в файл:if($key != $lineToKill) fwrite($fileHandle, $value);А если совпадают, то записывать в файл не будем, а напечатаем сообщение об успешном удалении:else echo "Строка ".$lineToKill." удалена.";И по окончании работы цикла, когда будет закончена и запись в файл, следует вежливо закрыть его:fclose($fileHandle);

  • Весь код в сборе будет выглядеть так:$lineToKill = 44;$stringsArray = file($fileName);
  • if($lineToKill $fileHandle = fopen($fileName, "w");

    $lineToKill--;

    foreach($stringsArray as $key => $value) {

    if($key != $lineToKill) fwrite($fileHandle, $value);

    else echo "Строка ".$lineToKill." удалена.";

    }

    fclose($fileHandle);

    }?>Разумеется, это простейший код, в котром нет защиты от всех осложнений, которые могут случиться в процессе работы скрипта в реальных условиях. К примеру, если файл содержит гигантское количество строк, то чтение их в массив отгрызёт от ресурсов сервера непозволительно большой для одного скрипта кусок. Конечно, работу с большим количеством данных следует организовывать через базы данных, а не текстовые файлы. Но всё же, в качестве учебного примера, приведём код, решающий и эту задачу. Здесь алгоритм будет отличаться от предыдущего: чтобы не хранить огромное количество строк в массиве, скрипт будет читать из исходного файла по одной строке и по одной записывать их во временный файл. По окончании этого процесса исходный файл будет удалён, а временный файл будет перемещён на его место.

  • Начинаться этот скрипт будет так же, как и предыдущий:
  • $fileName = "allStrings.txt";

    $lineToKill = 44;

    Затем для работы нужно создать временный файл. Сделаем это в папке "tmp" и префикс временному файлу дадим такой же:$tempFile = tempnam("/tmp", "tmp");Теперь попытаемся открыть исходный файл для чтения:if($fileHandle = @fopen($fileName,"rb")) {

    // этот код будет выполнен в случае нормального открытия исходного файла

    }Если этого сделать не удастся – дальнейшая работа скрипта не имеет смысла, убьём процесс с выдачей соответствующего сообщения:else die("Исходного файла не существует!");Если файл открылся нормально, то напечатаем оповещение об этом и попытаемся открыть ранее созданный временный файл с выдачей соответствующего сообщения:echo "Исходный файл существует";

    if($tempHandle = fopen($tempFile,"w")) echo "Временный файл был создан.";Теперь пора начинать цикл чтения строк из исходного файла, который будет продолжаться, пока не упрётся в окончание файла:while(!feof($fileHandle)) {

    // здесь будет код работы с текущей строкой

    }На каждом шагу цикла будем читать одну строку:$lineToWrite = fgets($fileHandle);И если это не та строка, которую надо удалить, то записывать её во временный файл. Счётчик строк $lineNum будет увеличиваться непосредственно в операции сравнения:if($lineToKill != (++$lineNum)) fwrite($tempHandle, $lineToWrite);Когда строки закончатся, закроем об файла:fclose($fileHandle);

    fclose($tempHandle);И в заключение переименуем временный файл в исходный. Если и эта операция будет удачна, то выдадим соответствующее сообщение:if(rename($tempFile,$fileName)) echo "Строка $lineToKill удалена";

  • Весь код в сборе:
  • $lineToKill = 44;$tempFile = tempnam("/tmp", "tmp");

    if($fileHandle = @fopen($fileName,"rb")){

    echo "Исходный файл существует";

    if($tempHandle = fopen($tempFile,"w")) echo "Временный файл создан.";

    }

    else die("Исходного файла не существует!");while(!feof($fileHandle)) {

    $lineToWrite = fgets($fileHandle);

    if($lineToKill != (++$lineNum)) fwrite($tempHandle, $lineToWrite);

    }fclose($fileHandle);

    fclose($tempHandle);

    if(rename($tempFile,$fileName)) echo "Строка $lineToKill удалена";?>

    Оцените статью!