記事一覧はこちら

windows+PHPで日本語ファイルを扱うrealpath_ja

windows環境でphpを使っている時に日本語のファイル&フォルダ名を扱う事が出来ます。 windows7 64bit + NTFS + PHP 5.4.1 で動作確認。

対応している関数は file_put_contents file_get_contents filetype lstat file fopen unlink rename copy です。

ダメ文字の処理がポイントで、そのままだと

C:ソフトソースコード.php
というファイルはエラーが出てしまいます。 そこでフォルダの区切り文字をから/にします。windowsがも/も認識してくれて助かった。
C:/ソフト/ソースコード.php
そしてダメ文字の後ろにエスケープ文字を付ける
C:/ソフト/ソースコード.php
そしてこれをsjis-winに文字コード変換。 もちろん事前に相対パスの解決を行なってから。

これで、phpファイルのフルパスに日本語が入っていても自由に日本語のファイル&ディレクトリを作る事が出来ます。fopenも出来るし。

mkdir(realpath_ja('./../../../日本語ディレクトリ とソフト'));
file_put_contents(realpath_ja('./../../../日本語ディレクトリ とソフト/日本語ファイル名.txt'),"ok");

ファイルの存在判定は

@filetype();
で・・・力技ですが。

function realpath_ja($path,$current=null,$escape=true){
    $pathChange=function($str){return preg_replace('{\\|/}','/',$str);};
    if($current===null){$current=mb_convert_encoding(getcwd(),"utf-8","sjis-win");}
    $path=$pathChange($path);
    $current=$pathChange($current);
//  printf("%10s → %10sn",$current,$path);
    $current=preg_replace('{/$}','',$current);
    $splitPath=explode("/",$path);
    $splitCurrent=explode("/",$current);
//  echo "--pathn",print_r($splitPath),"--current",$a=print_r($splitCurrent),"n";
    foreach($splitPath as $one){
        if(preg_match('{[a-zA-Z]:}',$one)){
            $splitCurrent=[$one];
        }else if($one=="."){
        }else if($one==".."){
            if(count($splitCurrent)!=1){
                array_pop($splitCurrent);
            }
        }else{
            $splitCurrent[]=$one;
        }
    }
    $path=implode('\',$splitCurrent);
    //相対パス絶対パスになった
    if($escape===true){
        $sjis="―ソЫⅨ噂浬欺圭構蚕十申曾箪貼能表暴予禄兔喀媾彌拿杤歃濬畚秉綵臀藹觸軆鐔饅鷭偆砡纊犾";
        $path=str_replace("\","/",$path);
        for($i=0;$i<mb_strlen($sjis,"utf8");$i++){
            $path=str_replace(mb_substr($sjis,$i,1),mb_substr($sjis,$i,1)."\",$path);
        }
    }
    $path=mb_convert_encoding($path,'sjis-win');
    if(strstr($path,"?")!==false){
        trigger_error("wrong path "?"",E_USER_WARNING );
        $path=str_replace("?","",$path);
    }
    return $path;
}