За последние 24 часа нас посетили 34473 программиста и 1693 робота. Сейчас ищут 644 программиста ...

safeFileName

Тема в разделе "Прочие вопросы по PHP", создана пользователем alexey_baranov, 20 май 2009.

  1. alexey_baranov

    alexey_baranov Активный пользователь

    С нами с:
    3 фев 2009
    Сообщения:
    647
    Симпатии:
    0
    Адрес:
    Сургут
    Добрый день!

    Наверное, каждый хоть раз сталкивался с такой проблемой. Матерился и перешагивал ее по своему. При отправке файлов пользователю он или вообще не получает файл или получает, но с неправильным названием. Я веду борьбу с этим несчастьем уже долгое время и накопил большой опыт. Причина этого в том, что я не прописываю имена файлов в коде, они динамически составляются из разных строк, на которые не наложено никаких ограничений. Это могут быть названия чего либо, даты, записки пользователя, строки из внешних систем и т.п. Я сталкивался и побеждал несколько причин таких ошибок. Вот они:
    • 1. Слишком длинное имя файла. Некоторые браузеры этого не переваривают- они просто режут его и пользователь получает файл без расширения;
      2. В названии встречаются запрещенные символы типа «/», «\», «?» и т.п.;
      3. В названии русские буквы. Опять же некоторые браузеры не обращают на это внимание, а например Сафари выдает абракадабру;
      4. В названии файла пробелы

    Посему открываю эту тему. Как всегда интересно послушатьть, кто как с этим борется. Сразу выкладываю свое решение:

    PHP:
    1.    
    2. <?php
    3.     static function SafeFileName($fileName) {
    4.         $fileName= ereg_replace('[:/\\\" ]', ' ', $fileName);
    5.         //(буква от 1 до 75)буквы.(неточки)
    6.         $name= ereg_replace("^(.{1,75}).*\\.([^\\.]+)$", "\\1", $fileName);
    7.         $ext=  ereg_replace("^(.{1,75}).*\\.([^\\.]+)$", "\\2", $fileName);
    8.         $cl= new CyrLat();
    9.         return "{$cl->cyr2lat($name)}.{$ext}";
    10.     }
    Тут смысл в том, что по очереди побеждаются все четыре причины ошибок. Кстати отсылаю файл вот так:
    PHP:
    1. <?php
    2. header("Content-Disposition: attachment;filename={$safeFileName}");
    3.  
    то есть имя файла не в кавычках. Некоторые умные браузеры понимают и так и эдак, поэтому опытным путем невозможно понять какой способ правильный. Но где-то в нете точно помню, читал, что правильно без кавычек.

    По поводу 3-го и 4-го пунктов много раз читал, что надо делать urlencode() и все будет хокей, но опять же в некоторых браузерах пользователи получали эту самую урлэнкоду вместо имени файла.

    Согласен, что такой путь не идеален. Для пользователя не очень приятно получить Отчет Инвентаризация ЗАО "Сургутский электрический свет" в виде Otchet_Inventarizatsiya_ZAO__Surgutskij_elektricheskij_svet_.xlsx И единственное почему я это делаю, это железобетонно работает. Во всех осях, во всех локалях и во всех браузерах. Безотказно, как автомат Калашникова.