Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: Удаление строк по времени

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


 Страниц (1): [1]   

> Описание: Как удалить строки из файла с прошедшей датой
AlexAngel
Отправлено: 29 Августа, 2014 - 09:27:34
Post Id


Новичок


Покинул форум
Сообщений всего: 4
Дата рег-ции: Авг. 2014  


Помог: 0 раз(а)




Добрый день, всем форумчанам!
Решил попрактиковаться в написании небольшой утилиты для выполнения работ. Вроде утилиту сделал, все хорошо, осталась самая малость.

Есть файл на сервере, в котором содержаться следующие строки:

Сделать_Работу_№1$Работа_Выполнена_Невыполнена$21.07.2014
Сделать_Работу_№2$Работа_Выполнена_Невыполнена$26.07.2014
Сделать_Работу_№3$Работа_Выполнена_Невыполнена$19.08.2014
Сделать_Работу_№4$Работа_Выполнена_Невыполнена$27.08.2014
Сделать_Работу_№5$Работа_Выполнена_Невыполнена$29.08.2014
Сделать_Работу_№6$Работа_Выполнена_Невыполнена$31.08.2014
Сделать_Работу_№7$Работа_Выполнена_Невыполнена$10.09.2014
Сделать_Работу_№8$Работа_Выполнена_Невыполнена$29.09.2014
Сделать_Работу_№9$Работа_Выполнена_Невыполнена$01.09.2015


Подскажите, как можно удалить из этого файла строки, дата которых прошла?

Делаю так:
Мой код PHP

PHP:
скопировать код в буфер обмена
  1. <?PHP
  2. $lines = file('Work.txt');
  3. $mydate = date("d.m.Y");
  4.  
  5.  
  6. foreach ($lines as $line) {
  7. if ($mydate > substr($line, 48, 57))
  8. {
  9.  
  10. foreach($file as $k=>$v)
  11. if (!stristr($v,$mydate))
  12. $nfile[]=$v;
  13. $file=fopen("Work.txt","w");
  14. fwrite($file,implode($nfile,""));
  15. fclose($file);
  16.  
  17. }
  18. }
  19. ?>

Но почему-то обнуляется весь файл. Смутно догадываюсь, что скорее всего не правильно работает сравнение строк или дат, но вот как правильно, не могу сообразить.
Подскажите, что я делаю не правильно?
 
 Top
RickMan
Отправлено: 29 Августа, 2014 - 09:36:08
Post Id


Участник


Покинул форум
Сообщений всего: 1033
Дата рег-ции: Май 2012  


Помог: 30 раз(а)




Делай сравнение дат как минимум так:

PHP:
скопировать код в буфер обмена
  1.  
  2. if (strtotime($date1)<strtotime($date2)){
  3.  
  4. }
  5.  


И что за переменная $file используетсмя там, которая не объявлена нигде?
 
 Top
Мелкий Супермодератор
Отправлено: 29 Августа, 2014 - 09:41:48
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




Вы в цикле перезаписываете файл.

Мой вариант:
PHP:
скопировать код в буфер обмена
  1. $rNow = new \datetime('midnight');
  2.  
  3. $rgOut = array_filter(file('test.csv'), function($row) use ($rNow) {
  4.         $rgRow = str_getcsv($row, '$');
  5.         assert('count($rgRow)==3');
  6.         $rDate = \datetime::createFromFormat('d.m.Y H:i:s', $rgRow[2].' 00:00:00');
  7.         assert('is_object($rDate)');
  8.         return $rNow < $rDate;
  9.         });
  10.  
  11. file_put_contents('test.csv', join(PHP_EOL, $rgOut));


-----
PostgreSQL DBA
 
 Top
AlexAngel
Отправлено: 29 Августа, 2014 - 09:59:57
Post Id


Новичок


Покинул форум
Сообщений всего: 4
Дата рег-ции: Авг. 2014  


Помог: 0 раз(а)




RickMan пишет:
И что за переменная $file используетсмя там, которая не объявлена нигде?

Прошу прощения, действительно за место $file должен стоять $lines
Но все равно не работает.
(Добавление)
Мелкий пишет:
Мой вариант:

Что-то этот код для меня тяжеловат пока для восприятия. Буду вчитываться Радость
(Добавление)
Мелкий
Подскажите, а что получиться, если "Work.txt" файл будет на сервере и несколько человек к нему обратятся одновременно через php с вашим вариантом?
Может такое произойти, что файл "Work.txt" будет недоступен кому-либо из людей (при условии, что в файле будет не более 10000 строк) ?
 
 Top
Мелкий Супермодератор
Отправлено: 29 Августа, 2014 - 10:25:25
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




AlexAngel пишет:
Может такое произойти, что файл "Work.txt" будет недоступен кому-либо из людей (при условии, что в файле будет не более 10000 строк) ?

Недоступен - нет, не может. Файл всегда будет. Вот только вопрос, что будет в файле...
Но race condition мой код не учитывает. Вот тут не уверен, возможно достаточно будет только указания флага LOCK_EX у file_put_contents, возможно надо на flock заменять.


-----
PostgreSQL DBA
 
 Top
AlexAngel
Отправлено: 30 Августа, 2014 - 05:52:15
Post Id


Новичок


Покинул форум
Сообщений всего: 4
Дата рег-ции: Авг. 2014  


Помог: 0 раз(а)




Мелкий Спасибо, действительно работает!
Но для меня этот код сложноват оказался, поэтому я переделал по аналогии так:
PHP:
скопировать код в буфер обмена
  1. <?PHP
  2.  
  3.       $fileName = 'work.txt';
  4.  
  5.         $lines = file($fileName);
  6.         $mydate = date('Y.m.d');
  7.         $nfile = array();
  8.         foreach ($lines as $line) {
  9.             $cols = explode('$', $line);
  10.             if ($mydate < $cols[2]) {
  11.                 $nfile[] = $line;
  12.             }
  13.         }
  14.         $file = fopen($fileName, 'w');
  15.         fwrite($file, implode($nfile));
  16.         fclose($file);
  17. ?>


Как избежать ситуации "race condition"?

Ведь если просто сделать так:

PHP:
скопировать код в буфер обмена
  1. <?PHP
  2.  
  3.       $fileName = 'work.txt';
  4.  
  5.         $lines = file($fileName);
  6.         $mydate = date('Y.m.d');
  7.         $nfile = array();
  8.         foreach ($lines as $line) {
  9.             $cols = explode('$', $line);
  10.             if ($mydate < $cols[2]) {
  11.                 $nfile[] = $line;
  12.             }
  13.         }
  14.         $file = fopen($fileName, 'w');
  15.         if (flock($file, LOCK_EX))
  16.          { // выполнить эксплюзивное запирание 
  17.         fwrite($file, implode($nfile));
  18.             flock($file, LOCK_UN); // отпираем файл
  19.        
  20.         }
  21.         else {
  22.          echo "Не могу запереть файл !";
  23.                  }
  24.         fclose($file);   
  25. ?>


Получиться, что только один человек может записывать файл одновременно, а для второго будет выходить ошибка, или я не прав?
Как сделать чтобы и удаляло, не тормозило и работало если обращается одновременно больше 10 человек?
 
 Top
likvidator
Отправлено: 30 Августа, 2014 - 09:03:11
Post Id


Посетитель


Покинул форум
Сообщений всего: 416
Дата рег-ции: Март 2012  


Помог: 4 раз(а)

[+]


AlexAngel пишет:
Как сделать чтобы и удаляло, не тормозило и работало если обращается одновременно больше 10 человек?

БД? Не,не слышал... Вообще,почему именно файл?
 
 Top
AlexAngel
Отправлено: 30 Августа, 2014 - 10:01:11
Post Id


Новичок


Покинул форум
Сообщений всего: 4
Дата рег-ции: Авг. 2014  


Помог: 0 раз(а)




Просто с БД на php не работал еще.
Вот например как перевести мой код на mysql ?
 
 Top
likvidator
Отправлено: 30 Августа, 2014 - 16:02:08
Post Id


Посетитель


Покинул форум
Сообщений всего: 416
Дата рег-ции: Март 2012  


Помог: 4 раз(а)

[+]


AlexAngel пишет:
Вот например как перевести мой код на mysql ?

Ну.. начать нужно не с чтения,а с записи данных в бд ( запись в файл вы не выложили)...
 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« Вопросы новичков »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB