problème de codage avec preg_replace () et scandir ()
-
20-09-2019 - |
Question
OS-X (PHP5.2.11) J'ai un fichier: siësta.doc (et des milliers d'autres noms de fichiers Unicode) et je veux convertir les noms de fichiers dans un format consommable web (a-zA-Z0-9 .). Si je hardcode le nom de fichier ci-dessus, je peux faire la conversion droite:
<?php
$file = 'siësta.doc';
echo preg_replace("/[^a-zA-Z0-9.]/u", '_', $file);
// Output: si_sta.doc
?>
Mais si je lis les noms de fichiers avec scandir, j'ai des conversions étranges:
<?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
}
?>
J'ai essayé de détecter le codage, Choisit l'encodage, le convertir avec des fonctions iconv. J'ai essayé les fonctions MB_ aussi. Mais il était pire. Qu'est-ce que je fait de mal?
Merci d'avance
La solution
. Après un peu j'ai trouvé recherché que les noms de fichiers stocke OSX comme "unicode décomposé" (voir http://developer.apple.com/mac/library/qa/qa2001/qa1173.html ). Autrement dit, "ë" est représentée comme "e" + symbole tréma (0xcc88).
Autres conseils
Vous avez essayé utf8_encode? (Fonctionne sous Windows au moins)
<?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
}
?>
Le problème est la communication entre les fenêtres et php. D'une manière pas possible d'obtenir les noms de fichiers unicode, car ils dépendent des fenêtres non-unicode langue de l'application.
La meilleure solution consiste à exécuter une commande dir et obtenir des informations à traiter, mais vous devez le faire si par un cmd et obtenir les fenêtres des noms courts:
chcp 65001
dir /x c:\test\ > myinfo.txt
Il retourne:
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
Ensuite, vous pouvez lire myinfo.txt pour obtenir la connexion entre le nom d'origine et les fenêtres nom court.
Certaines fonctions PHP fonctionne très bien avec des noms courts et vous pouvez construire et tableau comme si vous avez besoin afficher:
$array['short_name']= $original_name;
Par exemple: is_dir, is_file
fonctionne bien . Cependant, scandir
ou is_readable
échoue avec des noms courts trop . La solution à utiliser ces fonctions consiste à réexécuter une commande dir récursive.
Pour obtenir des informations à partir du fichier txt, vous pouvez utiliser une expression régulière ou substr, en rejetant les cinq premières lignes et les deux derniers. Par exemple:
for($k=6;$k<(count($array)-2);$k++) ...