cómo iterar sobre los nombres de archivo no inglesa en PHP
-
05-10-2019 - |
Pregunta
Tengo un directorio que contiene varios archivos, muchos de los cuales tiene nombre no Inglés. Estoy usando PHP en Windows 7.
Quiero que el nombre del archivo y su contenido usando PHP.
Actualmente estoy usando DirectoryIterator
y file_get_contents
. Esto funciona para archivos de nombres de Inglés, pero no para los no-Inglés nombres de archivo (chino).
Por ejemplo, tengo nombres de archivo como "?? ?? ?????????. EML", "hola ? ? ? ? ? ? .eml".
-
DirectoryIterator
no es capaz de obtener el nombre del archivo usando->getFilename()
-
file_get_contents
tampoco es capaz de abrir incluso si codificar el nombre de archivo en su parámetro.
¿Cómo puedo hacerlo?
Solución
Esto no es posible. Es una limitación de PHP. PHP utiliza las versiones de varios bytes de API de Windows; que está limitado a los personajes de su página de código puede representar.
Contenido del directorio:
D:\Users\Cataphract\Desktop\teste2>dir Volume in drive D is GRANDEDISCO Volume Serial Number is 945F-DB89 Directory of D:\Users\Cataphract\Desktop\teste2 01-06-2010 17:16 . 01-06-2010 17:16 .. 01-06-2010 17:15 0 coptic small letter shima follows ϭ.txt 01-06-2010 17:18 86 teste.php 2 File(s) 86 bytes 2 Dir(s) 12.178.505.728 bytes free
contenido de los archivos de prueba:
<?php
exec('pause');
foreach (new DirectoryIterator(".") as $v) {
echo $v."\n";
}
Prueba de archivos resultados:
. .. coptic small letter shima follows ?.txt teste.php
salida del depurador:
pila de llamadas (PHP 5.3.0):
> php5ts_debug.dll!readdir_r(DIR * dp=0x02f94068, dirent * entry=0x00a7e7cc, dirent * * result=0x00a7e7c0) Line 80 C php5ts_debug.dll!php_plain_files_dirstream_read(_php_stream * stream=0x02b94280, char * buf=0x02b9437c, unsigned int count=260, void * * * tsrm_ls=0x028a15c0) Line 820 + 0x17 bytes C php5ts_debug.dll!_php_stream_read(_php_stream * stream=0x02b94280, char * buf=0x02b9437c, unsigned int size=260, void * * * tsrm_ls=0x028a15c0) Line 603 + 0x1c bytes C php5ts_debug.dll!_php_stream_readdir(_php_stream * dirstream=0x02b94280, _php_stream_dirent * ent=0x02b9437c, void * * * tsrm_ls=0x028a15c0) Line 1806 + 0x16 bytes C php5ts_debug.dll!spl_filesystem_dir_read(_spl_filesystem_object * intern=0x02b94340, void * * * tsrm_ls=0x028a15c0) Line 199 + 0x20 bytes C php5ts_debug.dll!spl_filesystem_dir_open(_spl_filesystem_object * intern=0x02b94340, char * path=0x02b957f0, void * * * tsrm_ls=0x028a15c0) Line 238 + 0xd bytes C php5ts_debug.dll!spl_filesystem_object_construct(int ht=1, _zval_struct * return_value=0x02b91f88, _zval_struct * * return_value_ptr=0x00000000, _zval_struct * this_ptr=0x02b92028, int return_value_used=0, void * * * tsrm_ls=0x028a15c0, long ctor_flags=0) Line 645 + 0x11 bytes C php5ts_debug.dll!zim_spl_DirectoryIterator___construct(int ht=1, _zval_struct * return_value=0x02b91f88, _zval_struct * * return_value_ptr=0x00000000, _zval_struct * this_ptr=0x02b92028, int return_value_used=0, void * * * tsrm_ls=0x028a15c0) Line 658 + 0x1f bytes C php5ts_debug.dll!zend_do_fcall_common_helper_SPEC(_zend_execute_data * execute_data=0x02bc0098, void * * * tsrm_ls=0x028a15c0) Line 313 + 0x78 bytes C php5ts_debug.dll!ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER(_zend_execute_data * execute_data=0x02bc0098, void * * * tsrm_ls=0x028a15c0) Line 423 C php5ts_debug.dll!execute(_zend_op_array * op_array=0x02b93888, void * * * tsrm_ls=0x028a15c0) Line 104 + 0x11 bytes C php5ts_debug.dll!zend_execute_scripts(int type=8, void * * * tsrm_ls=0x028a15c0, _zval_struct * * retval=0x00000000, int file_count=3, ...) Line 1188 + 0x21 bytes C php5ts_debug.dll!php_execute_script(_zend_file_handle * primary_file=0x00a7fad4, void * * * tsrm_ls=0x028a15c0) Line 2196 + 0x1b bytes C php.exe!main(int argc=2, char * * argv=0x028a14c0) Line 1188 + 0x13 bytes C php.exe!__tmainCRTStartup() Line 555 + 0x19 bytes C php.exe!mainCRTStartup() Line 371 C
¿Es realmente un signo de interrogación?
dp->fileinfo {dwFileAttributes=32 ftCreationTime={...} ftLastAccessTime={...} ...} dwFileAttributes: 32 ftCreationTime: {dwLowDateTime=2784934701 dwHighDateTime=30081445 } ftLastAccessTime: {dwLowDateTime=2784934701 dwHighDateTime=30081445 } ftLastWriteTime: {dwLowDateTime=2784934701 dwHighDateTime=30081445 } nFileSizeHigh: 0 nFileSizeLow: 0 dwReserved0: 3435973836 dwReserved1: 3435973836 cFileName: 0x02f9409c "coptic small letter shima follows ?.txt" cAlternateFileName: 0x02f941a0 "COPTIC~1.TXT" dp->fileinfo.cFileName[34] 63 '?'
Sí! Es de carácter # 63.
Otros consejos
Breve respuesta:
En Windows, no se puede acceder a los nombres de archivos arbitrarios con PHP; que se limitan a los nombres de los archivos cuyo nombre se puede representar con la "página de códigos" seleccionado en ese momento (véase regional y de idioma", '' panel y 'Formato Administrativo' panel de pestañas 'Idioma para programas no Unicode').
Respuesta larga:
Windows utiliza UTF-16 para la codificación de archivos desde Win2000, pero PHP comunicarse con el sistema de archivos subyacente como un "programa cuenta no Unicode". Esto significa que hay una "tabla de páginas de código" corriente que tranlates de cadenas de PHP a UTF-16 cuerdas y viceversa. A partir de PHP de la página de códigos actual puede ser recuperada por setlocale () en la forma "language_country.codepage", por ejemplo:
setlocale (LC_CTYPE, 0) ==> "english_United States.1252"
donde 1252 es la tabla de páginas de códigos de Windows seleccionado desde el panel de control; nombres de los archivos recuperados del sistema de archivos se codifican con esa página de códigos; nombres de los archivos generados a partir de PHP deben ser codificados de acuerdo a la página de códigos. Las cosas son aún más complicadas por el hecho de que los nombres de archivo UTF-16 se TRADUCIDO a cadenas de PHP utilizando el "ajuste mejor página de códigos", que es una representación approxymated de los caracteres / palabras reales, por lo que no se puede confiar en los nombres de archivo y rutas recuperado del sistema de archivos, ya que podrían ser destrozados arbitrariamente.
Referencias:
http://en.wikipedia.org/wiki/Windows_code_page "¿Qué páginas de códigos de Windows" son.
https://bugs.php.net/bug.php?id=47096 Más detalles sobre este tema.
Do descubrir los archivos que tengo este script:
$content = scandir($directory);
$list = "<select size = 5 name ='file' id='file'>\n";
for($i = 0; $i < count ( $content ); $i ++) {
$list .= "<option>$content[$i] </option>\n";
}
$list .= "</select>\n";
Este éxito se encuentra el archivo: ? ? ? ? ? ? Lo he probado aquí en una distribución de Linux, aunque ..
a lo leyó que utilice: Línea por línea:
$lines = file('file.txt');
//loop through our array, show HTML source as HTML source; and line numbers too.
foreach ($lines as $line_num => $line) {
print "Line #<b>{$line_num}</b> : " . htmlspecialchars($line) . "<br />\n";//or try it without the htmlspecialchars
}