我想使用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 ("..");
}
答案 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
在脚本的同一目录中。