PHP Conference Japan 2024

FTP 函数

目录

  • ftp_alloc — 分配要上传的文件的空间
  • ftp_append — 将文件内容追加到 FTP 服务器上的另一个文件
  • ftp_cdup — 更改到父目录
  • ftp_chdir — 更改 FTP 服务器上的当前目录
  • ftp_chmod — 通过 FTP 设置文件权限
  • ftp_close — 关闭 FTP 连接
  • ftp_connect — 打开 FTP 连接
  • ftp_delete — 删除 FTP 服务器上的文件
  • ftp_exec — 请求在 FTP 服务器上执行命令
  • ftp_fget — 从 FTP 服务器下载文件并保存到打开的文件中
  • ftp_fput — 将打开的文件上传到 FTP 服务器
  • ftp_get — 从 FTP 服务器下载文件
  • ftp_get_option — 检索当前 FTP 连接的各种运行时行为
  • ftp_login — 登录到 FTP 连接
  • ftp_mdtm — 返回给定文件的上次修改时间
  • ftp_mkdir — 创建目录
  • ftp_mlsd — 返回给定目录中的文件列表
  • ftp_nb_continue — 继续检索/发送文件(非阻塞)
  • ftp_nb_fget — 从 FTP 服务器检索文件并将其写入打开的文件(非阻塞)
  • ftp_nb_fput — 将文件从打开的文件存储到 FTP 服务器(非阻塞)
  • ftp_nb_get — 从 FTP 服务器检索文件并将其写入本地文件(非阻塞)
  • ftp_nb_put — 将文件存储到 FTP 服务器(非阻塞)
  • ftp_nlist — 返回给定目录中的文件列表
  • ftp_pasv — 打开或关闭被动模式
  • ftp_put — 将文件上传到 FTP 服务器
  • ftp_pwd — 返回当前目录名称
  • ftp_quit — ftp_close 的别名
  • ftp_raw — 将任意命令发送到 FTP 服务器
  • ftp_rawlist — 返回给定目录中的详细文件列表
  • ftp_rename — 重命名 FTP 服务器上的文件或目录
  • ftp_rmdir — 删除目录
  • ftp_set_option — 设置各种运行时 FTP 选项
  • ftp_site — 将 SITE 命令发送到服务器
  • ftp_size — 返回给定文件的大小
  • ftp_ssl_connect — 打开安全的 SSL-FTP 连接
  • ftp_systype — 返回远程 FTP 服务器的系统类型标识符
添加注释

用户贡献的注释 16 条注释

4
nicklas at programmera dot nu
18 年前
我不太喜欢我的 FTP 程序,因为我每次重新启动客户端时都必须重新设置所有设置,所以我为简单的 FTP 上传制作了这个脚本,它作为 CLI 应用程序运行。



<?php

//如果 STDIN 未定义,则定义它
if (!defined("STDIN"))
{

define("STDIN", fopen("php://stdin", "r"));

}

echo
"FTP 文件上传器\r\n\r\n";

echo
"服务器: ";

//使用 trim() 处理所有 fgets 获取的结果,因为它似乎会添加一个 \n
$server = trim(fgets(STDIN));

echo
"用户名: ";

$username = trim(fgets(STDIN));

echo
"密码: ";

$password = trim(fgets(STDIN));

$connect = ftp_connect($server);
$login = ftp_login($connect, $username, $password);

if ((!
$connect) || (!$login))
{

exit(
"登录失败。\r\n");

}

echo
"已连接\r\n";

echo
"PASV (Y/任意键 = 关闭): ";

if(
trim(fgets(STDIN)) == "Y")
{

//启用被动模式
ftp_pasv($connect, true);

echo
"PASV: 开启\r\n";

}
else
{

echo
"PASV: 关闭\r\n";

}

$showContent = ftp_nlist($connect, "");

echo
"列出内容:\r\n";

var_dump($showContent);

echo
"要上传的文件: ";

$file = trim(fgets(STDIN));

//输入 "exit;" 退出上传过程
if ($file == "exit;")
{

exit;

}

//使用 "$file, $file" 因为文件不应该重命名,如果它是二进制文件,则将最后一个参数更改为 FTP_BINARY
$upload = ftp_put($connect, $file, $file, FTP_ASCII);

if (!
$upload)
{

exit(
"上传失败。\r\n");

}
else
{

echo
"文件 \"" . $file . "\" 上传成功!:) \r\n\"" . $file . "\" 的大小: " . filesize($file) / 1024 ."kb。\r\n";
echo
"我的工作完成了,再见。\r\n";

}

ftp_close($connect);

?>
3
[email protected] (Chris Gray)
18 年前
在寻找“完全可用”的 FTP 上传脚本时,我最终通过使用网络上找到的许多不同脚本,完成了这个脚本。如果您找到更好的方法,请告诉我。谢谢,并享受!

<?php
if(isset($_POST['SubmitFile'])){
$myFile = $_FILES['txt_file']; // 将文件信息存储到数组中。
$file = $myFile['tmp_name']; // 将数组转换为包含服务器上文件路径名的字符串。

$myFileName = basename($_POST['txt_fileName']); // 从文件路径中获取文件名

$destination_file = "/".$myFileName; // 您希望将文件放置在 Web 服务器上的位置(相对于您的登录目录)

// 连接设置
$ftp_server = "127.0.0.1"; // FTP 服务器地址。
$ftp_user_name = "您的用户名"; // 用户名
$ftp_user_pass = "您的密码"; // 密码

$conn_id = ftp_connect($ftp_server); // 建立基本连接
$login_result = ftp_login($conn_id, $ftp_user_name, $ftp_user_pass) or die("<h2>您无权访问此 FTP 服务器!</h2>"); // 使用用户名和密码登录,或显示无效用户消息
if ((!$conn_id) || (!$login_result)) { // 检查连接
// 由于 ftp_login 上的 die 调用,永远不会到达这里
echo "FTP 连接失败! <br />";
echo
"尝试连接到 $ftp_server,用户 $ftp_user_name";
exit;
} else {
// echo "已连接到 $ftp_server,用户 $ftp_user_name <br />";
}

$upload = ftp_put($conn_id, $destination_file, $file, FTP_BINARY); // 上传文件
if (!$upload) { // 检查上传状态
echo "<h2>FTP 上传 $myFileName 失败!</h2> <br />";
} else {
echo
"上传 $myFileName 完成!<br /><br />";
}

ftp_close($conn_id); // 关闭 FTP 流
}
?>

<html>
<head>

</head>
<body>
<form enctype="multipart/form-data" action="<?php echo $_SERVER['PHP_SELF'];?>" method="POST">
请选择文件: <input name="txt_file" type="file" id="txt_file" tabindex="1" size="35" onChange="txt_fileName.value=txt_file.value" />
<input name="txt_fileName" type="hidden" id="txt_fileName" tabindex="99" size="1" />

<input type="submit" name="SubmitFile" value="上传文件" accesskey="ENTER" tabindex="2" />
</form>
</body>
<html>
2
[email protected]
17 年前
我花了几个小时才解决这个问题。它基于下面的代码,我刚刚添加了一个字符串替换来将 Windows 给出的路径名转换为 Unix 路径名。希望它能为某些人节省一些时间。享受!(此外,还包括删除文件的功能:))

<?php
$myFile
= $_FILES['file']; // 将文件信息存储到数组中。
$file = $myFile['tmp_name']; // 将数组转换为包含服务器上文件路径的新字符串。
$myFileName = $_POST['MyFile']; // 获取文件路径和文件名
$myfile_replace = str_replace('\\', '/', $myFileName); // 将路径转换为 Unix 格式
$myfile = basename($myfile_replace); // 从路径中提取文件名
$destination_file = "/".$myfile; // 您希望将文件上传到的 Web 服务器位置(相对于您的登录目录)
// 连接设置
$ftp_server = "127.0.0.1"; // FTP 服务器地址(省略 ftp://)
$ftp_user_name = ""; // 用户名
$ftp_user_pass = ""; // 密码
$conn_id = ftp_connect($ftp_server); // 建立基本连接
// 使用用户名和密码登录,或显示无效用户消息
$login_result = ftp_login($conn_id, $ftp_user_name, $ftp_user_pass) or die("<h1>您没有访问此 FTP 服务器的权限!</h1>");
$upload = ftp_put($conn_id, $destination_file, $file, FTP_BINARY); // 上传文件
if (!$upload) { // 检查上传状态
echo "<h2>FTP 上传 $myFileName 失败!</h2> <br />";
}
/*
// 尝试删除 $file
if (ftp_delete($conn_id, $destination_file)) {
echo "$destination_file 已删除!\n";
} else {
echo "无法删除 $destination_file!\n";
}
*/
ftp_close($conn_id); // 关闭 FTP 流
}
?>
<form name="form" enctype="multipart/form-data" action="<?php echo $_SERVER['PHP_SELF']; ?>" method="POST" >
请选择文件: <input type="file" name="file" accept="text/plain" onChange="MyFile.value=file.value">
<input name="MyFile" type="hidden" id="MyFile" tabindex="99" size="1" />
<input type="submit" name="submit" value="上传" style="vertical-align:middle"/><br/><br/>
</form>
1
ras "at" fyn {dot} dk
17 年前
缺少一个获取远程文件并返回其内容(而不是保存到本地文件)的功能 - 这里就是它

function ftp_fetch($ftp_stream, $remote_file) {
ob_end_flush();
ob_start();
$out = fopen('php://output', 'w');
if (!ftp_fget($ftp_stream, $out, $remote_file, FTP_ASCII)) die('无法获取文件:' . $remote_file);
fclose($out);
$data = ob_get_clean();
return $data;
}

它的工作原理与 ftp_get() 相同,但返回远程文件的内容 - 例如

$ftp = ftp_connect('my.server.com', 21, 60);
ftp_login($ftp, 'username', 'password');
$data = ftp_fetch($ftp, 'path/to/remote.file');
echo $data;

注意,我用它来从服务器获取文本文件 - 如果您需要获取二进制文件,请将 FTP_ASCII 更改为 FTP_BINARY .. 但大多数情况下,将文件获取到内存中仅适用于较小的文件,例如纯文本、xml 等。
0
dickiedyce at uk dot com
19 年前
对于其他人来说,这似乎是显而易见的,但它让我困惑了近一个小时!如果您能够连接到 FTP 站点,但某些功能(list、put、get 等)无法正常工作,请尝试使用 ftp_pasv 并打开被动模式。

<?php

// 在此处之前设置 $host 和 $file 变量以适合您的设置。

$hostip = gethostbyname($host);
$conn_id = ftp_connect($hostip);

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

// 重要!打开被动模式
ftp_pasv ( $conn_id, true );

if ((!
$conn_id) || (!$login_result)) {
echo
"FTP 连接失败!";
echo
"尝试连接到 $host 的用户 $ftp_user_name";
die;
} else {
echo
"已连接到 $host,用户 $ftp_user_name<br>";
echo
"主机 IP 为 $hostip<br>";

// 上传文件
if (ftp_put($conn_id, $remote_file, $file, FTP_ASCII)) {
echo
"已成功上传 $file<br>";
} else {
echo
"上传 $file 时出现问题<br>";
}

// 关闭连接
ftp_close($conn_id);
}
?>
0
postmaster at alishomepage dot com
20 年前
我编写了一个开源的 ZIP2FTP 接口,它实际上获取给定的 ZIP 文件并在您指定的 FTP 服务器上的文件夹中解压缩它...

因此,对于您对 FTP 感兴趣的人来说,它可能很有趣,它的地址是 http://zip2ftp.alishomepage.com;那些直接需要源代码的人可以访问 http://zip2ftp.alishomepage.com/?do=getSource
0
Vikrant Korde <vakorde at hotmail dot com>
21 年前
<?

//如果您想将文件夹层次结构从当前服务器移动或复制到另一个远程服务器。那么这将很有帮助,因为它将浏览当前服务器的目录,同时也将该文件复制到远程服务器上的同一目录中。

//此脚本将通过 FTP 将此目录和子目录中的所有文件复制到另一个远程服务器

function rec_copy ($source_path, $destination_path, $con)
{
ftp_mkdir($con, $destination_path);
ftp_site($con, 'CHMOD 0777 '.$destination_path);
ftp_chdir($con,$destination_path);

if (is_dir($source_path))
{
chdir($source_path);
$handle=opendir('.');
while (($file = readdir($handle))!==false)
{
if (($file != ".") && ($file != ".."))
{
if (is_dir($file))
{
// 在这里,我限制了文件夹名称“propertyimages”不被复制到远程服务器。 -- VK
if($file != "propertyimages")
{
rec_copy ($source_path."/".$file, $file, $con);
chdir($source_path);
ftp_cdup($con);
}
}
if (is_file($file))
{
$fp = fopen($file,"r");
// 这将把空格转换为下划线,以便不会引发错误。 -- VK
ftp_fput ($con, str_replace(" ", "_", $file), $fp,FTP_BINARY);
ftp_site($con, 'CHMOD 0755 '.str_replace(" ", "_", $file));
}
}
}
closedir($handle);
}
}

// 建立 FTP 连接 --VK
$con = ftp_connect("69.18.213.131",21);
$login_result = ftp_login($con,"username","password");

// 这是远程服务器的根路径 -- VK
$rootpath = "mainwebsite_html";

// 这是源目录的物理路径。实际上,您也可以使用相对路径。 -- VK
$sourcepath = realpath("../")."/resdesk";

// 此目录名称只会更改最顶层的目录,而不是内部目录 -- VK
$destination_dir_name = "resdesk_".$account_id."/";

rec_copy ($sourcepath, $destination_dir_name, $con);
if (function_exists("ftp_close"))
{
ftp_close($con);
}
?>
0
NOSPAMkent at ioflux dot NOSPAM dot com
22年前
我认为有些其他帖子试图表达的内容可能需要澄清,那就是在 PHP 4.2.3 中,ftp_connect("myhost.com") 大部分时间都会失败,除了它每隔几分钟就会工作一次。

解决方法是 ftp_connect 似乎在解析地址时存在错误。如果您执行以下操作

$hostip = gethostbyname($host);
$conn_id = ftp_connect($hostip);

它似乎解决了问题。
(其他用户提到了 ftpbuf() 错误……不确定那是什么,但这应该可以解决。)
-1
Kristy Christie (kristy at isp7 dot net)
20 年前
这是一个我创建的小函数,用于递归遍历本地目录并将整个内容上传到远程 FTP 服务器。

在这个例子中,我试图将位于 /home/kristy/scripts/iwm 的整个 "iwm" 目录通过 FTP 复制到远程服务器的 /public_html/test/。

唯一的问题是,对于 "if (!ftp_chdir($ftpc,$ftproot.$srcrela))" 这行代码,我用它来检查目录是否已存在于远程服务器上,如果不存在,它会输出一条关于无法更改到该目录的警告。

但是错误处理程序应该可以处理它。

感谢发布了在目录中检索文件列表的代码片段的人。

对于在递归和上传过程中回显其进度的脚本版本,请访问:http://pastebin.com/73784

<?php

// --------------------------------------------------------------------
// 触发器
// --------------------------------------------------------------------

// 设置各种变量
$ftproot = "/public_html/test/";
$srcroot = "/home/kristy/scripts/";
$srcrela = "iwm/";

// 连接到目标 FTP 并进入本地和远程的相应目录
$ftpc = ftp_connect("ftp.mydomain.com");
$ftpr = ftp_login($ftpc,"username","password");

if ((!
$ftpc) || (!$ftpr)) { echo "FTP 连接未建立!"; die(); }
if (!
chdir($srcroot)) { echo "无法进入本地源根目录。"; die(); }
if (!
ftp_chdir($ftpc,$ftproot)) { echo "无法进入 FTP 根目录。"; die(); }

// 开始递归通过 FTP 上传目录
ftpRec ($srcrela);

// 关闭 FTP 连接
ftp_close($ftpc);

// --------------------------------------------------------------------
// 实际函数
// --------------------------------------------------------------------
function ftpRec ($srcrela)
{
global
$srcroot;
global
$ftproot;
global
$ftpc;
global
$ftpr;

// 进入要递归遍历的本地目录
chdir($srcroot.$srcrela);

// 检查目录是否存在并在目标上切换到该目录
if (!ftp_chdir($ftpc,$ftproot.$srcrela))
{
// 远程目录不存在,因此创建并进入它
ftp_mkdir ($ftpc,$ftproot.$srcrela);
ftp_chdir ($ftpc,$ftproot.$srcrela);
}

if (
$handle = opendir("."))
{
while (
false !== ($fil = readdir($handle)))
{
if (
$fil != "." && $fil != "..")
{
// 检查它是文件还是目录
if (!is_dir($fil))
{
// 它是文件,因此上传它
ftp_put($ftpc, $ftproot.$srcrela.$fil, $fil, FTP_BINARY);
}
else
{
// 它是目录,因此递归遍历它
if ($fil == "templates")
{
// 我希望脚本忽略任何名为“templates”的目录
// 因此,不递归遍历它们并上传其内容
}
else
{
ftpRec ($srcrela.$fil."/");
chdir ("../");
}
}
}
}
closedir($handle);
}
}
?>
-1
spam at kacke dot de
16年前
这是一个支持大多数命令的 FTP 抽象类。

它还可以通过使用 stream_crypto_enable() 在 TLS、SSLv2 等上工作。

http://kacke.de/php_samples/source.php?f=ftp.cls.php

经过这么多年,非常感谢 WEZ。

Toppi
-1
leonardo at rol dot com dot ro
19 年前
这是一个将远程 ftp 结构下载到本地服务器的示例,对于将站点从一个服务器迁移到另一个服务器很有用,尤其是在您升级 ensim 时;)

http://leonardo.rol.ro/ftpleech.txt
-4
sven at cartell-network dot de
22年前
通过代理连接到 ftp 服务器

$ftp_server = "proxy"; 例如 123.456.789.10
$ftp_user_name = "username@ftpserver"; 例如 [email protected]
$ftp_user_pass = "password";

$conn_id = ftp_connect($ftp_server, 2121);
$login_result = ftp_login( $conn_id, $ftp_user_name, $ftp_user_pass );
-2
postmaster at alishomepage dot com
21 年前
这是另一个通过 PHP 的 FTP 界面(也使用 MySQL)

http://myftp.alishomepage.com

PS:此脚本还允许您下载其源代码……因此对于您程序员来说也变得有趣:D
-3
arjen at queek dot nl
20 年前
如果您更喜欢对 FTP 函数使用面向对象的方法,您可以使用此代码片段(仅限 PHP5!并且会增加一些开销)。这只是一个“启动”,可以根据需要扩展/改进……
您可以将所有 ftp_* 函数传递给您的对象并剥离函数名称的 ftp_。此外,您不必将 ftp 资源作为第一个参数传递。

例如
<?php
ftp_delete
($ftp, $file); // 其中 $ftp 是您的 ftp 资源
?>

可以变成
<?php
$ftp
->delete($file); // 其中 $ftp 是您的 FTP 对象
?>

代码
<?php

class FTP {

private
$ftp;

/* public Void __construct(): 构造函数 */
public function __construct($host, $port = 21, $timeout = 90) {
$this->ftp = ftp_connect($host, $port, $timeout);
}

/* public Void __destruct(): 析构函数 */
public function __destruct() {
@
ftp_close($this->ftp);
}

/* public Mixed __call(): 将所有函数调用重定向到PHP函数 */
public function __call($function, $arguments) {
// 将ftp资源预添加到参数数组
array_unshift($arguments, $this->ftp);

// 调用PHP函数
return call_user_func_array('ftp_' . $function, $arguments);
}

}

?>
-4
breese at pipetech dot tv
17 年前
我修复了以下上传脚本,使其适用于Windows上传(并更新了一些语法)。我还为那些不使用PHP 5.2的用户添加了一个Javascript“进度指示器”。

<?php
if(isset($_POST['start_upload']) && $_FILES['txt_file']['name'] != ""){

$local_file = $_FILES['txt_file']['tmp_name']; // 定义要上传的本地文件名称

$destination_file = "/".basename($_FILES['txt_file']['name']); // 文件上传路径(相对于您的登录目录)

// 全局连接设置
$ftp_server = "127.0.0.1"; // FTP服务器地址(不包括 ftp://)
$ftp_user_name = "username"; // FTP服务器用户名
$ftp_user_pass = "password"; // 密码

// 连接到FTP服务器
$conn_id = ftp_connect($ftp_server);
// 登录到FTP服务器
$login_result = ftp_login($conn_id, $ftp_user_name, $ftp_user_pass);

// 验证登录状态
if ((!$conn_id) || (!$login_result)) {
echo
"FTP连接失败! <br />";
echo
"尝试连接到 $ftp_server 用户 $ftp_user_name";
exit;
} else {
echo
"已连接到 $ftp_server,用户 $ftp_user_name <br />";
}

$upload = ftp_put($conn_id, $destination_file, $local_file, FTP_BINARY); // 上传文件

// 验证上传状态
if (!$upload) {
echo
"<h2>FTP上传 ".$_FILES['txt_file']['name']." 失败!</h2><br /><br />";
} else {
echo
"成功!<br />" . $_FILES['txt_file']['name'] . " 已上传到 " . $ftp_server . $destination_file . "!<br /><br />";
}

ftp_close($conn_id); // 关闭FTP连接
}
?>

<html>
<head>
<script type="text/javascript">
window.onload = function() {
document.getElementById("progress").style.visibility = "hidden";
document.getElementById("prog_text").style.visibility = "hidden";
}

function dispProgress() {
document.getElementById("progress").style.visibility = "visible";
document.getElementById("prog_text").style.visibility = "visible";
}

</script>

</head>
<body>
<form action="<?php echo $_SERVER['PHP_SELF'];?>" method="POST" enctype="multipart/form-data">
请选择一个文件: <input name="txt_file" type="file" size="35" />
<input type="submit" name="start_upload" value="上传文件" onClick="dispProgress()" />
</form>

<!-- 进度文件链接:有关动画gif,请参阅 http://www.ajaxload.info/ -->
<img id="progress" src="http://www.your.site/images/progress.gif" />
<p id="prog_text" style="display:inline;"> 上传已开始!</p>

</body>
<html>
-3
magic2lantern at mail dot ru
18 年前
这是一个我编写的简单脚本,允许用户
在控制台中运行它并从FTP服务器获取树状结构。

<?php
$argv
= $_SERVER["argv"];
$argv = array_slice($argv,1);
if (
getenv("HTTP_HOST")) {exit("仅供bash执行!");}
if ((empty(
$argv[0])) || (empty($argv[1]))) {exit("用法:thisscript.php 10.0.0.10 /games/Arcade/
其中10.0.0.10是FTP服务器,/games/Arcade是FTP上的起始路径\n"
);}

// 连接到ftp服务器
$connect_id = ftp_connect($argv[0]);
// 登录服务器
if ($connect_id) { $login_result = ftp_login($connect_id, 'anonymous', 'JustForFun'); }
// 检查连接
if ((!$connect_id) || (!$login_result)) {
echo
"无法连接远程FTP服务器!\n";
exit;
}
function
ftp_get_dir ($ftp_dir) {
global
$connect_id;
$ftp_contents = ftp_nlist ($connect_id, $ftp_dir);
for (
$myCounter_for_server_elements = 0; !empty ($ftp_contents[$myCounter_for_server_elements]);
$myCounter_for_server_elements++)
{
// 获取当前目录中的元素列表
echo $argv[0] . $ftp_dir . $ftp_contents[$myCounter_for_server_elements] . "\n";
ftp_get_dir ($ftp_dir . $ftp_contents[$myCounter_for_server_elements] . '/');
}
}
ftp_get_dir ($argv[1]);
// 关闭连接
ftp_close($connect_id);
?>
To Top