SQL.RU
 client/server technologies
 
 Главная | Документация | Статьи | Книги | Форум | Опросы | Рассылка | Работа | Поиск | FAQ |

Добро пожаловать в форум, Guest  >>  Войти | Регистрация | Правила |
Новое сообщение
Форум:Все форумы / PHP,Perl
Автор:    
Пароль:
Эмоции:
Тема:
           Помощь
Сообщение:
 
Приложить файл (максимальный размер 150Kb)
Публикуемые сообщения должны соответствовать правилам форума на sql.ru
Для тех у кого нет русской клавиатуры, предлагаем: Показать виртуальную клавиатуру

 (AJAX) Как сделать контроль загрузки файлов на сервер? 
Berkut
Member

Откуда: Karelia
Сообщений: 1615
Привет! В AJAX я пока что новичок, поэтому строго не судите. :)

Допустим, есть форма с загрузкой файлов на сервер.

1. Требуется по нажатию кнопки "Загрузить" в фоне вызвать скрипт для загрузки файла.
2. Если все "OK", то вернуть название файла, который грузится в данный момент на сервер ($_FILES['userfile']['tmp_name']) и его размер с помощью XmlHttpRequest.responseText.
3. Затем каждые 2 секунды также в фоне опрашивать текущий размер файла, до тех пор пока он не загрузится.
4. После успешной загрузки обновить содержимое страницы.

Это мое видение как должно быть. Поправьте, если что не так. :)

2 вопроса:

1. Не совсем понятно как выполнить отправку формы "без сабмита". Другими словами, чтобы страница не обновлялась.
2. Пока смутно представляю алгоритм "опрашивания" текущего размера файла, но это уже скорее всего дело техники.
30 май 06, 17:21    [2721802] Ответить | Цитировать    Сообщить модератору

 Re: (AJAX) Как сделать контроль загрузки файлов на сервер? 
twistfire
Member

Откуда: Украина
Сообщений: 709
мониторинг загрузки файла на сервер в PHP (AJAX)
30 май 06, 19:07    [2722474] Ответить | Цитировать    Сообщить модератору

 Re: (AJAX) Как сделать контроль загрузки файлов на сервер? 
*
Guest
Такое ощущение, что тема там была создана после аналогичной здесь :)
sql.ru/forum/actualthread.aspx?tid=273947
30 май 06, 21:11    [2722764] Ответить | Цитировать    Сообщить модератору

 Re: (AJAX) Как сделать контроль загрузки файлов на сервер? 
Berkut
Member

Откуда: Karelia
Сообщений: 1615
Спасибо за ссылки.

А как выполнить загрузку файла в невидимом фрейме?
С остальным вроде бы понятно пока...
31 май 06, 14:51    [2725873] Ответить | Цитировать    Сообщить модератору

 Re: (AJAX) Как сделать контроль загрузки файлов на сервер? 
Berkut
Member

Откуда: Karelia
Сообщений: 1615
Привет!

Осталась последняя проблема: нарисовать прогресс-бар.

Для этого надо определить размер загружаемого файла на сервер.
После отправки формы эти данные можно вытащить из $_SERVER['CONTENT_LENGTH'] и записать в файл.

Но вот незадача...
Скрипт, который проверяет степень загруженности файла, определяет общий размер после завершения скрипта загрузки upload.php.

Как быть?
13 июн 06, 12:44    [2765157] Ответить | Цитировать    Сообщить модератору

 Re: (AJAX) Как сделать контроль загрузки файлов на сервер? 
Berkut
Member

Откуда: Karelia
Сообщений: 1615
При загрузке файла на сервер видно, что общий размер определяется не сразу (третий параметр).

filemanager.php
<?php
session_start();

// определяем временную директорию, куда грузятся файлы на сервер
$tmp_dir = '';

if (!isset($_SESSION['upload_tmp_dir']))
{
    $tmp_dir_ok = false;
    
    $tmp_dir = ini_get('upload_tmp_dir');

    $tmp_dir_ok = true;

    // если директива upload_tmp_dir не задана в php.ini, то
    if (!is_dir($tmp_dir) || $tmp_dir=='')
    {
        // искуссвенным путем определяем временную директорию в системе
        $tmp_dir = dirname(tempnam('127631782631827', 'foo'));
    
        if (!is_dir($tmp_dir))
        {
            echo "<script>alert('Не удается определить временную директорию системы.');</script>";
            $tmp_dir_ok = false;
        }
    }

    // сохраняем значение временной директории в сессии 
    if ($tmp_dir_ok)
    {
        $_SESSION['upload_tmp_dir'] = $tmp_dir;
    }
}
?>
<html>
<head>
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
 
<script language="JavaScript">
<!--
var start_date = null;
var start_time = null;                  // время, прошедшее в миллисекундах

var time_limit = 30;                    // тайм-лимит в секундах для опроса сервера

var r = false;                          // XMLHttpRequest-object
var secs_elapsed = 0;                   // время прошедшее с момента загрузки

var uploaded = false;                   // флаг загрузки

function uploadFile()
{
    if (document.forms[0].upload_file.value!='')
    {
        document.getElementById('progressMess').innerHTML = 'Подождите ответа сервера...';
            
        document.forms[0].btnupload.disabled = true;

        start_date = new Date();
        start_time = start_date.getTime();
            
        uploaded = false;
            
        document.getElementById('progressProcents').style.width = '0%';
            
        setTimeout("document.forms[0].submit()", 1000);
        request();
    }
    else
    {
        alert('Не выбран файл!');
        return false;
    }
}

/**
 * Выполняет асинхронный запрос к серверу
 */
function request()
{
    var n = new Date();
    
    var current_time = n.getTime();
    
    secs_elapsed = Math.round((current_time-start_time)/1000);
    iSecs = secs_elapsed%60;
    
    document.getElementById('progressTime').innerHTML = '00:'+ (iSecs>9 ? iSecs : '0'+iSecs);
    
    if (secs_elapsed>=time_limit)
    {
        document.getElementById('progressMess').innerHTML = 'Время опрашивания сервера истекло...';
        document.forms[0].btnupload.disabled = false;
        
        return false;
    }
    
    r = false;
    
    try 
    {
        r = new XMLHttpRequest();
    }
    catch(trymicrosoft)
    {
        try
        {
            r = new ActiveXObject("Msxml2.XMLHTTP");
        }
        catch (othermicrosoft)
        {
            try
            {
                r = new ActiveXObject("Microsoft.XMLHTTP");
            }
            catch(failed)
            {
                r = false;
            }
        }
    }

    if (!r)
    {
        alert("Error initializing XMLHttpRequest! Your browser does not support XMLHttpRequest object.");
        window.close();
        return false;
    }
        
    r.open('GET', 'whileuploading.php', true);
    r.onreadystatechange = progressUpdate;
    r.send(null);
}

/**
 * Проверяет состояние запроса и обновляет содержимое страницы.
 */
function progressUpdate()
{
    if (r.readyState==4)
    {
        if (r.status==200)
        {
            /*
                параметры возвращаются в формате
            
                current_human_filesize|current_filesize|total_filesize
            */
            
            var response = r.responseText;

            var t = response.split('|');
            
            if (t[0]!='undefined')
            {
                uploaded = true;
            }
            
            document.getElementById('progressBytes').innerHTML = response;

            /*if (t[1]>0 && t[2]>0)
            {
                runProgressBar(Math.round(t[1]/t[2]*100));
            }*/
            
            if (uploaded && t[0]=='undefined')      // загрузка уже выполнена
            {
                document.getElementById('progressMess').innerHTML = 'Загрузка завершена...';
                document.forms[0].btnupload.disabled = false;
                
                return;
            }
            
            setTimeout('request()', 1000);
        }
        else if (r.status == 404)
        {
            alert("Error: request URL does not exist");
        }
        else
        {
            alert("Error: status code is " + r.status);
        }
    }
}
//-->
</script>
</head>
<body leftmargin="0" topmargin="0" rightmargin="0" bottommargin="0" marginwidth="1" marginheight="1">
<iframe name="upload_frame" src="upload.php" width="1" height="1" style="border: 0;"></iframe>

<form method="post" action="upload.php" enctype="multipart/form-data" target="upload_frame">
<table border="0" cellpadding="2" cellspacing="1" width="60%" style="margin: 10px; border: 1px solid black;">
<tr>
    <td colspan="4"><input type="file" name="upload_file" class="input"></td>
</tr>
<tr>
    <td width="12%"><b>Загружено</b>:</td>
    <td width="16%" nowrap><span id="progressBytes" style="color: blue; font-size: 13px">undefined</span></td>
    <td width="10%" nowrap><span id="progressProcents">0</span> %</td>
    <td width="62%"><span id="progressMess"> </span></td>
</tr>
<tr>
    <td><b>Время</b>:</td>
    <td colspan="3"><span id="progressTime">00:00</span> сек.</td>
</tr>
<tr>
    <td colspan="4"><input type="button" name="btnupload" value="Загрузить" onClick="uploadFile();"></td>
</tr>
</table>
</form>
</body>
</html>

upload.php
<?php 
// определяем размер загружаемого файла и запоминаем значение в файле
$content_length = isset($_SERVER['CONTENT_LENGTH']) ? $_SERVER['CONTENT_LENGTH'] : 0;

$fp = fopen('filesize', 'w');
fwrite($fp, $content_length);
fclose($fp);

// move_uploaded_file() не используем, т.к. нужен сам факт загрузки файла на сервер
?>

whileuploading.php
<?php
session_start();

// определяем временную директорию
$tmp_dir = isset($_SESSION['upload_tmp_dir']) ? $_SESSION['upload_tmp_dir'] : ini_get('upload_tmp_dir');

// общий размер загружаемого файла на сервер
$content_length = file_get_contents('filesize');

// очищаем кэш состояния файлов
clearstatcache();

$tmp_file = '';

if (isset($_SESSION['tmp_file']) && is_file($_SESSION['tmp_file']))
{
    $tmp_file = $_SESSION['tmp_file'];
}
else 
{
    $tmp_file = findTemporaryFile($tmp_dir, '/[p][h][p]*');
}

// определяем размер временного файла и формируем вывод
if (false===($output = filesize($tmp_file)))
{
	$humanFileSize = 'undefined';
	$output = 0;
}
else 
{
    $humanFileSize = humanFileSize($output);
}

$output = $humanFileSize.'|'.$output.'|'.$content_length;

header('Content-Length: '.strlen($output));
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');

echo $output;

/** 
 * Ищет загружаемый файл во временной папке.
 * Возвращает имя временного файла в случае успеха.
 *
 * @param   string      $tmp_dir        имя временной директории, в которой ищется файл
 * @param   string      $pattern        шаблон, по которому ищутся файлы
 *
 * @return  boolean
 */
function findTemporaryFile($tmp_dir, $pattern)
{
    $found = false;
    
	if (is_dir($tmp_dir)) 
	{
        $phptempfiles = glob($tmp_dir.$pattern);
        
		if (count($phptempfiles)==1) 
		{
			$found = $phptempfiles[0];
		}
	}
    
	return $found;
}

/**
 * Форматирует и возвращает представление размера файла в более удобочитаемое.
 * 
 * @param   integer     $size       размер файла
 *
 * @return  string
 */
function humanFileSize($size)
{
    $filesizename = array(" Bytes", " KB", " MB", " GB", " TB", " PB", " EB", " ZB", " YB");
    return $size ? round($size/pow(1024, ($i = floor(log($size, 1024)))), 2) . $filesizename[$i] : '0 Bytes';
}
?>
13 июн 06, 14:57    [2766009] Ответить | Цитировать    Сообщить модератору

 Re: (AJAX) Как сделать контроль загрузки файлов на сервер? 
_Berkut_
Guest
актуально
14 июн 06, 17:30    [2771191] Ответить | Цитировать    Сообщить модератору

 Re: (AJAX) Как сделать контроль загрузки файлов на сервер? 
4m@t!c
Member

Откуда: //Украина/Киев (иногда Запорожье)
Сообщений: 2677
автор
Since the XMLHttpRequest object doesn’t support file uploads, this had to be done using iframes. Whenever the file input changes, the file is uploaded to the cgi-script in a hidden iframe. The cgi-script writes the total size of the upload and the actual uploaded file to temporary files.


http://ajaxian.com/archives/asynchronous-file-upload-with-ajax-progress-bar-in-php
----------------------------------------
Артисты не приехали, приехали цыгане
14 июн 06, 17:48    [2771307] Ответить | Цитировать    Сообщить модератору

 Re: (AJAX) Как сделать контроль загрузки файлов на сервер? 
Berkut
Member

Откуда: Karelia
Сообщений: 1615
4m@t!c, спасибо за линк.

Если правильно понял, то чтобы определить общий размер файла надо писать загрузку на другом языке (Perl)?

To be clear, there are exactly two means to achieve this “in” PHP: patching the PHP RFC1867 handler or handing processing off to a script written in a different language.
15 июн 06, 10:43    [2773223] Ответить | Цитировать    Сообщить модератору

 Re: (AJAX) Как сделать контроль загрузки файлов на сервер? 
twistfire
Member

Откуда: Украина
Сообщений: 709
а зачем именно прогресс-бар?
это необходимость или просто хочется?
12 авг 06, 10:29    [2995802] Ответить | Цитировать    Сообщить модератору

Generated time: 31ms.
Rambler's Top100 Powered by ActualForum 1.5.3 [s1] Copyright (c) Alex Sibilev 2000-2010