2010-06-01 17 views
14

Birçok ingilizce olmayan adı olan çeşitli dosyaları içeren bir dizinim var. Windows 7'de PHP kullanıyorum.PHP'de İngilizce olmayan dosya adları üzerinde yineleme nasıl yapılır?

Dosya adını ve içeriklerini PHP kullanarak listelemek istiyorum.

Şu anda DirectoryIterator ve file_get_contents kullanıyorum. Bu ingilizce dosya isimleri için çalışır, ancak ingilizce (Çince) dosya adları için değil. Örneğin, "एक और प्रोब्लेम. Eml", "merhaba 鶨 鶖 鵨 鶣 鎹 鎣 .eml" gibi dosya adlarım var.

  1. DirectoryIterator->getFilename()
  2. file_get_contents kullanarak dosya adını almak mümkün değildir, aynı zamanda açmak mümkün olmasa bile ben zor kodun parametresinde dosya adı eğer.

Nasıl yapabilirim? Bu başarıyla dosyayı bulacaksınız

$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"; 

:

+0

Bu soru, yanıtlandığı şekilde etiketlenmeyi hak ediyor. Artefacto doğru bilgi sağlamak için büyük çaba sarf etti. –

+0

Evet. Bu harika bir cevap. – Sabya

cevap

4

. PHP'nin bir kısıtlaması. PHP, Windows API'larının çok baytlı sürümlerini kullanır; Kod sayfanızın gösterebileceği karakterlerle sınırlısınız.

Bkz. this answer.

Dizin içeriği:

 
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 

Testi dosyası içeriği:

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

Testi dosyası sonuçları:

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

Debugger çıkışı:

Çağrı yığını (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 

Gerçekten bir soru işareti mi?

 
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 '?' 

Evet! Bu 63 numaralı karakter.

+0

Sadece isimleri tek bayt olarak okuyamaz ve yazamaz mı? –

+0

@ Álvaro G. Vicario Olabilirdi, ama uygun isimlere sahip olamazdı. NTFS, uygun UCS-2 dosya adlarını destekler, tanımladığınız şey bir saldırıdır. – Artefacto

+0

Açıklamanız daha iyi olamazdı. Bugün çok şey öğrendim :) –

0

Bu senaryoyu sahip dosyaları keşfetmek mı 鶨 鶖 鵨 鶣 鎹 鎣 olsa bir Linux dağıtımı burada denedim ..

için çizgi hattı ile:: kullanmak okumak Bu mümkün değil

$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

Evet, sorun Windows. – Artefacto

3

Kısa Cevap:

Windows altında

, PHP ile rasgele dosya adları erişemez; adı seçili "kod sayfası" ile temsil edilebilen dosya adları ile sınırlıdır (bkz. Bölge ve Dil Seçenekleri "," Biçim "paneli ve" Yönetim "sekmesi paneli" Unicode olmayan programlar için dil ").

Uzun cevap:

, Windows UTF-16 Win2000 beri dosya kodlama için kullanır, ancak PHP bir "Unicode olmayan farkında programı" olarak altta yatan dosya sistemi ile iletişim kurarlar. Bu, PHP dizelerinden UTF-16 dizelerine ve tam tersine çeviren geçerli bir "kod sayfası tablosu" olduğu anlamına gelir. PHP itibaren geçerli kod sayfası örneğin, "language_country.codepage" şeklinde setlocale() tarafından alınabilir:

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

1252 kontrol panelinden şu anda seçili olan Windows kod sayfası tablosu; dosya sisteminden alınan dosya adları bu kod sayfası kullanılarak kodlanır; PHP'den oluşturulan dosya adları bu kod sayfasına göre kodlanmalıdır. UTF-16 dosya adlarının "en uygun kod sayfası" nı kullanarak PHP dizgileri ile kestirilmesi, yani gerçek karakterlerin/sözcüklerin bir onaylanmış temsili olması, bu nedenle dosya adlarına ve yollarına güvenemeyeceğiniz şeyler daha da karmaşıktır. Dosya sisteminden rasgele karıştırılmış olabileceği için alındı.

Referanslar:

http://en.wikipedia.org/wiki/Windows_code_page

"Windows kod sayfaları" nelerdir.

https://bugs.php.net/bug.php?id=47096 Bu sorun hakkında daha fazla bilgi.

İlgili konular