Удаление всех каталогов в FTP-архиве с определенным именем с использованием PHP - PullRequest
1 голос
/ 09 ноября 2008

Как можно было бы удалить все каталоги в дереве каталогов с определенным именем, если единственный доступ к серверу доступен через FTP?

Чтобы уточнить, я хотел бы перебрать дерево каталогов и удалить каждый каталог, имя которого соответствует определенной строке через FTP. Было бы неплохо реализовать это в PHP - с чего мне начать? Кроме того, если кто-нибудь знает какие-либо утилиты, которые бы уже делали это, это было бы замечательно.

Ответы [ 3 ]

4 голосов
/ 09 ноября 2008

Вот отправная точка - функция, которая сканирует каталог FTP и печатает имя любого каталога в дереве, которое соответствует шаблону. Я проверил это кратко.

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);
            }
        } 
    }
}

Тогда сделай что-нибудь подобное

$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/');

К сожалению, вы можете удалить только пустой каталог с помощью ftp_rmdir(), но если вы посмотрите здесь , есть функция с именем ftp_rmAll(), которую вы можете использовать для удаления целых структур каталогов, которые вы найдете.

Кроме того, я тестировал только в Unix прием использования состояния сбоя, возвращаемого из ftp_size(), в качестве метода проверки, является ли элемент, возвращаемый ftp_nlist(), каталогом.

1 голос
/ 09 ноября 2008

Предположительно, в этом вопросе больше, чем кажется на первый взгляд.

FTP поддерживает DIR для просмотра содержимого каталогов, RMDIR для удаления каталогов и DEL для удаления файлов, поэтому он поддерживает необходимые операции.

Или вы спрашиваете, как перебирать дерево каталогов FTP?

У вас есть предпочитаемый / необходимый язык реализации для этого?

0 голосов
/ 16 ноября 2008

Ну, это сценарий, который я в итоге использовал. Это довольно специфический случай, когда нужно было бы использовать это, но если вы находитесь в том же затруднительном положении, в котором я находился, просто введите свой адрес ftp-сервера, имя пользователя, пароль, имя папки, которую вы хотите удалить, и путь к файлу. папка для запуска, и она будет перебирать каталог, удаляя все папки, которые соответствуют имени. Существует ошибка при переподключении, если соединение с сервером разорвано, поэтому вам может потребоваться запустить сценарий снова, если он отключится.


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;
}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...