zipファイルに,ファイル名が日本語のファイルを2つ圧縮格納して,コースにファイルをアップロードして「展開」すると,ファイル名が文字化けしてしまいます。どなたか対策をご存知でしたらお教えください。
環境:Moodle 1.9.17+, CentOS5, config.phpに以下の2行は追加してあります。
$CFG->unicodedb = true;
$CFG->unicodecleanfilename = true;
よろしくお願いします。
よろしければ、下記プログラム修正をお試しください。
修正対象プログラム: lib/moodlelib.php
修正箇所: 7790行目
[ 修正前 ]
function unzip_cleanfilename ($p_event, &$p_header) {
//This function is used as callback in unzip_file() function
//to clean illegal characters for given platform and to prevent directory traversal.
//Produces the same result as info-zip unzip.
$p_header['filename'] = ereg_replace(':cntrl:', '', $p_header['filename']); //strip control chars first!
$p_header['filename'] = ereg_replace('\.\.+', '', $p_header['filename']); //directory traversal protection
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
[ 修正後 ]
function unzip_cleanfilename ($p_event, &$p_header) {
//This function is used as callback in unzip_file() function
//to clean illegal characters for given platform and to prevent directory traversal.
//Produces the same result as info-zip unzip.
$p_header['filename'] = mb_convert_encoding($p_header['filename'], 'UTF-8', 'SJIS');
$p_header['filename'] = ereg_replace(':cntrl:', '', $p_header['filename']); //strip control chars first!
$p_header['filename'] = ereg_replace('\.\.+', '', $p_header['filename']); //directory traversal protection
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
参考資料:
[Re: ファイルのアップロード、ダウンロード時に文字化けします by Tatsuya Shirai - Saturday, 19 January 2008, 12:35 PM]
https://moodle.org/mod/forum/discuss.php?d=86504&parent=390779
やはり unzipfileserror とてで展開できません。zipファイル名が半角英数ならうまくいくのですが。
ご確認ありがとうございます。
Moodleからは離れますが、下記ページが今回の問題解決のヒントになるかと思います。
[Shift_JIS なファイル名を含む Zip ファイルを解凍する unzip パッケージの作り方 - forest book]
http://d.hatena.ne.jp/t2y-1979/20090628/1246157403
情報ありがとうございます。ご紹介いただいたページを見てみました。rpmはインストールしていませんが,Shift_JISなファイル名を含むZIPファイルを解凍するunzipパッケージを使っても問題は解決しないと予想しました。理由はMoodle内蔵のunzipがsift_jis対応しているようだからです。
以下,「test.zip」と「テスト.zip」は日本語ファイル名のファイルを2つ含む同じzipファイルとします。まず「サイト管理 > サーバ > システムパス」内の「 unzipのパス」を空欄にします。するとMoodleはMoodle内蔵のunzipを使います。この場合,test.zipは正しく展開され,テスト.zipは展開されません。
次に「サイト管理 > サーバ > システムパス」内の「 unzipのパス」を/usr/bin/unzipとします。するとMoodleは/usr/bin/unzipのunzipを使います。この場合,test.zipは文字化けして展開され,テスト.zipは展開されません。
したがって,Moodleが内蔵のunzipにファイル名が日本語のzipファイルを正しく渡せるようにすれば問題が解決しそうに思います。
ありがとうございます。やはりうまくいきません。当方環境は
Moodle 1.9.17+ (Build: 20120315)
CentOS 5.9
Apache/2.2.3
PHP Version 5.1.6
です。ひとつ気付いたのは,lib/moodlelib.phpが吉田さんのリストと若干違うことです。当方のリストでは1行追加する行の:cntrl:が[[]]で囲まれていました。[[]]を削除してやってみましたが結果は同じでした。
$p_header['filename'] = mb_convert_encoding($p_header['filename'], 'UTF-8', 'SJIS');
$p_header['filename'] = ereg_replace(':cntrl:', '', $p_header['filename']); //strip control chars first!
もしかしたら、PHP関数の basename() が影響しているかもしれませんので、下記修正をお試し頂けませんでしょうか。
修正対象プログラム: files/index.php
修正箇所: 539行目
[ 修正前 ]
case "unzip":
html_header($course, $wdir);
if (($file != '') and confirm_sesskey()) {
$strok = get_string("ok");
$strunpacking = get_string("unpacking", "", $file);
echo "<p align=\"center\">$strunpacking:</p>";
$file = basename($file);
if (!unzip_file("$basedir$wdir/$file")) {
print_error("cannotunzipfile", "error");
}
[ 修正後 ]
case "unzip":
html_header($course, $wdir);
if (($file != '') and confirm_sesskey()) {
$strok = get_string("ok");
$strunpacking = get_string("unpacking", "", $file);
echo "<p align=\"center\">$strunpacking:</p>";
$file = end(split('/', $file));
if (!unzip_file("$basedir$wdir/$file")) {
print_error("cannotunzipfile", "error");
}
phpを5.3にバージョンアップしたところ,文字化け問題は解決しました。何度もアドバイスありがとうございました。なお,files/index.phpのbasenameの修正は行わずに,元に戻しました。
今回の修正,私のメモ
http://kilin.clas.kitasato-u.ac.jp/howto/moodle.html
にも追加させて頂きました。