Delete folder and all files on FTP connection - php

Trying to add the ability to delete a Folder using FTP and all subfolders and files contained within that folder.
I have built a recursive function to do so, and I feel like the logic is right, but still doesnt work.
I did some testing, I am able to delete on first run if the path is just an empty folder or just a file, but can't delete if it is a folder containing one file or a folder containing one empty subfolder. So it seems to be a problem with traversing through the folder(s) and using the function to delete.
Any ideas?
function ftpDelete($directory)
{
if(empty($directory))//Validate that a directory was sent, otherwise will delete ALL files/folders
return json_encode(false);
else{
global $conn_id;
# here we attempt to delete the file/directory
if( !(#ftp_rmdir($conn_id,$directory) || #ftp_delete($conn_id,$directory)) )
{
# if the attempt to delete fails, get the file listing
$filelist = #ftp_nlist($conn_id, $directory);
# loop through the file list and recursively delete the FILE in the list
foreach($filelist as $file)
ftpDelete($file);
#if the file list is empty, delete the DIRECTORY we passed
ftpDelete($directory);
}
else
return json_encode(true);
}
};

I took some time to write my own version of a recursive delete function over ftp, this one should be fully functional (I tested it myself).
Try it out and modify it to fit your needs, if it's still not working there are other problems. Have you checked the permissions on the files you are trying to delete?
function ftp_rdel ($handle, $path) {
if (#ftp_delete ($handle, $path) === false) {
if ($children = #ftp_nlist ($handle, $path)) {
foreach ($children as $p)
ftp_rdel ($handle, $p);
}
#ftp_rmdir ($handle, $path);
}
}

Ok found my problem. Since I wasn't moving into the exact directory I was trying to delete, the path for each recursive file being called wasn't absolute:
function ftpDeleteDirectory($directory)
{
global $conn_id;
if(empty($directory))//Validate that a directory was sent, otherwise will delete ALL files/folders
return json_encode(false);
else{
# here we attempt to delete the file/directory
if( !(#ftp_rmdir($conn_id,$directory) || #ftp_delete($conn_id,$directory)) )
{
# if the attempt to delete fails, get the file listing
$filelist = #ftp_nlist($conn_id, $directory);
# loop through the file list and recursively delete the FILE in the list
foreach($filelist as $file)
{
// return json_encode($filelist);
ftpDeleteDirectory($directory.'/'.$file);/***THIS IS WHERE I MUST RESEND ABSOLUTE PATH TO FILE***/
}
#if the file list is empty, delete the DIRECTORY we passed
ftpDeleteDirectory($directory);
}
}
return json_encode(true);
};

function recursiveDelete($handle, $directory)
{ echo $handle;
# here we attempt to delete the file/directory
if( !(#ftp_rmdir($handle, $directory) || #ftp_delete($handle, $directory)) )
{
# if the attempt to delete fails, get the file listing
$filelist = #ftp_nlist($handle, $directory);
// var_dump($filelist);exit;
# loop through the file list and recursively delete the FILE in the list
foreach($filelist as $file) {
recursiveDelete($handle, $file);
}
recursiveDelete($handle, $directory);
}
}

You have to check (using ftp_chdir) for every "file" you get from ftp_nlist to check if it is a directory:
foreach($filelist as $file)
{
$inDir = #ftp_chdir($conn_id, $file);
ftpDelete($file)
if ($inDir) #ftp_cdup($conn_id);
}
This easy trick will work, because if ftp_chdir works, the current $file is actually a folder, and you've moved into it. Then you call ftpDelete recursively, to let it delete the files in that folder. Afterwards, you move back (ftp_cdup) to continue.

Related

How can I use this function?

function ftpDeleteDirectory($directory)
{
global $conn_id;
if(empty($directory))//Validate that a directory was sent, otherwise will delete ALL files/folders
return json_encode(false);
else{
# here we attempt to delete the file/directory
if( !(#ftp_rmdir($conn_id,$directory) || #ftp_delete($conn_id,$directory)) )
{
# if the attempt to delete fails, get the file listing
$filelist = #ftp_nlist($conn_id, $directory);
# loop through the file list and recursively delete the FILE in the list
foreach($filelist as $file)
{
// return json_encode($filelist);
ftpDeleteDirectory($directory.'/'.$file);/***THIS IS WHERE I MUST RESEND ABSOLUTE PATH TO FILE***/
}
#if the file list is empty, delete the DIRECTORY we passed
ftpDeleteDirectory($directory);
}
}
return json_encode(true);
};
How can I use this function written about ftp?
Trying to add the ability to delete a Folder using FTP and all subfolders and files contained within that folder.

How to make rmdir() not leave "unaccessible" folder behind?

I'm using rmdir() within PHP on Windows to recursively delete a folder structure. It deletes all the contents of the folder fine, but leaves the base folder in an "unaccessible" state. I still have to delete that folder manually, even though the system says it can't be found. Somehow the act of "deleting" reminds the OS that it needs to actually remove it.
Here's my code with sources commented in:
function rrmdir($dir)
{
// Taken from:
// https://stackoverflow.com/a/3338133/6674014
if(is_dir($dir))
{
$objects = scandir($dir);
foreach($objects as $object)
{
if($object != "." && $object != "..")
{
if(is_dir($dir."/".$object))
$this->rrmdir($dir."/".$object);
else
{
// Added modification from comment attached to:
// https://stackoverflow.com/a/12148318/6674014
$objPath = $dir.'/'.$object;
chmod($objPath, 999);
unlink($objPath);
}
}
}
rmdir($dir);
}
}
I've also used the $handle method, as well as the Folder Iterator Thing. These have also not worked.
And here's the error when I double-click the ghost folder:
How can this problem be fixed? Is it my code or OS that's messing up?

Delete all files in one directory with Codeigniter

I've got one problem when I want to delete all files in one directory with Codeigniter..
I've been watching and trying from any tutorials, and just having one problem.. It always can't delete any files.
here's my script :
#view
Delete All File
#controller
public function delete_allfile()
{
$files = glob($_SERVER['DOCUMENT_ROOT'].'upload/perizinan/*'); // get all file names
if(is_dir($path))
{
$this->session->set_flashdata('message',
'
Wrong directory !
');
redirect('sia/perizinan');
}else
{
foreach($files as $file)
{ // iterate files
if(is_file($file))
unlink($file); // delete file
}
redirect('sia/perizinan');
}
}
Try using Codeigniter's file helper for deleting files. It does exactly what you're trying to do. Of course it won't work if the permissions are wrong on the folder (It requires the permission: rwxrwxrwx (0777)), but it makes for a bit cleaner and easier to debug code.
In the controller's constructor add:
$this->load->helper('file');
And replace:
foreach($files as $file)
{ // iterate files
if(is_file($file))
unlink($file); // delete file
}
with
delete_files('./path/to/directory/');
Or if you want to include subfolders recursvively
delete_files('./path/to/directory/', TRUE);
This deletes ALL files in the folder/subfolders so if you want more control you're better off doing it with unlink so you can decide what to delete.
Do you get any error message on the page or in the log file? Have you checked the folder/ files permissions? You can use the chmod and fileperms functions
It's Simple and Easy.. You can Try this.
$files = glob('/home/xxx/public_html/project_name/application/*');
foreach($files as $file){
if(is_file($file))
unlink($file);
}
It will probably work, I have used
$this->load->helper('directory');
$this->load->helper("file");
$dir_fiels = directory_map('resources/captcha/');
$len = sizeOf($dir_fiels);
for($i=0; $i<$len;$i++){
unlink('resources/captcha/'.$dir_fiels[$i]);
}

Deleting A Specific FIle WIth Filename From All Sub-directories In PHP

Suppose there's a directory in which there are numerous sub-directories. Now how can I scan all the subdirectories to find a file with name, say, abc.php and delete this file wherever its is found.
I tried doing something like this -
$oAllSubDirectories = scandir(getcwd());
foreach ($oAllSubDirectories as $oSubDirectory)
{
//Delete code here
}
But this code doesn't check directories inside the subdirectories. Any idea how can I do this ?
In general, you put the code inside a function and make it recursive: when it encounters a directory it calls itself in order to process its contents. Something like this:
function processDirectoryTree($path) {
foreach (scandir($path) as $file) {
$thisPath = $path.DIRECTORY_SEPARATOR.$file;
if (is_dir($thisPath) && trim($thisPath, '.') !== '') {
// it's a directory, call ourself recursively
processDirectoryTree($thisPath);
}
else {
// it's a file, do whatever you want with it
}
}
}
In this particular case you don't need to do that because PHP offers the ready-made RecursiveDirectoryIterator that does this automatically:
$it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(getcdw()));
while($it->valid()) {
if ($it->getFilename() == 'abc.php') {
unlink($it->getPathname());
}
$it->next();
}

How to Delete ALL .txt files From a Directory using PHP

Im trying to Delete ALL Text files from a directory using a php script.
Here is what I have tried.....
<?php array_map('unlink', glob("/paste/*.txt")); ?>
I dont get an Error when I run this, yet It doesnt do the job.
Is there a snippet for this? Im not sure what else to try.
Your Implementation works all you need to do is use Use full PATH
Example
$fullPath = __DIR__ . "/test/" ;
array_map('unlink', glob( "$fullPath*.log"))
I expanded the submitted answers a little bit so that you can flexibly and recursively unlink text files located underneath as it's often the case.
// #param string Target directory
// #param string Target file extension
// #return boolean True on success, False on failure
function unlink_recursive($dir_name, $ext) {
// Exit if there's no such directory
if (!file_exists($dir_name)) {
return false;
}
// Open the target directory
$dir_handle = dir($dir_name);
// Take entries in the directory one at a time
while (false !== ($entry = $dir_handle->read())) {
if ($entry == '.' || $entry == '..') {
continue;
}
$abs_name = "$dir_name/$entry";
if (is_file($abs_name) && preg_match("/^.+\.$ext$/", $entry)) {
if (unlink($abs_name)) {
continue;
}
return false;
}
// Recurse on the children if the current entry happens to be a "directory"
if (is_dir($abs_name) || is_link($abs_name)) {
unlink_recursive($abs_name, $ext);
}
}
$dir_handle->close();
return true;
}
You could modify the method below but be careful. Make sure you have permissions to delete files. If all else fails, send an exec command and let linux do it
static function getFiles($directory) {
$looper = new RecursiveDirectoryIterator($directory);
foreach (new RecursiveIteratorIterator($looper) as $filename => $cur) {
$ext = trim($cur->getExtension());
if($ext=="txt"){
// remove file:
}
}
return $out;
}
i have modified submitted answers and made my own version,
in which i have made function which will iterate recursively in current directory and its all child level directories,
and it will unlink all the files with extension of .txt or whatever .[extension] you want to remove from all the directories, sub-directories and its all child level directories.
i have used :
glob() From the php doc:
The glob() function searches for all the pathnames matching pattern
according to the rules used by the libc glob() function, which is
similar to the rules used by common shells.
i have used GLOB_ONLYDIR flag because it will iterate through only directories, so it will be easier to get only directories and unlink the desired files from that directory.
<?php
//extension of files you want to remove.
$remove_ext = 'txt';
//remove desired extension files in current directory
array_map('unlink', glob("./*.$remove_ext"));
// below function will remove desired extensions files from all the directories recursively.
function removeRecursive($directory, $ext) {
array_map('unlink', glob("$directory/*.$ext"));
foreach (glob("$directory/*",GLOB_ONLYDIR) as $dir) {
removeRecursive($dir, $ext);
}
return true;
}
//traverse through all the directories in current directory
foreach (glob('./*',GLOB_ONLYDIR) as $dir) {
removeRecursive($dir, $remove_ext);
}
?>
For anyone who wonder how to delete (for example: All PDF files under public directory) you can do this:
array_map('unlink', glob( public_path('*.pdf')));

Categories