preg_replace () 및 scandir ()의 인코딩 문제
-
20-09-2019 - |
문제
OS-X (PHP5.2.11)에는 siësta.doc (및 유니 코드 파일 이름이있는 수천 개의 다른) 파일이 있으며 파일 이름을 웹에 소비 할 수있는 형식 (a-za-z0-9)으로 변환하려고합니다. 위의 파일 이름을 하드 코딩하면 올바른 변환을 수행 할 수 있습니다.
<?php
$file = 'siësta.doc';
echo preg_replace("/[^a-zA-Z0-9.]/u", '_', $file);
// Output: si_sta.doc
?>
그러나 Scandir로 파일 이름을 읽으면 이상한 변환이 있습니다.
<?php
$files = scandir(DIRNAME);
foreach ($files as $file) {
echo preg_replace("/[^a-zA-Z0-9.]/u", '_', $file);
// Output for the file above: sie_sta.doc
}
?>
인코딩을 감지하고 인코딩을 설정하고 ICONV 기능으로 변환하려고했습니다. MB_ 함수도 시도했습니다. 그러나 그것은 더 나빴습니다. 내가 뭘 잘못 했어?
미리 감사드립니다
해결책
흥미로운. 약간의 Recherché 후 OSX가 파일 이름을 "분해 유니 코드"로 저장한다는 것을 알았습니다 ( http://developer.apple.com/mac/library/qa/qa2001/qa1173.html). 즉, "ë"는 "e" + 일기 기호 (0xcc88)로 표시됩니다.
다른 팁
UTF8_encode를 사용해 보셨습니까? (최소한 창에서 작동)
<?php
$files = scandir(DIRNAME);
foreach ($files as $file) {
echo preg_replace("/[^a-zA-Z0-9.]/u", '_', utf8_encode($file));
// Output for the file above: sie_sta.doc
}
?>
문제는 Windows와 PHP 간의 의사 소통입니다. 유니 코드 파일 이름을 얻을 수는 없습니다. 비 전구가 아닌 Windows 응용 프로그램 언어에 의존하기 때문입니다.
가장 좋은 솔루션은 DIR 명령을 실행하고 정보를 처리 할 수있는 것이지만 CMD를 통해이를 수행하고 Windows 짧은 이름을 가져와야합니다.
chcp 65001
dir /x c:\test\ > myinfo.txt
반환 :
El volumen de la unidad C es Windows8_OS
El número de serie del volumen es: 14A3-025F
Directorio de C:\test
22/12/2015 22:11 <DIR> .
22/12/2015 22:11 <DIR> ..
22/12/2015 22:12 0 a.txt
22/12/2015 22:10 <DIR> English
22/12/2015 22:10 <DIR> ESPAOL~1 Español
22/12/2015 22:11 <DIR> 8311~1 ру́сский язы́к
22/12/2015 22:10 <DIR> _0B41~1 عربي ,عربى
22/12/2015 22:10 <DIR> 8F4C~1 北方話
1 archivos 0 bytes
7 dirs 839.672.786.944 bytes libres
그런 다음 MyInfo.txt를 읽고 원래 이름과 Windows Short Name 사이의 연결을 얻을 수 있습니다.
일부 PHP 기능은 짧은 이름으로 잘 작동하며 표시가 필요한 것처럼 빌드 및 배열을 만들 수 있습니다.
$array['short_name']= $original_name;
예를 들어: is_dir, is_file
잘 작동합니다. 하지만, scandir
또는 is_readable
짧은 이름도 실패합니다. 이러한 기능을 사용하는 솔루션은 DIR 명령을 재귀 적으로 다시 실행하는 것입니다.
txt 파일에서 정보를 얻으려면 처음 5 줄과 마지막 2 줄을 버리는 정규 표현식 또는 기판을 사용할 수 있습니다. 예를 들어:
for($k=6;$k<(count($array)-2);$k++) ...