Для простоты я загружаю файлы на веб-сайт с помощью XHR. Эти файлы переименовываются и «очищаются» (специальные символы и т. д.), прежде чем сохранять их имена в базе данных и хранить их в моей папке.
Когда я загружаю любые документы с любыми странными символами в них, с Mac все проходит очень гладко, и никто не страдает. Когда я пытаюсь сделать то же самое с теми же файлами на ПК с Windows, мой файл не переименовывается. Хуже всего то, что специальные символы заменяются вопросительными знаками, и тогда их невозможно удалить с моего FTP.
Я только что попытался внести некоторые изменения в свое регулярное выражение, но я запутался, потому что он работает с Mac, но не с Windows. Так что я предполагаю, что это может быть связано с тем, как ОС передает кодировку файла перед загрузкой или что-то в этом роде.
Вот мой JS:
$("#assist-form").submit(function() {
var str = $(this).serialize(),
progress = document.getElementById("progress"),
bar = document.getElementById("progress-bar"),
percent = document.getElementById("percent");
$.ajax({
xhr: function() {
var xhr = new window.XMLHttpRequest();
progress.style.display = "block";
xhr.upload.addEventListener("progress", function(evt) {
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total;
percentComplete = parseInt(percentComplete * 100);
var percentVal = percentComplete + "%";
bar.style.width=percentVal;
//console.info(percentVal);
percent.innerHTML = percentVal;
}
}, false);
return xhr;
},
type: "POST",
url: "'.CONTROLLERS.'assistManage.php",
data: new FormData( this ),
processData: false,
contentType: false,
dataType: "json",
success: function(msg) {
if (msg.result == 0 || msg.result == 1 || msg.result == 2) {
window.location.href = "'.ASSISTS.'&resu = "+msg.result+"";
} else {
$.bootstrapGrowl(msg.result, {
type: "danger",
width: "350"
});
}
}
});
return false;
});
И часть моего PHP, где я обрабатываю файлы:
if ( isset($_FILES['files']) && $_FILES["files"]["error"][0] == 0 )
{
$allowed = array('png', 'jpg', 'gif', 'xls', 'xlsx', 'doc', 'docx', 'pdf', 'eml', 'msg', 'rtf');
$docs = $_FILES['files'];
foreach ( $docs['tmp_name'] as $key => $tmp_name )
{
$file_ext = pathinfo($docs['name'][$key], PATHINFO_EXTENSION);
$file_name = Engine::cleanStr($docs['name'][$key], true);
$file_size = $docs['size'][$key];
$file_name_final = 'assist_'.$id.'-'.$file_name;
if ( !in_array(strtolower($file_ext), $allowed) )
$error .= $file_name.' : format de fichier non autorisé<br />';
elseif ( $file_size > 5000000 ) // 5 Mb
$error .= $file_name.' : fichier trop lourd<br />';
else
{
if ( move_uploaded_file($tmp_name, '../'.UPLOADS.$file_name_final) )
$req .= "INSERT INTO ".PREFIX."files VALUES ('0', '$id', '$file_name_final');";
else
$error .= $file_name.' : Erreur à l\'upload du fichier';
}
}
}
И моя функция "очистить" имена файлов:
static function cleanStr ( $txt, $punctuation = false )
{
$txt = trim($txt);
$txt = str_replace('œ', 'oe', $txt);
$txt = str_replace('Œ', 'Oe', $txt);
$txt = str_replace('æ', 'ae', $txt);
$txt = str_replace('Æ', 'Ae', $txt);
$txt = str_replace('²', '2', $txt);
$txt = str_replace('³', '3', $txt);
$txt = str_replace('°', '', $txt);
$txt = iconv("UTF-8", "ISO-8859-1//IGNORE", $txt);
if ( $punctuation )
{
$punct_array = array(',', ':', ';', '?', '!', '(', ')', '[', ']', '#', '&');
$punct_array2 = array(' ', "'", '---', '--');
$txt = str_replace($punct_array, '' , $txt);
$txt = str_replace($punct_array2, '-' , $txt);
}
return strtolower($txt);
}
Подводя итог, имя файла, подобное этому «Reçu-de-billet-électronique.txt», становится «recu-de-billet-electronique.txt» при загрузке с Mac и «re?u-de-billet-?lectronique.txt». " при загрузке из Windows.
Тот же файл, на том же сайте, с тем же скриптом, но с совершенно другим результатом. Я уже не знаю, где искать.
Это уже так настроено. Пока что все, что пробовал, приводит к тем же результатам -_-
Попробуйте заменить
$txt = iconv("UTF-8", "ISO-8859-1//IGNORE", $txt);
с этим
setlocale(LC_CTYPE, 'cs_CZ');
$txt = iconv('UTF-8', 'ASCII//IGNORE', $txt);
источник - https://www.php.net/manual/en/function.iconv.php
Мой скрипт «зависает», когда я добавляю $txt = iconv('UTF-8', 'ASCII//TRANSLIT', $txt);
к своей функции
@jnvgi Попробуйте заменить TRANSLIT на IGNORE.
Оно работает ! Ну специальные символы просто игнорируются. Таким образом, «reçu» становится «reu» (только в Windows, хорошо работает на Mac). Пока это не имеет большого значения. По крайней мере, у нас эта штука работает! Спасибо :)
@jnvgi Да, он будет игнорировать недоступные символы.
Я предполагаю, что это проблема с кодировкой. Но я не уверен. В любом случае, попробуйте установить
charset=utf-8