php how to test if file has been uploaded completely

后端 未结 11 1531
耶瑟儿~
耶瑟儿~ 2021-02-01 15:24

Is there any way to check if file has been uploaded completely on the server? My scenario: User uploads file over ftp and my other PHP task is running in cronjob. Now I would li

相关标签:
11条回答
  • 2021-02-01 16:04

    I had the same scenario and found a quick solution that worked for me:

    While a file is uploading via FTP, the value of filemtime($yourfile) is continuously modified. When time() minus filemtime($yourfile) is more than X, uploading has stopped. In my scenario, 30 was a good value for x, you might want to use any diferent value, but it should usefully be at least 3.

    I do know that this method doesn’t guarantee the file’s integrity, but, as no one but me is going to upload, i dare to assume that.

    0 讨论(0)
  • 2021-02-01 16:07

    By checking upload error message you can confirm whethere file complete uploaded or partial uploaded

    If upload Error Code is 3 then file uploaded partially

    let say your file upload field name 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
    }
    

    In case 3 you can check partial upload

    If you want to Track file Upload Via FTP Programme if you are running VSFTPD then you can track

    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
    

    any problem in understanding please reply

    0 讨论(0)
  • 2021-02-01 16:08

    There are many different ways to solve this. Just to name a few:

    1. Use a signal file that is created before the upload and removed when it's completed.
    2. Find out if your FTP server has a configuration option that for example gives uncompleted files the extension ".part" or locks the file on the file system level (like vsftp).
    3. Get a list of all currently opened files in that directory by parsing the output of the UNIX/Linux lsof command and check if the file you're checking is in that list (take Nasir's comment from above into account if you encounter permission problems).
    4. Check if the last modification of that file is longer ago than a specific threshold.

    As it seems your users can use any FTP client they want, the first method (signal file) can't be used. The second and third answers need a deeper understanding of UNIX/Linux and are system dependend.

    So I think that method #4 is the way to go in PHP as long as processing latency (depending on the configured threshold) is no problem. It is straightforward and doesn't depend on any external commands:

    // 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();
    }
    

    I hope this helps anyone having this problem.


    Similar questions:

    Verify whether ftp is complete or not?

    PHP: How do I avoid reading partial files that are pushed to me with FTP?

    0 讨论(0)
  • 2021-02-01 16:09

    Agreed with Hasan. You can check it by using php's file_exist function.

    save your filename which your and getting while user uploading a file (or a renamed file if you are renaming it) to any table in database. Now your cron will get that name from database table each time it runs and will check if that file had been uploaded or not.

    <?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.
    }
    ?>
    
    0 讨论(0)
  • 2021-02-01 16:11

    A possible solution would be to check the file size every few seconds using a loop, and if the size is the same between two loops assume it's uploaded.

    something like:

        $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);
    
    }
    
    0 讨论(0)
  • 2021-02-01 16:15

    you can set a thread to get details using : ll -h

    and getting the size column and comparing it after a certain time interval if it stays the same for 2 or 3 time interval then the upload could be finished.

    if you need a more precise solution and if you are looking for a more complicated way (but efficient) to do it, check this out :

    http://www.php.net/manual/en/function.inotify-read.php

    You can take a look at this example in the link I gave, You will need to check for the event code IN_CLOSE_WRITE

    Taken from : LINUX: how to detect that ftp file upload is finished

    0 讨论(0)
提交回复
热议问题