I am using this peice of code:
$target = 'extracted/' . $name[0];
$scan = scandir($target);
To scan the directory of a folder which is used for zip uploads. I want to be able to find all the folders inside my $target
folder so I can delete them and their contents, leaving only the files in the $target
directory.
Once I have returned the contents of the folder, I don't know how to differentiate between the folders and the files to be able to delete the folders.
Also, I have been told that the rmdir()
function can't delete folders which have content inside them, is there any way around this?
Thanks, Ben.
First off, rmdir() cannot delete a folder with contents. If safe mode is disabled you can use the following.
exec("rm -rf folder/");
Also look at is_dir()/is_file() or even better the PHP SPL.
To determine whether or not you have a folder or file use the functions is_dir()
and is_file()
For example:
$path = 'extracted/' . $name[0]; $results = scandir($path); foreach ($results as $result) { if ($result === '.' or $result === '..') continue; if (is_dir($path . '/' . $result)) { //code to use if directory } }
$directories = scandir('images');
foreach($directories as $directory){
if($directory=='.' or $directory=='..' ){
echo 'dot';
}else{
if(is_dir($directory)){
echo $directory .'<br />';
}
}
}
a simpler and perhaps faster version
Better to use DirectoryIterator
$path = 'extracted'; // '.' for current
foreach (new DirectoryIterator($path) as $file) {
if ($file->isDot()) continue;
if ($file->isDir()) {
print $file->getFilename() . '<br />';
}
}
scandir will scan the entire directory, you can manually filter.
but if you are lazy like I am, then use glob
$scan = glob($target."/*",GLOB_ONLYDIR);
and it will output an array of all your directories of your target.
You also wanted to remove items if they were inside that directory. rmdir does not allow you to remove directories containing files. But there is a simple sollution.
array_map('unlink', glob($target.'/*/*'));
array_map('rmdir',glob($target."/*",GLOB_ONLYDIR));
First it will unlink all the files in all sub-directories.
Secondly it will remove all directories, because they contain no files.
If you got sub-sub-directories, then you should add another 2 lines like this:
array_map('unlink', glob($target.'/*/*/*')); //remove sub-sub-files
array_map('rmdir',glob($target."/*/*",GLOB_ONLYDIR)); //remove sub-sub-directories
array_map('unlink', glob($target.'/*/*')); //remove sub-files
array_map('rmdir',glob($target."/*",GLOB_ONLYDIR)); //remove sub-directories
The quick and dirty way:
$folders = glob("<path>/*", GLOB_ONLYDIR);
A more versatile and object-oriented solution, inspired by earlier answers using DirectoryIterator but slightly more concise and general purpose:
$path = '<path>';
$folders = [];
foreach (new \DirectoryIterator($path) as $file)
{
if (!$file->isDot() && $file->isDir())
{
$folders[] = $file;
}
}
To get all the files in all the sub, sub folders
function myfunction($dir){
foreach ($dir as $dirname => $file) {
if(is_dir($file) && $file != '.' && $file != '..' ) {
// echo $file;
$newDir = scandir($file);
myfunction($newDir);
}elseif($file !='.' && $file != '..'){
echo "<br>File name is ---";
echo $file;
}
} // end foreach
} //function ends
$dirpass = scandir($mypath3); // set directory
echo myfunction($dirpass); // pass directory
We will get the result like below (plz ignore file names )
File name is ----->index.PHP
File name is -----> 100000045 Invoices Sales Magento Admin.png
File name is -----> 100000142 Orders Sales Magento Admin(1).png
File name is -----> 100000142 Orders Sales Magento Admin.png
File name is ----->hrc-siberian-tiger-2-jpg_21253111.jpg
File name is ----->images (3rd copy).jpeg
File name is ----->images (4th copy).jpeg
File name is ----->images (5th copy).jpeg
File name is ----->images (another copy).jpeg
File name is ----->images (copy).jpeg
File name is ----->images.jpeg
File name is ----->JPEG_example_JPG_RIP_100.jpg
File name is ----->preload
File name is ----->Stonehenge (3rd copy).jpg
File name is ----->Stonehenge (4th copy).jpg
File name is ----->Stonehenge (5th copy).jpg
File name is ----->Stonehenge (another copy).jpg
File name is ----->Stonehenge (copy).jpg
File name is ----->Stonehenge.jpg
here is one function i used mostly to parse archives and directories
function scan_full_dir($dir,$child=false){
$dir_content_list = scandir($dir);
foreach($dir_content_list as $value)
{
if($value === '.' || $value === '..') {continue;}
// check if we have file
if(is_file($dir.'/'.$value)) {
echo '<br> File Name --> '.$value;
continue;
}
// check if we have directory
if (is_dir($dir.'/'.$value)) {
if(!$child){
echo '<br> parent --> '.$value;
}else{
echo '<br> child of '.$child.' --> '.$value;
}
scan_full_dir($dir.'/'.$value,$value);
}
}
}
output sample
parent --> fonts
File Name --> standard
parent --> steps
child of steps --> pcb
File Name --> .attrlist.sum
File Name --> .profile.sum
File Name --> .stephdr.sum
File Name --> attrlist
child of pcb --> netlists
child of netlists --> cadnet
File Name --> .netlist.sum
File Name --> netlist
File Name --> profile
File Name --> stephdr
// to scan dir
scan_full_dir('path/of/myfolder');
// to scan archive without opening it , supported formats : gz, zip, tar and bz files.
scan_full_dir('phar://uploads/youarchive.zip);