windows上のfuelphpでのFileクラス

あまりWindowsではphpのシステムを構築することは少ないのだが、しかもWindowsのファイルを見てごちゃこちゃやらないといけないプロジェクトでのこと。

エンドユーザーがファイルを置くため一応の前提としては日本語を使わないでくださいってことにはしているのだが…

日本語が紛れ込んでいる場合にエラー発生。でも原因がよくわからなかったので深く追及することに。

あるファイルをコピーするため、事前にファイルの存在チェックをかけている

$srcPath_sjis = mb_convert_encoding($srcPath, 'sjis-win', 'UTF-8');
if( false === File::exists($srcPath_sjis) ){// sjisでチェックする
    Log::debug("file nothing ".$srcPath);
    throw new Exception();
}

存在するのになぜかtrueにはならない。SJISの問題としては5cの問題がまず浮かぶだろうが使っている文字列にはそういうのは含まれていない。 しかしis_file()やfile_exists()だとOKだけどFile::copyでも例外が発生

Cannot copy file: given path: “ほげほげ” is not a file.

とかいわれた。ここでもファイルがないという認識だ。ファイル名の一部が削れちゃっている

FIle::existsのコードを見てみると

$path = rtrim(static::instance($area)->get_path($path), '\\/');

// resolve symlinks
while ($path and is_link($path))
{
	$path = readlink($path);
}

return is_file($path);

単にis_file()との違いはFileareaのget_path()を呼んでいるぐらい

FIle::copyのコードを見てみると

$path      = static::instance($source_area)->get_path($path);
$new_path  = static::instance($target_area ?: $source_area)->get_path($new_path);

if ( ! is_file($path))
{
	throw new \InvalidPathException('Cannot copy file: given path: "'.$path.'" is not a file.');
}
elseif (file_exists($new_path))
{
	throw new \FileAccessException('Cannot copy file: new path: "'.$new_path.'" already exists.');
}
return copy($path, $new_path);

こちらも同じようなもの

ということはget_path()がほぼ原因と分かったわけだけど

fuelphpのバグかと思いきや

get_path()にも不審な点がないので

よく見るとpathinfoを使っている

$pathinfo = is_dir($path) ? array('dirname' => $path, 'extension' => null, 'basename' => '') : pathinfo($path);

pathinfoでとったもののbasenameをデバッグしてみるとビンゴ。ここが原因

pathinfo()の注意にこんなことが

pathinfo()

注意:

pathinfo() はロケールを考慮して処理を行います。 マルチバイト文字を含むパスを正しく処理するには、正しいロケールを setlocale() 関数で設定しておかなければなりません。

fuelphpのconfig.phpのlocale設定はたいていnullにしているのだがwindowsでは

locale = ‘Japanese_Japan.932′

にするか

bootstrap.phpなどで

setlocale(LC_ALL, ”)

setlocale()

をしなければならない

カテゴリー: php タグ: , ,

関連してるかも記事

この記事へのコメント

※コメントはスパム対策の為、承認制となっています。あらかじめご了承ください。

トラックバックURL