В своих проектах я в последнее время для загрузки пользовательских картинок использую jQuery File Upload . Если вкратце, то этот чудесный продукт в виде нескольких файлов на JavaScript + класса на PHP позволяет дать нашим юзерам загружать им картинки в наши проекты через AJAX и сразу несколько картинок.
Собственно загружать можно не только картинки. У jQuery File Upload есть куча всяких функций по контролю за размерами картинок, за типа загружаемых файлов и т.п. Всё это хозяйство легко встраивается в проекты. Я делал проекты в которых использовал jQuery File Upload на CodeInteger, Yii ( для Yii даже есть готовый плагин, но я его не использовал ) и для плагинов WordPress ( довольно глупое решение, ибо в WP есть свой загрузчик, логично было бы использовать его, но надо было по быстрому приколхозить ).
Но есть у jQuery File Upload и недостатки, которые пришлось поправлять.
Так по мелочи на самом деле. Но…
1. На хостинге с PHP <5.3 File Upload выдавал ошибку на функцию array_replace_recursive. Так как она есть только в PHP 5.3, пришлось делать так:
Вместо
1 |
array_replace_recursive($this->options, $options) |
Делаем
1 |
$this->options = (!function_exists('array_replace_recursive')) ? $this->azzrael_array_replace_recursive($this->options, $options) : array_replace_recursive($this->options, $options); |
И добавляем перед закрытием класса:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
// ** Azz - to run under PHP < 5.3 private function azzrael_array_replace_recursive($array, $array1){ function recurse($array, $array1) { foreach ($array1 as $key => $value) { // create new key in $array, if it is empty or not an array if (!isset($array[$key]) || (isset($array[$key]) && !is_array($array[$key]))) { $array[$key] = array(); } // overwrite the value in the base array if (is_array($value)) { $value = recurse($array[$key], $value); } $array[$key] = $value; } return $array; } // handle the arguments, merge one by one $args = func_get_args(); $array = $args[0]; if (!is_array($array)) { return $array; } for ($i = 1; $i < count($args); $i++) { if (is_array($args[$i])) { $array = recurse($array, $args[$i]); } } return $array; } |
Аналогичная ситуация с:
1 |
json_encode($info) |
Которую иногда просто любят отключать на некоторых хостингах. Хотя это довольно редкая ситуация.
Меняем на:
1 |
echo (!function_exists('json_encode')) ? $this->azzrael_json_encode($info) :json_encode($info); |
И перед закрытием класса:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
// ** Azz - to run under PHP < 5.2 private function azzrael_json_encode($data) { switch ($type = gettype($data)) { case 'NULL': return 'null'; case 'boolean': return ($data ? 'true' : 'false'); case 'integer': case 'double': case 'float': return $data; case 'string': return '"' . addslashes($data) . '"'; case 'object': $data = get_object_vars($data); case 'array': $output_index_count = 0; $output_indexed = array(); $output_associative = array(); foreach ($data as $key => $value) { $output_indexed[] = $this->uh_json_encode($value); $output_associative[] = $this->uh_json_encode($key) . ':' . $this->uh_json_encode($value); if ($output_index_count !== NULL && $output_index_count++ !== $key) { $output_index_count = NULL; } } if ($output_index_count !== NULL) { return '[' . implode(',', $output_indexed) . ']'; } else { return '{' . implode(',', $output_associative) . '}'; } default: return ''; // Not supported } } |
Следующий тюнинг не проблема jQuery File Upload, а скорее необходимы функционал
Многие юзеры загружают картинки со всякими идиотскими названиями. Часто названия совпадают. Что делать при таких коллизиях? Хорошо бы их при загрузке на сервер как то уникально переименовывать. Для этого сразу после:
1 2 |
protected function handle_file_upload($uploaded_file, $name, $size, $type, $error, $index = null) { $file = new stdClass(); |
Добавить что-то типа:
1 2 3 4 5 |
// + Azz - rename file $name_ext = explode('.', $name); // Отделяем расширение $name_ext[0] = date('ymd-Hi')."-".rand(0,9999); // Левую часть переименовываем $name = implode('.', $name_ext); // - Azz |
В данном случае новое имя файла это дата со временем плюс случайное число. Всё в целом исключаем возможность коллизий. Можно придумать и какие то другие правила переименования файла. Например добавлять имя юзера, транслитерацию заголовка поста или что-то типа того.
Сергей 2015-05-01