Контроль состояния загрузки — это так называемый progress bar. В интеренете полно реализаций на том же flash: выглядит это решение красиво и эффектно, но имеет один минус — требует наличия у пользователя установленного flash плеера. Сама по себе необходимость такой фичи на сайте сомнительна, но есть проект, на котором пользователю предоставляется возможность загружать файлы до одного гигабайта. Тут это скорее необходимость. Как же это сделать не прибегая к решению с флеш-загрузкой?! Оказывается, очень просто.
Первое, можно скачать Uber-Uploader: там все делатеся через SSI, при наличии perl на сервере. Но мы же php-программисты, тем более что это уж очень монстрообразный скрипт.
Итак, что нам нужно!
Устанавливаем модуль php_apc. В php.ini добавляем следующие строки:
extension=php_apc.dll apc.rfc1867 = on
Далее устанавливаем следующие перменные в такие значения:
file_uploads = On max_execution_time = 60 max_input_time = 7200 memory_limit = 128M post_max_size = 1000M upload_max_filesize = 1000M
Все, перезапускаем apache.
Простейшее решение на PHP + Javascript:
UploadForm.php
<html> <head> <title>UploadProgress</title> <script type="text/javascript"> function UpdateProgress(){ document.getElementById("UploadProgress").style.display = ""; document.getElementById("UploadForm").style.display = "none"; var e = document.createElement('SCRIPT'); e.type = 'text/javascript'; e.src = "JavaScriptInjection.php?DownloadProgressID=" + UploadForm.APC_UPLOAD_PROGRESS.value + "&CachePrevention=" + (new Date()).getTime(); document.getElementsByTagName('head').item(0).appendChild(e); setTimeout("UpdateProgress()", 500); } function UpdateClient(data) { try { document.getElementById("ProgressText").innerHTML = "Uploaded " + (data["current"]/1024/1024).toFixed(2) + "MB of " + (data["total"]/1024/1024).toFixed(2) + "MB"; document.getElementById("ProgressBar").style.width = (data["current"]/data["total"]*100) + "%"; } catch (e) { null; } } </script> </head> <body> <form id="UploadForm" enctype="multipart/form-data" action="ProcessForm.php" method="POST" onsubmit="UpdateProgress();"> <input type="hidden" name="APC_UPLOAD_PROGRESS" value="<?php echo uniqid() ?>"/> <input type="file" name="up_file_1"/><br> <input type="file" name="up_file_2"/> <input type="submit" value="Upload!"/> </form> <div id="UploadProgress" style="display:none;"> <span id="ProgressText"></span><br/> <div style='width:600px; background:#CCCCCC;'><div id="ProgressBar" style="background-color:#00CC66; width:0%;"></div></div> </div> </body> </html>
JavaScriptInjection.php
<?php if ($e = apc_fetch("upload_{$_GET['DownloadProgressID']}")) echo "UpdateClient(" . json_encode($e) . ")"; ?>
ProcessForm.php
<?php // At this point file upload is complete. // move_uploaded_file($_FILES["up_file_1"]["tmp_name"], "c:\\upload\\" . $_FILES["up_file_1"]["name"]); ?> Загрузка завершена.
Ну вот, данный скрипт будет работать. Сразу скажу пример кода не мой: я реализовал все по-другому: Ajax, подсчет данных и прочее, но скрипт коммерческий, поэтому не могу его выставить на обозрения — то, что оплачивал заказчик остается у заказчика — по крайней мере в паблик не выкладываю, хотя путь указал, да и мои контактные данные тоже имеются на сайте ;).
Преимущества данного решения:
- Не требует переустановки или сборки php
- Не использует CGI/Perl и другиз сторонних решений
- Работает на версиях php 5.2 и выше с установленным модулем php_apc
- Не требует от клиента никаких дополнителных примочек к браузеру
Что еще хочу добавить по скрипту: если захотите передалать загрузку и контроль состояния с помощью Ajax то не забывайте
- убивать таймер
- javascript c файлами не работает, следовательно Ajax-ом не отправишь форму с файлом — приходится хитрить, способы есть.
Как минус, это обязательное наличие библиотеки, но имея dedicated server, такой минус можно опустить ибо настройка занимает около двух минут.
Современные браузеры (FF 3.6, webkit) поддерживают отправку файлов через XHR с информацией о прогрессе загрузки как по одному файлу, так и по всем.
Это здорово, но если учесть что пользователи ИЕ6 не вымерли, а тот же ИЕ7-8 твердо стоит на ногах нельзя пока принебрегать. Кстати данный пример также отображает загрузку нескольких файлов.
сделай демку
к сожалению хостинг на котором находится блог не поддерживает php_apc :((
Согласен, замечание дельное, это нужно также предусматривать.
Спасибо, обязательно попробую.
Настройте пожалуйста, стили для печати нормальным образом, а то из FireFox 3.6.3 информация распечатывается в виде длинного и узкого столбца читать который не возможно(((
Если ваше сообщение не спам, то даже не знаю что сказать 🙂 у меня у самого последний ФФ и все корректно
Теперь понял, сори, поправлю, спасибО!
А как быть с хостингами не поддерживающих php_apc? Может есть какое нибудь альтернативное решение?
пока не знаю, на ум приходит только использование CGI