D
D
Dmitry Mityaev2018-03-19 13:16:39
PHP
Dmitry Mityaev, 2018-03-19 13:16:39

PHP: Renaming part of a filename in a directory?

People! Can you please tell
me How can I use a script to rename crooked file names to normal ones in a directory?
On the hosting, the files are with names like: #U0411#U0430#U043b#U0430#U043d#U0441_#U043d#U0430_01012017.pdf
And it should be: Balance_on_01012017.pdf You
need a php script that will rename all files in the directory to normal.
How can this be done better?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
S
Stalker_RED, 2018-03-19
@Stalker_RED

Autocorrect + copy-paste from the manual =

tyts
<?php

$badname = "#U0411#U0430#U043b#U0430#U043d#U0441_#U043d#U0430_01012017.pdf";
$converted = preg_replace('/#U([0-9a-f]{1,4})/', '&#x${1};', $badname);
echo preg_replace_callback('/&#([0-9a-fx]+);/mi', 'replace_num_entity', $converted);


function replace_num_entity($ord)
{
    $ord = $ord[1];
    if (preg_match('/^x([0-9a-f]+)$/i', $ord, $match))
    {
        $ord = hexdec($match[1]);
    }
    else
    {
        $ord = intval($ord);
    }
    
    $no_bytes = 0;
    $byte = array();

    if ($ord < 128)
    {
        return chr($ord);
    }
    elseif ($ord < 2048)
    {
        $no_bytes = 2;
    }
    elseif ($ord < 65536)
    {
        $no_bytes = 3;
    }
    elseif ($ord < 1114112)
    {
        $no_bytes = 4;
    }
    else
    {
        return;
    }

    switch($no_bytes)
    {
        case 2:
        {
            $prefix = array(31, 192);
            break;
        }
        case 3:
        {
            $prefix = array(15, 224);
            break;
        }
        case 4:
        {
            $prefix = array(7, 240);
        }
    }

    for ($i = 0; $i < $no_bytes; $i++)
    {
        $byte[$no_bytes - $i - 1] = (($ord & (63 * pow(2, 6 * $i))) / pow(2, 6 * $i)) & 63 | 128;
    }

    $byte[0] = ($byte[0] & $prefix[0]) | $prefix[1];

    $ret = '';
    for ($i = 0; $i < $no_bytes; $i++)
    {
        $ret .= chr($byte[$i]);
    }

    return $ret;
}
demo
You can use DirectoryIterator to traverse the folder , or just plain old glob() + foreach.

D
Dmitry Mityaev, 2018-03-21
@DMityaev

Thanks, it helped! Here is the solution code:

<?
header("Content-Type: text/html; charset=utf-8");


Echo "Текущая кодировка:&nbsp;" . mb_internal_encoding(); ?> </br> <?

$ArrDir = glob("*.*");                                   //соберем файлы в текущей директории в массив

Echo "<b>Файлы в директории запуска скрипта:</b></br>";

foreach ($ArrDir as $key => $value) 
{
Echo "Ключ:&nbsp;{$key} => Значение:&nbsp;{$value}</br> "; 
}
             

Echo "<hr><b>Переменование битых имен файлов</b></br><hr>";

foreach($ArrDir as $name)
{
   Echo  "Имя файла до: $name</br>";  
 
   $name_decoded = preg_replace_callback('/[#_]u([0-9a-fA-F]{4})/i', function ($match) {
       return mb_convert_encoding(pack('H*', $match[1]), 'UTF-8', 'UCS-2BE');
       }, $name);

   Echo  "Имя файла после: $name_decoded</br><hr>";  

rename($name, $name_decoded);  

}

?>

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question