我已经得到了一个涉及ftp_nlist和in_array的答案但是,正如你们中的一些人可能已经猜到的那样,当一个目录包含大量项目时,这很慢.
由于缺少对SIZE的支持,fopen在读取模式下使用时总是会失败(请记住,FTP包装器不支持x),而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命令),它很难关闭并重新打开连接.
你对此有什么想法吗?
虽然缺少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"; } }
或者,表示为一个功能:
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,$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); }
在评论中,讨论了LIST的结果是多么有用和可靠.让我说一些额外的句子……
在服务器上创建文件
请注意,您应该避免依赖以下内容:
if(file_not_exists_on_server($filename)) { create_file_on_server($filename); }
因为有可能该文件将由第一个和第二个函数之间的另一个客户端创建.虽然在本地文件系统上也是如此,但它可以更容易地在分布式客户端服务器应用程序中发生,因为与本地文件系统相比,响应时间更长,并且可能有许多甚至是匿名客户端(如上例所示)
在远程创建文件时,我建议在公共可写文件夹中遵循强大的命名方案,以避免冲突.遵循这个方案,然后只写和不关心.可能发生的最糟糕的事情是你覆盖了其他人偶然创造的东西.但谁偶然创建了像/client/id/file_name.txt这样的东西?