Remove all directories in FTP archive with a specific name using PHP

How can you delete all directories in a directory tree with a specific name if the server is only accessible via FTP?

To clarify, I would like to loop through the directory tree and delete every directory whose name matches a specific string via FTP. A way to implement this in PHP would be nice - where should I start? Also, if anyone knows of any utilities that would already do this, that would be great.

+1


source to share


3 answers


Here's a starting point - a function that will scan through an FTP directory and print the name of any directory in the tree that matches the pattern. I checked it out for a little while.

function scan_ftp_dir($conn, $dir, $pattern) {
    $files = ftp_nlist($conn, $dir);
    if (!$files) {
        return;
    }

    foreach ($files as $file) {
        //the quickest way i can think of to check if is a directory
        if (ftp_size($conn, $file) == -1) {

            //get just the directory name
            $dirName = substr($file, strrpos($file, '/') + 1);

            if (preg_match($pattern, $dirName)) {
                echo $file . ' matched pattern';
            } else {        
                //directory didn't match pattern, recurse   
                scan_ftp_dir($conn, $file, $pattern);
            }
        } 
    }
}

      

Then do something like this



$host = 'localhost';
$user = 'user';
$pass = 'pass';


if (false === ($conn = ftp_connect($host))) {
    die ('cannot connect');
}

if (!ftp_login($conn, $user, $pass)) die ('cannot authenticate');


scan_ftp_dir($conn, '.', '/^beginswith/');

      

Unfortunately, you can only delete an empty directory with help ftp_rmdir()

, but if you look here , there is a function ftp_rmAll()

that you can use to remove entire directory structures that you find.

Also I only tested the Unix trick of using the abandon status returned from ftp_size()

as a method of checking if an item returned by a ftp_nlist()

directory is.

+4


source


Presumably there is more to this question than before.

FTP supports DIR to display directory contents, RMDIR to delete directories, and DEL to delete files, so it supports the operations you need.



Or are you asking how to iterate over your FTP directory tree?

Do you have a preferred / required implementation language for this?

+1


source


Well, this is the script I ended up using. This is a pretty specific instance where one would need to use this, but if you are in the same predicament as me, just enter the ftp server address, username, password, the name of the folders you want to delete, and the path folder to run, and this will navigate to the directory, deleting all folders matching the name. There is a reconnect error if the connection to the server is broken, so you may need to run the script again if it disconnects.


if( $argc == 2 ) {
        $directoryToSearch = $argv[1];
        $host = '';
        $username = '';
        $password = '';
        $connection = connect( $host, $username, $password );
        deleteDirectoriesWithName( $connection, 'directoryToDelete', $directoryToSearch );
        ftp_close( $connection );
        exit( 0 );
}
else {
        cliPrint( "This script currently only supports 1 argument.\n");
        cliPrint( "Usage: php deleteDirectories.php directoryNameToSearch\n");
        exit( 1 );
}

/**
 * Recursively traverse directories and files starting with the path
 * passed in and then delete all directories that match the name
 * passed in
 * @param $connection the connection resource to the database.  
 * @param $name the name of the directories that should be * deleted.
 * @param $path the path to start searching from
 */
function deleteDirectoriesWithName( &$connection, $name, $path ) {
        global $host, $username, $password;
        cliPrint( "At path: $path\n" );
        //Get a list of files in the directory
        $list = ftp_nlist( $connection, $path );
        if ( empty( $list ) ) {
                $rawList = ftp_rawlist( $connection, $path );
                if( empty( $rawList ) ) {
                        cliPrint( "Reconnecting\n");
                        ftp_close( $connection );
                        $connection = connect( $host, $username, $password );
                        cliPrint( "Reconnected\n" );
                        deleteDirectoriesWithName( $connection, $name, $path );
                        return true;
                }

                $pathToPass = addSlashToEnd( $path );
                $list = RawlistToNlist( $rawList, $pathToPass );
        }
        //If we have selected a directory, then 'visit' the files (or directories) in the dir
        if ( $list[0] != $path ) {
                $path = addSlashToEnd( $path );
                //iterate through all of the items listed in the directory
                foreach ( $list as $item ) {
                        //if the directory matches the name to be deleted, delete it recursively
                        if ( $item == $name ) {
                                DeleteDirRecursive( $connection, $path . $item );
                        }

                        //otherwise continue traversing
                        else if ( $item != '..' && $item != '.' ) {
                                deleteDirectoriesWithName( $connection, $name, $path . $item );
                        }
                }
        }
        return true;
}

/**
 *Put output to STDOUT
 */
function cliPrint( $string ) {
        fwrite( STDOUT, $string );
}

/**
 *Connect to the ftp server
 */
function connect( $host, $username, $password ) {
        $connection = ftp_connect( $host );
        if ( !$connection ) {
                die('Could not connect to server: ' . $host );
        }
        $loginSuccessful = ftp_login( $connection, $username, $password );
        if ( !$loginSuccessful ) {
                die( 'Could not login as: ' . $username . '@' . $host );
        }
        cliPrint( "Connection successful\n" );
        return $connection;
}

/**
 *    Delete the provided directory and all its contents from the FTP-server.
 *
 *    @param string $path Path to the directory on the FTP-server relative to
 *    the current working directory
 */
function DeleteDirRecursive(&$resource, $path) {
        global $host, $username, $password;
        cliPrint( $path . "\n" );
        $result_message = "";

        //Get a list of files and directories in the current directory
        $list = ftp_nlist($resource, $path);

        if ( empty($list) ) {
                $listToPass = ftp_rawlist( $resource, $path );
                if ( empty( $listToPass ) ) {
                        cliPrint( "Reconnecting\n" );
                        ftp_close( $resource );
                        $resource = connect( $host, $username, $password );
                        $result_message = "Reconnected\n";
                        cliPrint( "Reconnected\n" );
                        $result_message .= DeleteDirRecursive( $resource, $path );
                        return $result_message;
                }
                $list = RawlistToNlist( $listToPass, addSlashToEnd( $path ) );
        }

        //if the current path is a directory, recursively delete the file within and then
        //delete the empty directory
        if ($list[0] != $path) {
                $path = addSlashToEnd( $path );
                foreach ($list as $item) {
                        if ($item != ".." && $item != ".") {
                                $result_message .= DeleteDirRecursive($resource, $path . $item);
                        }
                }
                cliPrint( 'Delete: ' . $path . "\n" );
                if (ftp_rmdir ($resource, $path)) {

                        cliPrint( "Successfully deleted $path\n" );
                } else {

                        cliPrint( "There was a problem deleting $path\n" );
                }
        }
        //otherwise delete the file
        else {
                cliPrint( 'Delete file: ' . $path . "\n" );
                if (ftp_delete ($resource, $path)) {
                        cliPrint( "Successfully deleted $path\n" );
                } else {

                        cliPrint( "There was a problem deleting $path\n" );
                }
        }
        return $result_message;
}

/**
*    Convert a result from ftp_rawlist() to a result of ftp_nlist()
*
*    @param array $rawlist        Result from ftp_rawlist();
*    @param string $path Path to the directory on the FTP-server relative 
*    to the current working directory
*    @return array An array with the paths of the files in the directory
*/
function RawlistToNlist($rawlist, $path) {
        $array = array();
        foreach ($rawlist as $item) {
                $filename = trim(substr($item, 55, strlen($item) - 55));
                if ($filename != "." || $filename != "..") {
                        $array[] = $filename;
                }
        }
        return $array;
}

/**
 *Adds a '/' to the end of the path if it is not already present.
 */
function addSlashToEnd( $path ) {
        $endOfPath = substr( $path, strlen( $path ) - 1, 1 );
        if( $endOfPath == '/' ) {
                $pathEnding = '';
        }
        else {
                $pathEnding = '/';
        }

        return $path . $pathEnding;
}

      

0


source







All Articles