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 like to check if file has been uploaded or if user is still uploading. It is essential because then I know if I can work with that file or wait until it is uploaded. Thank you.
-
What is your FTP server? – galymzhan Apr 01 '12 at 13:19
-
1There is certainly no trivial way of realising this with php alone. If no information about the file that is being uploaded is known (e.g. a hash sum) beforehand, there is no way of determining whether the file transfer is complete or still in progress, or was maybe interrupted, without analysing the ftp service process itself. You would need to communicate with the ftp service, and see if it can provide information for requirements. – thrau Apr 01 '12 at 13:21
-
2possible duplicate of [PHP: How do I avoid reading partial files that are pushed to me with FTP?](http://stackoverflow.com/questions/5826890/php-how-do-i-avoid-reading-partial-files-that-are-pushed-to-me-with-ftp) This may help – Lawrence Cherone Apr 01 '12 at 13:25
-
3How about checking if the file is being used by a process? You could use [LSOF](https://www.google.com/search?q=lsof) for that. Your newly discovered file should be "open" in the FTP server process until it's completely uploaded. – Hubro Apr 01 '12 at 13:30
-
so there's no reliable way to check for incomplete uploads? :( – Alex Sep 18 '13 at 09:31
-
Which FTP server is being used? – Jonathan Amend Sep 18 '13 at 13:57
-
There's another solution on SO if you are willing to use proftpd http://stackoverflow.com/questions/7241978/how-to-determine-wheter-a-file-is-still-being-transferred-via-ftp – aleation Sep 19 '13 at 11:38
-
If you're expecting a particular file format, you can check it for validity assuming it isn't a format where a partial file is valid. e.g.: checking an XML file for a closed root element. – Kevin Stricker Sep 19 '13 at 15:21
-
Many similar questions on SO. [This answer](http://stackoverflow.com/questions/12038476/detecting-whether-a-file-is-complete-or-partial-in-php#12039012) describing a technique similar to that suggested by Codemonkey above is the best I've seen. – Steve Chambers Sep 23 '13 at 21:09
-
What is the user-action to upload the file? Is it controlled via a web-form, or are you simply polling the directory cold, to check for new uploads? – cartbeforehorse Sep 24 '13 at 15:55
11 Answers
If you have control over the application doing the upload, you can require that it upload the file to name.tmp
, and when it's done uploading rename it to name.final
. Your PHP script could look only for *.final
names.

- 741,623
- 53
- 500
- 612
-
kind of a useless answer. Obviously this would be the first option in many cases, I'm sure OP has thought of it b4 asking the Q. But what if you don't have access to the ftp server settings or maybe you don't want to add another dependency in your app (the ftp settings) – Alex Sep 25 '13 at 19:45
-
2@Alex Actually, my experience over the years is that most people who ask this question have never considered this method. They're all looking for some automatic method. This isn't dependent on any server settings. – Barmar Sep 25 '13 at 19:46
-
it is if your app needs to see only complete files and you rely on another app config for it - the ftp srv – Alex Sep 25 '13 at 19:53
-
@Alex My method is just dependent on the client renaming the file after it uploads it, not the server doing anything special. And I specifically said that this is only applicable if you can modify the client application. – Barmar Sep 25 '13 at 19:56
-
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.
if you are running php on linux then lsof can help you
$output = array();
exec("lsof | grep file/path/and/name.ext",$output);
if (count($output)) {
echo 'file in use';
} else {
echo 'file is ready';
}
EDIT: in case of permission issue. by using sudo or suid methods php script can get required permissions to execute lsof command. to set suid you have to issue following command as root.
su root
chmod u+s /usr/sbin/lsof

- 909
- 7
- 24
-
This doesn't work. I see the processes that are using that file when I run the command in the linux console, but when I run the command with PHP exec nothing is returned. Probably because PHP doesn't have the rights to see the processes that are using the file ? – Alex Sep 22 '13 at 12:55
-
-
2See http://stackoverflow.com/a/2527080/1488762 for a more efficient use of `lsof`, resulting in: `exec("lsof $filename >/dev/null", $dummy, $status); if (!$status) { /*in use*/ }` – Roger Dueck Oct 10 '16 at 17:13
There are many different ways to solve this. Just to name a few:
- Use a
signal file
that is created before the upload and removed when it's completed. - Find out if your
FTP server
has aconfiguration option
that for example gives uncompleted files the extension ".part" or locks the file on the file system level (like vsftp). - 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). - 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?
-
@Alex Thanks, I wasn't aware of that and updated my answer. But as Nasir pointed out, it's a matter of permissions and can be fixed. In the end that only strengthens me in my opinion that method #4 is the most straightforward way :) – flu Sep 24 '13 at 12:16
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);
}

- 1,643
- 2
- 16
- 29
-
2That's still just an assumption. There are lots of situations where the file size would remain unchanged between two such intervals – Hubro Apr 01 '12 at 13:59
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

- 1
- 1

- 5,388
- 2
- 32
- 50
keep sql record of date modified and check if you have newely modified file.
<?php
$filename = 'somefile.txt';
if (file_exists($filename)) {
echo "$filename was last modified: " . date ("F d Y H:i:s.", filemtime($filename));
}
?>

- 45
- 9
-
2This will tell when the upload has started, it won't tell when the upload has finished. – Barmar Sep 25 '13 at 14:56
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

- 670
- 8
- 9
-
1He's not using an upload script on the web page, he's uploading to an FTP server. A background process needs to check whether the upload has completed. – Barmar Sep 25 '13 at 14:54
Check for the file after uploading by next code
if (file_exists('http://www.domain.com/images/'.$filename)) :
// Write some response as you like as a success message
endif;
Notice: you have to change images path by yours ,
good luck :)
-
1please use "\`" to mark code - i.e. `if (file_exists('http://www.domain.com/images/'.$filename))` – rebeliagamer Sep 23 '13 at 14:22
-
3This will report that the file exists as soon as the client starts uploading it, it won't wait for the upload to complete. – Barmar Sep 25 '13 at 14:57
-
Hi , but it will check if file exists after moving it to preferred folder not in temp folder – Hasan Gad Sep 25 '13 at 21:29
-
2You suppose that the ftp-server will act so - that's not granted. There are also servers uploading files in place. You also check the file's existence over `http`, not mentioning why. This simply doesn't answer the question. – Scolytus Sep 27 '13 at 03:39
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.
}
?>

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

- 700
- 2
- 14
- 24