PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


 Страниц (1): [1]   

> Без описания
teddy
Отправлено: 13 Декабря, 2013 - 00:37:57
Post Id


Участник


Покинул форум
Сообщений всего: 1462
Дата рег-ции: Апр. 2013  


Помог: 91 раз(а)




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

Вот код класса(так же файл с кодом приложил к сообщению). Сори что криво отформатирован, не помещается в монитор кодУлыбка В приложенном файле чуть лучшеУлыбка)
Внимание: после обсуждения класс потерпел некоторые изменения. Ввиду того что мне сейчас пора уходить, этот код я полностью редактировать не стал. Актуальная версия кода лежит в приложенном файле. Немного изменился принцип использования. Пример лежит в сообщении, которое я написал 13 Декабря, 2013 - 01:54:25
Спойлер (Отобразить)

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

Теперь о том, как работает класс, его полезные свойства и способы применения.

Свойства:

public $hash - хранит в себе массив с названием/ями загруженных файлов. Его можно использовать после загрузки файлов для того, что бы добавить название загруженных файлов в БД(для тех, кто хранит имя файла в специальном поле БД и подгружает по названию файлы из папки). Хеширование происходит в методе setHash, там всего одна строчка, return $this->hash[] = md5(uniqid($filename)).$filename;
Если Вам нужен свой способ хеширования, то можно его описать изменив данную строчку.

private $_mimeTypes - это своего рода "база данных класса о MIME типах", которые класс может обработать. Свойство расширяемое, если необходимо сообщить классу о новых MIME типах, которые он может обработать, то достаточно добавить нужный нам MIME тип в это свойство как элемент массива и указать в качестве ключа соответствующее ему расширение.

private $_allowExt - Используется при создании объекта от данного класса. Туда необходимо передавать расширение файлов, которые вы хотите допустить к загрузке пользователем. Например Вы хотите что бы пользователь смог загружать только gif и jpeg файлы, то нужно передать следующие значения в это свойство:
PHP:
скопировать код в буфер обмена
  1. $loader = new FileLoader(array('gif', 'jpeg'),100,'inputname','foldername');

Для чего нужны другие параметры, опишу чуть ниже.
Если приватное свойство(массив) класса $_mimeTypes знает о MIME типах, ключами которых является те значения, которые переданы первым параметром в конструктор при создании объекта, то класс обработает запрос клиента таким образом, что для загрузки будут доступны только те файлы, MIME типы которых соответствуют ключам, переданным первым параметром в конструктор в виде массива.

Второй параметр - Размер загружаемого файла в килобайтах

Третий параметр - Названия инпута, который используется для загрузки файлов.
Например <input type="file" name="upload" />

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

Технические требования:
Перед использованием данного класса убедитесь, что в php.ini раскомментировано расширение extension=php_fileinfo.dll

Пример использования:
Загрузка одиночных файлов:
Если требуется загружать только одиночный файл, то после создания объекта необходимо вызвать метод upload
PHP:
скопировать код в буфер обмена
  1.  
  2. if($_SERVER['REQUEST_METHOD'] == 'POST'){
  3. $loader = new FileLoader(array('gif', 'jpeg', 'bmp', 'msword'),1000,'upload','myfolder');
  4. $loader->upload();
  5. echo $loader->hash[0];//здесь лежит хеш-название загруженного файла
  6. }
  7.  

CODE (html):
скопировать код в буфер обмена
  1.  
  2. <form action="" method="post" enctype="multipart/form-data">
  3.     <input type="file" name="upload" />     <input type="submit" value="Загрузить" />
  4. </form>
  5.  

Загрузка нескольких файлов одновременно:
Если требуется загружать несколько файлов одновременно, то после создания объекта необходимо вызвать метод multiUpload
PHP:
скопировать код в буфер обмена
  1.  
  2. if($_SERVER['REQUEST_METHOD'] == 'POST'){
  3. $loader = new FileLoader(array('gif', 'jpeg', 'bmp', 'msword'),1000,'upload','myfolder');
  4. $loader->multiUpload();
  5.     print_r($loader->hash);//здесь лежат хеши-названия всех загруженных файлов
  6. }
  7.  

CODE (html):
скопировать код в буфер обмена
  1.  
  2. <form action="" method="post" enctype="multipart/form-data">
  3.     <input type="file" name="upload[]" />     <input type="file" name="upload[]" />     <input type="file" name="upload[]" />     <input type="submit" value="Загрузить" />
  4. </form>
  5.  

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

Безопасность
На мой взгляд всё ровно, но что скажете Вы?

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

Если Вы нашли какие то баги, то прошу мне о них сообщить.

Вроде бы ничего не забыл. Буду признателен за любую адекватную и правильную оценку.
Скачать файл: floader.php
Скачан раз: 61

(Отредактировано автором: 13 Декабря, 2013 - 02:34:12)

 
 Top
Panoptik
Отправлено: 13 Декабря, 2013 - 01:07:34
Post Id



Постоянный участник


Покинул форум
Сообщений всего: 2496
Дата рег-ции: Нояб. 2011  
Откуда: Одесса, Украина


Помог: 131 раз(а)




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

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

первое что бросается в глаза - echo
нормальные классы никогда не выдают ничего непосредственно на вывод, только return если что-то нужно сказать сохранить - используйте свойства для накопления информации об ошибках, логировании и дебага

ну и функционал довольно специфичный

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

но за труды объявляю благодарность

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


-----
Just do it
 
 Top
teddy
Отправлено: 13 Декабря, 2013 - 01:17:48
Post Id


Участник


Покинул форум
Сообщений всего: 1462
Дата рег-ции: Апр. 2013  


Помог: 91 раз(а)




Panoptik
Если честно, когда писал класс про AJAX даже и не вспомнил Улыбка
Panoptik пишет:
но в каждом конкретном случае разные настройки

Регулирование базовых настроек я предоставил

Panoptik пишет:
первое что бросается в глаза - echo

echo - только для вывода ошибок или сообщения об успешной загрузке, в целом согласен с замечанием, но с другой стороны хотелось оставить как меньше кода на поверхности. В случае если загруженные файлы не прошли валидацию, будет вызван метод, который выведет ошибки. Это не критично, можно легко переделать написав вместо echo returnУлыбка

Panoptik пишет:
для академических действий - работа хорошая, с практической точки зрения - уже существует много хороших проверенных решений, и ваше по сравнению с ними увы - очередной велоспиед

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

Panoptik пишет:
но за труды объявляю благодарность

Улыбка Не за что, заинтересовался, написал, и мог не поделиться Улыбка Благодарю и Вас за отзыв

(Отредактировано автором: 13 Декабря, 2013 - 01:20:01)

 
 Top
DelphinPRO
Отправлено: 13 Декабря, 2013 - 01:30:35
Post Id



Активный участник


Покинул форум
Сообщений всего: 7190
Дата рег-ции: Февр. 2012  


Помог: 352 раз(а)




teddy пишет:
echo - только для вывода ошибок или сообщения об успешной загрузке

нет-нет-нет. если у меня вся логика отрабатывается еще до начала рендеринга шаблонов, то ваши эки мне всю страницу поломают, не говоря уже о невозможности контролировать отправку заголовков. Ну и упомянутый аякс, как правило, ведет обмен данными в json формате, и эки, опять же, поломают данные.
В общем завязывайте с подобной практикой как можно скорее.
(Добавление)
По поводу универсального использования. Я так понял файлы сохраняются с именами md5-hash. Лучше, чтобы была возможность задавать формат имени файла. Или callback функцию для генерации имени (этот вариант мне кажется лучшим).


-----
Чем больше узнаю, тем больше я не знаю.
 
 Top
teddy
Отправлено: 13 Декабря, 2013 - 01:54:25
Post Id


Участник


Покинул форум
Сообщений всего: 1462
Дата рег-ции: Апр. 2013  


Помог: 91 раз(а)




DelphinPRO пишет:
нет-нет-нет. если у меня вся логика отрабатывается еще до начала рендеринга шаблонов, то ваши эки мне всю страницу поломают

Исправил, нету больше echo Улыбка Теперь нужные для загрузки методы стали boolean, свойство в котором лежат ошибки стало публичным, был удален приватный метод showErrors. Соответственно изменилось и использование. Пример:
PHP:
скопировать код в буфер обмена
  1. if($_SERVER['REQUEST_METHOD'] == 'POST'){
  2.  
  3. $loader = new FileLoader(array('gif', 'jpeg', 'bmp', 'msword'),1000,'upload','foldername');
  4.  
  5. if($loader->upload()){
  6.     print_r($loader->hash);
  7. }else{
  8.     foreach($loader->errors as $errors){
  9.         echo $errors.'<br />';
  10.     }
  11. }
  12.  
  13. }

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

В методе который отвечает за хеширование всего одна строчка, если понадобится изменить способ хеширования, то можно выбрать другой способ изменив одну строчку в методе setHash, от этого ничего не сломается Улыбка
Цитата:
не говоря уже о невозможности контролировать отправку заголовков

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

(Отредактировано автором: 13 Декабря, 2013 - 02:51:27)

 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 1 (гостей: 1, зарегистрированных: 0)
« Пользовательские функции »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB