ФорумПрограммированиеPHP для идиотов → Возня с менеджером закачки файлов

Возня с менеджером закачки файлов

  • artoodetoo

    Сообщения: 5147 Репутация: N Группа: в ухо

    Spritz 28 июля 2010 г. 2:49, спустя 1 день 20 часов 32 минуты

    Выношу на обсуждение класс загрузки/скачки файлов. Здесь нет красивой оболочки, только базовые классы и простенький тест.

    Класс FileStorage управляет хранимыми файлами. Имеет методы upload, download и delete.

    Класс FileRecordManager хранит записи о загруженных файлах. Имеет метод getIterator():ArrayIterator для доступа к записям.

    Оба класса унаследованы от Component. Component дает удобный интерфейс для инициализации объекта, навешивания событий и некоторой магии со свойствами.

    Загрузка файла выглядит так:

    $storage = new FileStorage($config);
    $storage->addEvent('onUpload', 'extraImageCheck');

    $num = $storage->upload('attach', $subject);
    $errors = $storage->getErrors();

    здесь extraImaheCheck - колбэк для тестирования файла после загрузки, attach - имя поля с файлом, $subject - комментарий к файлу/пачке файлов. getErrors() вернет массив сообщений с ошибками (если были)

    Если загрузка прошла ($num>0), то можно добыть инфу о только что сохраненных файлах:

    $newRecords = $storage->getRecords();

    где каждый элемент масива $newRecords выглядит как

    array(
    'type'     => $type, // mime
    'target'   => $target, // путь до сохраненного файла
    'name'     => $name, // оригинальное имя файла
    'size'     => $size, // размер
    'subject'  => $this->_subject, // коментарий
    'uploaded' => $this->_uploaded // время
    )

    эту инфу сам FileStorage не сохраняет на постоянку, необходимо поручить это FileRecordManager

    $manager = new FileRecordManager($config);
    $it = $manager->getIterator();
    foreach ($newRecords as $rec) {
    $it->append($rec);
    }
    $manager->close();


    Для скачки надо проделать такую работу: получить по id запись из FileRecordManager и подсунуть эту запись в FileStorage download()

    Таким образом я разделил функционал. Менеджер записей и Хранилище файлов знают только свою часть картины. В примере записи хранятся в файле в сериализованном виде. В перспективе будет версия с БД.

    От вас, господа, я жду замечаний по существу. Может быть кто-то укажет на потенциальные уязвимости. Что будет если подсунуть фейковые данные в post-запрос? Достаточно ли я защищен если использую move_uploaded_file() ?

    update: не поленитесь промотать тему, есть более свежие и интересные версии
    ιιlllιlllι унц-унц
  • phpdude

    Сообщения: 26646 Репутация: N Группа: в ухо

    Spritz 13 июля 2010 г. 3:56, спустя 1 час 7 минут 10 секунд

    где каждый элемент масива $newRecords выглядит как

    так хорошо все начиналось, а закончилось массивами :)))))))))))))) переделай на FileStorageEntry чтобы пхпдоку было не стремно твой класс показать ;)
    Сапожник без сапог
  • artoodetoo

    Сообщения: 5147 Репутация: N Группа: в ухо

    Spritz 13 июля 2010 г. 6:12, спустя 2 часа 15 минут 33 секунды

    Я не такой фанат объектов чтобы искоренять массивы.
    Спустя 253 сек.
    не вижу резона
    ιιlllιlllι унц-унц
  • artoodetoo

    Сообщения: 5147 Репутация: N Группа: в ухо

    Spritz 13 июля 2010 г. 7:42, спустя 1 час 29 минут 32 секунды

    В архиве был косяк. Обновил — теперь должно работать правильно.
    ιιlllιlllι унц-унц
  • phpdude

    Сообщения: 26646 Репутация: N Группа: в ухо

    Spritz 13 июля 2010 г. 8:20, спустя 38 минут 1 секунду

    array(
    'type' => $type, // mime
    'target' => $target, // путь до сохраненного файла
    'name' => $name, // оригинальное имя файла
    'size' => $size, // размер
    'subject' => $this->_subject, // коментарий
    'uploaded' => $this->_uploaded // время
    )
    ну вот если сохранять в объект, то вот эта инфа не понадобится и твоимклассом можно пользоваться не читая документацию - большой плюс,а так надо в голоу опять очередной мануал сохранять, что не айсово :)
    Сапожник без сапог
  • artoodetoo

    Сообщения: 5147 Репутация: N Группа: в ухо

    Spritz 13 июля 2010 г. 9:06, спустя 46 минут 44 секунды

    этот массив делается не ручками и не ручками сохраняется :) можно ничего не читать. я так, для общей картины привел инфу. видимо зря.
    единственное место где напрямую читаются элементы - при формировании страницы со ссылками на загруженные файлы. точно также понадобилось бы знать а какие там есть поля. (ну конечно умный нетбинс мог бы выдавать подсказки, только это для совсем ленивых :))
    ιιlllιlllι унц-унц
  • kostyl

    Сообщения: 5210 Репутация: N Группа: Джедаи

    Spritz 13 июля 2010 г. 13:46, спустя 4 часа 39 минут 30 секунд

    artoodetoo, прости за оффтом, но если программер щупает массив руками, то как вы считаете надо объектом сделать его? а если программер щупает его пару раз только - ну типа как конфиг?
  • artoodetoo

    Сообщения: 5147 Репутация: N Группа: в ухо

    Spritz 13 июля 2010 г. 14:13, спустя 27 минут 2 секунды

    хз. я полагаюсь на интуицию )
    ιιlllιlllι унц-унц
  • artoodetoo

    Сообщения: 5147 Репутация: N Группа: в ухо

    Spritz 16 июля 2010 г. 7:46, спустя 2 дня 17 часов 33 минуты

    up

    Будет третий класс :) Картинки — это особый случай, который нельзя игнорировать.

    Итого:
    [tt]FileStorage[/tt] для аплоада/даунлоада,
    [tt]FileRecordManager[/tt] для ведения учетных записей и
    [tt]ImageView[/tt] для создания превьюшек и генерации ссылок на них.

    Правило для размещения превьюшки очень похоже на правило для размещения файла в FileStorage, раскладываем превьюшки по папкам, чтобы в одной не скапливалось слишком много + для каждого размера своя папочка.

    У превьюшек есть два основных типа. Один подгоняет размер картинки по меньшей стороне, а бОльшую обрезает (crop), другой подгоняет по большей, а меньшую вычисляет как получится (fit). Есть еще два способа, но они для идиотов

    Нередко случается, что картинка на сайте ВНЕЗАПНО показывается на боку, хотя хозяин в своём вьювере видет её нормальной. Проблема в том, что JPEG может хранить в себе инфу с фотика (гироскоп?) о повороте камеры присъемке. Эту инфу умный ImageView должен учитывать.

    Я ничего не забыл?
    ιιlllιlllι унц-унц
  • Faster

    Сообщения: 1159 Репутация: N Группа: Кто попало

    Spritz 16 июля 2010 г. 9:07, спустя 1 час 20 минут 31 секунду

    я нарезаю превью с сохранением аспект ратио , crop по большей стороне
    только IM
  • phpdude

    Сообщения: 26646 Репутация: N Группа: в ухо

    Spritz 16 июля 2010 г. 9:17, спустя 10 минут 4 секунды

    Нередко случается, что картинка на сайте ВНЕЗАПНО показывается на боку, хотя хозяин в своём вьювере видет её нормальной. Проблема в том, что JPEG может хранить в себе инфу с фотика (гироскоп?) о повороте камеры присъемке. Эту инфу умный ImageView должен учитывать.

    забавно не знал :)
    ну знал что жпег дофига умеет, но что фотики угол наклона сохраняют)
    Сапожник без сапог
  • artoodetoo

    Сообщения: 5147 Репутация: N Группа: в ухо

    Spritz 28 июля 2010 г. 2:53, спустя 11 дней 17 часов 35 минут

    Забыл слово как это называется, в общем цепочкой буду вызывать методы

    $iv = new ImageView($params);
    $iv->load($originalFile)
      ->autoRotate()
      ->sharp()
      ->resizeFit($width1, $height1)
      ->save($preview1)
      ->resizeCrop($width2, $height2)
      ->save($preview2)
      ->free();
    Спустя 121 сек.
    нука тест
    Спустя 49 сек.
    ага, превьюшка на боку. а вот когда я смотрб фотку в XnView - она в правильной портретной ориентации.
    Спустя 140 сек.
    так вот, мой класс будет смотреть инфу "как XnView". пример есть в комментариях к [man]exif_read_data[/man]

    $exif = exif_read_data($filename);
    $ort = $exif['IFD0']['Orientation'];


    update: для одного начинающего сделал функцию resize + autorotate, где демонстрируется этот фокус
    http://pyha.ru/forum/topic/4745.msg103105#msg103105
    ιιlllιlllι унц-унц
  • artoodetoo

    Сообщения: 5147 Репутация: N Группа: в ухо

    Spritz 16 июля 2010 г. 9:55, спустя 7 часов 2 минуты 14 секунд

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

    $fileName = $o->buildString(
    'img/{$size}/{$id:0,3}/{$id:3,3}/{$id:6,3}.{$ext}',
    array(
    'id' => $id,
    'size' => $sizeName,
    'ext' => 'jpg'));
    Спустя 170 сек.
    риальне я не уверен какие именно параметры придется передавать, а какие часть предопределённой конфигурации
    Спустя 160 сек.
    мне бы хотелось, чтобы пример выше выглядел так:

    $iv = new ImageView($params);
    $iv->load($originalFile)
    ->autoRotate()
    ->sharp()
    ->resizeFit('medium')
    ->save()
    ->resizeCrop('thumb')
    ->save()
    ->free();

    ιιlllιlllι унц-унц
  • phpdude

    Сообщения: 26646 Репутация: N Группа: в ухо

    Spritz 16 июля 2010 г. 10:34, спустя 39 минут 20 секунд

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

    ты чуток неправильно понял насчет истребителя)

    в общем если у тебя класс для настроек(и подобных вещей, которые хардкорно используются внутри класса) использует какой то массив, то использовать объект с соотвтетствующим именем, а если как сейчас - динамические данные, которые программист завел сам и использует сам, то тут конечно глупо :
    Сапожник без сапог
  • Абырвалг

    Сообщения: 6480 Репутация: N Группа: Джедаи

    Spritz 16 июля 2010 г. 10:58, спустя 23 минуты 45 секунд

    чайнинг это называется
    Спустя 97 сек.
    сделай тогда уж ImageView::init(); Что бы цепочка была непрерываема

Пожалуйста, авторизуйтесь, чтобы написать комментарий!