Офис НП AMWAY в Ярославле
→ На карте Купить AMWAY в ЯрославлеПриобрести высококачественную продукцию Амвей в Ярославле, получить консультации по бизнесу, заказать продукцию или получить заказ:
●Адрес: улица Валентины Терешковой, дом 1 (Вход со двора)
●Телефон: +7 (920) 112-00-91
●Email: matyxho@mail.ru
●Сайт: https://www.amway.ru/user/lebedem
●Визитка: http://yar.meweb.ru
Иерархия статей
Статьи » Программирование » PHP: Удаление строки из файла
Сниппет
Я понимаю, что запись в файл сейчас, скорее, исключение, однако иногда подобное может понадобиться. Но в статье буду рассматривать не саму запись, а удаление определенной строки из файла.
PHP: Удаление строки из файла
Недавно понадобилось мне удалить строку из файла. Так как ранее о записи в файл я имел весьма смутное представление, решил немного погуглить. Вариантов выдало много, но все они были однотипные, видимо, кто-то один придумал, а остальные лишь подхватили данное решение, каждый добавив что–то свое: ну, типа, рерайт. Меня же во всех этих примерах не устраивало несколько обстоятельств: там везде был задействован цикл for, нигде, ни в одном из примеров, не была учтена буферизация (запись в файл по 8кб), что при нагруженности ресурса и одновременно нескольких потоках записи могло бы привести к "микшированию" данных: то есть, 8кб от одного потока, 8кб от другого, затем опять 8кб от первого... Практически ни в одном из найденных примеров не была реализована блокировка файла во время записи, что также могло привести к потере данных (всех или части). Ко всему прочему, почти во всех примерах использовалась языковая конструкция unset(), хотя почти во всех случаях работа шла с элементами массива. А что у нас самое лучшее для перебора массивов в пэхапэ? Правильно, конструкция foreach. Доказано, что эта конструкция работает с массивами быстрее, чем, например, for (пруф). Именно поэтому я и решил написать свой велосипед удаления строки из файла, а ты уж сам решай, уважаемый читатель, кто прав, а кто виноват.
Итак, пример будет реальный. Возьмем для записи файл .htaccess, чтобы максимально обострить чувство опасности при работе с ним. Например наш файл имеет такое содержимое:
Что бы нам удалить? Ну давайте, например, RewriteEngine on. Далее пойдет немного кода, безусловно, с подробными пояснениями:
Если мы "раздампим" после explode() переменную $lines, то увидим примерно такую структуру массива:
То есть нужное нам значение имеет ключ 4 (не забываем, что отсчет начинается с 0). Но это так, для наглядности.
Вот и все. В итоге после записи в файл мы получим
То есть, нужная нам строка будет успешно удалена, а файл безопасно перезаписан. Если мы вместо оператора (управляющей конструкции) continue; используем оператор break;, то цикл остановится на нужном нам значении массива и данные, которые будут ниже искомого значения (в том числе и оно) не запишутся: кому–то может понадобиться именно такой вариант.
На этом пока все. Всем всего доброго.
Итак, пример будет реальный. Возьмем для записи файл .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;, то цикл остановится на нужном нам значении массива и данные, которые будут ниже искомого значения (в том числе и оно) не запишутся: кому–то может понадобиться именно такой вариант.
На этом пока все. Всем всего доброго.
Понравилась статья?
Метки для данной статьи
Поделиться:
Последние активные темы форума
Темы | Просмотров | Ответов | Последние сообщения | |
Вопрос по переделке bb-кода PHP, MySQL |
22350 | 5 | Pisatel 26. мая 2017 |
|
Вопросы по Ajax форме обратной связи CMS PHP Fusion |
68694 | 48 | Ditrin 19. февраля 2017 |
|
BBCode YouTube Video Colorbox mod CMS PHP Fusion |
15373 | 2 | Pisatel 10. декабря 2016 |
|
Как лучше создать собственную страницу? CMS PHP Fusion |
17919 | 17 | Pisatel 11. мая 2016 |
|
Небольшие вопросы по скриптам магазина и катало... PHP, MySQL |
145076 | 80 | Pisatel 11. января 2016 |
|
BBCode Code mod CMS PHP Fusion |
14430 | 0 | Pisatel 31. августа 2015 |
|
Ajax Like Dislike Article Panel CMS PHP Fusion |
22573 | 16 | Pisatel 07. июля 2015 |
|
Хлебные крошки / BreadCrumbs SEO Panel CMS PHP Fusion |
26279 | 17 | Pisatel 04. июля 2015 |
|
Abbr Description BBCode CMS PHP Fusion |
7671 | 0 | Pisatel 15. июня 2015 |
|
Плагин Email рассылки Mail To All by Pisatel CMS PHP Fusion |
37046 | 32 | Pisatel 26. апреля 2015 |
|
Подозрительный трафик и прочие страшилки Всякая хрень |
11812 | 2 | Ditrin 23. апреля 2015 |
|
Мод Newsletter - рассылка писем пользователям с... CMS PHP Fusion |
31061 | 13 | Pisatel 10. апреля 2015 |
|
Мод отправки писем PHPMailer для PHP-Fusion CMS PHP Fusion |
128616 | 113 | Ditrin 06. апреля 2015 |
|
Появление неизвестного файла subscriptions.php CMS PHP Fusion |
8853 | 2 | Pisatel 06. апреля 2015 |
|
Autoban on IP CMS PHP Fusion |
23209 | 13 | Pisatel 03. апреля 2015 |