Как стать автором
Обновить

Upload progress средствами PHP 5.4

PHP *
Из песочницы
В текущее время существует множество вариантов определения прогресса загрузки файла: как с помощью клиентских технологий, так и с помощью серверных. Примером клиентских технологий служат swfupload с использованием Flash, примером серверных — nginx_uploadprogress_module.
Грядущий релиз PHP преподносит нам подарок в виде родного инструмента для определения прогресса закачки файла.
Разберемся с ним.

Пока еще PHP находится в стадии RC, но в скором времени он появится на выделенных серверах, VDS и особо смелых хостингах. В любом случае в неопределенном будущем PHP 5.4 станет основной ветвью, а PHP 5.3 объявят deprecated.
Начнем с формы:

<form action="" method="POST" enctype="multipart/form-data">
    <input type="hidden" name="<?=ini_get("session.upload_progress.name")?>"
            value="uniqueValue" /><br />
    <input type="file" name="file" /><br />
    <input type="submit" />
</form>


Единственное примечательное в ней место — скрытое поле с именем PHP_SESSION_UPLOAD_PROGRESS(которое может меняться, поэтому определено здесь через функцию). И любым уникальным значением.

Поместим форму в iframe на целевую страницу.
И поместим туда же наш скрипт для определения процента загрузки:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script>
    $(function() {
        setInterval(function() {
            $.get('?ajax', function(data) {
                $('#ajax').html(data);
            });
        }, 500);
    });
</script>
<div id="ajax"></div>

Для асинхронного запроса я применил библиотеку jQuery для уменьшения кода и улучшения его читаемости.
В данном случае все, что мы получаем из асинхронных запросов, я вывожу в блок с идентификатором ajax.

И последняя часть — серверный обработчик асинхронного запроса:

if (isset($_SESSION["upload_progress_uniqueValue"])) {
    $progress = $_SESSION["upload_progress_uniqueValue"];
    $percent = round(100 * $progress['bytes_processed'] / $progress['content_length']);
    echo "Upload progress: $percent%<br /><pre>" . print_r($progress, 1) . '</pre>';
} else {
    echo 'no uploading';
}

Это отладочный вариант, и он содержит ненужные для рабочего проекта данные. Но мы просто хотим на них посмотреть и тоже вываливаем в ответ.

Помещаем это все на одну страницу, код небольшой(полстраницы) и поэтому я выложу его прямо здесь:
<?php
session_start();
$uploadName = 'test'; // уникальное имя
if (isset($_GET['ajax'])) { // асинхронный запрос
    if (isset($_SESSION["upload_progress_$uploadName"])) { // файл загружается в данный момент
        $progress = $_SESSION["upload_progress_$uploadName"];
        $percent = round(100 * $progress['bytes_processed'] / $progress['content_length']);
        echo "Upload progress: $percent%<br /><pre>" . print_r($progress, 1) . '</pre>';
    } else {
        echo 'no uploading';
    }
    exit;
} elseif (isset($_GET['frame'])) { // покажем фрейм ?>
    <form action="" method="POST" enctype="multipart/form-data">
        <input type="hidden" name="<?=ini_get("session.upload_progress.name")?>"
                value="<?=$uploadName?>" /><br />
        <input type="file" name="file" /><br />
        <input type="submit" />
    </form>
<?php } else { ?>
    <iframe src="?frame" height="100" width="500"></iframe>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
    <script>
        $(function() {
            setInterval(function() { // вызываем периодически
                $.get('?ajax', function(data) { // и принимаем значения
                    $('#ajax').html(data); // записывая их на страницу
                });
            }, 500);
        });
    </script>
    <div id="ajax"></div>
<?php }

Верстка невалидная — специально сокращена для примера настолько, насколько возможно.

Скриншот для наглядности:


Статья предоставляет базовые сведения, которые можно найти и в документации, но в виду того, что в текущей актуальной документации этого нет, а в книгах — тем более, я посчитал, что она будет полезна для PHP-разработчиков.
Теги:
Хабы:
Всего голосов 101: ↑94 и ↓7 +87
Просмотры 18K
Комментарии Комментарии 73