You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP实现远程FTP大文件夹清理、重排及跨FTP传输方案问询

Alright, let's tackle this complex FTP file processing workflow with PHP. I'll walk you through a step-by-step, efficient solution that handles large nested folders (50MB–4GB) while hitting all your requirements:

1. Initialize FTP Connections & Local Temporary Storage

First, we need to establish connections to both FTP servers and set up a local temporary directory to work with the files—processing large files directly in memory isn't feasible.

// FTP1 (source server) credentials
$ftp1Host = 'ftp1.example.com';
$ftp1User = 'your-ftp1-username';
$ftp1Pass = 'your-ftp1-password';

// Target FTP server credentials
$targetFtpHost = 'target-ftp.example.com';
$targetFtpUser = 'your-target-username';
$targetFtpPass = 'your-target-password';

// Create a unique temporary local directory
$tempDir = sys_get_temp_dir() . '/ftp_process_' . uniqid();
mkdir($tempDir, 0777, true);

// Connect to source FTP
$ftp1Conn = ftp_connect($ftp1Host);
ftp_login($ftp1Conn, $ftp1User, $ftp1Pass);
ftp_pasv($ftp1Conn, true); // Enable passive mode for better firewall compatibility

// Connect to target FTP
$targetFtpConn = ftp_connect($targetFtpHost);
ftp_login($targetFtpConn, $targetFtpUser, $targetFtpPass);
ftp_pasv($targetFtpConn, true);
2. Download Entire Folder from FTP1

We'll use a recursive function to download all files and subdirectories from the source FTP. This handles the complex folder structure seamlessly:

function downloadFtpDirectory($ftpConn, $remoteDir, $localDir) {
    $files = ftp_nlist($ftpConn, $remoteDir);
    
    foreach ($files as $file) {
        // Skip "." and ".." entries
        if (in_array(basename($file), ['.', '..'])) continue;
        
        $localPath = $localDir . '/' . basename($file);
        
        // Check if it's a directory
        if (ftp_chdir($ftpConn, $file)) {
            ftp_chdir($ftpConn, '..'); // Go back to parent
            mkdir($localPath, 0777, true);
            downloadFtpDirectory($ftpConn, $file, $localPath);
        } else {
            // Download the file in binary mode to preserve integrity
            ftp_get($ftpConn, $localPath, $file, FTP_BINARY);
        }
    }
}

// Start downloading from the source FTP's target folder (adjust path as needed)
$remoteRoot = '/path/to/source/folder';
downloadFtpDirectory($ftp1Conn, $remoteRoot, $tempDir);
3. Clean Up Non-Necessary Files & Flatten the Directory

Next, we'll delete all .exe, .pdf, and other unwanted files, then move all remaining files to the root of our temporary directory to flatten the nested structure:

// Define unwanted file extensions
$unwantedExts = ['exe', 'pdf'];

function processLocalFiles($dir, $targetRoot, $unwantedExts) {
    $items = scandir($dir);
    
    foreach ($items as $item) {
        if (in_array($item, ['.', '..'])) continue;
        
        $fullPath = $dir . '/' . $item;
        
        if (is_dir($fullPath)) {
            processLocalFiles($fullPath, $targetRoot, $unwantedExts);
            // Delete empty directory after processing its contents
            rmdir($fullPath);
        } else {
            $ext = strtolower(pathinfo($fullPath, PATHINFO_EXTENSION));
            
            // Delete unwanted files
            if (in_array($ext, $unwantedExts)) {
                unlink($fullPath);
                continue;
            }
            
            // Move file to root, handle duplicates by appending a counter
            $targetPath = $targetRoot . '/' . basename($fullPath);
            $counter = 1;
            while (file_exists($targetPath)) {
                $filename = pathinfo($fullPath, PATHINFO_FILENAME);
                $targetPath = $targetRoot . "/{$filename}_{$counter}.{$ext}";
                $counter++;
            }
            rename($fullPath, $targetPath);
        }
    }
}

processLocalFiles($tempDir, $tempDir, $unwantedExts);
4. Reorganize Files into Preset Directory Structure

Now we'll sort the flattened files into your predefined directory structure. For example, let's use a common structure based on file types:

// Define your preset directory structure and associated extensions
$presetStructure = [
    'docs' => ['txt', 'docx', 'doc', 'odt'],
    'images' => ['jpg', 'jpeg', 'png', 'gif', 'svg'],
    'data' => ['csv', 'json', 'xml', 'xlsx']
];

// Create preset directories if they don't exist
foreach (array_keys($presetStructure) as $dir) {
    $presetDir = $tempDir . '/' . $dir;
    if (!is_dir($presetDir)) mkdir($presetDir, 0777, true);
}

// Move files to their respective directories
$files = scandir($tempDir);
foreach ($files as $file) {
    if (in_array($file, ['.', '..']) || is_dir($tempDir . '/' . $file)) continue;
    
    $ext = strtolower(pathinfo($file, PATHINFO_EXTENSION));
    $moved = false;
    
    foreach ($presetStructure as $dir => $exts) {
        if (in_array($ext, $exts)) {
            rename($tempDir . '/' . $file, $tempDir . '/' . $dir . '/' . $file);
            $moved = true;
            break;
        }
    }
    
    // Optional: Handle uncategorized files by moving to a "misc" folder
    if (!$moved) {
        $miscDir = $tempDir . '/misc';
        if (!is_dir($miscDir)) mkdir($miscDir, 0777, true);
        rename($tempDir . '/' . $file, $miscDir . '/' . $file);
    }
}
5. Upload Processed Files to Target FTP

Finally, we'll upload the reorganized directory to the target FTP server using another recursive function:

function uploadFtpDirectory($ftpConn, $localDir, $remoteDir) {
    // Create remote directory if it doesn't exist
    if (!@ftp_chdir($ftpConn, $remoteDir)) {
        ftp_mkdir($ftpConn, $remoteDir);
        ftp_chdir($ftpConn, $remoteDir);
    }
    
    $items = scandir($localDir);
    
    foreach ($items as $item) {
        if (in_array($item, ['.', '..'])) continue;
        
        $localPath = $localDir . '/' . $item;
        $remotePath = $remoteDir . '/' . $item;
        
        if (is_dir($localPath)) {
            uploadFtpDirectory($ftpConn, $localPath, $remotePath);
        } else {
            ftp_put($ftpConn, $remotePath, $localPath, FTP_BINARY);
        }
    }
}

// Upload to target FTP's destination folder (adjust path as needed)
$targetRemoteRoot = '/path/to/target/folder';
uploadFtpDirectory($targetFtpConn, $tempDir, $targetRemoteRoot);
6. Clean Up Local Resources

Don't forget to clean up the temporary directory and close FTP connections to free up resources:

// Close FTP connections
ftp_close($ftp1Conn);
ftp_close($targetFtpConn);

// Delete temporary directory and all contents
function deleteDirectory($dir) {
    $items = scandir($dir);
    foreach ($items as $item) {
        if (in_array($item, ['.', '..'])) continue;
        $path = $dir . '/' . $item;
        is_dir($path) ? deleteDirectory($path) : unlink($path);
    }
    rmdir($dir);
}
deleteDirectory($tempDir);

Key Notes for Production Use

  • Timeout Settings: Increase FTP timeout for large files with ftp_set_option($ftpConn, FTP_TIMEOUT_SEC, 300);
  • Error Handling: Add try/catch blocks and check return values of all FTP/file functions to log errors properly
  • Memory & Disk Space: Ensure your server has enough disk space to handle the largest 4GB folder
  • Filename Encoding: Use ftp_raw($ftpConn, 'OPTS UTF8 ON'); if your FTP servers use UTF-8 filenames to avoid garbled text
  • Performance: For extremely large folders, consider processing files in batches to avoid overwhelming the server

内容的提问来源于stack exchange,提问作者Atnaize

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:30:30