Php удалить файл через время
Я регистрирую некоторый XML-контент в текстовом файле, используя file_put_contents() если он мне нужен для отладки.
Как удалить этот файл через определенное время?
У меня есть ограничительный .htaccess в папке журнала, но я бы предпочел не оставлять информацию (будет иметь адреса клиентов и т.д.) В Интернете надолго.
Вы можете настроить серверную запланированную задачу (наиболее известную как Cron Job в системах * nix) для регулярной работы и удаления левых файлов журналов. Задача заключалась бы в выполнении кода PHP, который будет выполнять эту работу.
Вы должны использовать функцию PHP error_log(), которая будет уважать настройки php.ini.
Ну, соглашаясь со всеми, что вы используете неправильный инструмент для работы, ваш вопрос довольно прост, так что вы здесь:
-
написать скрипт PHP, который будет запускаться из командной строки используйте инструмент, например, задание cron или windows вызывать cron каждую минуту/пять минут/и т.д.
Ваш скрипт будет довольно простым:
Вы также можете использовать find если работаете в Linux, но я вижу, что @Rawkode сообщил, что, пока я писал это, я оставил бы вам свой элегантный ответ для этого решения.
Вы можете использовать встроенную функцию - filectime - отслеживать дату создания файлов журнала, а затем удалять те, которые достаточно стары, чтобы их можно было удалить.
Этот код выполняет поиск по каталогу журналов и удаляет журналы, возраст которых составляет 2 недели.
Вы должны лучше обрабатывать свой журнал, но чтобы ответить на ваш вопрос, я бы использовал команду find * nix.
find/path/to/files* -mtime +5 -delete
Это приведет к удалению всех файлов, которые не были изменены за пять дней. Отрегулируйте свои потребности.
Есть два способа, которыми вы можете это решить:
если вы записываете журнал только в один файл, вы можете очистить файл, используя что-то вроде этого:
если вы создаете много файлов, вы можете написать функцию очистки следующим образом:
Какая нафиг база? Какой PHP? Зачем это всё здесь? Денормализовать данные файловой системы, сделать решение не поддерживаемыми, хромым на обе ноги и склонным к глюкам?
find /путь/к/каталого/с/файлами -mtime +5 -delete
А вообще man finde конечно.
Можно, пишите в БД путь к файлу и дату загрузки, по крону удаляете старые. Какой .htaccess.Создаёте таблицу в БД, куда будете вносить данные о загружаемых файлах: имя, дату загрузки, размер. Пишете PHP скрипт, который будет выбирать записи из БД, соответствующие определённым условиям (загруженные более 5 дней назад; последние записи, суммарный размер которых составляет 100 мб.). Затем в цикле удаляете эти файлы функцией unlink.
Теперь осталось создать задачу для крона. Например, будем каждый день в полночь проводить чистку. В панели управления сервером выбираете нужный интервал. В качестве команды укажите путь к интерпретатору с параметром - путь к скрипту, который будет чистить. Например: /usr/bin/php /home/user/www/cleaner_cron.php
Путь к интерпретатору ищите в FAQ'е хостинга или же спросите в службе поддержки
Можно и без крона: при сохранении очередного файла запускать заодно чистку. Причём чистка не обязательно должна быть полной: достаточно стереть несколько подлежащих удалению старых файлов. Ведь этот процесс запускается при каждом сохранении нового файла.
Для ускорения чистки можно при сохранении именовать новый файлы таким образом, чтобы они были отстортированы по времени создания, например, в подпапки по дням, и по времени:
Итак, мой вопрос: как я могу оптимизировать автоматическое удаление записей ровно через 24 часа.
Что вам нужно знать:
Я ищу решение, которое также позволит мне удалить файлы, связанные с этой записью в базе данных.
Моя идея:
Моя первоначальная идея заключалась в том, чтобы запустить Perl-скрипт, который будет проверять каждый час, была ли самая ранняя запись создана 24 часа назад или нет, и если это так, удалите запись и файл, связанный с этой записью, но сначала я нахожу это решение немного некрасиво, и я уверен, что есть лучшее решение, чем это, более оптимизированное и стильное!
Таблица:
Если у вас есть вдохновение, расскажите мне!
4 ответа
Вы можете использовать планировщик событий MySQL:
для автоматического удаления таких записей по истечении срока их действия:
для регулярного запуска автоматической очистки всех просроченных записей:
Я подумал об этом, и что ж, записи расположены в хронологическом порядке:
Если запись 25 должна быть удалена в 00:01, запись 26 будет удалена в то же время или после 00:01.
Я не хочу создавать одно задание cron для каждой записи, потому что я знаю, что записей будет много.
Моя идея предполагает, что сценарий проверит хотя бы один раз, чтобы получить метку времени записи и ее идентификатор.
Я знаю, что это, вероятно, не самый оптимизированный способ, но я хочу поделиться этим мнением.
Идея:
Таким образом, для каждой записи будет одно задание cron, но у нас может быть только одно задание cron.
Вы можете использовать
Итак, когда вы можете сделать, это настроить задание at при первоначальной загрузке entires, чтобы оно сработало через 24 часа.
Напишите свой sql-запрос в файл php, а затем настройте задание cron для этого файла.
CPanel, поскольку эта функция встроена и проста в использовании
Команда для запуска будет выглядеть примерно так
Если у вас нет cPanel, взгляните на это
Я только сейчас увидел ваш ответ PRPGFerret. Есть ли в ваших записях sql метки времени? Чаще запускайте задание cron и позвольте php проверять отметку времени, а если прошел час, удалите запись.
Давайте попробуем решить простую задачу по удалению одного файла или нескольких файлов средствами PHP. В целом, здесь нет ничего сложного, но есть масса деталей, а также вариантов решений, о которых Вам стоит знать. В своей статье я не берусь объять необъятное, но растолковать пару вопросов и привести несколько примеров, думаю, смогу. Приступим?
PHP функция unlink()
А начну я с php-функции unlink() , которая и осуществляет удаление файла:
bool unlink( string $filename [, resource $context ] )
Здесь $filename – путь к файлу, а $context (не обязательно) – описание контекстов для работы с потоками (поддерживается в PHP, начиная с 5.0.0) . Функция возвращает TRUE в случае успешного завершения или FALSE в случае возникновения ошибки.
Пример использования php-функции unlink():
$filename = './path/to/file.txt';
if ( !(@unlink($filename)) ) die('Error Delete File.');
Почему эта функция называется unlink()?
Дело в том, что в файловой системе Unix имеется различие между физическим расположением файлов на носителе и соответствующей структурой каталога. Поэтому при сохранении файла в определенной точке файловой системы эта точка дерева каталогов связывается с физическим местом хранения данных файла. Другими словами, путь к файлу в Unix, фактически, представляет собой уникальных идентификатор для одного из этих узлов.
Примечательно здесь и то, что в Unix можно связать несколько таких точек с одними и теми же данными. Таки данные будут существовать до тех пор, пока существует хотя бы одна ссылка на них. Но если все ссылки будут уничтожены, то и сами данные будут уничтожены. Таким образом, функция unlink() предназначена для удаления именно ссылок, и уже как следствия данных файла.
В Windows такого нет и функция unlink() удаляет именно файл. Более того, некоторые версии PHP для Windows вообще не поддерживают unlink() . В таком случае используется команда del через system() или exec() , например:
$filename = '/2014/04/file.txt';
if ( isset($_ENV['WINDIR']) ) @exec('del '. $filename);
if ( file_exists($filename) ) die('Error Delete File.');
> else if ( !(@unlink($filename)) ) die('Error Delete File.');
>
В данном случае переменная среды $_ENV['WINDIR'] может служить маркером использования Windows-платформы, а проверка выполнения удаления файла осуществляется через php-функцию file_exists() , которая осуществляет проверку существования файла.
Как удалить файл(ы) в PHP?
В некоторых случаях может получиться и так, что функция unlink() не будет иметь доступа к удалению файла, т.е. получаем ошибку [function.unlink]: permission denied. Это может быть связано с неправильно указанным путём к файлу или отсутствием прав доступа.
Интересным вариантом для работы с путями к файлу является использование php-функций getcwd() (получает имя текущего рабочего каталога) и chdir() (изменяет текущий каталог на указанный) , например:
$file_path = 'path/to';
$file_name = '/2014/04/file.txt';
$old = getcwd();
if ( !(@chdir($file_path)) ) die('Error open path.');
if ( !(@unlink($file_name)) ) die('Error Delete File.');
chdir($old);
Как вы видите, так в чём-то проще ориентироваться и отследить проблему. В тоже время, будет не лишним, после выполнения удаления вернуться в текущий каталог $old .
Что же до проблем доступа, то здесь можно попробовать использовать php-функцию chmod() (изменяет режим доступа к файлу) , например:
$filename = '/2014/04/path/to/file.txt';
@chmod($filename, 0666);
if ( !(@unlink($filename)) ) die('Error Delete File.');
Если Вам необходимо удалить все файлы в директории удобно использовать комбинацию из php-функций array_map() (применяет callback-функцию ко всем элементам массива) и glob() (находит файловые пути, совпадающие с шаблоном) , например:
Решение проблемы многопоточности при удалении файлов
Гораздо сложнее, когда речь заходит о крупных сайтах, где велико количество одновременных запросов (потоков) к скрипту. Здесь существует ряд решений. Я же приведу лишь одно из них, основное на использовании семафоров.
Как таковой, семафор служит своеобразным маркером процесса. При захвате семафора одним процессом, его значение уменьшается на единицу, а при отпускании — увеличивается на единицу. При этом, если текущее значение семафора равно нулю, процессу не удастся его захватить и он будет ожидать освобождения семафора.
Для получения ресурса семафора используется функция sem_get() . Функцией можно получить семафор со значением, отличающимся от единицы, и тогда захватить семафор смогут несколько потоков. Для захвата используется функция sem_acquire() . Пример:
$sem = sem_get(1);
if ( sem_acquire($sem) && file_exists($filename) ) @unlink($filename);
sem_remove($sem);
Обратить внимание на то, что здесь используется дополнительная проверка на существование файла file_exists() . Дело в том, что когда первый поток захватит семафор, удалит файл и отпустит семафор, второй поток сможет продолжить выполнение без удаления файл, которого уже нет.
Важную роль здесь играет функция sem_remove() , которая отпускает занятый семафора. Если семафор не отпустить, то параллельный поток останется в состоянии ожидания вплоть до окончания работы текущего. Поэтому функция и должна быть вне условия.
На этом у меня всё. Надеюсь, что моя статья была Вам полезна или просто познавательно. Спасибо за внимание. Удачи!
Читайте также: