PHP에서는 HFS+ 대 다른 곳에서 인코딩 된 파일 이름의 차이를 어떻게 처리합니까?

StackOverflow https://stackoverflow.com/questions/773574

문제

검색 데이터베이스가 한 줄 당 파일 이름이 하나 인 텍스트 파일 인 매우 간단한 파일 검색을 만들고 있습니다. 데이터베이스는 PHP와 함께 구축되며 파일 (PHP와 함께)을 철회하여 일치합니다.

이것은 Linux에서 잘 작동하지만 비 ASCII 문자가 사용될 때 MAC에 있지 않습니다. 이름이 EG Ext3 (Linux)의 HFS+ (MACOSX)에서 다르게 인코딩되는 것처럼 보입니다. 다음은 test.php입니다.

<?php
$mystring = "abcóüÚdefå";
file_put_contents($mystring, "");
$h = dir('.');
$h->read(); // "."
$h->read(); // ".."
$filename = $h->read();

print "string: $mystring and filename: $filename are ";

if ($mystring == $filename) print "equal\n";
else print "different\n";

MacOSX를 실행할 때 :

$ php test.php
string: abcóüÚdefå and filename: abcóüÚdefå are different
$ php test.php |cat -evt
string: abcóü?M-^Zdefå$ and filename: abco?M-^Au?M-^HU?M-^Adefa?M-^J are different$

Linux에서 실행할 때 (또는 MacOSX의 NFS 장착 ERF3 파일 시스템) :

$ php test.php
string: abcóüÚdefå and filename: abcóüÚdefå are equal
$ php test.php |cat -evt
string: abcM-CM-3M-CM-<M-CM-^ZdefM-CM-% and filename: abcM-CM-3M-CM-<M-CM-^ZdefM-CM-% are equal$

두 플랫폼 에서이 스크립트를 "동일"하게 만드는 방법이 있습니까?

도움이 되었습니까?

해결책

MacOSX는 정규화 양식 D (NFD)를 사용하여 UTF-8을 인코딩하는 반면 대부분의 다른 시스템은 NFC를 사용합니다.

NFC vs NFD

(unicode.org에서)

거기 있습니다 몇몇의 구현 NFD에서 NFC 변환에서. 여기서는 PHP를 사용했습니다 정상화 클래스 NFD 문자열을 감지하고 NFC로 변환합니다. PHP 5.3 또는 PECL 국제화 확장. 다음 수정안은 대본이 작동합니다.

...
$filename = $h->read();
if (!normalizer_is_normalized($filename)) {
   $filename = normalizer_normalize($filename);
}
...

다른 팁

Mac OS X/HFS+는 단일 문자 대신 문자 조합을 사용하는 것 같습니다. 그래서 ó (u+00f3)는 대신 AS로 인코딩됩니다 o (u +006f) + ´ (U+CC81, 급성 악센트 결합). 또한보십시오 Apple의 유니 코드 분해 테이블.

두 시스템 모두 동일한 로케일을 사용하는지 확인 했습니까?

PHP 스크립트는 두 시스템 모두에서 사용하는 인코딩은 무엇입니까?

나는 또한 사용해 볼 것입니다 strcmp 평등 연산자 대신. Equals 연산자가 내부적으로 STRCMP를 사용하는지 확실하지 않지만 귀하의 경우 테스트하는 것은 간단한 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top