una subido ruta reemplazar obtener nombre manejo leer funciones ficheros ejemplos desde carpeta archivos archivo abrir php utf-8 directory filesystems mkdir

ruta - obtener nombre de archivo subido php



¿Cómo uso las funciones del sistema de archivos en PHP, usando cadenas UTF-8? (8)

Con la extensión PHP de com_dotnet , puede acceder a Scripting.FileSystemObject Windows y luego hacer todo lo que desee con los nombres de archivos / carpetas UTF-8.

Empaqueté esto como un contenedor de flujo PHP, por lo que es muy fácil de usar:

https://github.com/nicolas-grekas/Patchwork-UTF8/blob/lab-windows-fs/class/Patchwork/Utf8/WinFsStreamWrapper.php

Primero verifique que la extensión com_dotnet esté habilitada en su php.ini luego habilite el contenedor con:

stream_wrapper_register(''win'', ''Patchwork/Utf8/WinFsStreamWrapper'');

Finalmente, use las funciones a las que está acostumbrado (mkdir, fopen, rename, etc.), pero prefija su ruta con win://

Por ejemplo:

<?php $dir_name = "Depósito"; mkdir(''win://'' . $dir_name ); ?>

No puedo usar mkdir para crear carpetas con caracteres UTF-8:

<?php $dir_name = "Depósito"; mkdir($dir_name); ?>

cuando navego por esta carpeta en el Explorador de Windows, el nombre de la carpeta es así:

Depósito

¿Que debería hacer?

Estoy usando php5


El problema es que Windows usa utf-16 para las cadenas del sistema de archivos, mientras que Linux y otros usan diferentes conjuntos de caracteres, pero a menudo utf-8. Proporcionó una cadena utf-8, pero esto se interpreta como otra codificación de conjunto de caracteres de 8 bits en Windows, tal vez Latin-1, y luego el carácter no ascii, que está codificado con 2 bytes en utf-8, se maneja como si fue 2 caracteres en Windows.

Una solución normal es mantener el código fuente al 100% en ascii y tener cadenas en otro lugar.


En Unix y Linux (y posiblemente también en OS X), la codificación del sistema de archivos actual viene dada por el parámetro LC_CTYPE locale (ver función setlocale() ). Por ejemplo, puede evaluar algo como en_US.UTF-8 que significa que la codificación es UTF-8. Luego, los nombres de los archivos y sus rutas se pueden crear con fopen() o recuperados por dir() con esta codificación.

En Windows, PHP funciona como un "programa no compatible con Unicode", luego los nombres de los archivos se convierten desde el UTF-16 utilizado por el sistema de archivos (Windows 2000 y posterior) a la "página de códigos" seleccionada. El panel de control "Configuración regional y de idioma", el panel de pestañas "Formatos" configura la página de códigos recuperada mediante la opción LC_CTYPE , mientras que "Administrativo -> Idioma para programas no Unicode" establece la página de códigos de traducción para los nombres de archivo. En los países occidentales, el parámetro LC_CTYPE se evalúa como language_country.1252 donde 1252 es la página de códigos, también conocida como "codificación Windows-1252", que es similar (pero no exactamente igual) a ISO-8859-1. En Japón, la página de códigos 932 generalmente se establece en su lugar, y así sucesivamente para otros países. En PHP, puede crear archivos cuyo nombre se pueda expresar con la página de códigos actual. Viceversa, los nombres de archivo y las rutas recuperadas del sistema de archivos se convierten de UTF-16 a bytes utilizando la página de códigos actual que mejor se ajusta .

Este mapeo es aproximado, por lo que algunos personajes pueden ser destrozados de una manera impredecible. Por ejemplo, Caffé Brillì.txt sería devuelto por dir() como la cadena PHP Caff/xE9 Brill/xEC.txt como se esperaba si la página de códigos actual es 1252, mientras que devolvería el Caffe Brilli.txt aproximado en un sistema japonés porque las vocales acentuadas faltan en la página de códigos 932 y luego se reemplazan por las vocales sin acentos que mejor se ajustan. Los caracteres que no se pueden traducir en absoluto se recuperan como ? (signo de interrogación). En general, en Windows no existe una forma segura de detectar dichos artefactos.

Más detalles están disponibles en mi respuesta al error de PHP no. 47096 .


Mi conjunto de herramientas para usar el sistema de archivos con UTF-8 en Windows O Linux a través de PHP y compatible con el archivo de verificación .htaccess existe:

function define_cur_os(){ //$cur_os=strtolower(php_uname()); $cur_os=strtolower(PHP_OS); if(substr($cur_os, 0, 3) === ''win''){ $cur_os=''windows''; } define(''CUR_OS'',$cur_os); } function filesystem_encode($file_name=''''){ $file_name=urldecode($file_name); if(CUR_OS==''windows''){ $file_name=iconv("UTF-8", "ISO-8859-1//TRANSLIT", $file_name); } return $file_name; } function custom_mkdir($dir_path='''', $chmod=0755){ $dir_path=filesystem_encode($dir_path); if(!is_dir($dir_path)){ if(!mkdir($dir_path, $chmod, true)){ //handle mkdir error } } return $dir_path; } function custom_fopen($dir_path='''', $file_name='''', $mode=''w''){ if($dir_path!='''' && $file_name!=''''){ $dir_path=custom_mkdir($dir_path); $file_name=filesystem_encode($file_name); return fopen($dir_path.$file_name, $mode); } return false; } function custom_file_exists($file_path=''''){ $file_path=filesystem_encode($file_path); return file_exists($file_path); } function custom_file_get_contents($file_path=''''){ $file_path=filesystem_encode($file_path); return file_get_contents($file_path); }

Recursos adicionales


PHP 7.1 admite nombres de archivos UTF-8 en Windows sin tener en cuenta la página de códigos OEM.


Pruebe el Ayudante de CodeIgniter Text desde este enlace Lea sobre la función convert_accented_characters (), se puede personalizar



Simplemente urlencode la cadena deseada como un nombre de archivo. Todos los caracteres devueltos desde urlencode son válidos en nombres de archivo (NTFS / HFS / UNIX), luego puede urldecode los nombres de los archivos nuevamente en UTF-8 (o en cualquier codificación en la que se encuentren).

Advertencias (todas se aplican a las siguientes soluciones también):

  • Después de la codificación url, el nombre de archivo debe ser menor a 255 caracteres (probablemente bytes).
  • UTF-8 tiene múltiples representaciones para muchos caracteres (usando caracteres combinados). Si no normaliza su UTF-8, puede tener problemas para buscar con glob o reabrir un archivo individual.
  • No puede confiar en scandir o funciones similares para alfa-sorting. Debe urldecode los nombres de los archivos y luego utilizar un algoritmo de clasificación que tenga en cuenta el UTF-8 (y las intercalaciones).

Peores soluciones

Las siguientes son soluciones menos atractivas, más complicadas y con más advertencias.

En Windows, el contenedor del sistema de archivos PHP espera y devuelve cadenas ISO-8859-1 para los nombres de archivos / directorios. Esto te da dos opciones:

  1. Use UTF-8 libremente en sus nombres de archivo, pero entienda que los caracteres que no son ASCII aparecerán incorrectos fuera de PHP. Un carácter no UTC-8 ASCII se almacenará como múltiples caracteres ISO-8859-1 individuales . Por ejemplo, aparecerá como ó en Windows Explorer.

  2. Limite sus nombres de archivo / directorio a caracteres representables en ISO-8859-1 . En la práctica, pasará sus cadenas UTF-8 a través de utf8_decode antes de usarlas en las funciones del sistema de archivos, y pasará las entradas que scandir le brinda a través de utf8_encode para obtener los nombres de archivo originales en UTF-8.

¡Expectativas en abundancia!

  • Si un byte transferido a una función del sistema de archivos coincide con un carácter de sistema de archivos de Windows no válido en ISO-8859-1, no tiene suerte.
  • Windows puede usar una codificación que no sea ISO-8859-1 en locales no ingleses. Supongo que generalmente será uno de ISO-8859- #, pero esto significa que necesitarás usar mb_convert_encoding lugar de utf8_decode .

Esta pesadilla es la razón por la que probablemente solo deberías transliterate para crear nombres de archivo.