Транслитерация PHP и переименование файлов

Это моя проблема. Файлы не переименовываются. Что я делаю не так? Что я не вижу? Этот скрипт должен работать в Windows и Unix. Файл сценария в UNIX UTF-8 без спецификации. Пробовал Windows 1251, ANSI, но все еще не работает.

 <?php
 function Transliteration($FileName){ 
 $CharReplace = array (
'А'=>'A', 'Б'=>'B', 'В'=>'V',
'Г'=>'G', 'Д'=>'D', 'Е'=>'E',
'Ё'=>'E', 'Ж'=>'ZH', 'З'=>'Z',
'И'=>'I', 'Й'=>'J', 'К'=>'K',
'Л'=>'L', 'М'=>'M', 'Н'=>'N',
'О'=>'O', 'П'=>'P', 'Р'=>'R',
'С'=>'S', 'Т'=>'T', 'У'=>'U',
'Ф'=>'F', 'Х'=>'H', 'Ц'=>'TS',
'Ч'=>'CH', 'Ш'=>'SH', 'Щ'=>'SHH',
'Ъ'=>'', 'Ы'=>'I', 'Ь'=>'',
'Э'=>'E', 'Ю'=>'YU', 'Я'=>'YA',
'а'=>'a', 'б'=>'b', 'в'=>'v',
'г'=>'g', 'д'=>'d', 'е'=>'e',
'ё'=>'yo', 'ж'=>'zh', 'з'=>'z',
'и'=>'i', 'й'=>'j', 'к'=>'k',
'л'=>'l', 'м'=>'m', 'н'=>'n',
'о'=>'o', 'п'=>'p', 'р'=>'r',
'с'=>'s', 'т'=>'t', 'у'=>'u',
'ф'=>'f', 'х'=>'h', 'ц'=>'ts',
'ч'=>'ch',  'ш'=>'sh', 'щ'=>'shh',
'ъ'=>'', 'ы'=>'i', 'ь'=>'',
'э'=>'e', 'ю'=>'yu', 'я'=>'ya',
"№"=>"N", " "=>"_", "–"=>"_",
"-"=>"_", " - "=>"_", ","=>"");
$FileNameTranslited = str_replace(array_keys($CharReplace), $CharReplace, $FileName);
return $FileNameTranslited;}

function Renaming(){
$WorkDir = opendir("ToRename") or die("Не могу открыть папку");
while ($CurrentFile = readdir($WorkDir)){
    if ($CurrentFile != "." && $CurrentFile != ".."){
        $TranslitedFile = Transliteration($CurrentFile);
        if (rename($CurrentFile, $TranslitedFile))
            {echo "File Renamed";}
            else{echo "Some shit happen!";}
        echo $CurrentFile." -> ".$TranslitedFile."<br>";}}}

 Renaming();
 ?>

Большое спасибо StathisG! Это правильный ключ к решению. Но это все еще не работает. Смотри сюда:

 function Renaming(){
 $directory = 'ToRename/';
 $WorkDir = opendir($directory) or die("Не могу открыть папку");
 while ($CurrentFile = readdir($WorkDir)){
   if ($CurrentFile != "." && $CurrentFile != ".."){
    $WhichCodingWeWant = 'UTF-8';
    $FileNameCoding = mb_detect_encoding($CurrentFile);
    echo $FileNameCoding."<br/>";
    $utf8_filename = mb_convert_encoding($CurrentFile, $WhichCodingWeWant, $FileNameCoding);
    $TranslitedFile = Transliteration($utf8_filename);
    mb_convert_encoding($TranslitedFile, $FileNameCoding, $WhichCodingWeWant);
    echo mb_detect_encoding($TranslitedFile)."<br/>";
    if (rename($directory . $CurrentFile, $directory . $TranslitedFile)) {
       echo "File Renamed<br/>";
       } else {
         echo "Some shit happen!<br/>";
          }
        echo $utf8_filename." -> ".$TranslitedFile."<br>";
       }
    }
 }
   Renaming(); 

Как видите, я добавляю новые переменные «$ WhichCodingWeWant» и «$ FileNameCoding». Имя входящего файла: «Новый текстовый документ.txt» из «Гîâû Г © _ГІГҐГЄГ ± òîâà »Г © _äîêóìåГГІ.txt" должен быть "Novij_textovij_document.txt" Мой мозг взорван .. .


Хорошо ... шаг 3. Входящие данные как раньше: Новый текстовый документ.txt

 function Renaming(){
 $directory = 'ToRename/';
 $WorkDir = opendir($directory) or die("Не могу открыть папку");
 while ($CurrentFile = readdir($WorkDir)){
    if ($CurrentFile != "." && $CurrentFile != ".."){
        echo "What name is come: ".$CurrentFile."<br/>";
        $WhichCodingWeWant = 'UTF-8';
        $FileNameCoding = mb_detect_encoding($CurrentFile);
        echo "File name encoding: ".$FileNameCoding."<br/>";

        $utf8_filename = mb_convert_encoding($CurrentFile, $WhichCodingWeWant, $FileNameCoding);
        echo "File name behind transliting: ".$utf8_filename."<br/>";
        $TranslitedFile = Transliteration($utf8_filename);
        echo "File name translited to: ".$TranslitedFile."<br/>";

        mb_convert_encoding($TranslitedFile, $FileNameCoding, $WhichCodingWeWant);
        echo "File name encoding converted to: ".mb_detect_encoding($TranslitedFile)."<br/>";

        if (rename($directory . $CurrentFile, $directory . $TranslitedFile)) {
            echo "File Renamed<br/>";
        } else {
            echo "Some shit happen!<br/>";
        }
        echo $utf8_filename." -> ".$TranslitedFile."<br>";
    }
 }
 }
 Renaming();

 Result is: 
 What name is come: Новый текстовый документ.txt
 File name encoding: UTF-8
 File name behind transliting: ????? ????????? ????????.txt
 File name translited to: ?????_?????????_????????.txt
 File name encoding converted to: ASCII

Предупреждение:: Нет ошибки в E: \ WEB \ XAMPP \ htdocs \ my \ Site \ test \ test6.php в строке 32 Какое-то дерьмо случается! ????? ????????? ????????. txt -> ????? ????????? ????????. txt И файл не переименовывается в папке .

Зачем ASCII, если я хочу и делаю UTF-8? Я так понимаю, мне нечего понять! В любом случае спасибо StathisG за попытку мне помочь! Завтра попробую этот скрипт в системе Linux. И расскажу о результатах. Если у вас будут какие-то идеи по этому поводу, я буду рад это увидеть :)


person Baaakaaa    schedule 27.07.2014    source источник
comment
Возможно, попробуйте использовать одну из функций многобайтовых строк.   -  person StathisG    schedule 27.07.2014
comment
Спасибо, но можете ли вы мне сказать, какой из них я должен использовать? Раньше никогда не использую.   -  person Baaakaaa    schedule 27.07.2014
comment
Сначала я подумал, что проблема с заменой символов, но оказалось, что есть другая проблема. Посмотри на мой ответ.   -  person StathisG    schedule 27.07.2014


Ответы (1)


Ваш код выдает следующее предупреждение:

Предупреждение: переименовать (test.txt, test.txt): система не может найти указанный файл.

Переменная $CurrentFile содержит только имя файла, а не полный путь к файлу. Попробуйте следующее:

function Renaming(){
    $directory = 'ToRename/';
    $WorkDir = opendir($directory) or die("Не могу открыть папку");
    while ($CurrentFile = readdir($WorkDir)){
        if ($CurrentFile != "." && $CurrentFile != ".."){
            $utf8_filename = mb_convert_encoding($CurrentFile, 'UTF-8', 'GREEK');
            $TranslitedFile = Transliteration($utf8_filename);
            if (rename($directory . $CurrentFile, $directory . $TranslitedFile)) {
                echo "File Renamed";
            } else {
                echo "Some shit happen!";
            }
            echo $utf8_filename." -> ".$TranslitedFile."<br>";
        }
    }
}
Renaming();

Я тестировал вашу переменную Transliteration отдельно, и, похоже, она работает нормально (см. Тест ниже), поэтому игнорируйте мой исходный комментарий о функциях многобайтовых строк.

echo Transliteration('Не могу открыть папку'); // produces 'Ne_mogu_otkrit_papku'

РЕДАКТИРОВАТЬ:

Я отредактировал приведенный выше код, добавив следующую строку:

$utf8_filename = mb_convert_encoding($CurrentFile, 'UTF-8', 'GREEK');

Затем я использовал $utf8_filename как переменную, переданную вашей функции Transliteration:

$TranslitedFile = Transliteration($utf8_filename);

Как вы могли заметить, я использовал «GREEK» в качестве кодировки имени файла, поскольку это единственный язык, который я знаю, кроме английского, поэтому я использовал греческие имена файлов для тестирования вашего кода.

Я создал файл с названием «τεστ.txt» и добавил в массив $CharReplace следующие значения: 'τ'=>'t', 'ε'=>'e', 'σ'=>'s'

Когда я запустил код, я получил следующее сообщение, и файл был успешно переименован в «test.txt».

File Renamed τεστ.txt -> test.txt

Согласно руководству по PHP, поддерживаемые кодировки для mb_convert_encoding: эти.

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

person StathisG    schedule 27.07.2014
comment
Да, я пробовал это раньше. Но это не работает. Например: в папке ToRename у нас есть файл Новый текстовый документ.txt, после этого скрипта у нас должен быть Novij_textovij_document.txt. Но у нас этого нет! После скрипта был изменен только Новый_текстовый_документ.txt Только пробелы. - person Baaakaaa; 27.07.2014
comment
Пожалуйста, не думайте обо мне, как о своем кошмаре :) Я отредактировал свой вопрос. - person Baaakaaa; 28.07.2014
comment
@Baaakaaa Лол, это нормально. :) К сожалению, я нашел много вопросов относительно кириллических символов (которые, как я полагаю, вам и нужны), которые не имеют решения, по крайней мере, для систем, работающих под управлением Windows. Например, посмотрите здесь, здесь и здесь. - person StathisG; 28.07.2014
comment
Кроме того, локаль машины тоже может иметь какое-то значение. Например, я могу писать по-гречески, может поэтому пример с греческими именами файлов сработал. Кстати, а что вы получите, если echo $CurrentFile; перед попыткой изменить кодировку? - person StathisG; 28.07.2014
comment
Привет, StathisG! Посмотрите на upades в посте (шаг 3) И спасибо за ссылки. Винда как всегда ... ничего хорошего. Какую ОС вы используете? Можете ли вы сделать для тестов файл с именем Новый текстовый документ.txt? - person Baaakaaa; 28.07.2014
comment
@Baaakaaa Я проводил тесты в Windows 7. Я тестировал похожие имена файлов, и в каждом тесте значение $CurrentFile состоит из вопросительных знаков. Исходя из вашего редактирования, исходное значение $CurrentFile, которое вы получаете, является правильным, поэтому мое первоначальное решение может сработать. Пожалуйста, попробуйте еще раз код моего ответа, удалив строку $utf8_filename = mb_convert_encoding... и изменив следующую на $TranslitedFile = Transliteration($CurrentFile);. Кроме того, повторяйте переменные на каждом этапе, чтобы определить, в чем проблема (как вы это делали при последнем редактировании), и настройте PHP для отображения всех ошибок и предупреждений. - person StathisG; 29.07.2014
comment
Привет, StathisG! Извините за долгое время без ответов. Я тестирую этот сценарий в Debian, и он отлично работает! Но все еще не работает в Windows. Время мой враг. Позже попробую ваши изменения в скрипте Windows (последний комментарий). - person Baaakaaa; 10.08.2014