PHP - 检查FTP服务器上是否存在没有SIZE支持的文件

Max*_*Art 8 php ftp

是的,我知道,很难相信这些FTP服务器仍然存在,但它们确实存在.IBM iSeries机器运行此类服务器.

我已经有涉及一个答案ftp_nlistin_array,但正如一些你可能已经猜到了,这是缓慢的,当一个目录中包含了大量的项目.

由于缺乏对SIZE的支持,fopen在读取模式下使用时总是会失败(请记住xFTP包装器不支持),而ftp_size总是返回-1(预期)并且file_exists总是返回false(可能因为它在内部使用SIZE?).

  • ftp_get并且ftp_fget做到这一点,但是如果它存在,他们会下载整个文件.不是很好.一种可能的解决方案是使用ftp_fget传递仅在读取模式下打开的文件的处理程序,并捕获引发的警告.当文件不存在时它会有所不同,但这个解决方案感觉粗鲁,我真的不知道它是否可行(也许有人可以给出一个例子).

  • 另一种解决方案使用ftp_nb_get/ ftp_nb_fget来尝试检索文件.如果函数返回0(FTP_FAILED),则该文件可能不存在.我仍然需要处理一个临时的本地文件,如果FTP_MOREDATA返回(或者无法发出其他FTP命令),它很难关闭并重新打开连接 .

你对此有什么想法吗?

hek*_*mgl 6

SIZE命令不是必需的。您可以简单地使用该函数来实现ftp_nlist()此目的,因为 FTPLIST命令允许传递目录和文件作为其参数。

尽管 PHP 文档没有提到它是在RFC 959(第 32 页)中指定的并且正在运行。这里有一个例子。(谢谢Debian!

$server = 'ftp.us.debian.org';
$port   =  21; 
$user   = 'anonymous';
$pwd    = 'foo@bar.xxx';

$conn = ftp_connect($server);
$ret = ftp_login($conn, $user, $pwd);

foreach(array(
    'debian/README.html',
    'NOT_FOUND.html'
) as $file) {
    $listing = ftp_nlist($conn, $file);
    if(empty($listing)) {
        echo "$file was not found on $server\n";
    } else {
        echo "$file was found on $server\n";
    }
}
Run Code Online (Sandbox Code Playgroud)

或者,表示为函数:

function ftp_file_exists(
    $server,
    $filename,
    $user = 'anonymous' ,
    $pwd = '',
    $port = 21
) {
    $conn = @ftp_connect($server);
    if($conn === FALSE) {
        die("Failed to connect to $server");
    }

    $ret = @ftp_login($conn, $user, $pwd);
    if($ret === FALSE) {
        die("Failed to login at $server");
    }

    $listing = @ftp_nlist($conn, $file);
    if($listing === FALSE) {
        die("Failed to obtain LIST response from $server");
    }

    return !empty($listing);
}
Run Code Online (Sandbox Code Playgroud)

在评论中,有人讨论了结果的有用性和可靠性LIST。让我补充几句……

在服务器上创建文件

请注意,您应该避免依赖以下内容:

if(file_not_exists_on_server($filename)) {
    create_file_on_server($filename);
}
Run Code Online (Sandbox Code Playgroud)

因为该文件可能会在第一个函数和第二个函数之间由另一个客户端创建。虽然这在本地文件系统上也是如此,但在分布式客户端服务器应用程序中更容易发生这种情况,因为与本地文件系统相比,响应时间更长,而且可能有很多甚至是匿名客户端(如上面的示例)

远程创建文件时,我建议在公共可写文件夹中遵循强命名方案,以避免冲突。当遵循这个方案时,就只管写就不用管了。可能发生的最糟糕的事情是您覆盖了其他人意外创建的内容。但谁会/client/id/file_name.txt偶然创造出这样的东西呢?


从服务器下载文件或移动、删除服务器上的文件

当尝试其中一项操作时,不必关心文件在操作之前是否存在。去做就对了。但如果失败了,你需要正确处理错误。