Загрузка файлов с помощью SWFUpload и PHP

Владимир | | HTML, JavaScript, PHP, Web разработка.

swfupload

О загрузке файлов на сервер рассказывается, наверное, в каждой книге о веб разработке. Обычно при этом приводится пример формы с тегом input type=file и объясняется, как работать с массивом $_FILES на стороне сервера. Это классический вариант. Он отлично работает, но имеет несколько ограничений.

1) Чтобы загрузить несколько файлов, нужно создать несколько тегов input. При этом пользователь должен будет выбирать каждый файл отдельно, что довольно неудобно при большом количестве файлов.

2) Невозможно показать процент загрузки файла.

3) Загрузка нескольких файлов будет выполнена в одном запросе. Тут нет ничего плохого, но может возникнуть проблема, если на сервере установлены ограничения на максимальный объем запросов и время выполнения скриптов.

4) Загрузка не будет асинхронной, т.е. произойдет перезагрузка страницы.

На сегодняшний день существует два основных варианта решения этих проблем. Использование iframe или flash (по-идее, silverlight тоже можно использовать для этих целей).

Кстати, о решении с помощью iframe я раньше рассказывал (Как реализовать асинхронную загрузку файлов с помощью JavaScript и PHP).

Сегодня речь пойдет об использовании flash, а точнее библиотеки SWFUpload.

На мой взгляд, это одно из лучших решений, т.к. несмотря на то, что отправка файлов осуществляется с помощью flash, настройка, управление и отслеживание процесса загрузки выполняется с помощью JavaScript.

Пересказывать возможности SWFUpload я не буду, просто покажу небольшой пример её использования.

Постановка задачи.

Допустим нам необходимо позволить пользователю загружать фотографии на сервер. При этом, сразу после загрузки они должны появляться внизу страницы.

Шаг 1. Создаём главную страницу (index.php).

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">

<head>
    <title>SWFUpload</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
    <h1>SWFUpload</h1>
    <div id="uploadButton"></div>
    <div id="status"></div>
    <div id="images"></div>
    <script type="text/javascript" src="js/jquery-1.4.2.min.js"></script>
    <script type="text/javascript" src="js/swfupload.js"></script>
    <script type="text/javascript" src="js/plugins/swfupload.queue.js"></script>
    <script type="text/javascript" src="js/main.js"></script>
</body>
</html>

Здесь мы создали три блока.

uploadButton – предназначен для размещения кнопки загрузчика.

status – здесь мы будем выводить сообщения о процессе загрузки.

images – в этом блоке будут показаны загруженные картинки.

В конце страницы подключены 4 js файла.

Первый – библиотека jquery (её использовать необязательно, я просто хотел немного сократить количество js кода в примере).

Второй – swfupload.js. Это основной скрипт библиотеки SWFUpload. Именно он создаёт кнопку загрузки.

Третий — plugins/swfupload.queue.js. Тоже входит в состав библиотеки. Позволяет загружать несколько файлов одновременно.

Четвёртый — main.js. Здесь находится код настройки библиотеки и обработчики событий. Его мы сейчас и рассмотрим.

Шаг 2. Настраиваем SWFUpload.

Для того, чтобы подключить библиотеку, нужно создать объект SWFUpload и передать ему хеш с настройками.

Делается это следующим образом (код из файла main.js).

var swfu = new SWFUpload(
	{
		upload_url : "upload.php",
		flash_url : "swfupload.swf",
		button_placeholder_id : "uploadButton",
		
		file_size_limit : "2 MB",
		file_types : "*.jpg; *.png; *.jpeg; *.gif",
		file_types_description : "Images",
		file_upload_limit : "0",
		debug: false,

		button_image_url: "button.png",
		button_width : 100,
		button_height : 30,
		button_text_left_padding: 15,
		button_text_top_padding: 2, 
		button_text : "<span class=\"uploadBtn\">Обзор...</span>",
		button_text_style : ".uploadBtn { font-size: 18px; font-family: Arial; background-color: #FF0000; }",
		
		file_dialog_complete_handler : fileDialogComplete,
		upload_success_handler : uploadSuccess,
		upload_complete_handler : uploadComplete,
		upload_start_handler : uploadStart,
		upload_progress_handler : uploadProgress
	}
);

Думаю, названия большинства параметров говорят сами за себя, но хочу обратить ваше внимание на некоторые моменты.

В параметре upload_url мы указываем адрес php скрипта, который принимает файлы.

С помощью параметров flash_url и button_placeholder_id указываем адрес флеш ролика, который создаёт кнопку загрузки и id элемента на странице, в котором эта кнопка будет размещена.

Затем идет несколько параметров, устанавливающих ограничения на загрузку файлов. Здесь указаны допустимые разрешения файлов, их максимальный размер и количество файлов, которые можно загрузить за один раз (0 – любое количество).

После этого указываем параметры, настраивающие внешний вид кнопки загрузки. Эта часть обязательная, т.к. по-умолчанию кнопка имеет размер 1х1 пиксель, и пользоваться ей будет невозможно.

Т.к. кнопка представляет собой флеш ролик, оформить её напрямую с помощью CSS не получится, но с помощью этих параметров вы можете указать фоновую картинку, шрифт и положения текста.

Оставшиеся параметры устанавливают обработчики событий. Рассмотрим их подробнее.

function uploadSuccess(file, serverData) {
	$('#images').append($(serverData));
}

function uploadComplete(file) {
	$('#status').append($('<p>Загрузка ' + file.name + ' завершена</p>'));
}

function uploadStart(file) {
	$('#status').append($('<p>Начата загрузка файла ' + file.name + '</p>'));
	return true;
}

function uploadProgress(file, bytesLoaded, bytesTotal) {
	$('#status').append($('<p>Загружено ' + Math.round(bytesLoaded/bytesTotal*100) + '% файла ' + file.name + '</p>'));
}

function fileDialogComplete(numFilesSelected, numFilesQueued) {
	$('#status').html($('<p>Выбрано ' + numFilesSelected + ' файл(ов), начинаем загрузку</p>'));
	this.startUpload(); 
}

Сразу хочу обратить ваше внимание. В этом примере использованы не все события, более полные примеры вы найдете на официальном сайте библиотеки.

Начнем с события file_dialog_complete. Оно возникает, когда пользователь выбирает файлы и нажимает кнопку «Open». В его обработчике (fileDialogComplete) вам обязательно нужно запустить загрузку (сама по себе она не начнётся!).

this.startUpload();

Также обратите внимание, что обработчик события upload_start должен возвращать true, для того, чтобы загрузка началась.

Большинство из приведённых здесь обработчиков, получают объект file в первом параметре. Как несложно догадаться в нём содержится информация о загружаемом файле. Имя файла можно получить так — file.name.

Ещё один интересный момент – разница между событиями upload_success и upload_complete. Первое срабатывает после того, как flash ролик завершает отправку файла, второе – после того как приходит ответ сервера. Учтите, что если вы после загрузки картинки на сервер будете выполнять её обработку (масштабирование, например), то задержка между этими событиями будет заметной.

В данном случае сервер просто возвращает тег img для загруженной картинки.

Шаг 3. Создаём серверный скрипт (upload.php).

<?php

$uploadDir = 'uploads/'; //папка для хранения файлов

$allowedExt = array('jpg', 'jpeg', 'png', 'gif');
$maxFileSize = 2 * 1024 * 1024; //2 MB

//если получен файл
if (isset($_FILES)) {
    //проверяем размер и тип файла
    $ext = end(explode('.', strtolower($_FILES['Filedata']['name'])));
    if (!in_array($ext, $allowedExt)) {
        return;
    }
    if ($maxFileSize < $_FILES['Filedata']['size']) {
        return;
    }
    if (is_uploaded_file($_FILES['Filedata']['tmp_name'])) {
        $fileName = $uploadDir.$_FILES['Filedata']['name'];
		//если файл с таким именем уже существует...
        if (file_exists($fileName)) {
            //...добавляем текущее время к имени файла
            $nameParts = explode('.', $_FILES['Filedata']['name']);
            $nameParts[count($nameParts)-2] .= time();
            $fileName = $uploadDir.implode('.', $nameParts);
        }
        move_uploaded_file($_FILES['Filedata']['tmp_name'], $fileName);
        echo '<img src="'.$fileName.'" alt="'.$fileName.'" />';
    }
}

В принципе, это один из самых простых вариантов скрипта загрузки файлов. Я уже упоминал, что SWFUpload отправляет файлы в отдельных запросах, поэтому в массиве $_FILES может быть только один файл.

Вначале скрипта указываем папку для загрузки файлов, допустимые расширения и размер. Эти же параметры указаны и при настройке flash загрузчика, но напоминаю, что доверять полученным от клиента данным нельзя.

Затем выполняем проверки (строки 11-18) и с помощью функции move_uploaded_file копируем загруженный файл в указанную папку.

Если файл с таким же именем уже был загружен, то добавляем к имени файла текущее время.

После этого, формируем тег img и отправляем его браузеру.

Как видите, ничего сложного. Использование библиотеки сводит количество вашего кода к минимуму. Хотя, если вы захотите создать красивый интерфейс, наглядно иллюстрирующий процесс загрузки, то поработать всё же придется 😉

Если хотите поэкспериментировать, качайте архив с этим примером.

Source

Вы можете распаковать его в любую папку на вашем сервере. Только убедитесь, что папка uploads доступна для записи.

Будут вопросы или замечания – пишите!

Удачи!

  • Спасибо =)

  • Игорь

    Спасибо за статью. Никогда не возникало ошибки 2038 при аплоаде нескольких файлов?

  • Объясните зачем загружать через SWFUpload или PHP когда есть куча FTP клиентов, которые все сделают быстро и без ошибок 🙂

    • Попробуй это же сказать блонде загружающей свои фоточки вкантактик.

  • пример задачи:
    есть форма через которую пользователь заливает картинки. К-во картинок выберает пользователь.
    (к примеру фотоальбом ВКонтакте).
    По 1 файлу(фотке) выбирать напряжно.
    + прогрес бар , красота …

  • Pingback: Дайджест за тиждень. Випуск №6, 20 серпня | Блоґ Виспянського Ігоря()

  • Очень удобно, спасибо!

  • Привет!
    А как несколько кнопочек-загрузчиков разместить на странице?

    Подскажите, пожалуйста, буду очень благодарен!

    Спасибо!

  • seomoney

    Спасибо. Очень удобно и практично!

  • Ошибки были, не уверен, что именно 2038, т.к. flash «падал» полностью.
    Убрал в настройках swfupload режим отладки.
    debug: false
    После этого проблемы исчезли.

    • Pavel Burdonow

      Здравствуйте Владимир, как мне можно с Вами связаться? Можно Ваши контакты? Или добавьте меня по следующим контактам:
      Skype: pawlay_hr1;
      ICQ: 656639387;
      Нужно реализовать одну схему, связанную с этим материалом, дело простое. За работу заплачу.

  • 1) Если вы не хотите или не можете предоставить ftp доступ.

    2) Если нужно выполнять какие-нибудь действия после загрузки файлов, например, создание миниатюр для картинок.

  • Я лучше дам ссылку на готовый пример
    http://demo.swfupload.org/v220/multiinstancedem

    Общая идея такая
    upload1 = new SWFUpload({
    //настройки для загрузчика 1
    })

    upload2 = new SWFUpload({
    //настройки для загрузчика 2
    })

  • orcoved

    Спасибо за статью и ссылки!
    Подскажите как сделать так чтобы фотки выводились по 3 штуки в строке?
    Я пробовал так:
    <div id=»uploadButton»></div>
    <div id=»status»></div>
    <div id=»images» width=»400px»></div>

    и так:
    <div id=»uploadButton»></div>
    <div id=»status»></div>
    <table id=»images» width=»400px»></table>

    и так:
    <div id=»uploadButton»></div>
    <div id=»status»></div>
    <table width=»400px»>
    <div id=»images»></div>
    </table>

    Но все равно фотки грузятся в 1 строку ((

  • Если вы используете таблицу, то где теги td и tr ?
    Если без таблицы (внутри div), то все зависит от размера фотографий. Вы задаете общую ширину 400px, значит ширина изображений должны быть не более 133px.
    Просто добавляйте теги img внутрь div.

    • Freddyblazin

      фотки

      • Frankenstein

        прошу прощения, не block, a inline-block;

        • inline-block к какому элементу применяется?

  • Anonimous

    А меня интересует другой аспект:
    файлы загружаются флешкой. Флешка выполняется хоть и в браузере, но как бы с компа — тобишь даже если пользователь авторизовался на сайте, флешка (флеш-аплоадер, расположенный на этом сайте) не знает об этом — не посылает куки. Или это у меня глюк?

    А чтобы серверная часть заработала, приходится отключать проверку авторизации, а в этом случае пользователь может подменить данные и, например, загруженные им картинки присвоить другому юзеру и т.п…

    Как вы выкручиваетесь? Или это я что-то сделал не так?

    • Нет, эта проблема не только у вас.Обсуждение можно почитать здесь.Кроме того, есть страница, демонстрирующая этот баг —http://demo.swfupload.org/v220/cookiebugdemo/index.phpТакже в дистрибутив входит плагин swfupload.cookies.js, которыйавтоматически собирает все cookie и добавляет их в post_params.

      • А можно попросить продублировать ссылку на обсуждение или возможные решения? Что-то я не могу разобраться как заставить COOKIE работать под IE.

        • «The page you asked for does not exist.», но это впрочем символично… устарел swfUpload… к сожалению.

        • К сожалению, вы правы. Последняя версия swfUpload вышла в марте 2010. Хотя, flash решения для построения графиков до сих пор используются очень широко. Например, не смотря на то, что Google активно продвигает JavaScript, в Google Analytics графики реализованы с помощью flash.

  • Не плохо, сегодня попробую этот метод на деле)

  • Andrey

    Полезная статья. Но у меня возник вопрос: можно ли скрыть флешовую кнопку, и вызвать диалог выбора файлов с помощью JS?

  • Andrey

    Полезная статья. Но у меня возник вопрос: можно ли скрыть флешовую кнопку, и вызвать диалог выбора файлов с помощью JS?

    • Andrey

      Пробовал swfu.getMovieElement().SelectFiles()
      Не работает :=(
      Может я что то делаю не так, или это в принципе не предусмотрено?

      • В документации насчет selectFiles() сказано

        Deprecated. Not compatible with Flash Player 10.

        Готового метода для открытия окна я не нашел. Но, наверное, вам лучше задать этот вопрос специалисту по флешу.

  • Nabla

    Привет! Очень хорошая статья — наконец-то нашел, что хотел.
    Но.
    Мне не нравится само отображения процесса загрузки.
    Например:
    Выбрано 1 файл(ов), начинаем загрузку
    Начата загрузка файла slezy remix.mp3
    Загружено 0% файла slezy remix.mp3
    Загружено 3% файла slezy remix.mp3
    Загружено 4% файла slezy remix.mp3
    Загружено 6% файла slezy remix.mp3
    Загружено 7% файла slezy remix.mp3
    Загружено 8% файла slezy remix.mp3

    Как это можно изменить?
    Хотелось бы, чтобы обновлялась строчка — а не создавались новые строчки.

    • Измените uploadProgress. Вместо append используйте html.Например$('#status').html($('Загружено ' + Math.round(bytesLoaded/bytesTotal*100) + '% файла ' + file.name + ''));

  • Flame

    Здравствуйте, возможно вы сможете помочь….
    SWFUpload — проблема в следующем маленькие файлы грузит на ура! а вот с файлами более 2MB работать отказывается, аякс работает проценты пробегают, но вот перемещения не происходит (по всей видимости с функцией move_uploaded_file проблемы или в флэшэ может быть зашито ограничение)…..
    Объём разрешенных файлов в файлах сменил….
    upload.php
    <?php
    set_time_limit(0);
    $uploadDir = '../uploads/';
    $allowedExt = array('jpg', 'jpeg', 'png', 'gif');
    $maxFileSize = ((2 * 1024) * 1024) * 1024;
    if (isset($_FILES)) {
    $ext = end(explode('.', strtolower($_FILES['Filedata']['name'])));
    if (!in_array($ext, $allowedExt)) {
    return;
    }
    if ($maxFileSize

    main.js
    $(document).ready(function() {
    function uploadComplete(file) {
    $('#status').html($('Загрузка завершена'));
    }
    function uploadStart(file) {
    $('#status').html($('Начата загрузка файла ' + file.name + »));
    return true;
    }
    function uploadProgress(file, bytesLoaded, bytesTotal) {
    $('#status').html($('Загружено ' + Math.round(bytesLoaded/bytesTotal*100) + '% '));
    }
    function fileDialogComplete(numFilesSelected, numFilesQueued) {
    $('#status').html($('Выбрано ' + numFilesSelected + ' файл(ов), начинаем загрузку'));
    this.startUpload();
    }
    var swfu = new SWFUpload(
    {
    upload_url : «SWFUI/upload.php»,
    flash_url : «SWFUI/swfupload.swf»,
    button_placeholder_id : «uploadButton»,
    file_size_limit : «100000 MB»,
    file_types : «*.jpg; *.png; *.jpeg; *.jpg; *.gif; *.JPG; *.PNG; *.JPEG; *.JPG; *.GIF;»,
    file_types_description : «Файлы»,
    file_upload_limit : «0»,
    button_image_url: «SWFUI/button.png»,
    button_width : 160,
    button_height : 23,
    button_text_left_padding: 10,
    button_text_top_padding: 1,
    button_text : «Загрузить файл(ы)…»,
    button_text_style : «.uploadBtn { font-size: 14px; font-family: Arial; font-color: #0a412d; }»,
    file_dialog_complete_handler : fileDialogComplete,
    upload_complete_handler : uploadComplete,
    upload_start_handler : uploadStart,
    upload_progress_handler : uploadProgress
    }
    );
    });
    убрал некоторые не нужные вещи что с ними что без них не перемещает более 2 MB

    • Andrey

      В php.ini есть ограничение
      upload_max_filesize = 2M
      Подправьте ini файл, если есть к нему доступ, или в upload.php в начале добавьте
      ini_set(«upload_max_filesize», «32M»);
      Вместо 32mb желаемую величину.

      • SavenetsNN

        а как сделать функционал для отмены загрузки?

        • SavenetsNN

          И еще, почему Не могу при неправильном размере показать ошибку юзерам. Последнее что происходит это this.startUpload(); После этого концы теряются. не привета не ответа. Подскажите пожалуйста как побороть

          А так ваш скрипт бомба хотябы можна разобраться нормально, не то что офф примеры. ппц (два дня насмарку)

        • Есть две функции cancelUpload и stopUpload. Думаю, одна из них вам подойдет.

          Насчет ошибки ничего конкретного сказать не могу. По-идее, должно возникать событие uploadError. Попробуйте поменять версию плагина, обновить flash и т.д.

        • SavenetsNN

          еще вопросик. как бы мне с бекенда upload.php возвращать json объект. пробовал в upload.php писать
          $name,
          'type' => $type
          );

          echo json_encode($json);
          ?>

          не могу никак в main.js его принять пробовал eval или просто serverData.name не выходит

          Подскажите пожалуйста если можна на примере потому что перепробовал пару возможных вариантов пишет undefined

        • Смотрите firebug'ом что приходит от сервера. Потому что код, который вы привели, правильный.

        • Vic

          Для IE обязательно нужно выдавать заголовок, например
          header(«Content-type:text/plain; charset=utf-8»);

  • У меня возникла проблема загрузки видео файлов с использованием SWFUpload в CodeIgniter. Может, кто сталкивался? Подскажите, пожалуйста. Там нужно добавить mime типы правильные.

    • С такой проблемой сталкивался, правда, довольно давно.
      По-моему, я просто вывел содержимое массива
      $this->upload->data() и в нем посмотрел mime тип, который передается браузером. После этого просто прописал этот тип в allowed_types. В config/mimes.php есть массив со всеми типами.

      И еще, желательно проверять работу загрузчика в нескольких браузерах, т.к. mime тип может меняться. Хотя в данном случае этого не должно происходить, т.к. отправка осуществляется с помощью flash.

      • Спасибо, Владимир. Буду разбираться.

  • Flame

    Здравствуйте снова 🙂
    Andrey с размерами файлов разобрался СПАСИБО БОЛЬШОЕ!, но нарисовалась новая проблема а именно с сессиями, скрипт под названием upload.php не в какую не хочет запускать сессию и брать оттуда данные… как-то можно решить эту проблему, очень нужно…..

    • Andrey

      Нужно передавать параметры сессии через POST, для этого нужно добавить
      var swfu= new SWFUpload({

      post_params: {«»: «»},

      })

      • Andrey

        там были PHP теги, при добавлении коммента обрезались
        post_params: {«session_name()»: «session_id»}

        • Я дополню ответ ссылкой на решение для CI.

        • Flame

          Andrey, Владимир — Огромное вам спасибо! 🙂 очень выручили к тому же ещё небольшой багаж знаний дали в придачу 🙂

        • Iam

          для этого надо код создания аплоадера вынести из main.js в какой-либо php исполняемый шаблон

  • SavenetsNN

    А как добавить параметр serverData в функцию
    function uploadComplete(file) ???

    Подскажите очень надо!

    • Обработчкик uploadComplete параметр serverData не передается, поэтому напрямую получить его нельзя. Но можно сделать так:

      1) Установить обработчик uploadSuccess (он будет вызван ранее uploadComplete и получит serverData).

      2) В этом обработчике (uploadSuccess) присвоить serverData какой-нибудь глобальной переменной (объявлена за пределами обработчика, можно объявить ее в самом начале скрипта).

      3) В обработчике uploadComplete прочитать данные из этой переменной.

  • Zimpsonz

    Вот проблемка не получается вывести имя файла функцией echo
    . Подскажите в какой переменной хранится само имя, все перепробовал и не выводит=(

    • В массиве $_FILES

      • Xtra

        никак не вывести echo со ссылкой на файл 🙁

  • usp

    А у меня не загружаются файлы размером больше 8 мегабайт. В php ini ограничение стоит 2 GB, а в swfuploader'e file_size_limit : «2048 MB».
    Не понимаю, в чем дело, может, кто сталкивался?

    • У меня тоже была такая проблема. Посмотрите в php.ini переменную post_max_size

    • Sulatskov Vladimir

      php.ini
      Параметры : upload_max_filesize и post_max_size.

    • Gagaevmark

      у вас скорее всего в настройках сервера стоит не более 8 мб. какой у вас сервер?

      • Gagaevmark

        сорри спросонок, в настройках пхп

  • Reddog

    Спасибо 🙂

  • Dema

    А как сделать чтобы ф-л upload.php введенный через строку браузера (напр. ввв.сайт.ру/upload.php) не выполнялся?

    • Для данного примера — никак, т.е. если вы запретите его выполнение, то и файлы загружаться не будут.
      Просто проверяйте в upload.php все значения и выдавайте соответствующий ответ.

    • Andrey

      В начале upload.php добавить:
      if(!$_FILES) exit(«there is no uploaded files»);

  • codefather

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

    • Да, можно.
      Добавьте обычное текстовое поле. Далее, в uploadComplete (вызывается после успешной загрузки файла) добавляете отправку ajax запроса в котором и передайте нужный текст.
      Естественно, на сервере должен быть скрипт, который обработает запрос и сохранит текст в БД.

      • Iam

        да
        спасибо. так и сделал.
        кстати, что странно
        не обрабатываются ошибки
        например, если upload php нет в принципе, весь процесс проходит якобы успешно, разве только uploadComplete не происходит. диагностики нет

        • Iam

          добавлю вопрос
          а как правильно дебажить?
          вот я правлю upload.php
          заменяю странные if ($maxFileSize < $_FILES['Filedata']['size']) {
          return;
          }
          на
          die ('too big file');

          а как теперь в клиенте поймать это сообщение?

        • Вообще, есть специальные программы — снифферы, которые позволяют анализировать весь сетевой трафик.

          Но часто удобнее просто вести лог на сервере. Большинство фреймворков имеет встроенные библиотеки для ведения логов. Если фреймворк не используется, можно попробовать эту библиотеку (на освоение уйдет минут 10).

    • Andrey

      Через пост параметры
      swfu.addPostParam(«name», «value»);

  • Большое спасибо, рабочий пример.
    Возникает только сложность с загрузкой файла например: 1 Canto para limpiar malas energias y diablos.mp3
    swfup говорит, что все загружено, а на серваке ничего не появляется.
    в $_FILE пусто
    при этом с другими файлами такого не возникает, даже с таким «2 типа 2.mp3»

    • Проверьте размер файла, во втором листинге, строка 7 установлено ограничение
      file_size_limit : «2 MB»,

  • Xpaco

    Огромное человеческое спасибо 🙂
    -Programax Team http://www.progra-max.ru

  • Xaoc-

    Приятный сайт у Вас 🙂
    Подскажите, может ли этот аплоадер загружать не только изображения но и файлы другого типа? (*.rar, *.psd)? И если да, то как это реализовать?

    • Xaoc-

      Так, разобрался как с *.rar, не могу понять почему тоже самое не прокатывает с *.psd??

      • Уточните, пожалуйста. psd файл не отправляется на сервер или не принимается сервером? Не понятно где искать проблему, в настройках swf uploader или есть какие-то ограничения на стороне сервера.

  • Роман

    Выводится только надпись SWFUpload. Что делать?

    • Посмотреть firebug'ом какие запросы были отправлены и какие скрипты загрузились.

  • Sergserg1

    Спасибо за статью!!!
    Я исп

    Я использую этот скрипт для выгрузки на сервер фото и отображения их в ДИВе с ID «thumbnails». Нужно что бы рядом с каждым фото появлялась маленькая кнопочка или ссылка при нажатии, на которую загруженное фото удаляется.

    На одном сайте нашел реально работающий скрипт удаления

    function addImageToMaxCount(){
    var oldVar = parseInt(swfu.getSetting('file_upload_limit'));
    if (isNaN(oldVar)) oldVar = 0;
    var newVal = oldVar + 1;
    swfu.setFileUploadLimit(newVal);
    swfu.setFileQueueLimit(newVal);
    }
    $('#thumbnails a').click(function(){
    $.ajax({
    url: $(this).attr('href'),
    cache: false
    });
    $(this).parent().remove();
    addImageToMaxCount();
    return false;
    });

    Сам скрипт загрузки выглядит примерно так

    var swfu;
    var sid = 'rql399h93i64ijcmdttsnqqdv1';
    $(document).ready( function () {
    var maxUpload = parseInt('5') — $('#thumbnails .uploadsList').size();
    if (maxUpload < 1) maxUpload = 'null';
    swfu = new SWFUpload({
    // Backend Settings
    upload_url: "/uploadphoto.php",….
    ….
    file_upload_limit : maxUpload,
    file_queue_limit : maxUpload,…

    Но у меня функция удаления не работает, поскольку я не знаю, как сделать так чтобы в ДИВе thumbnails в процессе загрузки фотографий появлялись тэги a с атрибутами attr('href')и элементами parent(). Функцию удаления должен вызывать JQuery при клике на $('#thumbnails a')

    • Вы не сможете удалить файл на сервере с помощью только JavaScript.
      Нужен серверный скрипт (PHP), который и будет удалять файлы.

      • Sergserg1

        Владимир,
        Если Вы внимательно посмотрите на код функции удаления, а именно на фрагмент
        $('#thumbnails a').click(function(){
        $.ajax({
        url: $(this).attr('href'),
        cache: false
        });
        $(this).parent().remove();
        addImageToMaxCount();
        return false;
        });
        То увидите, что JavaScript на сервере ничего не удаляет, а обнуляет на клиенте атрибут href для тега и удаляет родительский для него контейнер $(this).parent().remove() которым очевидно является картинка thumbnail
        Все эти манипуляции выполняются на клиенте. Сами изображения, вероятно, сохраняются не в сессии, а в кеше сервера.
        Скрипт удаления всего лишь очищает атрибут href тега
        и удаляет его родительский контейнер, т.е. картинку.
        Приведу пример сайта где сделано то что я имею ввиду: возможность удаления картинки на клиенте
        http://unidom.ua/advertisment/addflat/type/sale/
        Там рядом с каждой картинкой есть крестик, чтобы ее удалить. Удаление идет только на клиенте. Сделано изящно!!
        Владимир, попробуйте предположить как именно сделанно.
        Удаление некоторых из загруженных картинок это напрашивающийся и востребованный функционал, и странно, что он не включен в SWFUpload

        • Я понял, в общих чертах, что Вы хотите сделать. Давайте рассмотрим процесс загрузки.

          1. С помощью SWFUpload Вы отправляете картинки на сервер. Обратите внимание, отправляете, а не сохраняете. Ни одна клиентская технология не может работать с файлами на сервере напрямую.

          2. Серверный скрипт (в моем примере это upload.php) сохраняет файл в папку на сервере ($uploadDir) и формирует тег img. Обратите внимание, SWFUpload или JS скрипт не смогут правильно установить атрибут src тега img, т.к. не знают куда серверный скрипт сохранил картинку.

          3. Браузер получает ответ от upload.php и может показать его. Тут вариантов может быть очень много. Например, Вы хотите получить следующую разметку.

          <a href="#">Удалить</a>

          Тогда можно использовать следующий JS код.


          var link = $('<a href="#">Удалить</a>');
          var container = $('').append(img).append(link);
          $('#thumbnails').append(container);

          Тут предполагается, что в переменная img содержит ответ от upload.php, т.е. тег img.

          4. Удаление картинки. Для этого нужно создать обработчик события клика по ссылке.

          $('div.thumb').live('click', function() {
          $(this).parent().remove();
          });

          В таком виде обработчик удалит картинку со страницы, но не с сервера! Для удаления картинки с сервера можно отправить ajax запрос серверному скрипту, который и будет удалять картинку.
          В примере, который Вы привели, этот запрос выглядит так.


          $.ajax({
          url: $(this).attr('href'),
          cache: false
          });

  • Tatyana

    Доброго дня!
    А скажите, пожалуйста, а как сделать, чтобы имя файла заменялась на другое, автоматически.
    Насколько я понимаю, $_FILES['Filedata']['name'] содержит и расширение файла, а нужно чтобы заменялось только имя на указанное в переменной.
    И еще вопрос 🙂 а как сделать, чтобы не время добавлялось, если такой файл уже в базе есть, а цифра добавлялась, например image? image1? image2 и т.д.

    • При вызове move_uploaded_file во втором параметре укажите нужное имя файла.

      Замените вызов time() на подходящее число.

      • Tatyana

        🙂 Спасибо, но я немного не то имела в виду. Если числло постоянное, то понятно. А если нужно, чтобы он каждый следующий одноименный файл переименовывал в $name.n+1. N/t считал количество одноименных файлов и присваивал следующему файлу номер на один больше.

        • Я понял, что вы имели ввиду. Только проблема в том, что я не знаю в каком виде хранятся ссылки на файлы в базе данных.
          В целом алгоритм выглядит так:
          1) получаем имя файла $_FILES['Filedata']['tmp_name']
          2) ищем это имя в БД (select …) при этом, скорее всего, придется использовать like в запросе, чтобы выбрать сразу все имена файлов (my_file_1, my_file_2, my_file_3 и т.д.)
          3) Формируем имя для нового файла (находим файл с самым большим номером и прибавляем к этому номеру 1).

  • Alexey Lomaka

    Полезная штука.
    Только вот как заставить ее выдавать какие-то ошибки?
    Например после загрузки, которая завершилась удачно, была проверка на что-то и обнаружилась ошибка.
    Как в статус показать эту ошибку?

    • Сервер должен отправить сообщение с описанием этой ошибки. Т.е. вместо тега img, как в этом примере (строка 28) отправьте другой текст.

  • Alexey Lomaka

    Спасибо. Разобрался.
    Просто думал
    есть встроенный обработчик сообщений и нужен формат.
    Оказалось можно с легкостью отпарсить результат и выдать то, что нужно.

  • Serg

    Спасибо за статью. Сделал на домене в зоне ru, все работает отлично, а вот в зоне рф не хочет (((

    • К сожалению, не все разработчики знают о существовании этой зоны 🙂

      • скрипт напрочь отказывается работать если домен состоит из: xn--80adxhks.xn--p1ai

        наверное есть где-то в файле swfupload.js всего-то строка которую надо поправить??

  • Lector

    Спасибо все отлично, но я не понял как разобраться с сессиями, у меня есть $_SESSION[«last_id»]=$user в одном php файле, а upload.php не видит ее все равно $last=$_SESSION[«last_id»] пишу, как мне ее поймать? очень нужно

    • В начале каждого скрипта должен быть вызов session_start

      • Lector

        пробовал, все равно не видит! как правильно передать и принять?

        • В архиве с дистрибутивом есть примеры. Смотрите
          swfupload/samples/php/upload.php

          там приведен такой код
              if (isset($_POST[«PHPSESSID»])) {
                  session_id($_POST[«PHPSESSID»]);
              } else if (isset($_GET[«PHPSESSID»])) {
                  session_id($_GET[«PHPSESSID»]);
              }

              session_start();

          Как видите, идентификатор сессии передается в массиве POST. Это связано с тем, что flash плеер не во всех случаях правильно передает cookies.

          Кроме того, может понадобиться плагин swfupload.cookies.js (тоже в архиве).

  • Dl12345665

    люди у меня вопрос есть скрипт отправки анонимных писем вапрос а можна ли прикрепить swfupload к скрипту анонимных отправок писем если можна то напишите как можна в асю 609-603-736

    • А какое отношение имеет swfupload к скрипту отправки анонимных писем?

  • Dl12345665

    Владимир: но хотябы прикрутить аттач

    • А в вашем скрипте отправки анонимных писем добавление аттача вообще предусмотрено?
      Дело в том, что swfupload только отправит файл на ваш сервер, прикрепить его к письму он не сможет.

  • яув221

    Владимир по поводу ответа: А в вашем скрипте отправки анонимных писем добавление аттача вообще предусмотрено?Дело в том, что swfupload только отправит файл на ваш сервер, прикрепить его к письму он не сможет.
    Вапрос 1; а как можна прикрепить к маему скрипту аттач, вапрос 2 слышал незнаю правда не правда но что спомощью swfupload можна закачивать фотки в кантакт и маил если это правда то поскажите как с помощью swfupload это делается

    • 1. Я не видел ваш скрипт, поэтому рассказать как к нему «прикрутить аттач» не могу 😉
      2. swfupload только отправляет файлы. Социальные сети используют свои API для загрузки файлов, публикации сообщений и т.п. Те решения о которых вы слышали, скорее всего,  выполняют загрузку файлов на собственный сервер (с помощью swfupload) и затем отправку в социальную сеть. Т.е. одним swfupload вы не обойдетесь.

  • яув221

    Владимир есть скрипт и есть две формы аттача но незнаю как их прикрепить к маему скрипту штоб ничево из маево скрипта неуберать и прикрепить аттачь вот скрипт:
    send($target,$subject,$message,$from,$times);   }  
    function html() {     error_reporting(0);         $target = $_POST['target'];         $subject = $_POST['subject'];         $message = $_POST['message'];         $from = $_POST['from'];         $times = $_POST['times'];   print »      Спамилка  мыл      body {   background-color: #350000;   color:#99ff32;   font-size: 15px;   }  
    input {   background-color: #222222;   border: 1px solid #FFFFFF;   color:#76defc;   }   a {   color: #FFFFFF;   }               E-mail Жертвы :    Текст сообщения :    Тема :    От кого :    Кол-во писем (1-9999) :                «;  
      $this->send($target,$subject,$message,$from,$times);   }  

    function send($target,$subject,$message,$from,$times) {     $headers = «From: » . $from;      $i = 1;      while($i html(); // For HTML version   #$bomb->cli(); // For CLI version  
    ?>
    ————
    в нём всё рабочия и каличество тоже правда ненакаждом сервере каличество работает, вот 1вая форма каторую я немагу прикрутить к маему скрипту с одним аттачем:
        Тег FORM, атрибут enctype        Загрузите файл с картинкой    
    ————-
    единственое што я понел тут это где handler.php тут надо праписать названия самово .php скрипта дальше мне непонятно куда ево вставлять и што праписовать?
    ————————
    Вот втарая форма толька пачему форма мне непонятно ведь по сути это должен быть готовый скрипт для отправки писем на почту но мне на форах сказали што это не скрипт а простая форма но я не согласен может проста чевото нехватает тут уже не один аттач всмысле один но с 6тью формами загрузки но припроверки этот скрипт или (форма) неработает может вы мне поможете найдёте в моих вопросах ошибки:
    E-mail : Текст сообщения : Тема : От кого : Отправить раз:

    • Вставьте формы в метод html класса Bomb.
      О каком handler.php вы пишите я тоже не понял.
      Вторая форма — это действительно только форма.

  • Гость

    Прошу прощения, а можно пути указать к файлам из/для этой библиотеки?

    • Пути указаны в первом (строки 14 и 15) и втором (строка 4) листингах.

  • Гость

    Прошу прощения, а можно пути указать к файлам из/для этой библиотеки?

  • Shurek

    На маке не работает мульти закгрузка

    • Я читал, что у SWFUpload есть проблемы при использовании на Mac и Linux. Но, насколько я понял они связаны с flash плеером и разработчики SWFUpload их решать не будут.

  • Shurek

    Но сервно спасибо очень долго искал

  • Евгений

    Здравствуйте! Подскажите, пожалуйста, как реализовать создание ссылки download на загруженный файл и вернуть его на страницу после загрузки без перезагрузки страницы? Я могу в upload.php создать линк для скачки текстом:
    $upload_link = «http://».$_SERVER [«HTTP_HOST»].dirname ($_SERVER [«PHP_SELF»]).$upload_dir.$upload_filename;
    А как передать обратно его значение?

    В этой функции выводится сообщение об успешной загрузке файла (в переменной  
    PhotosResult):
    function photos_uploadComplete(file) { try { if (this.getStats().files_queued > 0) { this.startUpload(); } else { $('#UploadPhotos').hide(); $('#Buttons').prepend(» + PhotosResult + »); } } catch (ex) { }}

    Что надо еще добавить, чтобы на каждый загруженный файл выводилась ссылка?

    • В примере шаг 3, строка 28, формируется тег img. В его атрибуте src вставляется ссылка на файл.
      Т.е. вы можете заменить эту строку на
      echo '<a href=»'.$fileName.'»></a>';

      • Евгений

        Подождите, но для этого надо, чтобы страница перезагружалась, и загружался файл upload.php. А у меня на странице с кнопкой выбора файла (swfupload) выполняется загрузка файла, передачей данных файлу upload.php, а после успешной загрузки выводит сообщение о количестве загруженных фалов (в моем случае этот параметр содержит переменная  PhotosResult). Ей значение присваивается в функции:

        function photos_fileDialogComplete(numFilesSelected, numFilesQueued) { try { if (numFilesQueued > 0) { if (numFilesQueued == 1) { PhotosResult =' файл'; } else if (numFilesQueued == 2 || numFilesQueued == 3 || numFilesQueued == 4) { PhotosResult =' файла'; } else { PhotosResult =' файлов'; } PhotosResult = numFilesQueued + PhotosResult + » загружено»; Count = parseInt(numFilesQueued); $('#AddPhotos').val('Загрузка…'); $('#submitStatus') .attr('disabled', 'disabled') .addClass('disabled'); this.startUpload(); } } catch (ex) { }}

        Вопрос в том, как вернуть в javascript ссылки на файлы, т.е. значение переменной $upload_link в upoad.php??? И как их вывести в виде ссылок поочередно?

        • Прошу прощения, не правильно понял вопрос 😉
          Все достаточно просто. Обработчик uploadSuccess в третьем параметре получает нужные данные.

          .bind('uploadSuccess', function(event, file, serverData){ var link='<a href=»'+serverData+'»>Имя файла</a>';}

          Я код не тестировал, проверьте остальные параметры, возможно, данные в них вам понадобятся.

  • Aandr83

    Подскажите как вывести это все в нужной мне кодировке? Менял в заголовке, все равно краказябры получаются.

    • Поясните, пожалуйста, что именно нужно вывести в нужной кодировке? В статье пример загрузки файла на сервер. Этот скрипт ничего не выводит кроме тега img.

  • Mark

    у меня все время пишет ошибку ввода вывода (server (IO) error). ее код вроде 2038. погуглил, решения не нашел. помогите плиз. думал с правами связано на папку для загрузки, поставил ей 777, не помогло. пути все проверил, с путями ок, но выдает эту ошибку…
    чередует иногда с ошибкой Upload Error: 404. debug стоит щас в true, если поставить false то всегда выводит Upload Error: 404. очень нужен хелп. Юзаю swfupload в проекте на symfony 1, гдето краем глаза видел что может быть связано с .htaccess… но так и не накопал ничего.
    спасибо

  • Mark

    короче, поковырялся еще чуть-чуть и кое-чего добился. в общем при выгрузке на боевой сервак(nginx) все заработало, а вот на локальном апаче так ничего и не пашет) если есть соображения, с удовольствием послушаю, спасибо

    • Делать предположения в такой ситуации — занятие не благодарное 🙂
      Судя по вашему описанию, проблема в настройках сервера.
      Прежде всего проверьте загружаются эти же через обычную форму? Таким образом, вы исключите либо сервер, либо swfupload. Если проблема в сервере, то попробуйте загрузить файлы меньшего размера с другим расширением. И проверьте параметры post_max_size, upload_max_filesize.

      • Mark

        разобрался, да у меня локальный апач не настроен как надо) спасибо

  • Piroteh

    Супер!!! После небольшой доработки только им и пользуюсь!
    Только как бы уменьшить размер выводимых изображений?…

    • Есть много хороших библиотек с помощью которых можно сделать ресайз картинки. Выбирайте любую 😉

  • Подскажите, пожалуйста,
    как мне подстроить данную загрузку
    под свои нужды:
    я хочу, чтобы картинка загружалась в единственном экземпляре
    в поле комментариев
    на стене
    социалки
    http://looonger.ru/index.php?option=com_community&view=profile&Itemid=161&lang=ru 

    • Если честно, я не вижу никакого смысла в использовании flash загрузчика для одной картинки. Если бы речь шла о большом файле или о нескольких маленьких, тогда понятно, нужно отображать процесс загрузки, а одна картинка загрузится быстрее чем посетитель рассмотрит прогресс бар.

  • Gost

    подскажите как в конце загрузки вывести надпись

    • Gost

      только в конце всей загрузки, а каждого файла

      • Используйте метод getStats(). Один из параметров, которые он возвращает files_queued — количество файлов в очереди. В конце загрузки каждого файла проверяете это значение и если оно равно 0 — выводите сообщение.

        • Gost

          А не покажете
          на примере. Я наверное делаю что то не так, и все надписи прогресса загрузки
          пропали.

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

        • Gost

          Я ничего не
          менял из вашего примера, только пытался это сделать if
          (this.getStats().files_queued = 0)

          Но может по
          незнанию или малоопотности ничего не выходит. Там выкладывать нечего.

          Покажите кусочек
          кода, где это работает, заранее благодарен.

        • Gost

          вроде разобрался:
          function uploadComplete(file) {        if (this.getStats().files_queued === 0) {                $('#status5').html($('все'));        }}

  • Liblit

    Как  при загрузке выводить
    кнопку стоп, вместо обзор. Покажите на примере,  если можно.

    • Замените в строке 18 (шаг 2) слово «Обзор…» на «Стоп» 🙂

      • Liblit

        Вы не так
        поняли. В процессе загрузки, чтоб выводилась кнопка стоп вместо кнопки обзор, с
        соответствующим действием (остановка  или
        отмена всей загрузки)

        • Дело в том, что убирать кнопку «Обзор…» не совсем правильно. Она представляет собой swf объект и выполняет загрузку.

          Но можно сделать ее не активной. Для этого, нужно картинку (параметр button_image_url), которая используется для отображения кнопки сделать в виде спрайтов. Спрайты должны идти в следующем порядке: normal, hover, down/click, disabled.

          После этого, в обработчик события начала загрузки добавляем вызов
          setButtonDisabled

          function uploadStart(file) {
              $('#status').append($('Начата загрузка файла ' + file.name + »));
              this.setButtonDisabled();

              return true;
          }

          Создаем кнопку отмены загрузки.

          На страницу добавляем

          И обработчик клика по этой кнопке$('#stopUpload').click(function() {
              swfu.cancelUpload();
              return true;
          });

        • Liblit

          Извините, а
          вы пробовали этот метод setButtonDisabled, просто у меня кнопка остается кликоспособной.

        • Да, проверял. Но пример в предыдущем комментарии я написал по памяти и допустил небольшую ошибку. Должно быть так:
          swfu.cancelUpload(true);

  • Andriy

    добрый день, как можно создать всплывающую подсказку для кнопки разгрузчика 
    button_placeholder_id : «uploadButton»? спасибо

    • В принципе, подойдет любое готовое решение для создания подсказок (поищите javascript tooltip).

      Можно реализовать и свое решение. Отслеживаете событие mouseover. В его обработчике создаете div с подсказкой. Этот div позиционируете абсолютно и «привязываете» к координатам курсора.

      • Andriy

        мне не совсем понятно  как реально привязать тот же tooltip или другой элемент подсказок к конкретному объекту — swfupload swfu? вы можете показать маленький пример такой реализации проблемы? спасибо

        • Пример маленьким не получится. Я очень рекомендую вам попробовать одно из готовых решений для создания подсказок.  В их документации есть много готовых примеров и они гораздо лучше чем маленький пример в комментариях 😉

  • Гость

    Отличная вещь,
    спасибо.

    Только один
    момент интересует: как скрипту upload.php передать дополнительные данные,
    допустим размер изображения, для уменьшения?

    • Есть пример в комментариях к статье на форуме

      • Гость1

        Пример в комментариях
        не работает. По крайней мере у меня заставит его передавать значения не
        получилось. Есть у кого этот метод заработал?

        • Что именно не работает? SwfUpload не передает POST параметр? Попробуйте использовать addPostParam

        • Гость1

          Да, не передает POST параметр. Можете небольшой рабочий  кусок кода в качестве примера привести.

        • Без проблем — http://pastebin.com/rJMyfixT
          За основу взят код из этой статьи и добавлен параметр test (строка 13).

        • Гость1

          http://pastebin.com/rJMyfixT

          добавлен параметр
          test (строка 13).

           

          На IE этот метод не работает. на Firefox и
          Chrome прекрасно передается.

          Есть какие решения для IE

        • Странно, я видел сообщения об обратной ситуации. Хотя в них речь, наверное, шла о старых версиях FF.
          Параметры не передаются во всех версиях IE или каких-то конкретных?

        • Гость1

          У меня
          подключен swfupload.cookies.js, без него Firefox теряет сессию.

          Проверял на  IE9, сессию и без подключенного не теряет, а вот POST не передает.

           

          И на твоих
          ответах исчезла кнопка ответить

        • Если количество данных в параметрах не очень большое, можно попробовать использовать setUseQueryString.

          Кнопка «Ответить» исчезает, т.к. ограничен уровень вложенности комментариев. Можно ответить на комментарий на 1 уровень выше, тогда новый комментарий появится в конце этой же ветки.

  • Denri82

    Есть небольшая
    проблема. Это вроде уже поднималось в комментариях, но все же. Не загружает
    картинки тяжелее 4 Мб. У хостера стоит ограничение 8 Мб, специально в суппорт
    долбился. В вашем скрипте в строке file_size_limit, поставил тоже 8 Мб.

     Картинку в 3980 Кб загружает за 64 секунды, а
    вот картинку 4046 Кб доходит до 42 % примерно за 30 секунд, и все конец, и
    никаких ошибок не выдает.

    Прописывал в htaccess строчки

    php_value max_execution_time 300

    php_value max_input_time 300

    php_value upload_max_filesize 8M

    php_value post_max_size 8M

    никакого эффекта.

    Может в этом
    скрипте еще где ограничения есть?

    • SWFUpload действительно может ограничивать допустимый размер файла. Смотрите функцию setFileSizeLimit

      • Denri82

        в main.js
        стоит 8 Мб, в swfupload.js стоит 0, но там комент Default zero means
        «unlimited», других упоминаний про setFileSizeLimit, я не нашел. Может
        подскажете. Что делать?

        • Все-таки нужно выяснить где именно установлено ограничение. Сделайте страничку с обычной формой загрузки файла и посмотрите файл какого размера примет сервер. После этого область поиска сузится в двое 😉

  • тема

    А как выводить ошибки, возникающие при загрузке файла?

    • Точно так же, как и при обработке любого ajax запроса. В этом примере в строке 28 (upload.php) просто возвращается ссылка на файл, но вы можете вернуть любое другое сообщение (например, описание ошибки). После этого, выводите описание в обработчике запроса (третий листинг). Кроме того, будет правильно написать обработчик для события uploadError

  • Anton950712

    Здравствуйте. Подскажите пожалуйста, как сделать чтобы при наведении на кнопку курсор принимал вид руки, и чтобы эта кнопка не отображалась поверх всего? Заранее спасибо!

    • Для установки курсора используйте объект SWFUpload.CURSOR.

      На счет отображения кнопки я не совсем понял. Если убрать её на задний план, то она будет не видна и нажать на неё не получится. Тогда зачем она вообще?

      • Anton950712

        Спасибо большое, курсор появился)))) А вот насчёт второго вопроса, просто у меня при нажатии на картинку, она с помощью jquery появляется на весь экран, но эта кнопка оказывается поверх этой картинки. И вот как сделать чтобы она не появлялась поверх картинки? 

        • Можно решить с помощью z-index. Есть готовый пример.

        • Anton950712

          а как после загрузки файла всё это можно скрыть? 
          Выбрано 1 файл(ов), начинаем загрузкуНачата загрузка файла slezy remix.mp3Загружено 100% файла slezy remix.mp3 

        • Anton950712

          И не подскажете, куда именно ставить z-index для кнопки?

        • Anton950712

          Хотя я уже сделал, спасибо))

          А вот куда z-index подставить для кнопки я не пойму, помгите пожалуйста.

        • Поставьте z-index на div внутри которого находится кнопка (тег object). Но обязательно нужно проверить z-index для всех остальных блоков, которые должны выводиться над или под кнопкой.

  • Anton950712

    Здравствуйте ещё раз, а как можно вывести сообщение если лимит превышен?

    • В файле upload.php замените в строке 13 перед return добавьте код:
      echo 'Файл слишком большой';
      return не убирайте

      • Anton950712

        если у меня limit 5, а посетитель выбрал сразу 6 фоток, то вообще ничего не загружается, а как сделать чтобы 5 загрузилось и всё?

        • Anton950712

          и мне надо выводить сообщение когда кол-во фото превышено, а не размер

        • Anton950712

          у меня вот весь код, я тут почти и не менял:
          $(document).ready(function() {        function fileQueueError(file, error, message) {$('#status').html($('Лимит превышен'));     } (это я пытаюсь подставить)    function uploadSuccess(file, serverData) {        $('#images').append($(serverData));    }        function uploadComplete(file) {        $('#status').html($(»));    }        function uploadStart(file) {$('#status').append($(»));        return true;    }        function uploadProgress(file, bytesLoaded, bytesTotal) { $('#status').html($('Идёт загрузка фотографий'));     }    function fileDialogComplete(numFilesSelected, numFilesQueued) {        this.startUpload();    }    var swfu = new SWFUpload(        {            upload_url : «upload.php»,            flash_url : «swfupload.swf»,            button_placeholder_id : «uploadButton»,                        file_size_limit : «0»,            file_types : «*.jpg; *.png; *.jpeg; *.gif; *.JPG; *.PNG; *.GIF; *.JPEG»,            file_types_description : «Images»,                     file_upload_limit : «2»,            debug: false,            button_image_url: «img/zagr.png»,            button_width : 135,            button_height : 43,            button_text_left_padding: 15,            button_text_top_padding: 2,             button_text : «»,            button_text_style : «.uploadBtn { font-size: 18px; font-family: Arial; background-color: #0000 z-index: -1; position:relative; left:50px; top:95px; 00;}»,                        file_dialog_complete_handler : fileDialogComplete,            upload_success_handler : uploadSuccess,            upload_complete_handler : uploadComplete,            upload_start_handler : uploadStart,            upload_progress_handler : uploadProgress        }    ); });

           и я пытаюсь подставить такое:    function fileQueueError(file, error, message) {$('#status').html($('Лимит превышен')); }правильно ли я делаю? только вот что то не получается(

        • Антон, комментарии не очень удачное решение для обмена большими кусками кода. Есть несколько очень хороших сервисов, например, http://pastebin.com/ или http://jsfiddle.net/

        • Anton950712

          А нельзя ли как то так 
          function fileQueueError(file, error, message){$('#status').html($('Лимит превышен')); } или     function uploadError(file, error, message) {$('#status').html($('
          Лимит превышен ')); } чтобы вывести сообщение если лимит превышен? А то получается что если человек выбрал файлов больше чем лимит то ничего не происходит, а ему надо как то сказать об этом.

        • Anton950712

          Это последний мой вопрос, только помогите пожалуйста. И всё будет здорово.))

        • Anton950712

          Спасибо, я уже сделал, а нельзя ли как то подсчитать сколько файлов уже загружено или сколько процентов осталось общее, а не у каждого файла?

        • Можно. В обработчике события fileQueued вы получите объект file object, который содержит информацию о размере файла. Нужно создать хеш с размерами всех файлов.Что-то вроде:var files = {    file_1: {        size: 1024,        uploaded: 0    },    …};Затем в обработчике события uploadProgress в соответствующий элемент uploaded записываете количество байт, загруженных на данный момент.

          После этого нужно сложить все элементы size и uploaded и разделить.

        • Anton950712

          Хотя нет, получилось только если лимит сразу превышен, а надо чтобы 
          чтобы вывести сообщение если лимит превышен? А то получается что если человек выбрал файлов больше чем лимит то ничего не происходит, а ему надо как то сказать об этом.  

        • Запутался я в ваших комментариях.
          Если я не ошибаюсь, вы не сможете посчитать общий объем файлов во время их выбора. Эти данные можно получить только после того как файлы добавлены в очередь, т.е. при возникновении событий fileQueued и fileQueueError.

        • Anton950712

          вообще мне надо, чтобы если количество фотографий превышает file_upload_limit, то выводить сообщение что limit превышен

        • Все вопросы, которые вы перечислили решаются с помощью обработчиков для событий SWFUpload.
          Например, в обработчике fileQueueError вы сможете вывести сообщение об ошибке при превышении ограничения на количество файлов.

        • Anton950712

          А не могли бы подсказать, как и куда именно подставить это?

        • Anton950712

          А не могли бы подсказать, как и куда именно подставить это? чтобы выводилось сообщение, о том что limit превышен

        • Нет, не могу, т.к. в этом случае ответ зависит от вашего кода и разметки страницы. Но, судя по предыдущим комментариям, у вас уже есть несколько обработчиков для других событий. Добавляйте новые по аналогии.

  • Anton950712

    Я уже сам запутался) Мне надо чтобы вывести сообщение если количество файлов превышено.
    А то получается что если человек выбрал файлов больше чем лимит то ничего не происходит, а ему надо как то сказать об этом. Я вот так пробовал, но что то не так. Подскажите пожалуйста как нужно?
    function fileQueueError(file, error, message){$('#status').html($('
    Лимит превышен
    ')); } или     function uploadError(file, error, message) {$('#status').html($('Лимит превышен 
    ')); } 

    • Если лимит — 10 файлов, то будет как-то так

      queuedFiles = 0;

      function fileQueued(file)
      {
      queuedFiles++;
      if (queuedFiles > 10) {
      $('#status').html($('Лимит превышен'));
      }
      }
       

      • Anton950712

        что то не получается

        $(document).ready(function() {queuedFiles = 0;function fileQueued(file){queuedFiles++;if (queuedFiles > 10) {$('#status').html($('Лимит превышен'));}}     function uploadSuccess(file, serverData) {        $('#images').append($(serverData));}    …..
        правильно ли я делаю?

        • Нет, не правильно.
          Нужно установить Firebug (для Firefox) или использовать «Инструменты разработчика» (в Chrome) и посмотреть как реально выполняется код. Вызывается ли fileQueued при добавлении файла и как изменяется значение переменной queuedFile.

        • Anton950712

          Спасибо, я разобрался, только подставлял queuedFiles++;if (queuedFiles > 10) {$('#status').html($('
          Лимит превышен'));} не в функцию fileQueued а в uploadStart. Но всётаки с z-index не получается

          почему? Не подскажите. Вроде должно работать или в файле swfupload что то стоит, что мне мешает?

        • А у вас эти div'ы друг на друга накладываются?

        • Anton950712

          да, только хоть что делай, всё равно кнопка всегда сверху

        • Но в том примере, ссылку на который я приводил, кнопка перекрывается другим блоком. Т.е. если вы сделаете такую же разметку, то получите нужный эффект. После этого можно поэтапно изменять правила и разметку, и на каждом шаге проверять перекрывается ли кнопка.

      • Anton950712

        ещё 1 вопросик, а нельзя ли как то, допустим у меня limit файлов 10, а человек выбрал сразу 20, и нужно загрузить первые 10 файлов, а потом вывести сообщение что лимит превышен? Реально ли это сделать?

        • Да, реально. Когда разберетесь с выводом ошибки о превышении лимита, у вас будет работать и этот вариант.

  • Anton

    Здравствуйте, а подскажите пожалуйста, как написать, чтобы человек установил FlashPlayer, а то если он не установлен, то кнопки нет, а нужно предупредить об этом. Спасибо) 

    • Если не ошибаюсь, нужно в теге object указать параметр codebase.

      Примерно так:

      • Anton

        ага, спасибо)

  • Olga Ivanova

    Здравствуйте, хорошая статья, спасибо

    Но у меня проблема. Надо заставить SWFUpload загружать файлы на другой домен (или поддомен). 

    Я вставила crosdomain.xml (уже на оба домена) не помогло. Пишет Error Code: Security Error, File name: 14.jpg, Message: Error #2049

    Вы можете подсказать что с этим делать?

  • Артем

    Спасибо за статью. Подскажите пожалуйста, как отправить дополнительный POST запрос. Стандартная форма загрузки для нескольких файлов с дополнительным полем input (одинаковое описание для загруженных файлов), которое пойдет в БД. Что и куда надо прописать.

    • В какой момент вы хотите отправить запрос?

      • Артем

        При нажатии кнопки загрузки файлов на событие upload_complete

        • Тогда в обработчик upload_complete добавляете код отправки запроса.
          $.post(…)

        • Артем

          Владимир, я был в отпуске. Приехал, реализовал со свежей головой. Может кому пригодится.

          1. Добавляем поле в форму загрузки:

          2. В файле handlers.js на событие uploadStart(file) (Здесь отправляются post запросы) добавляем: this.addPostParam(«description», document.getElementById(«description»).value);

          Выглядит:

          function uploadStart(file) { try {

          this.addPostParam(«description», document.getElementById(«description»).value);
          /* I don't want to do any file validation or anything, I'll just update the UI and return true to indicate that the upload should start. It's important to update the UI here because in Linux no uploadProgress events are called. The best we can do is say we are uploading. */ var progress = new FileProgress(file, this.customSettings.progressTarget); progress.setStatus(«Uploading…»); progress.toggleCancel(true, this); } catch (ex) {} return true;}

          3. Переменная отправлена. Получаем ee в php:
          $description=$_POST['description'];

  • Antonio

    Подскажите пожалуйста почему у меня ничего не происходит после нажатия кнопки обзор?Не работает!Проверяю на денвере.

    • Примеры на оф. сайте у вас работают?

    • Посмотрите firebug'ом были ли какие-нибудь ошибки.

  • Antonio

    !!!!!! HELP !!!!!!

  • Alex

    Столкнулся с проблемой, в серверном скрипте upload.php не видно сессию. У меня в сеесию записана переменная и она необходима для записи изображения на сервер, передаю я ее через сессию. Не подскажите в чем может быть проблема?

  • Antonio

    Помогите мне! У меня ничего не происходит после нажатия на кнопку обзор! Проверяю на денвере.

  • Антон Ведянин

    Помогите мне! У меня ничего не происходит после нажатия на кнопку обзор! Все как положено,создал 3 тега на своей странице. Проверяю на денвере.

    • Проверьте, загрузился ли swf файл. Удобнее всего смотреть с помощью firebug или инструментов вебмастера в google chrome.

  • Антон Ведянин

    Приветствую еще раз! Пример не работает, ошибок не выдает. Не пойму в чем дело,все вроде правильно. Может что-то с java, хотя другие скрипты работают.

    • java — серверный язык, он здесь не используется.
      SWFUpload написан на flash, т.е. должен быть установлен flash player.

  • Антон Ведянин

    Может что-то с java, хотя
    другие скрипты работают. Как я понимаю после нажатия на кнопку
    обзор должно появиться окно с выбором директории файла? А в index.php достаточно
    присвоить тегам нужный id ! Обязательно чтобы это были дивы или тд сойдут?

    • div или td — не важно. Главное, чтобы ваш php скрипт сохранил файл на сервере и вернул его URL.

  • Lutsk

    Как сделать, чтобы файлы не отправлялись сразу, а только при нажатии кнопки?

    Пробовал такую конфигурацию http://demo.swfupload.org/v220/eidemo/index.php, но при нажатии на кнопку «Start Upload» срабатывает функция startUpload() только для одного файла. Каждый раз кликать по ней надо. Не удобно…

    • Из документации к плагину:

      All queued files are uploaded when startUpload() is called.
      If false is returned from uploadComplete then the queue upload is stopped.

      Т.е. пока обработчик события uploadComplete не вернет false, плагин будет загружать файлы из очереди.

  • Антон

    Здравствуйте Владимир.
    Подскажите как убрать вывод статистики загрузки, то есть все надписи про начало загрузки,проценты.Просто удалить или закомментировать их нельзя потому-что все перестанет работать.И еще не подскажите как сделать чтобы при загрузке отображались миниатюры, а сохранялись в папку изображения другого размера, какой мне нужен.

    • Почему вы решили, что нельзя убрать вывод сообщений? В третьем листинге вы можете закомментировать строки, которые содержат метод append.

      Изменить размер изображений можно на серверной стороне (т.е. с помощью PHP). Есть очень хорошая библиотека для этих целей — Imagine.

      • Антон

        Спасибо! Нашел урок по этой теме на вашем сайте, буду пробовать. Еще прочитал про модуль для nginx, может его заюзаю)

  • Антон

    Еще раз здравствуйте Владимир. Не могли бы вы подсказать как можно передать имена загружаемых файлов в переменную
    скрипта php или не в переменную,вообщем как-нибудь передать их php с уже добавленным временем если имя файла повторялось.Просто я не знаю как их отправить в бд посредством js.

    • Отправить в БД с помощью JS не получится. Вы отправляете файл по протоколу http, его принимает web сервер и затем передаёт php скрипту. Данные файла можно получить из массива $_FILES. Подробнее читайте здесь.

  • Vahagn

    Б коде ошибка вместо $maxFileSize = 2 * 1024 * 1024; //1 MB должно быть $maxFileSize = 2 * 1024 * 1024; //2 MB. И у меня вопрос. Когда размер файлов большая php скрипт не принемает $_POST параметри. Даже не видет PHPSESSID которий я добавляю ж post_params. Маленьким размером файлов все работает. Но ж большых примерно 8 MB. Размер файла в настройках даю большую (25 МБ), но все равно не доходят параметри. Если есть мислы буду благадарен.

    • Спасибо, исправил.

      В настройках PHP два параметра влияют на допустимый размер загружаемых файлов.

      upload_max_filesize = 32M
      post_max_size = 32M

      • Vahagn

        Спасибо. upload_max_filesize поменял, а про post_max_size забил после переустановки сервера.

  • Андрей

    Здравствуйте! Подскажите пожалуйста, можно ли сделать так, чтобы загружаемые файлы размещались в разные папки, а конкретно в ту папку, имя которой пользователь введет в поле ?

    • Вместо

      $uploadDir = 'uploads/';

      нужно использовать папку заданную пользователем, например

      $uploadDir = $_POST['dir'];

      Естественно, предварительно проверить что $_POST['dir'] содержит допустимое значение.

  • Neo

    Помогите пожалуста! У меня почему-то между загрузкой файла и запуском upload.php проходит очень много времени (до 1 мин.). На самом деле ошибка возможна так как я начал переделывать эту заготовку для загрузки файлов других форматов (pdf, djvu). Загрузка проиcходит нормально, но почему-то события uploadComplete ждать приходиться очень долго. Как сделать так чтобы этой паузы не было?

    • Прежде всего, нужно разобраться что именно происходит в течении этой минуты.

      1) Файл большой и он действительно столько времени загружается (проверить можно с помощью firebug или инструментов вебмастера в chrome, вкладка «Сеть»).

      2) Файл после загрузки обрабатывается PHP скриптом.

  • олег

    Владимир, у меня при обновлении страницы все картинки исчезают, можно ли это как то исправить?

    • Да, можно.

      1) в upload.php после сохранения картинки, запишите её url в базу данных.
      2) в index.php сформируйте теги img для всех картинок записи о которых есть в базе.

  • олег

    Владимир скажите а как сделать так чтобы при обновлении страницы картинки оставались

  • олег

    Спасибо!

  • Zura Blogger

    Очень понравилось полезтый скрипт!
    Но можете подсказать как внести в базу данных имене загруженых файлов?

    • В скрипте upload.php нужно выполнить запрос вида

      INSERT INTO имя_таблицы (…, имя_поля_с_именами_файлов, …) VALUES (…, $_FILES['Filedata']['name'], …);

      Естественно, очень желательно формировать запрос с помощью PDO или аналогичной библиотеки, это позволит избежать ряда проблем с SQL инекциями.

      • Петро

        привет класный скрипт вот бы подскажите как при загрузке картинок приделать ресайз нужно уменьшать рисунки

        • Есть очень хорошая библиотека https://imagine.readthedocs.org/en/latest/
          Я ей довольно часто пользуюсь.

        • Петро

          Привет а шо выполняют скрипты plugins что в архиве

        • Петро

          спасибо нашеел

        • Петро

          вот кому нужно такой ресайз вот скрипт upload

          class ImageResize
          {
          private $image;
          private $width;
          private $height;
          private $type;

          function __construct( $file )
          {
          if ( ! file_exists( $file ) ) {
          exit( 'File does not exist' );
          }
          if ( ! $this->setType( $file ) ) {
          exit( 'File is not an image' );
          }
          $this->openImage( $file );
          $this->setSize( );
          }

          private function setType( $file )
          {
          $pic = @getimagesize( $file );
          switch( $pic['mime'] )
          {
          case 'image/jpeg':
          $this->type = 'jpg';
          return true;
          case 'image/png':
          $this->type = 'png';
          return true;
          case 'image/gif':
          $this->type = 'gif';
          return true;
          default:
          return false;
          }
          }

          private function openImage( $file )
          {
          switch( $this->type )
          {
          case 'jpg':
          $this->image = @imagecreatefromJpeg( $file );
          break;
          case 'png':
          $this->image = @imagecreatefromPng( $file );
          break;
          case 'gif':
          $this->image = @imagecreatefromGif( $file );
          break;
          default:
          exit( 'File is not an image' );
          }
          }

          private function setSize( )
          {
          $this->width = imageSX( $this->image );
          $this->height = imageSY( $this->image );
          }

          function resize( $width = false, $height = false )
          {
          if ( is_numeric( $width ) && is_numeric( $height ) && $width > 0 && $height > 0 ) {
          $newSize = $this->getSizeByFramework( $width, $height );
          }
          elseif ( is_numeric( $width ) && $width > 0 ) {
          $newSize = $this->getSizeByWidth( $width );
          }
          elseif ( is_numeric( $height ) && $height > 0 ) {
          $newSize = $this->getSizeByHeight( $height );
          }
          else {
          $newSize = array( $this->width, $this->height );
          }
          $newImage = imagecreatetruecolor( $newSize[0], $newSize[1] );
          imagecopyresampled( $newImage, $this->image, 0, 0, 0, 0, $newSize[0], $newSize[1], $this->width, $this->height );
          $this->image = $newImage;
          $this->setSize( );
          return $this;
          }

          private function getSizeByFramework( $width, $height )
          {
          if ( $this->width height width, $this->height );
          }
          if ( $this->width / $width > $this->height / $height ) {
          $newSize[0] = $width;
          $newSize[1] = round( $this->height * $width / $this->width );
          }
          else {
          $newSize[0] = round( $this->width * $height / $this->height );
          $newSize[1] = $height;
          }
          return $newSize;
          }

          private function getSizeByWidth( $width )
          {
          if( $width >= $this->width ) {
          return array( $this->width, $this->height );
          }
          $newSize[0] = $width;
          $newSize[1] = round( $this->height * $width / $this->width );
          return $newSize;
          }

          private function getSizeByHeight( $height )
          {
          if ( $height >= $this->height ) {
          return array( $this->width, $this->height );
          }
          $newSize[1] = $height;
          $newSize[0] = round( $this->width * $height / $this->height );
          return $newSize;
          }

          function save( $path = », $fileName, $quality = 100 )
          {
          if ( trim( $fileName ) == » || $this->image === false ) {
          return false;
          }
          if ( ! is_dir( $path ) ) {
          return false;
          }
          if ( ! is_numeric( $quality ) || $quality 100) {
          $quality = 100;
          }
          $savePath = $path.trim( $fileName ).'.jpg';
          imagejpeg( $this->image, $savePath, $quality );
          return true;
          }

          }

          // Ширина и высота эскизов изображения:
          $webinar_width = '1000';
          $webinar_height = '415';

          // Ширина и высота больших изображения:
          $meeting_width = '1000';
          $meeting_height = '600';

          // Качество изображений:
          $webinar_quality = '70';
          $meeting_quality = '70';

          if ( ! isset( $_FILES['Filedata'] ) || ! is_uploaded_file( $_FILES['Filedata']['tmp_name'] ) || $_FILES['Filedata']['error'] != 0 ) {
          header( «HTTP/1.1 500 Internal Server Error» );
          echo «ошибка загрузки»;
          exit( 0 );
          }
          $file_name = basename($_FILES['Filedata']['name']);
          //$file_name = strval( $_FILES['Filedata']['tmp_name'] + rand( 1111111111, 9999999999 ) );

          ob_start( );
          $img = new ImageResize( $_FILES['Filedata']['tmp_name'] );
          $img->resize( $webinar_width, $webinar_height )->save( '../webinar/', $file_name, $webinar_quality );
          $imagevariable_webinar = ob_get_contents( );
          ob_end_clean( );

          ob_start( );
          $img = new ImageResize( $_FILES['Filedata']['tmp_name'] );
          $img->resize( $meeting_width, $meeting_height )->save('../meeting/', $file_name, $meeting_quality );
          $imagevariable_meeting = ob_get_contents( );
          ob_end_clean( );

        • Петро

          и еще один вопрос как задавать имя $file_name = strval( $_FILES['Filedata']['tmp_name'] + rand( 1111111111, 9999999999 ) );

          а типа 00001.jpg

          шото я никак не дохожу

        • Например, так
          $file_name = '00001.jpg'

          Если хотите, чтобы номера автоматически увеличивались на 1, то нужно где-то сохранить последний номер, который использовался. Например, в базе данных или файловом кеше. Тогда получится примерно так:

          $file_name = ((int)$last_index + 1).'jpg';

        • Петро

          извените еще один вопрос почему мне сохраняется рисунок

          Имя (name.jpg)и росширение .jpg вот так name.jpg.jpg

          $file_name = basename($_FILES['Filedata']['name']);

        • Петро

          извените разобрался

        • Петро

          а шо выполняют скрипты plugins что в архиве

        • Петро

          не совсем понял тоесть в другой папке сохранять рисунок скажем с именем 0.jpg

        • Не обязательно. Переменная $last_index нужна для того, чтобы имена файлов отличались. Т.е. можно сохранять в одной папке.

        • Pietro Boiko

          Привет а подскажите возможно ли удалять аякс и могли бы привести пример

        • Да можно. Полный пример привести не могу, т.к. он должен быть привязан к структуре страницы.

          Общая идея такая.

          У пользователя должна быть возможность выбрать файл (например, с помощью чекбокса) и нажать кнопку «Удалить».

          Затем отправляете ajax запрос. Код будет выглядеть как-то так
          $.post('removefile.php', {fileName: '0001.jpg'}, function() {
          //убираем файл из списка на странице
          });

          Серверный скрипт removefile.php должен удалить файл с указанным именем, естественно, предварительно нужно проверить права пользователя на удаление файла.

        • Pietro Boiko

          Привет я выложил выше скрипт ресайза но както он не правильно ресайзит могли бы вы исправить

        • А где именно выше? Я вижу только два ваших комментария. Кода в них нет.

  • спамер

    чтёблёнлапыхаще?

  • Денис

    День добрый, подскажите как проще передать имена файлов в базу.

    • Код будет зависеть от структуры вашей базы и библиотеки для работы с базой, которой вы пользуетесь. Если поле в котором будут храниться имена файлов называется files, то вам нужно выполнить запрос вроде:
      INSERT INTO table_name (…,'files',…) VALUES (…,'имя_файла',…);

      При этом желательно использовать PDO или аналогичную библиотеку, т.к. в них автоматически выполняется экранирование спецсимволов, т.е. есть защита от sql инъекций.

  • Михаил Нюйман

    Ничего не выходит…. больше 2 метров не загружает, что только не делал… кто может помочь? дам доступ или пришлю сборку сайта для решения проблемы…..

    • Вам нужно проверить в php.ini 2 параметра:

      upload_max_filesize

      post_max_size