有没有办法检查文件是否已完全上传到服务器上?我的场景:用户通过ftp上传文件,我的其他PHP任务在cronjob中运行。现在我想检查文件是否已上传或用户是否仍在上传。这是必不可少的,因为我知道我是否可以使用该文件或等到它上传。谢谢。
答案 0 :(得分:31)
如果您可以控制执行上传的应用程序,则可以要求将文件上传到name.tmp
,完成上传后将其重命名为name.final
。您的PHP脚本只能查找*.final
个名称。
答案 1 :(得分:20)
我有相同的情况,并找到了一个适合我的快速解决方案:
当文件通过FTP上传时,filemtime($yourfile)
的值会不断修改。当time() minus filemtime($yourfile)
超过X
时,上传已停止。在我的场景中,30对于x来说是一个很好的值,你可能想要使用任何不同的值,但它应该至少有3个。
我知道这种方法并不能保证文件的完整性,但是,除了我之外,没有人会上传,我敢于认为。
答案 2 :(得分: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';
}
编辑:如果有权限问题。通过使用sudo或suid方法,php脚本可以获得执行lsof命令所需的权限。要设置suid,你必须以root身份发出以下命令。
su root
chmod u+s /usr/sbin/lsof
答案 3 :(得分:10)
有许多不同的方法可以解决这个问题。仅举几例:
signal file
,并在完成后将其删除。FTP server
是否有configuration option
,例如为未完成的文件提供扩展名“.part”或将文件锁定在文件系统级别(如vsftp)。lsof
命令的输出获取该目录中所有当前打开文件的列表,并检查您正在检查的文件是否在该列表中(将Nasir的评论从上面考虑到如果遇到权限问题)。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();
}
我希望这可以帮助任何有此问题的人。
类似的问题:
Verify whether ftp is complete or not?
PHP: How do I avoid reading partial files that are pushed to me with FTP?
答案 4 :(得分:4)
一种可能的解决方案是使用循环每隔几秒检查文件大小,如果两个循环之间的大小相同则假定它已上传。
类似的东西:
$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);
}
答案 5 :(得分:3)
您可以使用以下命令设置线程以获取详细信息:
ll -h
获取size列并在一定时间间隔后比较它,如果它在2或3个时间间隔内保持不变,则上传可以完成。
如果您需要更精确的解决方案,并且如果您正在寻找更强大的复杂方式(但效率),请查看以下内容:
http://www.php.net/manual/en/function.inotify-read.php
您可以在我提供的链接中查看此example,
您需要检查事件代码IN_CLOSE_WRITE
答案 6 :(得分:2)
保持修改日期的sql记录,并检查你是否有新修改过的文件。
<?php
$filename = 'somefile.txt';
if (file_exists($filename)) {
echo "$filename was last modified: " . date ("F d Y H:i:s.", filemtime($filename));
}
?>
答案 7 :(得分:0)
通过检查上传错误消息,您可以确认文件已完成上传或部分上传
如果上传错误代码为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
理解中的任何问题请回复
答案 8 :(得分:-1)
按下一个代码上传后检查文件
if (file_exists('http://www.domain.com/images/'.$filename)) :
// Write some response as you like as a success message
endif;
注意:你必须改变你的图像路径,
祝你好运:)答案 9 :(得分:-5)
同意Hasan。您可以使用php的file_exist函数进行检查。
保存用户上传文件(或重命名文件,如果要重命名)时所获得的文件名到数据库中的任何表。现在,您的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.
}
?>
答案 10 :(得分:-6)
<?php
if (move_uploaded_file($_FILES["uploader_name"]["tmp_name"], $path_name)):
//print true condition
else:
//print false condition
endif;
?>