2009-12-08 5 views
1

У меня есть «дилемма» и интересно, что такое лучшая практика бизнеса.Какова наилучшая практика для проверки имени файла?

Я использую Uploadify для загрузки изображений. Теперь мне нужно проверить имя файла перед сохранением файла.

Я рассмотрел различные решения, но не могу перейти к одному хорошему решению.

Вот мои критерии:

  • Имя файла должно быть все в нижнем регистре
  • Имя файла может содержать только Charaters [а-Z0-9_-]
  • я должен быть в состоянии переименовать файл

Как бы вы шли, если имя файла my.file(name).jpeg?

Я могу взорвать имя файла на '.' и сохраните расширение, затем выполните размолвку, чтобы снова получить имя файла. Но не уверен, что это лучшее решение.

У меня есть следующие функции, которые помогают немного:

function getExts($filename) 
{ 
    $exts = explode("[/\\.]", $filename) ; 
    $n = count($exts)-1; 
    $exts = $exts[$n]; 
    return $exts; 
} 

function validFilename($filename) 
{ 
    $filename = str_replace(" ", "_", $filename); 
    $pattern = "/[^[a-z0-9_-]/"; 
    return preg_replace($pattern, "", strtolower($filename)); 
} 

UPDATE 1
Я ПОЛУЧАТЬ файл через $ _FILES. Это дает мне следующие данные:

  • $ _FILES [ "Файл"] [ "имя"] - имя загруженного файла
  • $ _FILES [ "Файл"] [ "тип"] - тип загруженного файла
  • $ _FILES ["file"] ["size"] - размер в байтах загруженного файла
  • $ _FILES ["file"] ["tmp_name"] - имя временной копии файла, хранящегося на сервере
  • $ _FILES ["file"] ["error"] - код ошибки в результате загрузки файла

UPDATE 2
Я только что нашел что-то. Я мог бы использовать getimagesize, который вернет массив из 7 элементов. Один из этих элементов [2] - IMAGETYPE_XXX.

Так что попробуйте использовать этот код:

function getExts2($filename) 
{ 
    list(,,$type) = getimagesize($filename); 
    return $type; 
} 

Но он возвращается только номер 2 ...

(я также попытался с помощью exif_imagetype, но только получить PHP Ошибка: Вызов неопределенной function.)

+0

Тип, возвращаемый 'getimagesize', может быть преобразован в расширение файла с помощью функции' image_type_to_extension': http://us2.php.net/function.image_type_to_extension –

+0

@Ben: см. Мои комментарии об использовании getimagesize. – Steven

ответ

4

Проверьте имя файла с регулярным выражением. Используйте информацию о mimetype. Сохраните файл на сервере с именем md5. Храните реальное имя файла на db.

+0

Сохранение файла с использованием md5 является хорошим. И да, я уже сохраняю имя файла в БД. Но я использую regexp. – Steven

+0

Хорошо, но для чего вы хотите проверить имя файла с регулярным выражением? Способ Mimetype не является хорошим? – hsz

+0

+1 для «шифрования» имени файла с помощью md5 – TheHippo

0

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

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

Если вам небезразлично, как выглядят URL-адреса, и в будущем они могут ориентироваться на международную аудиторию, обязательно конвертируйте Umlauts в их базовые символы или конвертируйте их. Немецкий пользователь (Умляуты ао Ü ß) будет ожидать преобразования:

Ä = ae 
Ö = oe 
Ü = ue 

в то время как скандинавы, кажется, в легкости, с

Ä => a 
Ö => o 
Ø => o 

и так далее.

Тогда существуют различные акцентированные символы é ао ...

отбрасывая те вообще приводит к URL-адресам, которые выглядят действительно бул и лок strng в bwsr адрес бр.

3

pathinfo() может предоставить вам имя файла и расширение. Однако я предупреждаю вас, что вы не можете полагаться на тестирование расширения файла, проверяя его имя. Вы захотите использовать функцию, которая фактически проверяет двоичное содержимое файла для этого. finfo_file() может выполнить это. Ох, и никогда не больно использовать basename() по файлу, предоставленному пользователем, чтобы предотвратить атаку обхода пути.

+0

Довольно сложно использовать basename(), если вы не знаете расширения. И, как вы говорите, использование pathinfo - это не лучший способ. Самым безопасным будет чтение acutal двоичных файлов. – Steven

0

Это должно сделать все, что вы хотите:

$filename = preg_replace('/[^[a-z0-9_-]/', '', str_replace(' ', '_', strtolower(pathinfo($filename, PATHINFO_FILENAME)))) . pathinfo($filename, PATHINFO_EXTENSION); 

И как Pekka объяснил это, если вы хотите заменить все акцентирование в имени файла, вы можете использовать следующую функцию:

function Unaccent($string) 
{ 
    return preg_replace('~&([a-z]{1,2})(acute|cedil|circ|grave|lig|orn|ring|slash|th|tilde|uml);~i', '$1', htmlentities($string, ENT_QUOTES, 'UTF-8')); 
} 
+0

Проблема с использованием [a-z0-9_-], то есть также удаляет точку перед расширением (?) – Steven

+0

@Steven: Вы хотя бы пробовали? Трюк заключается в использовании pathinfo ($ filename, PATHINFO_FILENAME) и pathinfo ($ filename, PATHINFO_EXTENSION), он работает так же, как вы этого хотите. –

0

I не думайте, что вы должны «подтвердить» имя файла, вы должны просто «исправить» его, если он не в нужном формате. Зачем отказываться от файла только потому, что кто-то сосет при именовании своих файлов или там есть какие-то необычные персонажи? Кроме того, если вы работаете с изображениями, вы можете использовать getimagesize, как вы упомянули, чтобы убедиться, что на самом деле это изображение, которое было загружено (должно быть неудачно, если это не изображение).

+0

Подтверждаю, я имею в виду проверку имени файла. Файлы не будут отклонены, но я удалю ненужные символы. – Steven

Смежные вопросы