I am making a Cron that will delete a folder older than 15days. I already made a function to delete the folder and it's content, what I don't have is to loop inside a folder then check each folder's age then if that is 15days old or above I will executue my delete function.
I want to loop inside public/uploads
in my uploads directory I store folders with content ex.
public/
uploads/
Test/
Test2/
I want to check how old those folder then delete it by calling
function Delete($path)
{
if (is_dir($path) === true)
{
$files = array_diff(scandir($path), array('.', '..'));
foreach ($files as $file)
{
Delete(realpath($path) . '/' . $file);
}
return rmdir($path);
}
else if (is_file($path) === true)
{
return unlink($path);
}
return false;
}
How do I do that? Thanks
The function you are looking for is filemtime(). This lets you determine the last modified date of a file (or directory). That in combination with the various directory functions will allow you to loop through them and check their dates.
This is something mocked up off the top of my head to give you a rough idea of how you may go about this:
$dir = '/path/to/my/folders';
$folders = scandir($dir);
foreach ($folders as $folder) {
$lastModified = filemtime($folder);
// Do a date comparison here and call your delete if necessary
}
Related
I have a question about the little code snippet below.
At the moment I use the first code snippet and it runs perfectly.
But wouldn't the second code be a better way to delete the folder and files in it?
My variable $target is everytime a path to the folder hwo needs to delete.
function deleteFilesAndDirectory($target)
{
if(is_dir($target))
{
$files = glob($target . '*', GLOB_MARK);
foreach($files as $file)
{
deleteFilesAndDirectory($file);
}
rmdir($target);
}
elseif(is_file($target))
{
unlink($target);
}
}
Why this code shouldn't be used?
function deleteFilesAndDirectory($target)
{
$files = glob($target . '*', GLOB_MARK);
foreach($files as $file)
{
unlink($file);
}
rmdir($target);
}
The second will work fine, so long as the directory to be deleted does not contain any subdirectories. To clean out subdirectories, a recursive function is the best way, which is why in the first code sample the function deleteFilesAndDirectory() calls itself.
So here comes the tricky part. There are specifically two Sub directories (the sub-directories also some contain file) in every Directory named lib and vendor. So when I used to have specific Dir name I used to use this
<?php
$dir = $_GET['fname'];
array_map('unlink', glob("$dir/lib/*.*"));
rmdir("$dir/lib");
array_map('unlink', glob("$dir/vendor/*.*"));
rmdir("$dir/vendor");
array_map('unlink', glob("$dir/*.*"));
rmdir($dir);`
So I used to have a specific directory name. but now i want to change this.
So whenever a user is redirected to my script
It should delete all the directories that are older that 5 min. Only
directories.
All the directories contain only and only 2 sub-directories named
lib and vendor.They Should be deleted too.
These Three Directories Shouldn't be deleted project , images and
assets.Except these all the directories should be deleted. Now
Please someone Help me out.
You can do this. First create a function to delete a directory
function deldirectory($dir){
$tfile = new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS);
$files = new RecursiveIteratorIterator($tfile,
RecursiveIteratorIterator::CHILD_FIRST);
foreach($files as $file) {
if ($file->isDir()){
rmdir($file->getRealPath());
} else {
unlink($file->getRealPath());
}
}
return rmdir($dir);
}
Call that function in foreach loop to check and delete the folder that are more then 5 minutes
foreach ($folders as $f){
$lastmodified = filemtime($f);
$farray = array("project","images","assets");//These folders are ignored
$file_life = 300;
if((time() - $lastmodified >= $file_life) && !in_array($f, $farray)){
deldirectory($f);
}
}
I need a little bit of help. I need to write a script that will look through all directories and sub-directories and delete specific extensions that are modified after specific time. I can get it to delete files from specific path, but I need the script to search inside sub directories. Is there any way to do that?
I have tried this for files but I have no idea on how to make it work with directories and sub directories
$path = '/path/to/file/';
if ($handle = opendir($path)) {
while (false !== ($file = readdir($handle))) {
$filelastmodified = filemtime($path . $file);
if( $filelastmodified > "MY TIME STAMP" )
{
unlink($path . $file);
}
echo "deleted";
}
closedir($handle);
}
Create a recursive function, if it finds a folder it calls itself passing the folder name.
I'm trying to list all PHP files in a specified directory and for it to recursively check all sub-directories until it finds no more, there could be numerous levels.
The function I have below works fine with the exception that it only recurses down one level.
I've spent hours trying to see where I'm going wrong, I'm calling the scanFiles() when it finds a new directory but this only seems to work one level down and stop, any help greatly appreciated.
Updated:
function scanFiles($pParentDirectory)
{
$vFileArray = scandir($pParentDirectory);
$vDirectories = array();
foreach ($vFileArray as $vKey => $vValue)
{
if (!in_array($vValue, array('.', '..')) && (strpos($vValue, '.php') || is_dir($vValue)))
{
if (!is_dir($vValue))
$vDirectories[] = $vValue;
else
{
$vDirectory = $vValue;
$vSubFiles = scanFiles($vDirectory);
foreach ($vSubFiles as $vKey => $vValue)
$vDirectories[] = $vDirectory.DIRECTORY_SEPARATOR.$vValue;
}
}
}
return $vDirectories;
}
You can do this easily like this:
// helper function
function getFiles(&$files, $dir) {
$items = glob($dir . "/*");
foreach ($items as $item) {
if (is_dir($item)) {
getFiles($files, $item);
} else {
if (end(explode('.', $item)) == 'php') {
$files[] = basename($item);
}
}
}
}
// usage
$files = array();
getFiles($files, "myDir");
// debug
var_dump($files);
myDir looks like this: has php files in all dirs
Output:
P.S. if you want the function to return the full path to the found .php files, remove the basename() from this line:
$files[] = basename($item);
This will then produce result like this:
hope this helps.
This is because $vDirectory is just a folder name, so scanDir looks in the current folder for it, not the sub folder.
What you want to do is to pass in the path to the folder, not just the name. This should be as simple as changing your recursive call to scanFiles($pParentDirectory . DIRECTORY_SEPARATOR . $vDirectory)
Your main problem is functions like scanDir or isDir need the full file path to work.
If you pass the full file path to them, it should work correctly.
$value can = a folder structure to the language file. Example: languages/english.php
$value can also = the files name. Example: english.php
So I need to get the current folder that $value is in and delete the folder ONLY if there are no other files/folders within that directory (after deleting the actual file as I am doing already, ofcourse).
foreach($module['languages'] as $lang => $langFile)
{
foreach ($langFile as $type => $value)
{
#unlink($module_path . '/' . $value);
// Now I need to delete the folder ONLY if there are no other directories inside the folder where it is currently at.
// And ONLY if there are NO OTHER files within that folder also.
}
}
How can I do this?? And wondering if this can be done without using a while loop, since a while loop within a foreach loop could take some time, and need this to be as quick as possible.
And just FYI, the $module_path should never be deleted. So if $value = english.php, it should never delete the $module_path. Ofcourse, there will always be another file in there, so checking for this is not necessary, but won't hurt either way.
Thanks guys :)
EDIT
Ok, now I'm using this code here and it is NOT working, it is not removing the folders or the files, and I don't get any errors either... so not sure what the problem is here:
foreach($module['languages'] as $lang => $langFile)
{
foreach ($langFile as $type => $value)
{
if (#unlink($module_path . '/' . $value))
#rmdir(dirname($module_path . '/' . $value));
}
}
NEVERMIND, this works a CHARM!!! Cheers Everyone!!
The easyest way is try to use rmdir. This don't delete folder if it is not empty
rmdir($module_path);
also you can check is folder empty by
if(count(glob($module_path.'*'))<3)//delete
2 for . and ..
UPD: as I reviewed maybe you should replace $module_path by dirname($module_path.'.'.$value);
Since the directory you care about might be part of the $value, you need to use dirname to figure out what the parent directory is, you can't just assume that it's $module_path.
$file_path = $module_path . '/' . $value;
if (#unlink($file_path)) {
#rmdir(dirname($file_path));
}
if (is_file($value)) {
unlink($value);
} else if (is_dir($value)) {
if (count(scandir($value)) == 2) }
unlink($value)
}
}
http://php.net/manual/en/function.is-dir.php
http://www.php.net/manual/en/function.scandir.php
The code below will take a path, check if it is a file (i.e. not a directory). If it is a file, it will extract the directory name, then delete the file, then iterate over the dir and count the files in it, if the files are zero it'll delete the dir.
Code is as an example and should work, however privileges and environment setup may result in it not working.
<?php
if(!is_dir ( string $filename )){ //if it is a file
$fileDir = dirname ( $filename );
if ($handle = opendir($fileDir)) {
echo "Directory handle: $handle\n";
echo "Files:\n";
$numFiles=0;
//delete the file
unlink($myFile);
//Loop the dir and count the file in it
while (false !== ($file = readdir($handle))) {
$numFiles = $numFiles + 1;
}
if($numFiles == 0) {
//delete the dir
rmdir($fileDir);
}
closedir($handle);
}
}
?>