En PHP, ¿cómo lidiar con la diferencia de nombres de archivos codificados en HFS + en comparación con otros lugares?

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

Pregunta

Estoy creando una búsqueda de archivos muy simple, donde la base de datos de búsqueda es un archivo de texto con un nombre de archivo por línea. La base de datos está construido con PHP, y se encuentran coincidencias por grepping el archivo (también con PHP).

Esto funciona muy bien en Linux, pero no en Mac cuando no ASCII caracteres se utilizan . Parece que los nombres están codificados de manera diferente en HFS + (MacOSX) que en, por ejemplo, ext3 (Linux). He aquí una prueba.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";

Cuando se ejecuta 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$

Cuando se ejecuta en Linux (o en un sistema de archivos ext3 NFS montado en MacOSX):

$ 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$

¿Hay una manera de hacer este retorno guión "iguales" en ambas plataformas?

¿Fue útil?

Solución

utiliza MacOSX forma normalización D (NFD) para codificar UTF-8, mientras más otros sistemas utilizan NFC .

NFC vs NFD

( de unicode.org )

Hay varios implementaciones en NFD a la conversión NFC. Aquí he utilizado la clase PHP Normalizador para detectar cadenas NFD y convertirlos a NFC. Está disponible en PHP 5.3 o a través de la PECL internacionalización extensión . La siguiente modificación hará que el script funcione:

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

Otros consejos

Parece que Mac OS X / HFS + está utilizando combinaciones de caracteres en lugar de caracteres individuales. Por lo que el ó (U + 00F3) en su lugar se codifica como o (U + 006F) + ´ (T + CC81, combinando AGUDA acento). Ver también Unicode Tabla de descomposición de Apple .

¿Ha comprobado que ambos sistemas utilizan el mismo local?

¿Qué es la codificación de la secuencia de comandos PHP usando en ambos sistemas?

Me gustaría también tratar de usar strcmp en lugar del operador de igualdad. No estoy seguro de si el operador igual utiliza strcmp internamente, pero es una cosa simple para probar su caso.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top