2010-06-01 11 views
14

Ho una directory che contiene diversi file, molti dei quali hanno un nome non inglese. Sto usando PHP in Windows 7.come iterare su nomi di file non inglesi in PHP

Voglio elencare il nome file e il loro contenuto utilizzando PHP.

Attualmente sto usando DirectoryIterator e file_get_contents. Funziona con nomi di file inglesi ma non con nomi di file non inglesi (cinesi).

Ad esempio, ho nomi di file come "एक और प्रोब्लेम. Eml", "ciao 鶨 鶖 鵨 鶣 鎹 鎣 .eml".

  1. DirectoryIterator non è in grado di ottenere il nome del file utilizzando ->getFilename()
  2. file_get_contents è anche in grado di aprire anche se mi codificare il nome del file nel suo parametro.

Come posso fare?

+0

Questa domanda merita di essere taggata come risposta. Artefacto ha fatto un grande sforzo per fornire informazioni accurate. –

+0

Sì. Questa è un'ottima risposta – Sabya

risposta

4

Questo non è possibile. È una limitazione di PHP. PHP utilizza le versioni multibyte delle API di Windows; sei limitato ai personaggi che la codepage può rappresentare.

Vedere this answer.

contenuto della directory:

 
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 

di prova contenuto del file:

<?php 
exec('pause'); 
foreach (new DirectoryIterator(".") as $v) { 
    echo $v."\n"; 
} 

risultati file di test:

 
. 
.. 
coptic small letter shima follows ?.txt 
teste.php 

Debugger uscita:

stack di chiamate (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 

È davvero un punto interrogativo?

 
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ì! È il personaggio n. 63.

+0

Non può semplicemente leggere e scrivere nomi come singoli byte? –

+0

@ Álvaro G. Vicario Poteva, ma non avrebbe nomi propri. NTFS supporta i nomi di file UCS-2 corretti, quello che stai descrivendo è un hack. – Artefacto

+0

La tua spiegazione non potrebbe essere migliore. Ho imparato molto oggi :) –

0

fare scoprire i file che ho questo 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"; 

Questo successo trovare il file: 鶨 鶖 鵨 鶣 鎹 鎣 ho provato qui su una distro Linux però ..

a leggere che è utilizzare: linea per linea:

$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 
} 
+0

Sì, il problema è Windows. – Artefacto

3

risposta breve:

In Windows, non è possibile accedere a nomi di file arbitrari con PHP; sei limitato a quei nomi di file il cui nome può essere rappresentato con la "code page" attualmente selezionata (vedi Opzioni internazionali e della lingua "," Formato "pannello e pannello" Amministrativo "" Lingua per programmi non Unicode ").

risposta più lunga:

Windows utilizza UTF-16 per la codifica di file dal Win2000, ma PHP comunicare con il file system sottostante come un "programma di conoscenza non Unicode". Ciò significa che esiste una "tabella di tabella di codici" corrente che si adatta da stringhe PHP a stringhe UTF-16 e viceversa. Da PHP tabella codici corrente può essere recuperato da setlocale() nella forma "language_country.codepage", ad esempio:

setlocale (LC_CTYPE, 0) ==> "english_United States.1252"

dove 1252 è la tabella della tabella codici di Windows attualmente selezionata dal pannello di controllo; i nomi dei file recuperati dal file system sono codificati usando quella tabella codici; i nomi di file generati da PHP devono essere codificati in base a tale tabella codici. Le cose sono anche più complicate dal fatto che i nomi dei file UTF-16 vengono convertiti in stringhe PHP usando la "code page best-fit", ovvero una rappresentazione approssimativa dei caratteri/parole reali, quindi non ci si può fidare dei nomi e dei percorsi dei file recuperati dal file system in quanto potrebbero essere mutilati arbitrariamente.

Riferimenti:

http://en.wikipedia.org/wiki/Windows_code_page Quali "pagine di codice di Windows" sono.

https://bugs.php.net/bug.php?id=47096 Ulteriori dettagli su questo problema.