从FTP服务器下载所有内容,没有时间限制

时间:2018-12-23 14:14:08

标签: php ftp

我想使用PHP从FTP服务器下载目录的内容(文件,文件夹和子文件夹)。

我可以使用以下功能做到这一点:

function ftp_sync ($dir) { 

    global $conn_id; 

    if ($dir != ".") { 
        if (ftp_chdir($conn_id, $dir) == false) { 
            echo ("Change Dir Failed: $dir<BR>\r\n"); 
            return; 
        } 
        if (!(is_dir($dir))) 
            mkdir($dir); 
        chdir ($dir); 
    } 

    $contents = ftp_nlist($conn_id, "."); 
    foreach ($contents as $file) { 

        if ($file == '.' || $file == '..') 
            continue; 

        if (@ftp_chdir($conn_id, $file)) { 
            ftp_chdir ($conn_id, ".."); 
            ftp_sync ($file); 
        } 
        else 
            ftp_get($conn_id, $file, $file, FTP_BINARY); 
    } 

    ftp_chdir ($conn_id, ".."); 
    chdir (".."); 

}

来源:https://stackoverflow.com/a/5650503/10349407

但是一段时间后;该脚本在浏览器中超时,因为该文件夹的内容很大,需要花费很长时间。

我尝试设置:

ini_set('max_execution_time', 0);
set_time_limit(0);

但是我仍然在共享主机上,但仍然收到错误Warning: set_time_limit() has been disabled for security reasons

所以,我的问题是:是否可以在上述PHP函数中进行重定向,以便为下载的每个文件启动一个新页面(这是我的建议,以防止超时限制)

像这样的一行:

header("Location: " . __FILE__ . "?file=$file");

应该在其中下载$_GET['file']值的文件,然后再次重定向,依此类推,直到下载完所有内容为止。

编辑: 这是我的尝试,但不起作用:/

function ftp_sync ($dir) { 

    global $conn_id; 

    if( isset($_GET['cd']) ) {
        $dir = $_GET['cd'];
    }

    if ($dir != ".") { 
        if (ftp_chdir($conn_id, $dir) == false) { 
            echo ("Change Dir Failed: $dir<BR>\r\n"); 
            return; 
        } 
        if (!(is_dir($dir))) 
            mkdir($dir); 
        chdir ($dir); 
    } 

    $contents = ftp_nlist($conn_id, "."); 
    foreach ($contents as $file) { 

        if ($file == '.' || $file == '..') 
            continue; 

        if (@ftp_chdir($conn_id, $file)) { 
            ftp_chdir ($conn_id, ".."); 
            ftp_sync ($file); 
            header("refresh:0.5;url=" . "ftp.php" . "?file=$file&cd=" . ftp_pwd($conn_id));
            die();
        } 
        else {
            ftp_get($conn_id, $file, $file, FTP_BINARY); 
        }
    } 

    ftp_chdir ($conn_id, ".."); 
    chdir (".."); 

} 

1 个答案:

答案 0 :(得分:4)

我终于独自完成了!

我所需要的只是一种以递归方式列出FTP服务器的所有内容(文件,目录,子目录)的方法。

我发现了一个很棒的课程:https://www.phpclasses.org/package/7707-PHP-List-recursively-all-files-in-a-FTP-server.html

因此,您要做的就是下载此类并编写我花了几个小时编写的脚本(尽管它是简单的xD)。

<?php
error_reporting(0);
set_time_limit(0);
session_start();

// SETTINGS
$ftp_hostname = "";
$ftp_port = 21;
$ftp_username = "";
$ftp_password = "";
$where_to_download = "."; // Without the last slash!
// ---------------------

// NOTE: If you want to end the current session; go to http://example.com/filename.php?end

if( isset($_GET['end']) ) {
    session_unset();
    session_destroy();
    die("Successfully ended the session.");
}

include("ftpcrawler.php");
$ftpcrawler = new ftpcrawler;
$ftpcrawler->server = "ftp://$ftp_username:$ftp_password@$ftp_hostname:$ftp_port/";
if( !isset($_SESSION['array']) ) {
    $_SESSION['array'] = $ftpcrawler->crawl();
}
if( empty($_SESSION['array']) ) {
    echo "Finished downloading everything , or theres no files to download.";
    session_unset();
    session_destroy();
    die();
}
foreach($_SESSION['array'] as $item) {
    if( $item['type'] == "file" ) {
        $ITEM_DIRECTORY = str_replace($item['name'], "", $item['path']);
    }
    if( $item['type'] == "directory" ) {
        $ITEM_DIRECTORY = $item['path'];
    }
    if (!file_exists($where_to_download . $ITEM_DIRECTORY) && !is_dir($where_to_download . $ITEM_DIRECTORY)) {
        mkdir($where_to_download . $ITEM_DIRECTORY, 0777, TRUE);         
    }
    if( $item['type'] == "file" ) {
        $data = @file_get_contents("ftp://$ftp_username:$ftp_password@$ftp_hostname:$ftp_port" . $item['path']);
        file_put_contents($where_to_download . $item['path'], $data);
    }
    unset($_SESSION['array'][$item['path']]); // Remove the item from the array.
    echo "Downloaded/Created Folder " . $item['path'] . " !";
    header( "refresh:0.2;url=" . basename(__FILE__) );
    die();
}
?>

使用所需名称保存文件,并确保ftpcrawler.php在脚本的同一目录中。