ftp_get

(PHP 4, PHP 5, PHP 7, PHP 8)

ftp_get从 FTP 服务器下载文件

描述

ftp_get(
    FTP\Connection $ftp,
    string $local_filename,
    string $remote_filename,
    int $mode = FTP_BINARY,
    int $offset = 0
): bool

ftp_get() 从 FTP 服务器检索远程文件,并将其保存到本地文件。

参数

ftp

一个 FTP\Connection 实例。

local_filename

本地文件路径(如果文件已存在,将被覆盖)。

remote_filename

远程文件路径。

mode

传输模式。必须是 FTP_ASCIIFTP_BINARY

offset

从远程文件中开始下载的位置。

返回值

成功时返回 true,失败时返回 false

变更日志

版本 描述
8.1.0 现在 ftp 参数需要一个 FTP\Connection 实例;以前需要一个 资源
7.3.0 mode 参数现在是可选的。以前它是必须的。

示例

示例 #1 ftp_get() 示例

<?php

// 定义一些变量
$local_file = 'local.zip';
$server_file = 'server.zip';

// 设置基本连接
$ftp = ftp_connect($ftp_server);

// 使用用户名和密码登录
$login_result = ftp_login($ftp, $ftp_user_name, $ftp_user_pass);

// 尝试下载 $server_file 并保存到 $local_file
if (ftp_get($ftp, $local_file, $server_file, FTP_BINARY)) {
echo
"成功写入 $local_file\n";
} else {
echo
"出现问题\n";
}

// 关闭连接
ftp_close($ftp);

?>

参见

  • ftp_pasv() - 打开或关闭被动模式
  • ftp_fget() - 从 FTP 服务器下载文件并保存到打开的文件
  • ftp_nb_get() - 从 FTP 服务器检索文件并将其写入本地文件(非阻塞)
  • ftp_nb_fget() - 从 FTP 服务器检索文件并将其写入打开的文件(非阻塞)

添加注释

用户贡献的注释 18 个注释

36
CuDi
14 年前
我今天尝试从我的 Web 服务器上通过 FTP 传输一个 7 MB 的文件。

我直接复制了这个示例,它告诉我。

端口命令成功
"出现问题"

我以为是大小的原因。
但我猜可能是我的防火墙造成的。

所以,我将 FTP 连接设置为被动模式

<?PHP

...
$login_result = ftp_login($conn_id, $ftp_user_name, $ftp_user_pass);
ftp_pasv($conn_id, true);

?>

再次运行脚本,它正常工作。

希望这对某些人有所帮助
36
bob at notallhere dot com
11 年前
不想使用中间文件?使用 'php://output' 作为文件名,然后使用输出缓冲捕获输出。

ob_start();
$result = ftp_get($ftp, "php://output", $file, FTP_BINARY);
$data = ob_get_contents();
ob_end_clean();

不要忘记检查 $result 以确保没有错误。之后,您可以根据需要操作 $data 变量。
14
ramiro at qusarcr dot com
21 年前
请记住,如果您的本地机器上存在同名文件,ftp_get 将覆盖该文件。
9
anomie at users dot sf dot net
17 年前
我不知道为什么没有 "ftp_get_contents" 函数。模拟一个需要一些工作,但这是可以做到的。
<?php
函数 ftp_get_contents($ftp_stream, $remote_file, $mode, $resume_pos=null){
$pipes=stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP);
如果(
$pipes===false) 返回 false;
如果(!
stream_set_blocking($pipes[1], 0)){
fclose($pipes[0]); fclose($pipes[1]);
返回
false;
}
$fail=false;
$data='';
如果(
is_null($resume_pos)){
$ret=ftp_nb_fget($ftp_stream, $pipes[0], $remote_file, $mode);
} 否则 {
$ret=ftp_nb_fget($ftp_stream, $pipes[0], $remote_file, $mode, $resume_pos);
}
循环(
$ret==FTP_MOREDATA){
循环(!
$fail && !feof($pipes[1])){
$r=fread($pipes[1], 8192);
如果(
$r==='') 中断循环;
如果(
$r===false){ $fail=true; 中断循环; }
$data.=$r;
}
$ret=ftp_nb_continue($ftp_stream);
}
循环(!
$fail && !feof($pipes[1])){
$r=fread($pipes[1], 8192);
如果(
$r==='') 中断循环;
如果(
$r===false){ $fail=true; 中断循环; }
$data.=$r;
}
fclose($pipes[0]); fclose($pipes[1]);
如果(
$fail || $ret!=FTP_FINISHED) 返回 false;
返回
$data;
}
?>

类似的方法也可以用来写一个ftp_put_contents函数。
4
来自ruggfamily.com的Nate
15年前
这里有一个快速函数,可以根据文件的扩展名来确定要使用的正确模式。

<?php
函数 get_ftp_mode($file)
{
$path_parts = pathinfo($file);

如果 (!isset(
$path_parts['extension'])) 返回 FTP_BINARY;
switch (
strtolower($path_parts['extension'])) {
case
'am':case 'asp':case 'bat':case 'c':case 'cfm':case 'cgi':case 'conf':
case
'cpp':case 'css':case 'dhtml':case 'diz':case 'h':case 'hpp':case 'htm':
case
'html':case 'in':case 'inc':case 'js':case 'm4':case 'mak':case 'nfs':
case
'nsi':case 'pas':case 'patch':case 'php':case 'php3':case 'php4':case 'php5':
case
'phtml':case 'pl':case 'po':case 'py':case 'qmail':case 'sh':case 'shtml':
case
'sql':case 'tcl':case 'tpl':case 'txt':case 'vbs':case 'xml':case 'xrc':
返回
FTP_ASCII;
}
返回
FTP_BINARY;
}

// 示例用法
ftp_get($conn_id, $local_file, $server_file, get_ftp_mode($server_file));
?>
7
gmx.net上的mroerick
15年前
ftp_sync 是一种遍历服务器目录结构并将每个目录和文件复制到本地相同位置的方法。

<?php
$ftp_server
= "ftp.example.com";
$conn_id = ftp_connect ($ftp_server)
或 die(
"无法连接到 $ftp_server");

$login_result = ftp_login($conn_id, "user", "pass");
如果 ((!
$conn_id) || (!$login_result))
die(
"FTP连接失败");

ftp_sync ("DirectoryToCopy"); // 如果您在当前目录中,请使用 "."

ftp_close($conn_id);

// ftp_sync - 复制目录和文件结构
函数 ftp_sync ($dir) {

全局
$conn_id;

如果 (
$dir != ".") {
如果 (
ftp_chdir($conn_id, $dir) == false) {
echo (
"更改目录失败: $dir<BR>\r\n");
返回;
}
如果 (!(
is_dir($dir)))
mkdir($dir);
chdir ($dir);
}

$contents = ftp_nlist($conn_id, ".");
遍历 (
$contents 作为 $file) {

如果 (
$file == '.' || $file == '..')
继续;

如果 (@
ftp_chdir($conn_id, $file)) {
ftp_chdir ($conn_id, "..");
ftp_sync ($file);
}
否则
ftp_get($conn_id, $file, $file, FTP_BINARY);
}

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

}
?>
1
Aditya P. Bhatt ([email protected])
16年前
<?php
// 定义一些变量
$folder_path = "您的文件夹路径";
$local_file = "本地文件路径";
$server_file = "服务器文件路径";

//-- 连接设置
$ftp_server = "IP 地址"; // FTP 服务器地址。
$ftp_user_name = "用户名"; // 用户名
$ftp_user_pass = "密码"; // 密码
#$destination_file = "FILEPATH";

// 建立基本连接
$conn_id = ftp_connect($ftp_server);

// 使用用户名和密码登录
$login_result = ftp_login($conn_id, $ftp_user_name, $ftp_user_pass);

// 尝试下载 $server_file 并保存到 $local_file
if (ftp_get($conn_id, $local_file, $server_file, FTP_BINARY)) {
echo
"成功写入到 $local_file\n";
} else {
echo
"出现问题\n";
}

// 关闭连接
ftp_close($conn_id);
?>
0
mpatnode at yahoo dot com
6 年前
请注意,PHP 默认情况下仍然使用 FTP 主动模式,自防火墙出现以来,主动模式几乎不再使用。不要忘记在您的 ftp_login 后添加 ftp_pasv($conn, true)。
0
anomie at users dot sf dot net
17 年前
糟糕。_nb_ 仅指从 FTP 服务器读取,而套接字对中的缓冲区只有大约 364 字节。因此,它不适用于大于该大小的文件。
0
thivierr at telus dot net
20 年前
如果您之前下载过文件(例如一个巨大的 Web 日志),并且只想获取剩余部分,请执行以下操作:

$local_file_size = filesize($local_file_path);
$get_result = ftp_get($conn_id, $local_file_path, $remote_file_path, FTP_BINARY, $local_file_size);

无论本地文件是否已存在,这段代码都可以正常工作。您应该首先测试以确保本地文件的大小不超过远程文件的大小。
-1
administrator at gesoft dot org
18 年前
大家好,

如果有人尝试将文件下载到同一个本地文件(某个临时文件),就像这里所示:

<?php
foreach ($files as $key=>$path) {
...
$result = ftp_get($ftpConnId, 'temp.tmp', $path, FTP_BINARY);
...
}
?>

请注意,您将遇到下载(获取)完整文件的重大问题。换句话说,'temp.tmp' 文件的大小始终将与第一个下载的文件的大小相同,而不管实际下载的文件大小如何。我不知道原因是什么!

如果有人认为问题仅仅在于获取正确的文件大小(可以使用 filssize() 函数获取),那么他们就错了。下载文件的大小在物理上并不等于源文件的大小,这意味着 fflush() 函数无法解决问题(我也尝试过)。

最终,找到了解决方案:在下载文件之前,您需要删除本地文件(如果存在 'temp.tmp')。因此,有效的代码如下:

<?php
foreach ($files as $key=>$path) {
...
if (
file_exists('temp.tmp')) {
unlink('temp.tmp');
}
$result = ftp_get($ftpConnId, 'temp.tmp', $path, FTP_BINARY);
...
}
?>

编写脚本时祝您好运 :-)

维塔利·西姆西夫
-1
miki at epoch dot co dot il
11 年前
如果您运行了示例并发现它在 90 秒后失败(超时)。

然后尝试添加
<?php
ftp_pasv
($ftp_conn, true);
?>
-2
corey-holzer at nyc dot rr dot com
20 年前
零大小文件并非副作用。当 ftp_get 开始时,它首先要做的是创建 inode/文件,它将向该文件流式传输数据,而该文件是一个具有您为本地文件指定名称的零大小文件。当下载失败时,它会将文件保留在原位。
-7
Ben Parish
12 年前
在 Windows(以及可能 *NIX)上,如果您指定的 local_file 路径包含尚不存在的目录路径,您将收到 "[function.ftp-get]: failed to open stream: No such file or directory in..." 错误。

即使拥有写入权限,ftp_get 也可以创建文件,但它不会像您预期的那样自动创建父目录。
-3
scott dot chu at udngroup dot com
7 年前
我建议使用 ftp_fget() 而不是 ftp_get(),因为后者只返回 TRUE 或 FALSE,并且没有明显的方法来获取失败的原因。

使用 ftp_fget,您必须将文件句柄作为本地文件传递,因此您必须先执行 fopen()。通过这种方式,您可以在调用 fopen() 时发现“权限被拒绝”问题。如果您使用 ftp_get(),则无法找到此错误原因。

在我的例子中,我使用“nobody”运行 httpd,并使用“haha”创建 FTP 本地文件夹。由于当时我使用了 ftp_get(),因此我花了很长时间才找到“权限被拒绝”问题。
-13
w dot danford at electronics-software dot com
15年前
ftp_get() 函数的一个细微问题。第二个参数,字符串 $local_file,是运行 PHP 脚本的服务器上的文件名。它不是运行浏览器的客户端计算机上的文件。我错误地尝试使用此 FTP 从我的网站下载文件到我的本地系统。我在运行 WIN XP 的系统上输入了以驱动器号开头的完整路径(“h:/...”),并一直收到无法打开(目标)文件的错误。只有在只输入文件名而不包含路径之后,我才看到文件被写入的位置。它位于我的网站上 PHP 脚本所在的目录中(托管是支持多个 URL 的托管共享 LAMP 服务器,GoDaddy 托管)。
-11
danny at ingeniarte dot com
13 年前
请记住,要使用您正在处理的目录的完整服务器路径。服务器路径与“FTP 路径”不同。

我一直使用我的 FTP 客户端显示的路径来下载和上传文件,并一直收到“未找到”或“权限被拒绝”错误。
-6
apurvavora19 at gmail dot com
6 年前
我使用 ftp_get 函数从 FTP 服务器下载文件到我的 Web 服务器,我的 PHP 脚本正在该服务器上运行。
在 Web 服务器上,我希望文件下载到以下结构的目录中 -> Data/Files/localfilename.exe

但是,当我在 ftp_get 的 $local_file_name 参数中指定上述字符串时,我收到一个错误,提示文件不存在。

我运行的是 Windows Server,并且 PHP 脚本从 C:/xampp/htdocs/file.php 运行。

有没有什么方法可以指定 Web 服务器上文件应下载到的路径?
To Top