15

いくつかのファイルを含むディレクトリがあり、その多くは英語以外の名前です。Windows 7 で PHP を使用しています。

PHP を使用して、ファイル名とその内容を一覧表示したいと考えています。

現在、私は と を使用DirectoryIteratorしてfile_get_contentsいます。これは、英語のファイル名には機能しますが、英語以外 (中国語) のファイル名には機能しません。

たとえば、"एक और प्रोब्लेम.eml"、"hello 鶨鶖鵨鶣鎹鎣.eml" のようなファイル名があります。

  1. DirectoryIteratorを使用してファイル名を取得できません->getFilename()
  2. file_get_contentsパラメータにファイル名をハードコーディングしても開くことができません。

どうすればいいですか?

4

3 に答える 3

4

これは不可能です。これはPHPの制限です。PHPはマルチバイトバージョンのWindowsAPIを使用します。コードページで表現できる文字に制限されています。

この回答を参照してください。

ディレクトリの内容:

D:\ Users \ Cataphract \ Desktop \ teste2> dir
 ドライブDのボリュームはGRANDEDISCOです
 ボリュームシリアル番号は945F-DB89です

 D:\ Users \ Cataphract \ Desktop\teste2のディレクトリ

2010年1月6日17:16。
2010年1月6日17:16..
2010年1月6日17:150コプト文字のシマがϭ.txtをフォロー
2010年1月6日17:1886teste.php
               2ファイル86バイト
               2ディレクトリ12.178.505.728バイト空き

テストファイルの内容:

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

テストファイルの結果:

。
..
コプトの小さな文字島が続く?.txt
teste.php

デバッガーの出力:

コールスタック(PHP 5.3.0):

> php5ts_debug.dll!readdir_r(DIR * dp = 0x02f94068、dirent * entry = 0x00a7e7cc、dirent * * result = 0x00a7e7c0)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)820行目+0x17バイトC
    php5ts_debug.dll!_php_stream_read(_php_stream * stream = 0x02b94280、char * buf = 0x02b9437c、unsigned int size = 260、void * * * tsrm_ls = 0x028a15c0)603行目+0x1cバイトC
    php5ts_debug.dll!_php_stream_readdir(_php_stream * dirstream = 0x02b94280、_php_stream_dirent * ent = 0x02b9437c、void * * * tsrm_ls = 0x028a15c0)1806行目+0x16バイトC
    php5ts_debug.dll!spl_filesystem_dir_read(_spl_filesystem_object * intern = 0x02b94340、void * * * tsrm_ls = 0x028a15c0)199行目+0x20バイトC
    php5ts_debug.dll!spl_filesystem_dir_open(_spl_filesystem_object * intern = 0x02b94340、char * path = 0x02b957f0、void * * * tsrm_ls = 0x028a15c0)238行目+0xdバイト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 +0x11バイト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 * *
    php5ts_debug.dll!zend_do_fcall_common_helper_SPEC(_zend_execute_data * execute_data = 0x02bc0098、void * * * tsrm_ls = 0x028a15c0)行313+0x78バイトC
    php5ts_debug.dll!ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER(_zend_execute_data * execute_data = 0x02bc0098、void * * * tsrm_ls = 0x028a15c0)423行目C
    php5ts_debug.dll!execute(_zend_op_array * op_array = 0x02b93888、void * * * tsrm_ls = 0x028a15c0)行104+0x11バイトC
    php5ts_debug.dll!zend_execute_scripts(int type = 8、void * * * tsrm_ls = 0x028a15c0、_zval_struct * * retval = 0x00000000、int file_count = 3、...)1188行目+0x21バイトC
    php5ts_debug.dll!php_execute_script(_zend_file_handle * primary_file = 0x00a7fad4、void * * * tsrm_ls = 0x028a15c0)2196行目+0x1bバイトC
    php.exe!main(int argc = 2、char * * argv = 0x028a14c0)1188行目+0x13バイトC
    php.exe!__ tmainCRTStartup()行555+0x19バイトC
    php.exe!mainCRTStartup()行371 C

本当に疑問符ですか?

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「コプト文字のシマが続く?.txt」
    cAlternateFileName:0x02f941a0 "COPTIC〜1.TXT"
dp-> fileinfo.cFileName [34]
63'?'

はい!キャラクター#63です。

于 2010-06-01T13:18:20.810 に答える
4

簡単な返信:

Windows では、PHP で任意のファイル名にアクセスすることはできません。現在選択されている「コード ページ」で名前を表すことができるファイル名に限定されます (「地域と言語のオプション」、「形式」パネル、および「管理」タブ パネルの「非 Unicode プログラムの言語」を参照してください)。

より長い返信:

Windows は Win2000 以降、ファイル エンコーディングに UTF-16 を使用していますが、PHP は「非 Unicode 対応プログラム」として基盤となるファイル システムと通信します。これは、PHP 文字列から UTF-16 文字列に、またはその逆に変換する現在の「コード ページ テーブル」があることを意味します。PHP から、現在のコード ページは setlocale() によって "language_country.codepage" の形式で取得できます。次に例を示します。

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

1252 は、コントロール パネルから現在選択されている Windows コード ページ テーブルです。ファイル システムから取得したファイル名は、そのコード ページを使用してエンコードされます。PHP から生成されたファイル名は、そのコード ページに従ってエンコードする必要があります。UTF-16 ファイル名は、実際の文字/単語のおおよその表現である「最適なコード ページ」を使用して PHP 文字列に変換されるため、事態はさらに複雑になります。そのため、ファイル名とパスを信頼することはできません。それらは恣意的に破壊される可能性があるため、ファイル システムから取得されます。

参考文献:

http://en.wikipedia.org/wiki/Windows_code_page 「Windows コード ページ」とは。

https://bugs.php.net/bug.php?id=47096 この問題の詳細。

于 2012-04-13T09:10:55.700 に答える
0

私がこのスクリプトを持っているファイルを見つけてください:

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

これにより、ファイルが正常に検出されます。

それを読むには、次を使用します: 行ごと:

$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
}
于 2010-06-01T07:54:46.357 に答える