Офис НП AMWAY в Ярославле
Купить продукцию Амвей в Ярославле, офис Amway
На карте Купить AMWAY: офис в ЯрославлеКонсультации, презентации, мастер–классы, знакомство с продукцией, заказ и выдача купленного товара:
Адрес: улица Валентины Терешковой, дом 1 (Вход со двора)
Телефон: +7 (920) 112-00-91
Email: matyxho@mail.ru
Сайт: https://www.amway.ru/user/lebedem
Визитка: http://yar.meweb.ru
Иерархия статей
Статьи » Программирование » PHP: Удаление строки из файла
Сниппет
Я понимаю, что запись в файл сейчас, скорее, исключение, однако иногда подобное может понадобиться. Но в статье буду рассматривать не саму запись, а удаление определенной строки из файла.
PHP: Удаление строки из файла
Опубликовал  Pisatel Добавлено  16-03-2015 20:54 16 Март 2015 20:54:02 2532  Прочтений 2532 Прочтений  4 Комментариев 4 Комментариев
Обновлено: 10-06-2015 12:33 Обновлено: 10 июня 2015 12:33:27  printer
Недавно понадобилось мне удалить строку из файла. Так как ранее о записи в файл я имел весьма смутное представление, решил немного погуглить. Вариантов выдало много, но все они были однотипные, видимо, кто-то один придумал, а остальные лишь подхватили данное решение, каждый добавив что–то свое: ну, типа, рерайт. Меня же во всех этих примерах не устраивало несколько обстоятельств: там везде был задействован цикл for, нигде, ни в одном из примеров, не была учтена буферизация (запись в файл по 8кб), что при нагруженности ресурса и одновременно нескольких потоках записи могло бы привести к "микшированию" данных: то есть, 8кб от одного потока, 8кб от другого, затем опять 8кб от первого... Практически ни в одном из найденных примеров не была реализована блокировка файла во время записи, что также могло привести к потере данных (всех или части). Ко всему прочему, почти во всех примерах использовалась языковая конструкция unset(), хотя почти во всех случаях работа шла с элементами массива. А что у нас самое лучшее для перебора массивов в пэхапэ? Правильно, конструкция foreach. Доказано, что эта конструкция работает с массивами быстрее, чем, например, for (пруф). Именно поэтому я и решил написать свой велосипед удаления строки из файла, а ты уж сам решай, уважаемый читатель, кто прав, а кто виноват.

Итак, пример будет реальный. Возьмем для записи файл .htaccess, чтобы максимально обострить чувство опасности при работе с ним. Например наш файл имеет такое содержимое:

Код: APACHE
DefaultLanguage ru

AddDefaultCharset windows-1251

ErrorDocument 404 /404.php

Options -Indexes

RewriteEngine on

RewriteCond %{HTTP_HOST} ^meweb\.ru$ [NC]

RewriteRule ^(.*)$ http://www.meweb.ru/$1 [R=301,L]

RewriteBase /




Что бы нам удалить? Ну давайте, например, RewriteEngine on. Далее пойдет немного кода, безусловно, с подробными пояснениями:

Код: PHP
    $htu = ".htaccess"; // задали путь к .htaccess для удобства

if ($fh = fopen($htu, "a+b")) { // открыли файл для чтения и записи, поместив указатель в конец

$lines = file_get_contents($htu); // прочитали файл в строку

$lines = explode("\n", $lines); // превратили строку в массив

// далее проверим, массив ли получился и найдем искомую строку

if (is_array($lines) && ($sline = array_search("RewriteEngine on", $lines)) !== false) {

// функция array_search вернула нам ключ нужной строки

// ну а далее- идем по массиву, и, найдя нужное значение, удаляем его

foreach ($lines as $key => $val) { // в переменной $vаl- значение, в $key- ключ значения

if ($key == $sline) continue; // именно это выражение удалит нужное значение

$lnht[] = $val; // собираем массив без искомого значения

}

} else {

$lnht = $lines; // иначе, если искомое значение не обнаружено, просто возвращаем все, что было в файле

}

$lnht = implode("\n", $lnht); // превращаем обратно массив в строку

// а далее- проверяем, можно ли вести запись в файл и сработает ли блокировка файла

if (is_writable($htu) && flock($fh, LOCK_EX | LOCK_NB)) {

ftruncate($fh, 0); // очищаем полностью файл

stream_set_write_buffer($fh, 0); // отключаем буферизацию, дабы не возникло ошибки при записи (теперь запись будет произведена полностью, а не по 8кб)

fwrite($fh, $lnht); // пишем в файл

flock($fh, LOCK_UN); // снимаем блокировку с файла

}

fclose($fh); // закрываем файл

clearstatcache(); // чистим кэш (в данном случае нужно лишь для функции is_writable, так как ее результат кэшируется)

}




Если мы "раздампим" после explode() переменную $lines, то увидим примерно такую структуру массива:

Код: PHP
array(8) {

[0]=> string(19) "DefaultLanguage ru "

[1]=> string(31) "AddDefaultCharset windows-1251 "

[2]=> string(27) "ErrorDocument 404 /404.php "

[3]=> string(17) "Options -Indexes "

[4]=> string(17) "RewriteEngine on "

[5]=> string(42) "RewriteCond %{HTTP_HOST} ^meweb\.ru$ [NC] "

[6]=> string(52) "RewriteRule ^(.*)$ http://www.meweb.ru/$1 [R=301,L] "

[7]=> string(14) "RewriteBase / "

}




То есть нужное нам значение имеет ключ 4 (не забываем, что отсчет начинается с 0). Но это так, для наглядности.

Вот и все. В итоге после записи в файл мы получим

Код: APACHE
DefaultLanguage ru

AddDefaultCharset windows-1251

ErrorDocument 404 /404.php

Options -Indexes

RewriteCond %{HTTP_HOST} ^meweb\.ru$ [NC]

RewriteRule ^(.*)$ http://www.meweb.ru/$1 [R=301,L]

RewriteBase /




То есть, нужная нам строка будет успешно удалена, а файл безопасно перезаписан. Если мы вместо оператора (управляющей конструкции) continue; используем оператор break;, то цикл остановится на нужном нам значении массива и данные, которые будут ниже искомого значения (в том числе и оно) не запишутся: кому–то может понадобиться именно такой вариант.

На этом пока все. Всем всего доброго.
Понравилась статья?
Метки для данной статьи
Поделиться:   
Комментарии
#1 | Vitalij 18 марта 2015 16:11:14
No Avatar
Гость
Ну почему раньше эту статью не нашел! буквально пару месяцев назад мчился спасибо!
#2 | Vitalij 18 марта 2015 16:18:41
No Avatar
Гость
Мучился))) а можно чуть подробнее чем отличается break от continue?
Avatar
Отсутствует
Супер Администратор
Активный
С 03. февраля 2013
Vitalij, всегда пожалуйста. Вкратце о continue vs break: оператор continue при переборе массива пропустит значение, заданное условием, но перебор массива при этом не закончится и будет продолжен. Оператор же break прервет перебор массива, остановившись на значении, заданном в условии. Поэтому, если понять, как работают эти операторы, можно значительно упростить и сократить код.
Я не европеец. И не азиат. Я русский. Я россиянин. Я за истинные семейные христианские ценности. И это - моя национальная идея.
#4 | Vitalij 18 марта 2015 20:43:35
No Avatar
Гость
Спасибо!
Добавить комментарий
Имя:

Проверочный код:
Последние активные темы форума
  Темы Просмотров Ответов Последние сообщения
folder Плагин Email рассылки Mail To All by Pisatel
CMS PHP Fusion
13811 33 promask
27. апреля 2019
folder Вопрос по переделке bb-кода
PHP, MySQL
3493 5 Pisatel
26. мая 2017
folder Вопросы по Ajax форме обратной связи
CMS PHP Fusion
14798 48 Ditrin
19. февраля 2017
folder BBCode YouTube Video Colorbox mod
CMS PHP Fusion
7989 2 Pisatel
10. декабря 2016
folder Как лучше создать собственную страницу?
CMS PHP Fusion
7629 17 Pisatel
11. мая 2016
folder Небольшие вопросы по скриптам магазина и катало...
PHP, MySQL
54602 80 Pisatel
11. января 2016
folder BBCode Code mod
CMS PHP Fusion
4209 0 Pisatel
31. августа 2015
folder Ajax Like Dislike Article Panel
CMS PHP Fusion
8397 16 Pisatel
07. июля 2015
folder Хлебные крошки / BreadCrumbs SEO Panel
CMS PHP Fusion
9707 17 Pisatel
04. июля 2015
folder Abbr Description BBCode
CMS PHP Fusion
3198 0 Pisatel
15. июня 2015
folder Подозрительный трафик и прочие страшилки
Всякая хрень
6312 2 Ditrin
23. апреля 2015
folder Мод Newsletter - рассылка писем пользователям с...
CMS PHP Fusion
8107 13 Pisatel
10. апреля 2015
folder Мод отправки писем PHPMailer для PHP-Fusion
CMS PHP Fusion
43281 113 Ditrin
06. апреля 2015
folder Появление неизвестного файла subscriptions.php
CMS PHP Fusion
3847 2 Pisatel
06. апреля 2015
folder Autoban on IP
CMS PHP Fusion
14154 13 Pisatel
03. апреля 2015