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

php如何测试文件是否已完全上传,php,Php,有没有办法检查文件是否已完全上传到服务器上?我的场景:用户通过ftp上传文件,我的另一个PHP任务正在cronjob中运行。现在我想检查文件是否已经上传或者用户是否还在上传。这是必要的,因为这样我就知道我是否可以使用该文件,或者等待它被上传。谢谢。 <?php if (move_uploaded_file($_FILES["uploader_name"]["tmp_name"], $path_name)): //print true condition el

有没有办法检查文件是否已完全上传到服务器上?我的场景:用户通过ftp上传文件,我的另一个PHP任务正在cronjob中运行。现在我想检查文件是否已经上传或者用户是否还在上传。这是必要的,因为这样我就知道我是否可以使用该文件,或者等待它被上传。谢谢。


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

一种可能的解决方案是使用循环每隔几秒钟检查一次文件大小,如果两个循环之间的大小相同,则假定文件已上载

比如:

    $filesize = array();
    $i = 0;
    while(file_exists('/myfile.ext')) {
    $i++;

    $filesize[$i] = filesize('/myfile.ext');

    if($filesize[$i - 1] == $filesize[$i]) {
    exit('Uploaded');
    }

sleep(5);

}

我也遇到了同样的情况,并找到了一个适合我的快速解决方案:

通过FTP上传文件时,
filemtime($yourfile)
的值会不断修改。当
time()减去filemtime($yourfile)
大于
X
时,上载已停止。在我的场景中,30是x的一个很好的值,您可能希望使用任何不同的值,但它至少应该是3


我确实知道这种方法不能保证文件的完整性,但是,因为除了我之外没有人会上传,我敢假设。

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

如果您在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';
}
编辑:如果出现权限问题。通过使用sudo或suid方法,php脚本可以获得执行lsof命令所需的权限。要设置suid,您必须以root用户身份发出以下命令

su root
chmod u+s /usr/sbin/lsof

有很多不同的方法来解决这个问题。仅举几个例子:

  • 使用在上载之前创建并在上载完成后删除的
    信号文件
  • 查看您的
    FTP服务器是否有
    配置选项
    ,例如为未完成的文件提供扩展名“.part”或在文件系统级别锁定文件(如vsftp)
  • 通过解析UNIX/Linux
    lsof
    命令的输出,获取该目录中当前打开的所有文件的列表,并检查您正在检查的文件是否在该列表中(如果遇到权限问题,请考虑上面Nasir的注释)
  • 检查该文件的上次修改是否早于特定阈值
  • 因为您的用户似乎可以使用他们想要的任何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();
    }
    
    我希望这能帮助任何有这个问题的人


    类似问题:


    按下一个代码上载后检查文件

    if (file_exists('http://www.domain.com/images/'.$filename)) :
    
        // Write some response as you like as a success message
    
    endif;
    
    注意:您必须更改自己的图像路径


    祝你好运:)

    同意哈桑的观点。您可以使用php的函数进行检查

    保存您的文件名,当用户将文件(或重命名的文件,如果您正在重命名)上载到数据库中的任何表时,保存您的文件名。现在,您的cron将在每次运行时从数据库表中获取该名称,并检查该文件是否已上载

    <?php
    $filename = '/var/www/YOUR_UPLOAD_FOLDER/xyz.txt'; //get xyz name from database
    
    if (file_exists($filename)) {
       // YOU CAN WORK WITH YOUR FILE AND CAN DELETE RELATIVE RECORD FROM DB TABLE.
    } else {
       // YOU SHOULD WAIT WHILE FILE IS UPLOADING.
    }
    ?>
    

    通过检查上传错误消息,您可以确认文件是完整上传还是部分上传

    如果上载错误代码为3,则部分上载文件

    假设您的文件上载字段名为myfile

    $error=$_FILES['myfile']['error'];
    if($error>0){
    //Upload Error IS Present check what type of error
    switch($error){
        case 1:
            // UPLOAD_ERR_INI_SIZE
            // Value: 1; The uploaded file exceeds the upload_max_filesize directive in php.ini.
            break;
        case 2:
            // UPLOAD_ERR_FORM_SIZE
            // Value: 2; The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.
            break;
        case 3:
            // UPLOAD_ERR_PARTIAL
            // Value: 3; The uploaded file was only partially uploaded.
            break;
        case 4:
            // UPLOAD_ERR_NO_FILE
            // Value: 4; No file was uploaded.
            break;
        case 6:
            // UPLOAD_ERR_NO_TMP_DIR
            // Value: 6; Missing a temporary folder. Introduced in PHP 4.3.10 and PHP 5.0.3.
            break;
        case 7:
            // UPLOAD_ERR_CANT_WRITE
            // Value: 7; Failed to write file to disk. Introduced in PHP 5.1.0.
            break;
        case 8:
            // UPLOAD_ERR_EXTENSION
            // Value: 8; A PHP extension stopped the file upload. PHP does not provide a way to ascertain which extension caused the file upload to stop; examining the list of loaded extensions with phpinfo() may help. Introduced in PHP 5.2.0.
            break;
    }
    
    }else{
        //File IS Uploaded you can move or validate other things
    }
    
    在案例3中,您可以检查部分上传

    如果您想通过FTP程序跟踪文件上载,如果您正在运行VSFTPD,则可以跟踪

    file=/var/log/vsftpd.log
    initial_files=`grep -c 'OK UPLOAD' $file`;
    while [ TRUE ]
    do
    current_files=`grep -c 'OK UPLOAD' $file`;
    if [ $current_files == $initial_files ]; then
         echo "old File Not Uploaded";
    else
         echo "new File Uploaded Process New File";
    new_file=`grep 'OK UPLOAD' $file | tail -1`;
    echo $new_file;
    initial_files=$current_files;
    fi
    sleep 1
    done
    

    如果理解有任何问题,请回复

    保留修改日期的sql记录,并检查您是否有新修改的文件

    <?php 
    $filename = 'somefile.txt';
    if (file_exists($filename)) {
    echo "$filename was last modified: " . date ("F d Y H:i:s.", filemtime($filename));
    }
    ?>
    

    您可以通过以下方式设置线程以获取详细信息:
    ll-h

    获取size列并在一定的时间间隔后进行比较,如果它在2或3个时间间隔内保持不变,则可以完成上载

    如果您需要更精确的解决方案,如果您正在寻找一种更复杂的方法(但效率更高),请查看以下内容:

    你可以在我给你的链接中看到这个, 您需要在_CLOSE_WRITE

    摘自:

    您的FTP服务器是什么?当然,单凭php是无法实现这一点的。如果事先不知道有关正在上载的文件的任何信息(例如哈希和),则在不分析ftp服务过程本身的情况下,无法确定文件传输是否已完成或仍在进行中,或者可能已中断。您需要与ftp服务进行通信,并查看它是否可以提供有关要求的信息。此服务的可能副本可能会有所帮助。检查文件是否正在由进程使用如何?你可以用它。新发现的文件应在FTP服务器进程中处于“打开”状态,直到完全上载。因此,没有可靠的方法检查不完整的上载吗(这仍然只是一个假设。在很多情况下,文件大小在两个这样的间隔之间保持不变。这不起作用。我在linux控制台中运行命令时看到正在使用该文件的进程,但当我使用PHP exec运行命令时,不会返回任何内容。可能是因为PHP没有权限。)o查看正在使用该文件的进程?您可以使用suid覆盖权限问题参见,以便更有效地使用
    lsof
    ,结果是:
    exec(“lsof$filename>/dev/null”、$dummy$status);如果(!$status){/*in use*/}
    请使用“`”标记代码-即
    if(fi