英文:
How to delete files older than 7 days, with specific filename or file extension
问题
我有一个每晚通过CRON运行的index.php脚本,用于备份我的网站上的MySQL数据库。该脚本将文件存储在脚本所在的文件夹中。我想创建另一个脚本,用于删除早于7天的备份文件。所以我从GitHub上使用了tdebatty的这个脚本:
<?php
function delete_older_than($dir, $max_age) {
$list = array();
$limit = time() - $max_age;
$dir = realpath($dir);
if (!is_dir($dir)) {
return;
}
$dh = opendir($dir);
if ($dh === false) {
return;
}
while (($file = readdir($dh)) !== false) {
$file = $dir . '/' . $file;
if (!is_file($file)) {
continue;
}
if (filemtime($file) < $limit) {
$list[] = $file;
unlink($file);
}
}
closedir($dh);
return $list;
}
// An example of how to use:
$dir = "/my/backups";
$to = "my@email.com";
// Delete backups older than 7 days
$deleted = delete_older_than($dir, 3600*24*7);
$txt = "Deleted " . count($deleted) . " old backup(s):\n" .
implode("\n", $deleted);
mail($to, "Backups cleanup", $txt);
这个脚本运行良好,但我想限制删除以"XXX"开头的文件或.sql.gz文件。在备份文件夹中,我有所有的.sql.gz备份,以及每天用于备份的index.php脚本。这个index.php文件在逐渐变老的过程中没有被修改,所以它会在某个时候被删除脚本删除。
谢谢!
我尝试修改现有的if条件:if (!is_file($file) || strpos($file, "XXX") !== 0) {
或 if (filemtime($file) < $limit && strpos($file, "XXX") === false) {
或 if (pathinfo($file, PATHINFO_EXTENSION) == 'sql.gz' && filemtime($file) < $limit) {
我还尝试在循环中添加另一个if条件:
if (strpos($file, "XXX") !== 0) {
continue;
}
这些都不起作用,我不明白为什么。脚本不再工作,没有任何反应。有什么线索吗?如果这很明显,我还在学习中,很抱歉:)
英文:
I have a index.php script that runs every night to backup a mySQL database (through CRON) on my website. The script store the file in the folder where the script is. I wanted to created another script that would delete backup files older than 7 days. So I used this one from tdebatty on GitHub:
<?php
function delete_older_than($dir, $max_age) {
$list = array();
$limit = time() - $max_age;
$dir = realpath($dir);
if (!is_dir($dir)) {
return;
}
$dh = opendir($dir);
if ($dh === false) {
return;
}
while (($file = readdir($dh)) !== false) {
$file = $dir . '/' . $file;
if (!is_file($file)) {
continue;
}
if (filemtime($file) < $limit) {
$list[] = $file;
unlink($file);
}
}
closedir($dh);
return $list;
}
// An example of how to use:
$dir = "/my/backups";
$to = "my@email.com";
// Delete backups older than 7 days
$deleted = delete_older_than($dir, 3600*24*7);
$txt = "Deleted " . count($deleted) . " old backup(s):\n" .
implode("\n", $deleted);
mail($to, "Backups cleanup", $txt);
The script works well, but I would like to limit deletion to files starting with "XXX' or .sql.gz files. In the backup folder i have all the .sql.gz backup alongside the index.php script that is used daily to backup. This index.php file is not modified as the days go by, so it gets older and it is deleted by the deletion script at some point.
Thank you !
I tried to modify existing if conditions: if (!is_file($file) || strpos($file, "XXX") !== 0) {
or if (filemtime($file) < $limit && strpos($file, "XXX") === false) {
or if (pathinfo($file, PATHINFO_EXTENSION) == 'sql.gz' && filemtime($file) < $limit) {
I also tried to add another if condition in the loop:
if (strpos($file, "XXX") !== 0) {
continue;
}
None of these works and I don't understand why. Script doesn't work anymore, nothin happens. Any clue? Sorry if it's obvious, I'm still learning
答案1
得分: 0
你尝试过str_contains()吗?
str_contains(string $haystack, string $needle): bool
if(filemtime(...) < $time && str_contains($file, 'XXX')) {
unlink
}
英文:
Have you tried str_contains()?
str_contains(string $haystack, string $needle): bool
if(filemtime(...) < $time && str_contains($file, 'XXX')) {
unlink
}
答案2
得分: 0
一个熟人找到了问题:当按扩展类型进行定位时,在我的情况下,文件扩展名是 "gz",而不是 "sql.gz"。
英文:
An acquaintance found the issue: when targeting by extension type, in my case file extension is "gz", not "sql.gz".
答案3
得分: 0
这是您的代码部分的翻译:
这是您的错误,脚本重新定义了 `$file` 为 `$file = $dir . '/' . $file;` 并且您创建了一个条件 `strpos($file, "XXX") !== 0`,所以您的条件将会是这样的 `strpos("/YOURPATH/XXX", "XXX") !== 0`
另外,您创建了这个条件 `pathinfo($file, PATHINFO_EXTENSION) == 'sql.gz'` 是错误的,因为 `pathinfo($file, PATHINFO_EXTENSION)` 的输出只是文件扩展名 (`gz`, `txt` 等)。
这是可工作的代码:
```php
function delete_older_than($dir, $max_age, $prefix = null, $extension = null) {
$list = array();
$limit = time() - $max_age;
$dir = realpath($dir);
if (!is_dir($dir)) {
return;
}
$dh = opendir($dir);
if ($dh === false) {
return;
}
while (($file = readdir($dh)) !== false) {
$fullpath = $dir . '/' . $file;
if (!is_file($fullpath)) {
continue;
}
if ($prefix !== null && !(strpos($file, $prefix) === 0)) {
continue;
}
if ($extension !== null && !(strlen($file) - strlen($extension) == strrpos($file,$extension))) {
continue;
}
if (filemtime($fullpath) < $limit) {
$list[] = $fullpath;
unlink($fullpath);
echo "Deleted $fullpath \n";
}
}
closedir($dh);
return $list;
}
用于生成随机文件的测试代码如下:
// 用于仅用于测试生成随机文件的函数
function randomFile($extension) {
$characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$randomString = '';
for ($i = 0; $i < 10; $i++) {
$randomString .= $characters[rand(0, strlen($characters) - 1)];
}
$filename = $randomString . $extension;
return $filename;
}
function generateFile($extension, $prefix = '') {
$directory = '/tmp'; // 文件将被创建的目录路径
//$extension = ".sql.gz"; // 所需的文件扩展名
for ($i = 1; $i <= 10; $i++) {
$filename = $directory . '/' . $prefix . randomFile($extension); // 构建文件名
$content = '这是文件编号 ' . $i; // 要写入文件的内容
// 创建文件并写入内容
file_put_contents($filename, $content);
echo "文件已创建:$filename \n";
}
}
然后使用它:
generateFile(".sql.gz", "XXX");
generateFile(".sql.gz", "IAMUNDELETED");
generateFile(".txt");
sleep(1);
delete_older_than("/tmp", 0, "XXX", "");
print_r(scandir("/tmp"));
delete_older_than("/tmp", 0, "", ".txt");
print_r(scandir("/tmp"));
在线代码测试:https://onlinephp.io/c/3fc02
<details>
<summary>英文:</summary>
Here your mistake, the script redefine `$file` with this `$file = $dir . '/' . $file;` and you create a condition `strpos($file, "XXX") !== 0`, so your condition will like this `strpos("/YOURPATH/XXX", "XXX") !== 0`
Also you create this condition `pathinfo($file, PATHINFO_EXTENSION) == 'sql.gz'` is wrong because output of `pathinfo($file, PATHINFO_EXTENSION)` is only extension (`gz`,`txt`,etc)
Here the working code
function delete_older_than($dir, $max_age, $prefix = null, $extension = null) {
$list = array();
$limit = time() - $max_age;
$dir = realpath($dir);
if (!is_dir($dir)) {
return;
}
$dh = opendir($dir);
if ($dh === false) {
return;
}
while (($file = readdir($dh)) !== false) {
$fullpath = $dir . '/' . $file;
if (!is_file($fullpath)) {
continue;
}
if ($prefix !== null && !(strpos($file, $prefix) === 0)) {
continue;
}
if ($extension !== null && !(strlen($file) - strlen($extension) == strrpos($file,$extension))) {
continue;
}
if (filemtime($fullpath) < $limit) {
$list[] = $fullpath;
unlink($fullpath);
echo "Deleted $fullpath \n";
}
}
closedir($dh);
return $list;
}
For testing, use this code for generate a random file.
// Function for generate random file for testing only
function randomFile($extension) {
$characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$randomString = '';
for ($i = 0; $i < 10; $i++) {
$randomString .= $characters[rand(0, strlen($characters) - 1)];
}
$filename = $randomString . $extension;
return $filename;
}
function generateFile($extension, $prefix = '') {
$directory = '/tmp'; // The directory path where the files will be created
//$extension = ".sql.gz"; // The desired file extension
for ($i = 1; $i <= 10; $i++) {
$filename = $directory . '/' . $prefix . randomFile($extension); // Construct the file name
$content = 'This is file number ' . $i; // Content to be written in the file
// Create the file and write the content
file_put_contents($filename, $content);
echo "File created: $filename \n";
}
}
Then use it
generateFile(".sql.gz","XXX");
generateFile(".sql.gz","IAMUNDELETED");
generateFile(".txt");
sleep(1);
delete_older_than("/tmp", 0, "XXX","");
print_r(scandir("/tmp"));
delete_older_than("/tmp", 0, "",".txt");
print_r(scandir("/tmp"));
Here live code test : https://onlinephp.io/c/3fc02
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论