如何使用FTP和PHP从远程主机下载文件夹?
我有用户名和密码以及要下载的文件夹... copy()?
让我知道,谢谢!
答案 0 :(得分:12)
<?php
$ftp_server = "ftp.example.com";
$conn_id = ftp_connect ($ftp_server)
or die("Couldn't connect to $ftp_server");
$login_result = ftp_login($conn_id, "user", "pass");
if ((!$conn_id) || (!$login_result))
die("FTP Connection Failed");
ftp_sync ("DirectoryToCopy"); // Use "." if you are in the current directory
ftp_close($conn_id);
// ftp_sync - Copy directory and file structure
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 ("..");
}
?>
答案 1 :(得分:2)
你有这些选择:
ftp wrapper:
$handle = opendir('ftp://user:password@host/path/to/dir') || die();
while (false !== ($file = readdir($handle))) {
if(is_file($file)){
$c = file_get_contents($file);
file_put_contents('/local/'.basename($file), $c);
}
}
closedir($handle);
使用php的ftp扩展
$c = ftp_connect('picasse.com');
ftp_login($c, 'file', 'password');
ftp_chdir($c, '/remote/dir');
$contents = ftp_nlist($c, '-la .');
foreach($contents as $line){
$file = preg_split('@\s+@', trim($line));
$name = $file[8];
$size = $file[4];
$mode = $file[0];
if(substr($mode, 0, 1) == '-'){
//file
$fd = fopen('/local/path/'.$name, 'w');
ftp_fget ($c, $fd, $name, FTP_BINARY);
fclose($fd);
}else{
//dir
}
}
使用外部程序,如wget或lftp
lftp -c commands.txt#其中commands.txt类似于:
connect user:password@ftp.host.com
mget /path/to/remote /path/to/local
答案 2 :(得分:1)
以递归方式复制远程SFTP服务器上的文件和文件夹(如果local_path以斜杠上传文件夹内容结束,否则上传文件夹本身)
Ftp::upload_dir($server, $user, $password, $local_path, $remote_path, $port = 22);
从远程FTP服务器下载目录(如果remote_dir以斜杠下载文件夹内容结束,否则下载文件夹本身)
Ftp::download_dir($server, $user, $password, $remote_dir, $local_dir,
$ port = 22);
对于这里的代码,但是你需要整个类来实现小实用程序函数的依赖。
/**
* Download a directory from remote FTP server
*
* If remote_dir ends with a slash download folder content
* otherwise download folder itself
*
* @param string $server
* @param string $user
* @param string $password
* @param string $remote_dir
* @param string $local_dir
* @param int $port
*
* @return bool $downloaded
*
*/
public static function download_dir($server, $user, $password, $remote_dir, $local_dir, $port = 21)
{
$downloaded = false;
try
{
if(is_dir($local_dir) && is_writable($local_dir))
{
if(false !== $cid = Ftp::login($server, $user, $password, $port))
{
# If remote_dir do not ends with /
if(!HString::ends_with($remote_dir, '/'))
{
# Create fisrt level directory on local filesystem
$local_dir = rtrim($local_dir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . basename($remote_dir);
mkdir($local_dir);
}
# Remove trailing slash
$local_dir = rtrim($local_dir, DIRECTORY_SEPARATOR);
$downloaded = Ftp::download_all($cid, $remote_dir, $local_dir);
ftp_close($cid);
}
}
else
{
throw new Exception("Local directory does not exist or is not writable", 1);
}
}
catch(Exception $e)
{
error_log("Ftp::download_dir : " . $e->getMessage());
}
return $downloaded;
}
/**
* Recursive function to download remote files
*
* @param ressource $cid
* @param string $remote_dir
* @param string $local_dir
*
* @return bool $download_all
*
*/
private static function download_all($cid, $remote_dir, $local_dir)
{
$download_all = false;
try
{
if(Ftp::is_dir($remote_dir, $cid))
{
$files = ftp_nlist($cid, $remote_dir);
if($files!==false)
{
$to_download = 0;
$downloaded = 0;
# do this for each file in the remote directory
foreach ($files as $file)
{
# To prevent an infinite loop
if ($file != "." && $file != "..")
{
$to_download++;
# do the following if it is a directory
if (Ftp::is_dir($file, $cid))// $remote_dir . DIRECTORY_SEPARATOR .
{
# Create directory on local filesystem
mkdir($local_dir . DIRECTORY_SEPARATOR . basename($file));
# Recursive part
if(Ftp::download_all($cid, $file, $local_dir . DIRECTORY_SEPARATOR . basename($file)))
{
$downloaded++;
}
}
else
{
# Download files
if(ftp_get($cid, $local_dir . DIRECTORY_SEPARATOR . basename($file), $file, FTP_BINARY))
{
$downloaded++;
}
}
}
}
# Check all files and folders have been downloaded
if($to_download===$downloaded)
{
$download_all = true;
}
}
}
}
catch(Exception $e)
{
error_log("Ftp::download_all : " . $e->getMessage());
}
return $download_all;
}
答案 3 :(得分:0)
答案 4 :(得分:0)
改进的功能(来自@Treffynnon)
<?php
$ftp_server = "ftp.xxx.com";
$cid = ftp_connect($ftp_server)
or die("Couldn't connect to $ftp_server");
$login_result = ftp_login($cid, "user", "pass");
if ((!$cid) || (!$login_result))
die("FTP Connection Failed");
ftp_pasv($cid, true); // passive FTP connection (comment-out if needed)
ftp_sync('/folder_on_ftp/www/', '/folder_on_new_server/www');
ftp_close($cid);
umask(0); // every directory will be chmod 777
function ftp_sync($_from = null, $_to = null) {
global $cid;
if (isset($_from)) {
if (!ftp_chdir($cid, $_from)) die("Dir on FTP not found: $_from");
if (isset($_to)) {
if (!is_dir($_to)) @mkdir($_to);
if (!chdir($_to)) die("Dir on local not exists? $_to");
}
}
$contents = ftp_mlsd($cid, '.');
foreach ($contents as $p) {
if ($p['type'] != 'dir' && $p['type'] != 'file') continue;
$file = $p['name'];
echo ftp_pwd($cid).'/'.$file;
if (file_exists($file) && !is_dir($file) && filemtime($file) >= strtotime($p['modify'])) {
echo " [EXISTS AND CURRENT]";
}
elseif ($p['type'] == 'file' && @ftp_get($cid, $file, $file, FTP_BINARY)) {
echo " [COPIED]";
}
elseif ($p['type'] == 'dir' && @ftp_chdir($cid, $file)) {
echo "Dir changed to $file<br>\n";
if (!is_dir($file)) mkdir($file);
chdir($file);
ftp_sync();
ftp_chdir($cid, '..');
chdir('..');
}
echo "<br>\n";
}
}