문제

나는 사용할 수 없다 mkdir UTF-8 문자로 폴더를 만들려면 :

<?php
$dir_name = "Depósito";
mkdir($dir_name);
?>

Windows 탐색기 에서이 폴더를 탐색하면 폴더 이름이 다음과 같습니다.

Depósito

어떻게해야합니까?

PHP5를 사용하고 있습니다

도움이 되었습니까?

해결책

단지 urlencode 문자열은 파일 이름으로 원하는 것입니다. 모두 캐릭터가 돌아 왔습니다 urlencode 파일 이름 (NTFS/HFS/UNIX)에서 유효합니다. 그러면 urldecode 파일 이름은 UTF-8 (또는 인코딩이 무엇이든)로 돌아갑니다.

경고 (모두 아래 솔루션에도 적용) :

  • URL 인코딩 후 파일 이름은 255 자 미만 (아마도 바이트)이어야합니다.
  • UTF-8이 있습니다 다중 표현 많은 문자의 경우 (문자 결합 사용). UTF-8을 정상화하지 않으면 검색에 어려움이있을 수 있습니다. glob 또는 개별 파일을 재개합니다.
  • 당신은 의존 할 수 없습니다 scandir 또는 알파-분류를위한 유사한 기능. 당신은해야합니다 urldecode 그런 다음 파일 이름은 UTF-8 (및 Collations)을 인식하는 정렬 알고리즘을 사용합니다.

더 나쁜 솔루션

다음은 덜 매력적인 솔루션이며 더 복잡하고 더 많은 경고가 있습니다.

Windows에서 PHP 파일 시스템 래퍼는 파일/디렉토리 이름에 대해 ISO-8859-1 문자열을 기대하고 반환합니다. 이것은 두 가지 선택을 제공합니다.

  1. 파일 이름에서 UTF-8을 자유롭게 사용하지만 ASCII가 아닌 문자가 잘못된 것 같습니다 PHP 외부. 비 ASCII UTF-8 char는 다중로 저장됩니다 하나의 ISO-8859-1 문자. 예를 들어 ó 표시됩니다 ó Windows 탐색기에서.

  2. 파일/디렉토리 이름을 제한하십시오 ISO-8859-1로 표현할 수있는 문자. 실제로, 당신은 당신의 UTF-8 현을 통과시킬 것입니다 utf8_decode 파일 시스템 기능에서 사용하기 전에 항목을 전달하십시오. scandir 당신에게 제공합니다 utf8_encode UTF-8에서 원래 파일 이름을 얻으려면.

경고가 풍부합니다!

  • 만약에 어떠한 바이트 파일 시스템 함수 일치에 전달됩니다 유효하지 않은 Windows 파일 시스템 문자 ISO-8859-1에서는 운이 좋지 않습니다.
  • 5월 영어 이외의 지역에서 ISO-8859-1 이외의 인코딩을 사용하십시오. 나는 그것이 일반적으로 ISO-8859-#중 하나 일 것이라고 생각하지만 이것은 당신이 사용해야한다는 것을 의미합니다. mb_convert_encoding 대신에 utf8_decode.

이 악몽은 아마도 당신이 아마도 그냥 해야하는 이유입니다 바꾸어 쓰다 파일 이름을 작성합니다.

다른 팁

Unix 및 Linux (및 OS X에서도) 아래에서 현재 파일 시스템 인코딩은 LC_CTYPE 로케일 매개 변수 (기능 참조 setlocale()). 예를 들어, 같은 것으로 평가할 수 있습니다 en_US.UTF-8 즉, 인코딩이 UTF-8임을 의미합니다. 그런 다음 파일 이름과 경로는 fopen() 또는 검색 dir() 이 인코딩으로.

Windows에서 PHP는 "비 유니 코드 인식 프로그램"으로 작동하며 파일 이름은 파일 시스템 (Windows 2000 이상)에서 사용하는 UTF-16에서 선택한 "코드 페이지"로 전환됩니다. 제어판 "지역 및 언어 옵션", 탭 패널 "형식"은 LC_CTYPE 옵션, "비공개 프로그램의 관리 -> 언어"는 파일 이름의 번역 코드 페이지를 설정합니다. 서구 국가에서 LC_CTYPE 매개 변수는 같은 것으로 평가됩니다 language_country.1252 여기서 1252는 코드 페이지이며, "Windows-1252 인코딩"이라고도하는 코드 페이지입니다. 일본에서는 932 코드 페이지가 일반적으로 다른 국가에서 설정됩니다. PHP에서는 현재 코드 페이지로 이름을 표현할 수있는 파일을 만들 수 있습니다. 반대로 파일 시스템에서 검색된 파일 이름 및 경로는 UTF-16에서 바이트로 변환됩니다. "가장 적합한"현재 코드 페이지.

이 매핑은 근사하므로 일부 문자는 예측할 수없는 방식으로 엉망이 될 수 있습니다. 예를 들어, Caffé Brillì.txt 반환됩니다 dir() PHP 문자열로 Caff\xE9 Brill\xEC.txt 현재 코드 페이지가 1252 인 경우 예상대로, 대략적인 것을 반환합니다. Caffe Brilli.txt 일본 시스템에서는 932 코드 페이지에서 악센트 모음이 누락 된 다음 "가장 적합한"모음이 아닌 모음으로 교체 되었기 때문입니다. 전혀 번역 할 수없는 문자는 다음과 같이 검색됩니다. ? (물음표). 일반적으로 창문 아래에는 그러한 유물을 감지 할 수있는 안전한 방법이 없습니다.

자세한 내용은 내 답장에서 확인할 수 있습니다 PHP 버그 번호. 47096.

PHP 7.1은 OEM CodePage를 무시하는 Windows의 UTF-8 파일 이름을 지원합니다.

문제는 Windows가 파일 시스템 스트링에 UTF-16을 사용하는 반면 Linux와 다른 사람들은 다른 문자 세트를 사용하지만 종종 UTF-8을 사용한다는 것입니다. UTF-8 문자열을 제공했지만 이것은 Windows에서 인코딩하는 또 다른 8 비트 문자 세트, 아마도 Latin-1 및 UTF-8에서 2 바이트로 인코딩 된 비 ASCII 문자로 해석됩니다. Windows에서 2자인 경우.

일반적인 솔루션은 소스 코드를 ASCII에서 100% 유지하고 다른 곳에 문자열을 갖는 것입니다.

사용 com_dotnet PHP 확장, Windows '에 액세스 할 수 있습니다. Scripting.FileSystemObject, 그런 다음 UTF-8 파일/폴더 이름으로 원하는 모든 것을 수행하십시오.

이것을 PHP 스트림 래퍼로 포장 했으므로 사용하기가 매우 쉽습니다.

https://github.com/nicolas-grekas/patchwork-utf8/blob/lab-windows-fs/class/patchwork/utf8/winfsstreamwrapper.php

먼저 그것을 확인하십시오 com_dotnet 확장자가 활성화되어 있습니다 php.ini그런 다음 래퍼를 사용하여 다음을 활성화합니다.

stream_wrapper_register('win', 'Patchwork\Utf8\WinFsStreamWrapper');

마지막으로, 당신이 사용하는 기능 (mkdir, fopen, ename 등)을 사용하지만 경로를 접두사하십시오. win://

예를 들어:

<?php
$dir_name = "Depósito";
mkdir('win://' . $dir_name );
?>

이 확장을 사용하여 문제를 해결할 수 있습니다. https://github.com/kenjiuno/php-wfio

$file = fopen("wfio://多国語.txt", "rb"); // in UTF-8
....
fclose($file);

Codeigniter 텍스트 도우미를 사용해보십시오 이 링크convert_accented_characters () 함수에 대해 읽으십시오. 의상을 입을 수 있습니다.

Windows에서 UTF-8과 함께 파일 시스템을 사용하는 도구 세트 또는 리눅스를 통해 PHP 그리고 호환 가능 .htaccess 확인 파일이 존재합니다.

function define_cur_os(){

    //$cur_os=strtolower(php_uname());

    $cur_os=strtolower(PHP_OS);

    if(substr($cur_os, 0, 3) === 'win'){

        $cur_os='windows';

    }

    define('CUR_OS',$cur_os);

}

function filesystem_encode($file_name=''){

    $file_name=urldecode($file_name);

    if(CUR_OS=='windows'){

        $file_name=iconv("UTF-8", "ISO-8859-1//TRANSLIT", $file_name);

    }     

    return $file_name;

}

function custom_mkdir($dir_path='', $chmod=0755){

    $dir_path=filesystem_encode($dir_path);

    if(!is_dir($dir_path)){

        if(!mkdir($dir_path, $chmod, true)){

            //handle mkdir error

        }
    }
    return $dir_path;
}

function custom_fopen($dir_path='', $file_name='', $mode='w'){

    if($dir_path!='' && $file_name!=''){

        $dir_path=custom_mkdir($dir_path);

        $file_name=filesystem_encode($file_name);

        return fopen($dir_path.$file_name, $mode);

    }

    return false;

}

function custom_file_exists($file_path=''){

    $file_path=filesystem_encode($file_path);

    return file_exists($file_path);

}

function custom_file_get_contents($file_path=''){

    $file_path=filesystem_encode($file_path);

    return file_get_contents($file_path);

}

추가 리소스

많이 쓸 필요가없고 잘 작동합니다.

<?php
$dir_name = mb_convert_encoding("Depósito", "ISO-8859-1", "UTF-8");
mkdir($dir_name);
?>
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top