Calender
Sun Mon Tue Wed Thu Fri Sat
   1234
567891011
12131415161718
19202122232425
262728293031 
<< March 2017 >>
広告
SEARCH

SELECTED ENTRIES
RECENT COMMENTS
RECENT TRACKBACK
CATEGORIES
ARCHIVES
LINKS
PROFILE
OTHERS
SKYPE
PC: skype.jojo.jp
chat
iPad: iphone.jojo.jp
chat call
THANKS



本日:
昨日:
多言語
広告
 ▼▲ 作業日報 ▼△
    What's under the hood?
<< バルーン風になびき過ぎ、 | main | OfficeVista(Excel2007) ビットマップボタンで強制終了_動画 >>
【PHP】pathinfo、basename関数の日本語ファイル名取得問題
更新日:09/05/20
Version 5.2.6-1+lenny3のLinux版ではNGでした。フォルダ区切りが"¥"だと良いようで、Win版のみ問題が出なくなっています
更新日:07/12/13
Version 5.2.2ではこの問題は修正されています

PHP 5.1.4 Windows2k
 ファイル名からファイル情報を取得する pathinfobasetype で"ファイル名"を取得すしたい場合、ファイル名の最初の文字がマルチバイト文字を利用していると(Win環境)ファイル名は取得できないことがありました。

(/usr/local/aaa/ccc.txt)....dirname=/usr/local/aaa basename=ccc.txt

(/usr/local/a.a.a/ccc.ddd.txt)....dirname=/usr/local/a.a.a basename=ccc.ddd.txt

(/usr/local/aaa/新しい.txt)....dirname=/usr/local/aaa basename=.txt

(/usr/local/aaa/a新しい.txt)....dirname=/usr/local/aaa basename=a新しい.txt

(/usr/local/aaa/新しい.かも.txt)....dirname=/usr/local/aaa basename=.かも.txt

(/usr/l o c a l/新しいフォルダ/a新しい.txt)...dirname=/usr/l o c a l/新しいフォルダ
   basename=a新しい.txt

(c:¥usr¥local¥新しいフォルダ¥新しい.txt)....dirname=c:¥usr¥local¥新しいフォルダ
   basename=.txt

(c:¥usr¥local¥新しいフォルダ¥新しい.txt)....dirname=c:¥usr¥local¥新しいフォルダ
   basename=.txt

Array
(
    [dirname] => c:¥usr¥local¥新しいフォルダ
    [basename] => .txt
    [extension] => txt
)

ソースコード:
$fname = '/usr/local/aaa/ccc.txt';
echo "($fname)..... dirname=".dirname( $fname ).' basename='.basename( $fname )."¥n¥n";

//ファイル・フォルダ名中のドット文字はOK
$fname = '/usr/local/a.a.a/ccc.ddd.txt';
echo "($fname)..... dirname=".dirname( $fname ).' basename='.basename( $fname )."¥n¥n";

//ファイル名第一文字がマルチバイトはNG
$fname = '/usr/local/aaa/新しい.txt';
echo "($fname)..... dirname=".dirname( $fname ).' basename='.basename( $fname )."¥n¥n";

//OK
 $fname = '/usr/local/aaa/a新しい.txt';
echo "($fname)..... dirname=".dirname( $fname ).' basename='.basename( $fname )."¥n¥n";

//どうも最初のMB文字が抜け落ちるようです
$fname = '/usr/local/aaa/新しい.かも.txt';
echo "($fname)..... dirname=".dirname( $fname ).' basename='.basename( $fname )."¥n¥n";

//フォルダ名のMB文字、空白はOK
$fname = '/usr/l o c a l/新しいフォルダ/a新しい.txt';
echo "($fname)..... dirname=".dirname( $fname ).' basename='.basename( $fname )."¥n¥n";

//フォルダ区切りを¥(円マーク)でも同じ
$fname = 'c:¥usr¥local¥新しいフォルダ¥新しい.txt';
echo "($fname)..... dirname=".dirname( $fname ).' basename='.basename( $fname )."¥n¥n";

//エスケープしても同じ
$fname = 'c:¥¥usr¥¥local¥¥新しいフォルダ¥¥新しい.txt';
echo "($fname)..... dirname=".dirname( $fname ).' basename='.basename( $fname )."¥n¥n";

//pathinfoも同じ現象
print_r( pathinfo($fname) );
echo "¥n¥n";
 Windowsでのテストなので、ファイル文字セットはSJIS(ソースコードはSJIS)です。
最初、エンコードの具合かと思いEUCに変換してやってみましたが同じでした。

ファイル名取得は下のようにしました。
$fname = 'c:/aaa/bbb/usr/あああ/aaa/新しい.かも.txt';

$arrfname0 = explode('/',$fname);
$arrfname1 = explode('/',dirname( $fname ));
$diff = array_diff( $arrfname0 ,$arrfname1);
//ファイル名の摘出
echo implode($diff);

可読性を気にしないなら
$fname = 'c:/aaa/bbb/usr/あああ/aaa/新しい.かも.txt';

//ファイル名の摘出
echo implode(array_diff( explode('/',$fname) ,explode('/',dirname( $fname ))));
追記:09/05/20 若しくは
echo strrchr("/$fname",'/');      .......該当文字から右側を取る関数
echo substr(strrchr("/$fname",'/'),1);  ..... basename()代替

/新しい.かも.txt
新しい.かも.txt

でも「ファイル名取得」って基本なので他でもやってたはずなんだけど、、問題なかったのかな、、ファイル名がEUCだと問題ないとか、、ひょっとしたら別のところに問題があるのかもしれません
後日みていたらこれはPHP5のバグらしいです、
Ver5では対応の予定はないとのこと、6に実装しますということだそうです、、↓
PHP Bugs: #37738: basename does not work with Japanese
PHP 5.1.4 Windows2k
追記:12/11/26
・この問題はそう簡単ではなさそうです。bugs.php.netのコメントにありますが、設定にファイル名のエンコーディングに関する設定もなく、非ASCII系のファイル名を自動的に解析するのは難しいようです(ECUとUTF,SJIS等の混在もあり得る)
 この辺りは設計側でファイル名のエンコードに合わせ、仕様化することで逃げる必要があるかと思います。
| 開発関連 | 15:05 | comments(0) | trackbacks(0) |









http://blog.jojo.jp/trackback/632412