2009年1月23日金曜日

cgiとutf8とphpとjs

追記)2017/6に,FreeBSD で fine-uploader を使ってみた(その1)というのを書いた。 そこでは fine-uploader という JavaScript のライブラリを使ったファイルのアップローダーについて書いている。 Uber Uploader はすでに古く更新されていないので,fine-uploader など新しいアップロードライブラリを使うことをお薦めする。
追記)2011/8時点での Uber-Uploader の最新版である Uber-Uploader 6.8.2 についてはUber-Uploader 6.8.2 の使い方(その1)で述べているので,参考にしてみて欲しい。

最近、同窓会に出席して同窓会のwebを担当することになった。とりあえず簡単に、と思って作り出したが、これまでいくつか作ってきたwebで培った技術を使いたくなってしまった。とりあえずはcgiを使ってメニューなど並べてみたりした。当初、JISコードで作ってみたが、最近の趨勢としてはUTF-8で作るようになりつつあるみたいなので、途中でページを全てUTF-8にしてみた。FreeBDS上に作っているのだが、最近はnkf -wでUTF-8にしてくれるようになっていた。いつのまに...
 さらに、そこにBBS(掲示板)を載せてみた。一から作るのはめんどくさいので、世の中に落ちてるcgiのソフトを拾ってきて,載せておいた。一発で動くかと思ったが,これが意外と手間取った。トラブった原因としては,一つには文字コードの問題。当初JISコードでwebを作っていたので、JISコードにしてみたら,全角の「:」などが文字化けして実行時にひっかかかる。そこで仕方なくShift_JISにしたらうまくいった。これはUTF-8にするのはかなり手間なのでやめておいた。それと改行の問題。もともとwindows用に書かれているらしく,改行コードがunix用になってなかった。そのままだとこれがうまく働かない。仕方ないのでこれも改行コードを変更してみた。ここでもnkfが活躍した。というか、FreeBSD上で他の方法を思いつかなかっただけなのだが。nkf -dってすると改行コードがLFのみになるみたいやった。あと,cgiが実行可能となっている下に作業用のdirectoryを置いておいたが,そこにある画像ファイルが表示されなかった。どうやらcgi実行可能なdirectoryの下に置いてはいけないみたい。これはcgi実行directoryから出したらうまくいった。でもBBSってみんな使うのかなぁ?

 UTF-8といえば、最近はperlでの日本語の文字コードの変換はjcode.plではなくて、Encode.pmJcode.pmを使うらしい、ということを知った。今回はEncode.pmを使ってみた。使い方は、cgiのトップに
use Encode;
use Encode::Guess qw/ shiftjis euc-jp utf8 7bit-jis /;
と書いておき、
$in_name = encode('utf8', decode('Guess', $in_name));
とすると、もとの文字コードを推定して、utf-8に変換してくれる。元の文字コードがわかっている場合なら、Guessの部分を文字コードのニックネームにしてもよいみたい。(追記)推定させる場合はJcode.pmの方がいいかも。数個後の投稿をみてみて

さらに写真などのファイルをアップロードしてもらおうと思って、アップローダを用意してみた。最初はhttp://www.hidekik.com/cookbook/p2h.cgi?id=upload に書いてあった方法を使ってみた。それは
use File::Copy;
use File::Basename;
を使う方法。これはとっても簡単だった。基本的に
my $fh = $query->upload('UPLOADFILE');
copy ($fh, "$newfile");
close($fh);
chmod(0664,$newfile);
だけで済んでしまう。

 上記の方法の欠点は、大きなファイルだとアップロードに時間かかるのに、進捗状況がわからない。やっぱり進捗状況がわかる方がかっこいい、と思っていろいろ探してみた。ネットでいくつかヒットした。一つには
Catalyst::Plugin::UploadProgress
これを使うにはいっぱいperlのモジュールが必要となる。CPANからダウンロードできるが、依存関係とかを考えると自動でインストールしてもらいたい、と思った。これは最近のFreeBSDなら最初からルーチンがあるので、
perl -MCPAN -e shell
とすれば、いろいろ設定を聞かれたけど、CPANからインストールできるようになった。やり方はCPAN, FreeBSD, 使い方、とかで検索すればいくつかのサイトが参考になった。

で、問題のCatalyst::Plugin::UploadProgressをインストールしてみた。
# cpan -i Catalyst::Plugin::UploadProgress
ってすればいけるのよ。今回はrootになって作業してみた。しばらく時間かかって、UploadProgressがインストールできたっぽい感じのメッセージがでた。途中、FastMmapがないだの、Simple.pmがないだの言われて、いっぱいモジュールを入れてしまった。さぁ、これで使える、と思ったけど、使い方がよくわからない。もともとUploadProgressもネットで検索して、インストール方法を知ったのだが、どうやって使うかという具体的な記述は見当たらなかった。これじゃすぐには使えない。だいたいCatalystの使い方を知らない。困った。

そこでとった作戦が別のモジュールを探す作戦。なんと安易な...。見つけたのは同じperlのApache2::UploadProgressってやつ。Catalystじゃないから、もう少しわかりやつに違いない、と思ってインストールしてみた。ところが、これも使い方がよくわからない。誰か教えてくれ〜〜、と言いたくなった。みんな「これは使えるっ!!!」とかってネット上で書いてるのに、意外と具体的な使い方を書いてくれてない。perl使いの人々は知ってて当たり前、というのが多いのだろうか?

どうしようとあれこれ検索しているうちに、uber_uploader ってのが見つかった。http://gigazine.net/index.php?/news/comments/20060513_ajax_uber_uploader/ に書いてあった。どうやらAjaxとphpとjsで書いてあるらしい。実はAjaxが何の事だかよくわからない。cgiは使った事あるけど、phpはないなぁ。でもとりあえずperlみたいだからなんとかなるだろうと思って、これまたインストール。これは http://sourceforge.net/projects/uber-uploader からダウンロードした。FreeBSDから直接いけばよかったのだが、作業環境上の都合でwindowsでダウンロードして、FreeBSDに送り込んだ。そのせいでまた改行コードと文字コードを変換しないといけなかったが...。
註:ここの記述はUber Uploader ver. 6.5です。バージョンがあがると微妙に構造が変わっているのでご注意を

さぁ、動かそうと思って設定して動かしてみたが、働かない。おや?何が悪いんだろう?cgiみたいには動かなくて、webのソースコードが見えてしまう。うーん、何か根本的なことがおかしい。....よく考えてみると、phpってもしかしてインストールしないといけないのだろうか?locate phpってしてみても出てくるのはportsのファイルのみ。どうやらphpをインストールしないといけないらしい。知らなかった。

これも検索してみると、現状ではphp5が新しいらしい。そこでportsからインストール。http://www.kishiro.com/FreeBSD/php5.html などを参考にしてみた。どうやら
/usr/ports/lang/php5

/usr/ports/lang/php5-extentions
をインストールすべきらしい。そこでそれらをインストールしてみた。ポイントは日本語のために2バイト文字(マルチバイト文字)と、UTF-8のオプションを選ぶことだった。

そんなこんなでやっとuber-uploaderが動いた。最初に動いた時には感動したねぇ。自分で作ってるサイトでいっちょまえにダウンロードの時に進捗状況がバーで増えていくんだもん。でもとりあえず作っているサイトと背景が違うとか、同じロゴをつけたい、とか、アップロードさせる時に名前とかを入力させてログファイルを作りたい、って欲求がでてきてしまった。そのためにはuber-uploaderの構造を知らないといけない。これが結構難しい。メインはubr_file_uplod.phpで書かれているが、初期設定にubr_init.phpやubr_default_config.phpをいじらないといけないし、ubr_file_upload.jsというJavaScriptのファイルを読ませてるし、plで動くubr_upload.plってのもある。うーん、どうなってるの、これ?アップロードが完了したらubr_finished.phpってのにたどり着いてるし。

いろいろ見た結果、どうやら、ubr_file_uplod.phpってのがuploadを受け付けるwebページそのもので、そこでJavaScriptを使って入力されたファイル名などのチェックをして、uploadの受けつけをしてる。ただ、実際のアップロードの作業はubr_upload.plでやらせてるみたい。なので、ログを書かせるのはubr_upload.plをいじらないといけなかった。具体的にはメインルーチンの最後(375行辺り)でログを書かせているが,そこをいじった。あとは、ubr_file_uplod.phpでメインの背景や名前の入力をさせるようにページをいじって、ubr_finished.phpで終了ページをちょっと改良した。それと入力で氏名などを入れさせるようにしたので、そのチェックをubr_file_upload.jsに加えた。雰囲気はこんな感じ
function checkEmailFormat(){
     if(document.uu_upload.elements['EMAIL'].value == ""){
          alert("メールアドレスを入力してください。\n");
          return true;
     }
     return false;
}

そんなこんなでちょいと時間を食ってしまったが、なんとかうまくアップロードできるようになった。うーん、かなり手強かったなぁ、ファイルアップローダー
(追記)(まだ中途半端です)
もうちょっと詳しく書いてみよう。
(1) 設定ファイルはubr_ini.phpubr_default_config.phpの二つである。
ubr_ini.phpはディレクトリの設定やリダイレクトまでの時間の設定などがある。
基本的にいじらなくてもいいが、ディレクトリを一部いじった。いじったところは
$PATH_TO_UPLOAD_SCRIPT       = '../cgi-bin/ubr_upload.pl';   // Path info
$PATH_TO_LINK_SCRIPT         = './ubr_link_upload.php';      // Path info
$PATH_TO_SET_PROGRESS_SCRIPT = './ubr_set_progress.php';     // Path info
$PATH_TO_GET_PROGRESS_SCRIPT = './ubr_get_progress.php';     // Path info
$PATH_TO_JS_SCRIPT           = './ubr_file_upload.js';       // Path info
$PATH_TO_CSS_FILE            = './ubr.css';                  // Path info
$DEFAULT_CONFIG              = './ubr_default_config.php';   // Path info
の最初の行のupload用のperlのスクリプトファイルの指定。これはcgiを動かせるところにしてある。確かcgiを使えるところに置け、とどこかに書いてあった記憶がある。それ以外は基本的にubr_file_upload.phpと同じディレクトリに置いてある。その他のファイルとしては、ubr_default_config.phpがもう一つの設定ファイルであり、細かいパラメータ等の設定はこのファイルに書いてある。また、ubr.cssは書式の設定を行うcssファイルであり、ubr_file_upload.jsubr_file_upload.phpの中で使われるJavaScriptの外部ファイルである。他のは詳しく見てないのでわからない。わからなくても使えたから、いじらないのがいいと思う。
(2) ubr_file_upload.phpがwebページの本体となる。いじった点は、いっぱいある。
・まずはタイトル。これはwebのタイトル行。具体的には
<title>Uber-Uploader - Free File Upload Progress Bar</title>
とあるところ。この<title>と</title>の間を書き換えればよい。ヘッダー部分(</head>まで)は他にはいじらなかったはず。
・body部分
<body class="yellow" onLoad="iniFilePage()">
....
</body>
までがwebの中身になる。
<body class="yellow" onLoad="iniFilePage()">のすぐ下にある<div class="ubrWrapper">の手前はプログレスバーとは直接関係ないので、自由に自分用の設定を書く事ができる。
<!-- Start Progress Bar -->から<!-- End Progress Bar -->までは、プログレスバーを表示する部分なので、いじってはいけないし、その下の部分もいじらない方がいいと思う。
アップロードのページの具体的な内容は<-- Start Upload Form -->から<-- End Upload Form -->の間に書く。特に
<?php
// Include extra values you want passed to the upload script here.
// eg. <input type="text" name="employee_num" value="5">
// Access the value in the CGI with $query->param('employee_num');
// Access the value in the PHP finished page with $_POST_DATA['employee_num'];
// DO NOT USE "upfile_" for any of your values.
?>
の中、あるいはその下に書く。このコメントには、他に入力させたければ、この下に
<input type="text" name="employee_num" value="5">
のように入力スペースを用意して、cgiルーチンで
$query->param('employee_num');
として読ませるか、
$_POST_DATA['employee_num'];
としてfinishページ(ubr_finished.php)で読み取る、と書いてある。
<div id="upload_slots">から対応する</div>までの間はファイル名の入力をさせる場所なので、ここもいじってはいけない。
<input type="button" id="reset_button" name="reset_button" value="Reset" onClick="resetForm();">
はリセットボタンであり、
<input type="button" id="reset_button" name="reset_button" value="入力のリセット" onClick="resetForm();">
と日本語にすると読みやすいでしょう。同様に
<input type="button" id="upload_button" name="upload_button" value="Upload" onClick="linkUpload();">

<input class="blue" type="button" id="upload_button" name="upload_button" value=" アップロードする " onClick="linkUpload();">
と日本語にしておきましょう。

(追記) 現在,Uber_uploaderの最新バージョンは6.8.2となっている。バージョン 6.5から比べると結構見た目が変わっている。しかし,折角作ったサイトをいじるのがめんどくさいので,バージョン 6.5 のままにしている。しかし最近バージョン 6.5 を使う際に2ヶ所ほど問題点が見つかった。それについて述べよう。
(A) 一個目は,Opera (現時点のバージョンは10.60) でアップロードしようとおもうと,うまくログファイルを書いてくれなかった。でも,Internet Explorer や Firefox ならちゃんとログファイルを書いていた。何が違うのかしらばく悩んでしまった。原因は,Uber_uploader 6.5 では,Opera や Safari の場合,iframeタグを用いて対処していたところ。しかし,現在(2010/7)それは必要ないみたい。そこで,ubr_default_config.php の中の $_CONFIG['opera_browser']$_CONFIG['safari_browser'] を,
$_CONFIG['opera_browser'] = 0;
$_CONFIG['safari_browser'] = 0;
としておかないといけない。
(B) コメントを入力してもらうようにしていたのだが,それがトラブルの原因となっていた。理由は改行コード。MacintoshかWindowsかUnixかで,改行コードが違っている。コメントを入力する時のOSjavascript:void(0)によって改行コードが違っている。特にMacintoshの場合がトラブルを起こしやすかった。コメントを入力しているところで,
$in_comment = str_replace("¥r¥n","<br>",$in_comment);
$in_comment = str_replace("¥r",'<br>',$in_comment);
$in_comment = str_replace("¥n","<br>",$in_comment);
(php の場合)などとして,改行コードを変換しておかないといけなかった。
(C) Macintosh の Safari からアップロードしようと思うと,うまくプログレスバーが表示されなかった。理由はいまいちよくわかってない。仕方ないので,バージョンを 6.8.2 に上げてみたが,それでもいまいちうまくいっていない。何故だろう??

ちなみに、Uber-Uploader 6.8.2 についてはUber-Uploader 6.8.2 の使い方(その1)で述べている。

0 件のコメント: