@eugene159

Как через PHP определить, подойдет ли длина строки для названия файла?

Я попробовал назвать .txt файл в Windows 10 английскими буквами. Я написал как можно больше букв. Получилось 244. Больше не влезает.
Попробовал русскими буквами. Получилось тоже 244.
Попробовал emoji. Получилось 124.

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

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

Вот код:

<?php
$filename1 = 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb';
echo 'Случай 1: ' . saveToFile($filename1);

echo '<br>';

$filename2 = 'ТУТ 124 ГРУСТНЫХ СМАЙЛИКА, qna.habr.com не дает их написать';
echo 'Случай 2: ' . saveToFile($filename2);

function saveToFile($filename) {
    $len = mb_strlen($filename);
    if ($len > 240) {
        $filename = mb_substr($filename, 0, 240);
    }
    $filename .= '.txt';
    $result = fopen($_SERVER['DOCUMENT_ROOT'] . $filename, 'w');

    return $result === false ? 'неудача' : 'успех';
}

В результате выведется такое;
Случай 1: успех
Случай 2: неудача
  • Вопрос задан
  • 178 просмотров
Пригласить эксперта
Ответы на вопрос 4
ThunderCat
@ThunderCat Куратор тега PHP
{PHP, MySql, HTML, JS, CSS} developer
strlen

UPD: Так как автор не читает документацию, и думает что "магия" длинны строки заключается в том что операционки не любят эмоджи, рекомендую протестировать скрипт, и подумать - почему так.
Ответ написан
iMedved2009
@iMedved2009
Не люблю людей
Ответ написан
Комментировать
@rPman
Считать нужно количество байт в имени а не символов.

Так же лимиты файловой и операционной системы очень разные, у windows одни у linux другие, плюс выбор файловой системы влияет на результат, плюс итоговый путь (т.е. в каком каталоге смонтировано хранилище).

Настоятельно рекомендую уйти от такой практики именования файлов пользовательскими не контролируемыми данными, помимо простых "../", позволяющих выйти за границы хранилища (а это уже опасно), пользователи могут создать файлы со служебными именами, удалить которые уже будет не так просто, и такие имена (типа null или con в windows) могут помешать обслуживанию архива.

Строки с именами нужно хранить в базе а файлы именовать чем то более нейтральным - например хеш в hex записи или числовой идентификатор
Ответ написан
Комментировать
delphinpro
@delphinpro Куратор тега PHP
frontend developer
1. не храните файлы с оригинальными названиями. Лучше их хешировать и сохранять на сервере в виде хешированных имен (md5, sha1).
2. Сделайте простую проверку на максимум if (strlen(sss) > 200) warn!!! никаких обрезаний, просто предупреждение – Имя файла слишком длинное. Пусть пользователь сам меняет название.
(strlen считает количество байтов, не символов. Ограничения в ОС как раз на количество байтов, скорее всего. Эмодзи в unicode занимают по 4-8 байтов, кириллица - по два, латиница по одному. )
3. Если нужно сохранить оригинальные названия (для отображения на сайте, или для скачивания) – храните в БД соответствие hash<->original. Для корректного хранения в БД символов юникода, следует выбрать кодировку utf8mb4

И никаких проблем.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы