Есть ли способ проверить, был ли файл полностью загружен на сервере? Мой сценарий: Пользователь загружает файл поверх ftp, а другая моя задача PHP работает в cronjob. Теперь я хотел бы проверить, был ли файл загружен или пользователь по-прежнему загружается. Это важно, потому что тогда я знаю, могу ли я работать с этим файлом или ждать, пока он будет загружен. Спасибо.
Php, как проверить, загружен ли файл полностью
Ответ 1
Если у вас есть контроль над приложением, загружающим приложение, вы можете потребовать, чтобы он загрузил файл в name.tmp
, и когда он загрузил его, переименуйте его в name.final
. Ваш PHP скрипт может выглядеть только для имен *.final
.
Ответ 2
У меня был такой же сценарий, и я нашел быстрое решение, которое сработало для меня:
Пока файл загружается через FTP, значение filemtime($yourfile)
постоянно изменяется. Когда time() minus filemtime($yourfile)
больше, чем X
, загрузка прекратилась. В моем сценарии 30 было хорошим значением для x, вы можете использовать любое другое значение, но оно должно быть полезно как минимум 3.
Я знаю, что этот метод не гарантирует целостность файлов, но, поскольку никто, кроме меня, не собирается загружать, я смею предположить, что.
Ответ 3
если вы используете php для linux, тогда 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 script может получить требуемые разрешения для выполнения команды lsof. чтобы установить suid, вы должны ввести следующую команду в качестве пользователя root.
su root
chmod u+s /usr/sbin/lsof
Ответ 4
Существует много разных способов решения этой проблемы. Просто чтобы назвать несколько:
- Используйте
signal file
, который создается перед загрузкой и удаляется при завершении. - Узнайте, есть ли у
FTP server
FTP server
, который, например, дает незавершенным файлам расширение ".part" или блокирует файл на уровне файловой системы (например, vsftp). - Получить список всех открытых в данный момент файлов в этом каталоге, проанализировав вывод команды UNIX/Linux
lsof
и проверьте, находится ли файл, который вы проверяете, в этом списке (примите во внимание комментарий Насира выше, если вы сталкиваются с проблемами разрешения). - Проверьте, что
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 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 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();
}
Надеюсь, это поможет любому, у кого есть эта проблема.
Похожие вопросы:
Проверьте, завершено ли ftp или нет?
PHP: Как мне избежать чтения частичных файлов, которые были перенесены мне с FTP?
Ответ 5
Возможным решением было бы проверить размер файла каждые несколько секунд, используя цикл, и если размер одного и того же между двумя циклами предполагает его загрузку.
что-то вроде:
$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);
}
Ответ 6
вы можете установить поток, чтобы получить детали, используя:
ll -h
и получить столбец размера и сравнить его после определенного интервала времени, если он останется таким же для 2 или 3 временных интервала, тогда загрузка может быть завершена.
если вам нужно более точное решение, и если вы ищете более сложный способ (, но эффективный), проверьте это:
http://www.php.net/manual/en/function.inotify-read.php
Вы можете посмотреть этот пример в ссылке, которую я дал,
Вам нужно будет проверить код события IN_CLOSE_WRITE
Взято из: LINUX: как определить, что загрузка файла ftp завершена
Ответ 7
сохранить дату изменения sql date и проверить, есть ли у вас новый файл.
<?php
$filename = 'somefile.txt';
if (file_exists($filename)) {
echo "$filename was last modified: " . date ("F d Y H:i:s.", filemtime($filename));
}
?>
Ответ 8
Проверяя сообщение об ошибке загрузки, вы можете подтвердить, что файл полностью загружен или частично загружен.
Если вы загружаете код ошибки 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
любая проблема в понимании, пожалуйста, ответьте
Ответ 9
Проверьте файл после загрузки по следующему коду
if (file_exists('http://www.domain.com/images/'.$filename)) :
// Write some response as you like as a success message
endif;
Примечание: вам нужно изменить путь к изображениям по своему усмотрению,
удачи:)
Ответ 10
Согласился с Хасаном. Вы можете проверить его, используя 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.
}
?>
Ответ 11
<?php
if (move_uploaded_file($_FILES["uploader_name"]["tmp_name"], $path_name)):
//print true condition
else:
//print false condition
endif;
?>