In PHP, come faccio a trattare con la differenza nei nomi dei file codificati in formato HFS + vs. altrove?

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

Domanda

Sto creando una semplice ricerca di file, in cui il database di ricerca è un file di testo con un nome di file per riga. Il database è costruito con PHP, e sono riscontrate da grep il file (anche con PHP).

Questa grande opera in Linux, ma non su Mac quando non ASCII caratteri vengono utilizzati . Sembra che i nomi sono codificati in modo diverso su HFS + (MacOSX) che su esempio ext3 (Linux). Ecco un 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";

Quando viene eseguito 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$

Quando viene eseguito su Linux (o su un filesystem ext3 NFS montato su 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$

C'è un modo per rendere questo ritorno script "pari" su entrambe le piattaforme?

È stato utile?

Soluzione

MacOSX utilizza forma normalizzazione D (NFD) per codificare UTF-8, mentre più altri sistemi utilizzano NFC .

NFC vs NFD

( da unicode.org )

Ci sono diversi implementazioni su NFD alla conversione NFC. Qui ho usato la classe PHP normalizzatore per rilevare le stringhe NFD e li converte per NFC. E 'disponibile in PHP 5.3 o tramite il PECL Internazionalizzazione estensione . Il seguente emendamento sarà far funzionare lo script:

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

Altri suggerimenti

Sembra che Mac OS X / HFS + utilizza combinazioni di caratteri invece di singoli caratteri. Così il ó (U + 00F3) è invece codificato come o (U + 006F) + ´ (U + CC81, COMBINANDO ACUTE ACCENT). Vedi anche Unicode decomposizione Tabella di Apple .

Hai controllato che entrambi i sistemi utilizzano lo stesso locale?

Che codifica è lo script PHP utilizzando su entrambi i sistemi?

Vorrei anche provare a utilizzare strcmp anziché l'operatore uguale. Non sono sicuro se l'operatore uguale utilizza strcmp internamente, ma è una cosa semplice da testare nel tuo caso.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top