problema di codifica con preg_replace () e scandir ()
-
20-09-2019 - |
Domanda
Su OS-X (PHP5.2.11) Ho un file: siësta.doc (e migliaia di altri con nomi di file Unicode) e voglio convertire i nomi dei file in un formato web-consumo (a-zA-Z0-9 .). Se io hardcode il nome del file di cui sopra che posso fare il diritto di conversione:
<?php
$file = 'siësta.doc';
echo preg_replace("/[^a-zA-Z0-9.]/u", '_', $file);
// Output: si_sta.doc
?>
Ma se leggo i nomi di file con scandir, ho strani conversioni:
<?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
}
?>
Ho provato a rilevare la codifica, impostare la codifica, convertirlo con funzioni iconv. Ho provato anche le funzioni mb_. Ma era solo peggio. Che cosa ho fatto di sbagliato?
Grazie in anticipo
Soluzione
Interessante. Dopo un po 'ricercato ho trovato che i negozi OSX nomi di file come "unicode decomposto" (vedi http://developer.apple.com/mac/library/qa/qa2001/qa1173.html ). Cioè, "E" è rappresentato come "e" + simbolo dieresi (0xcc88).
Altri suggerimenti
Hai fatto provare utf8_encode? (Funziona su Windows, almeno)
<?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
}
?>
Il problema è la comunicazione tra le finestre e php. E'nessun possibile ottenere i nomi dei file Unicode, perché dipendono da non Unicode lingua applicazione delle finestre.
La soluzione migliore è quella di eseguire un comando dir e ottenere informazioni da elaborare, ma è necessario farlo in modo attraverso un cmd, e ottenere le finestre nomi corti:
chcp 65001
dir /x c:\test\ > myinfo.txt
Si ritorna:
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
Quindi, si può leggere myinfo.txt per ottenere il collegamento tra il nome originale e finestre nome breve.
Alcune funzioni PHP funziona bene con i nomi brevi e si può costruire e array come se avete bisogno di visualizzarla:
$array['short_name']= $original_name;
Ad esempio: is_dir, is_file
funziona bene . Tuttavia, scandir
o is_readable
non riesce con brevi nomi troppo . La soluzione per utilizzare queste funzioni è quello di eseguire nuovamente il comando dir in modo ricorsivo.
Per ottenere informazioni da file txt, è possibile utilizzare un'espressione regolare o substr, scartando le prime cinque righe e gli ultimi due. Ad esempio:
for($k=6;$k<(count($array)-2);$k++) ...