php如何测试文件是否已完全上传

pet*_*ter 30 php

有没有办法检查文件是否已完全上传到服务器上?我的场景:用户通过ftp上传文件,我的其他PHP任务在cronjob中运行.现在我想检查文件是否已上传或用户是否仍在上传.这是必不可少的,因为我知道我是否可以使用该文件或等到它上传.谢谢.

Bar*_*mar 32

如果您可以控制执行上传的应用程序,则可以要求它将文件上传到name.tmp,并在完成上传后将其重命名为name.final.您的PHP脚本只能查找*.final名称.

  • @Alex实际上,我多年来的经验是,大多数提出这个问题的人从未考虑过这种方法.他们都在寻找一些自动方法.这不依赖于任何服务器设置. (2认同)

小智 20

我有相同的场景,并找到了一个适合我的快速解决方案:

当文件通过FTP上传时,值filemtime($yourfile)会不断修改.什么时候time() minus filemtime($yourfile)超过X,上传已经停止.在我的场景中,30对于x来说是一个很好的值,你可能想要使用任何不同的值,但它应该至少有3个.

我知道这种方法并不能保证文件的完整性,但是,除了我之外没人会上传,我敢于认为.


Nas*_*bal 14

如果你在Linux上运行php,那么lsof可以帮助你

$output = array();
exec("lsof | grep file/path/and/name.ext",$output);
if (count($output)) {
  echo 'file in use';
} else {
  echo 'file is ready';
}
Run Code Online (Sandbox Code Playgroud)

编辑:如果是许可问题.通过使用sudo或suid方法,php脚本可以获得执行lsof命令所需的权限.设置suid你必须以root身份发出以下命令.

su root
chmod u+s /usr/sbin/lsof
Run Code Online (Sandbox Code Playgroud)

  • 请访问http://stackoverflow.com/a/2527080/1488762以更有效地使用`lsof`,结果是:`exec("lsof $ filename>/dev/null",$ dummy,$ status); if(!$ status){/*in use*/}` (2认同)

flu*_*flu 10

有许多不同的方法可以解决这个问题.仅举几个:

  1. 使用signal file在上传之前创建的,并在完成后删除.
  2. 找出你FTP server是否有一个configuration option例如提供未完成文件的扩展名".part"或锁定文件系统级别的文件(如vsftp).
  3. 通过解析UNIX/Linux lsof命令的输出来获取该目录中所有当前打开的文件的列表,并检查您正在检查的文件是否在该列表中(如果遇到权限问题,请将Nasir的上述评论考虑在内).
  4. 检查last modification该文件的长度是否超过特定阈值.

由于您的用户似乎可以使用他们想要的任何FTP客户端,因此无法使用第一种方法(信号文件).第二个和第三个答案需要更深入地了解UNIX/Linux并且是系统依赖的.

所以我认为只要处理延迟(取决于配置的阈值)没问题,这method #4就是进入的方式PHP.它很简单,不依赖于任何外部命令:

// Threshold in seconds at which uploads are considered to be done.
$threshold = 300;

// Using the recursive iterator lets us check subdirectories too
// (as this is FTP anything is possible). Its also quite fast even for
// big directories.
$it = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($uploadDir);

while($it->valid()) {
  // Ignore ".", ".." and other directories. Just recursively check all files.
  if (!$it->isDot() && !$it->isDir()) {
    // $it->key() is the current file name we are checking.
    // Just check if it's last modification was more than $threshold seconds ago.
    if (time() - filemtime($it->key() > $threshold)) {
      printf("Upload of file \"%s\" finished\n", $it->key());

      // Your processing goes here...

      // Don't forget to move the file out so that it's not identified as
      // just being completed everytime this script runs. You might also mark
      // it in any way you like as being complete if you don't want to move it.
    }
  }
  $it->next();
}
Run Code Online (Sandbox Code Playgroud)

我希望这可以帮助任何人解决这个问题.


类似的问题:

验证ftp是否完整?

PHP:如何避免读取使用FTP推送给我的部分文件?


Wha*_*hen -7

<?php
    if (move_uploaded_file($_FILES["uploader_name"]["tmp_name"], $path_name)):
        //print true condition
    else:
        //print false condition
    endif;
?>
Run Code Online (Sandbox Code Playgroud)