システム奮闘記:その66
Webファイルマネージャー axlope導入
(2008年3月9日に掲載)
文書や画像を管理するファイルマネージャー。
Web上でファイルマネージャーができれば、どの端末からでも
ファイルをアップロードして保管したり、必要に応じて
ダウンロードできるから便利だ。
それらしき物は以前、PHPを使ってプログラムを作った事がある。
だが、日本語のファイル名が使えない問題があったり、
日本語のファイル名をアップロードできても、ダウンロードの際
文字化けするなどの問題があり、利用者にとって不便だった。
その上、PostgreSQLの中にファイルを格納する事から、ラージオブジェクトの
バックアップなどに難があったため、管理する側の手間もあった。
そのため、ほとんど活用される事なく、見事に消え去ったのだ。
詳しくは「システム奮闘記:その13」をご覧ください。
ファイルマネージャーではないが、ファイル共有という事で、
Sambaを使っている。
Sambaの話は「システム奮闘記:その34」をご覧ください。
だが、各人のデータの保管庫になってしまっているので、
ファイルの雛型や、書類などの掲載には向いていなかった。
そのため、Webに掲載する状態だった。
Webにファイルを載せる依頼があると、私がftpを使ったりして
アップロードする手間がかかったりした。
社内向けのホームページを、Pukiwikiにしてからも、
私が行うため、手間がかかる。
そこで、誰でも簡単にWeb上にアップロードできるようにしたい。
だが、ファイルマネージャーを探すが、海外版ばかりで
日本語対応がされていない物ばかりだ。
英語が読める人ばかりだと問題ないが、そうではないため、
日本語が使えるソフトでないと導入しても、意味がない。
そんな中、日本語のファイル名でも使えるという
日本発のオープンソース axlopeを見つける。
axlopeのサイト。
http://axlope.sourceforge.jp/
axlopeのダウンロードサイト。
http://sourceforge.jp/projects/axlope
そこで今回は日本発のオープンソースのWebファイルマネージャーの
axlopeを取り上げてみる事にしました。
早速、axlopeをダウンロードして使ってみる事にした。
最初は、RedHat9.0で使ってみる事にした。
ちなみに、PHPは5.2.5を使っています。
設定を行う。簡単にできる。
まずは、axlopeはWebを使ったファイルマネージャーなので、
Webコンテンツを置いているディレクトリー上に設置する。
そして、アップロードしたファイルの保管場所を設定する必要がある。
そこでアップロードしたファイルを格納するディレクトリーを
作成する必要がある。
axlopeのディレクトリー構造 |
|
ライブラリを格納する「lib」ディレクトリーについては後述しています。
今回は、アップロードしたファイルを格納するディレクトリーとして
「data」という名前のディレクトリーを作成した。
|
「data」というディレクトリーを設けた後、設定ファイルに記述する。
lib/conf/conf.inc の中身 |
<?php
//---------------------------------------------------------------------------
//Charactor set is UTF-8
//漢字コードはUTF−8
//---------------------------------------------------------------------------
$gLang = 'ja'; //メッセージファイル指定 ja , en
//$gRootDir = '/xampp/test'; //ファイルマネージャーのルートディレクトリ
$gRootDir = '/usr/local/apache/web/axlope/data'; //絶対パス、最後に / を付けてはいけない
//$gRootDir = '/home/user/files';
//---------------------------------------------------------------------------
?>
|
ピンクの部分がアップロードしたファイルを格納するディレクトリーの指定だ。
絶対パスで設定する必要がある。
|
早速、動かしてみるのだが・・・
文字化けしてるやん (--;;
文字化けの様子 |
|
PHPの内部処理の文字コードの設定等に問題があるのではないか。
そこで、PHPの設定ファイルの文字コードの設定に左右されないように、
ソースの中で文字コードの設定を行う必要がある。
axlopeでは、UTF-8を使っているので、以下の部分をindex.phpに埋め込む。
index.php のプログラムの先頭に
文字コードの処理を追加する |
追加前 |
<?php
//---------------------------------------------------------------------------
//Charactor set is UTF-8
//漢字コードはUTF−8
//---------------------------------------------------------------------------
|
追加後 |
<?php
mb_language('Japanese');
mb_internal_encoding('UTF-8');
ini_set('mbstring.http_input', 'auto');
mb_http_output('UTF-8');
mb_detect_order('auto');
//---------------------------------------------------------------------------
//Charactor set is UTF-8
//漢字コードはUTF−8
//---------------------------------------------------------------------------
|
内部処理、出力の文字コードをUTF-8に指定しておく。
これによって、PHP側の設定ファイルの「php.ini」の
文字コードの設定が変更した場合でも影響を受けなくなる。
|
そして動かしてみる。すると
文字化けが解消 |
|
これで安心だと思った。
さて、早速、ファイルをアップロードしてみる。
「アップロード」を選んでみると次の画面が出てきた。
アップロードの画面 |
|
Javascriptを使っているため、こんな画面になるのだが、
私はJavascriptが全く読めない・・・ (^^;;
|
早速、ファイルのアップロードを行ってみる。
ファイルのアップロード |
|
画面を拡大してみる |
|
まずは、アルファベッドのファイル名から
アップロードの実験を行ってみた。
|
「決定」のボタンを押した。
するとアップロードの成功を知らせる画面が出てきた。
ファイルのアップロードの成功の画面 |
|
本当にアップロードが成功しているのか。
実際に見てみた。
ファイルのアップロードの成功の画面 |
|
だが、画面表示だけであって、実際にファイルのアップロードが
成功しているかどうかを検証するため、アップロードしたファイルを
ダウンロードしてみる事にした。すると
見事、成功! (^^)
問題なくアルファベッドのファイル名のファイルをアップロードする事が
出来る事が確認できた。
さて、お次ぎは日本語のファイル名のアップロードを行ってみる。
日本語のファイル名のファイルのアップロード |
|
するとアップロード成功の画面が出てきた。
日本語のファイル名のアップロードの成功の画面 |
|
画面を拡大してみる |
|
一応、アップロード成功の画面が出てきた。
でも、確かめる必要がある。
さて、ファイルのリストを見てみる。
日本語のファイル名が載っていた |
|
これを見る限り、問題なく日本語のファイル名でも
アップロードが出来ている感じがする。
|
上の図を拡大してみると以下のようになる。
日本語のファイル名が問題なく載っている様子 |
|
さて、実際に、アップロードが出来ているかどうかを確認するため、
「ゆきだるま.gif」をダウンロードしてみる事にした。
すると・・・
文字化けが発生したのらー!!
日本語のファイル名のアップロードの成功の画面(拡大) |
|
「雪だるま.gif」のファイル名が文字化けしている様子。
どうやら、おかしな事が起こっているようだ。
|
実際に、ダウンロードした後、ダウンロード先のパソコンにある
ファイル名を見てみる。
すると・・・
ファイル名が文字化けしてるやん!
日本語のファイル名のアップロードの成功の画面(拡大) |
|
どうやら日本語の処理に問題がありそうだ。
|
日本語の処理に問題がありそうな気がした。
このaxlopeは、ファイルを分類するためのディレクトリーも
設ける事ができるので、日本語のディレクトリー名を設ける事にした。
ディレクトリー作成の画面 |
|
日本語のディレクトリー名を入れてみる。
日本語のディレクトリー名を入れてみる |
|
画面を拡大してみる |
|
「テスト」という名前のディレクトリー名を作成してみた。
すると・・・
やっぱり文字化けしてるやん!
ディレクトリー名が文字化けしている様子 |
|
「テスト」を入力したのに、変な文字になっている。
キリル文字かギリシャ文字のような感じだが、調べてみたが
どちらにも該当していないようだ。
|
さて、「テスト」が「P」に似た文字になった。
その「P」に似た文字を選んでみる。すると・・・
エラーが出た!
エラーの内容 |
|
画面を拡大してみる |
|
どうやら「P」に似た文字を正しくディレクトリーと
認識していないようだ。
|
うーん、日本語の扱いに難がありそうだ。
さて、文字化けや日本語処理の問題を見るためにアップロードした
日本語ファイルの削除を行ってみる事にした。
まずはアルファバッドのファイル名「map.gif」を削除してみる。
ファイルやディレクトリーの一覧(拡大) |
|
削除を選ぶと以下の画面が出てくる。
「削除」を行って良いのかの画面 |
|
これがあれば、誤って消去してしまう事も減るだろう。
なかなか良い。
|
もちろん「OK」を選ぶ。
アルファベッドのファイル名は問題なく削除できた。
アルファベッドのファイル名は問題なく削除できた |
|
次に、日本語のファイル名の「雪だるま.gif」の削除を行ってみる。
ファイルやディレクトリーの一覧(拡大) |
|
赤く囲んだ部分の「雪だるま.gif」が問題なく
削除できるかどうかを確かめてみる。
|
結果は・・・
エラーが出るやん!
エラーの内容 |
|
画面を拡大してみると
エラーの画面(拡大) |
|
「そんなファイルやディレクトリーはないぞ」とエラーが出ている。
どうやら日本語処理の部分に問題がありそうだ。
|
うーん、日本語が絡むと問題が発生している。
だが、2バイト文字の処理の話や、日本語文字コードに関する知識は
ほとんどないため、この時点で断念してしまう事になった。
どうもうまく動かない。
なので、この時点では「使えないソフトだ」と思った。
だが、数日後、何気なくCentOS4.4で動かしてみた。
ちなみに、PHPは5.2.5です。すると・・・
問題なく作動した!
だった。
ちなみに、OpenSUSE10.2でも動かしてみたら、問題なく作動した。
axlopeとディストリビューションの組合せ |
ディストリビューション |
動作の有無 |
RedHat9.0 | × |
CentOS4.4 | ○ |
OpenSUSE10.2 | ○ |
推測の域を超えないが、Sambaと同じ現象が起こっていると思う。
Samba-3.0系では、日本語ファイルの変換にiconv()関数を使っている。
これは、libiconvライブラリを使っている。
だが、glibcにも大きく影響されている。
正しく日本語の文字コード変換を行うには、glibc-2.3.3以降が必要で
glibc-2.3.2以下のバージョンではパッチを当てる必要がある。
Sambaの、たかはしものとぶさんの「Samba 3.0 での日本語」
http://www.monyo.com/technical/samba/docs/Japanese-HOWTO-3.0.ja.txt
ところで、PHPの場合、ソースコードを眺めた感じでは、
iconv関数を使っている様子はなかった。
だが、RedHat9.0は初期状態ではglibc-2.3.2が入っている。
正しく日本語変換ができるのは、glibc-2.3.3以降なので、
glibc-2.3.2の場合はパッチを当てる必要がある。
なので、PHPは国際化され他言語対応なのだが、コンパイルの際に、
日本語の文字コード変換の部分で支障が出ている可能性は捨てきれない。
だが、そこまで調査するだけの知識や技術力は、私には持っていない。
だって事務員だもーん (^^)V
困った時に使える、説得力のある言い訳なのだ (^^)
なので、RedHat9.0ではaxlopeは使えない事だけを報告します。
■■■ CentOS4.4で問題なく稼働している様子 ■■■
さて、CentOS4.4、OpenSuSE10.2では問題なく稼働した。
要するに、最近のディストリビューションなら問題なく稼働するようだ。
ただ、プログラムの最初の部分だけ、php.iniに左右されないように
以下のソースを追加しておくのが無難。
index.php のプログラムの先頭に
文字コードの処理を追加する |
追加前 |
<?php
//---------------------------------------------------------------------------
//Charactor set is UTF-8
//漢字コードはUTF−8
//---------------------------------------------------------------------------
|
追加後 |
<?php
mb_language('Japanese');
mb_internal_encoding('UTF-8');
ini_set('mbstring.http_input', 'auto');
mb_http_output('UTF-8');
mb_detect_order('auto');
//---------------------------------------------------------------------------
//Charactor set is UTF-8
//漢字コードはUTF−8
//---------------------------------------------------------------------------
|
内部処理、出力の文字コードをUTF-8に指定しておく。
これによって、PHP側の設定ファイルの「php.ini」の
文字コードの設定が変更した場合でも影響を受けなくなる。
|
そして、axlopeの画面を開いてみる。
axlopeの画面 |
|
拡大画面 |
|
ここからファイルの操作を行う。
Web上なので、複数人が使えるようになっている。
|
まずはファイルのアップロードをしてみる。
もちろん、日本語のファイル名を試してみる。
日本語のファイル名のファイルアップロード |
|
するとアップロード成功の画面が出てくる。
アップロード成功の表示 |
|
ファイルの表示画面に戻ってみる。
ファイル表示の画面 |
|
拡大画面 |
|
問題なく日本語のファイル名が載っている。
では、掲載したファイルのダウンロードを行ってみる。
RedHat9の時は、ダウンロードした際、ファイル名が文字化けした。
早速「雪だるま.gif」のファイルをダウンロードしてみる。
「雪だるま.gif」のファイルをダウンロード |
|
ファイル名が文字化けはしていないようだ
|
さて、ダウンロードしてフォルダーに保管された状態を見てみる。
ダウンロードした結果 |
|
ファイル名が文字化けはしていないようだ
|
日本語のファイル名でも、問題なくダウンロードできる事が確認できた。
さて、お次は、ディレクトリー名の作成だ。
RedHat9では、日本語のディレクトリー名を作成した時
文字化けが起こった。
日本語のディレクトリー名の作成 |
|
作成結果を見てみた。
日本語のディレクトリー作成結果 |
|
画面拡大 |
|
文字化けする事なく、ディレクトリー名が表示された
|
色々、触ってみたが、全く文字化けの心配はない。
なので、最近のディストリビューションで動かすには
全く問題がないと言っても良いと思う。
もちろん、全てのディストリビューションで検証していませんので
100%の保証はできませんが。
■■■ axlopeの改造 ■■■
オープンソースの魅力は、自由にソースコードを書き換える事だ。
なので、うちの会社の用途に合わせて改造できるのだ。
■■■ 表示するメッセージの変更 ■■■
ファイルやディレクトリーの一覧 |
|
これを見ていると、一般のパソコン利用者には、わかりにくい部分がある。
赤で囲んだ部分で「ディレクトリー」や「ルート」はUNIX用語であって
一般の人は、Windowsを使うので、用語で混乱しそうになる。
|
そこで、うちの会社で使うためには、表示の内容を変える必要が出てきた。
メッセージなどを格納している「lib/msg.ja.inc」を触れば良い
lib/msg.ja.inc を触る |
変更前 |
<?php
//---------------------------------------------------------------------------
//Japanese message definition file
//Charactor set is UTF-8
//漢字コードはUTF−8
//---------------------------------------------------------------------------
$gMsg['keywords'] = "PHP,File,Manager,Web,ファイル, マネージャー";
$gMsg['description'] = "axlope:PHPベースのファイル管理ソフト";
$gMsg['title tag'] = "axlope";
$gMsg['ScanFilesErr'] = "ディレクトリを見つけることができませんでした \n";
$gMsg['ScanFilesMsg'] = "現在のディレクトリ:";
$gMsg['footer'] = "axlope : PHP File Manager ver.1.0";
$gMsg['tree'] = "ディレクトリ一覧";
$gMsg['mkdir'] = "ディレクトリ作成";
$gMsg['th_name'] = "名前";
$gMsg['th_size'] = "サイズ";
$gMsg['th_date'] = "更新日";
$gMsg['cp'] = "複写";
$gMsg['mv'] = "移動";
$gMsg['del'] = "削除";
$gMsg['ren'] = "改名";
$gMsg['upload'] = "アップロード";
$gMsg['DirLogMsg'] = "ディレクトリを選んでください";
(以下省略)
|
変更後 |
<?php
//---------------------------------------------------------------------------
//Japanese message definition file
//Charactor set is UTF-8
//漢字コードはUTF−8
//---------------------------------------------------------------------------
$gMsg['keywords'] = "PHP,File,Manager,Web,ファイル, マネージャー";
$gMsg['description'] = "axlope:PHPベースのファイル管理ソフト";
$gMsg['title tag'] = "axlope";
$gMsg['ScanFilesErr'] = "フォルダーを見つけることができませんでした \n";
$gMsg['ScanFilesMsg'] = "現在のフォルダー:";
$gMsg['footer'] = "axlope : PHP File Manager ver.1.0";
$gMsg['tree'] = "フォルダー一覧";
$gMsg['mkdir'] = "フォルダー作成";
$gMsg['th_name'] = "名前";
$gMsg['th_size'] = "サイズ";
$gMsg['th_date'] = "更新日";
$gMsg['cp'] = "複写";
$gMsg['mv'] = "移動";
$gMsg['del'] = "削除";
$gMsg['ren'] = "改名";
$gMsg['upload'] = "アップロード";
$gMsg['DirLogMsg'] = "フォルダーを選んでください";
$gMsg['RootDir'] = "トップ";
(以下省略)
|
ファイルやディレクトリーの一覧(変更後) |
|
これだと一般の利用者にも馴染みやすい表示になる。
そもそもWindowsよりもUNIXの方が先に出たのだから、
MSは混乱を避けるため、UNIX用語を使うべきだったと思う。
|
■■■ 画像の表示 ■■■
さて、うちの会社では商品の画像などを社内向けのWebに載せておけば
カタログや資料の作成の際、ダウンロードできれば便利になる。
こんな絵を載せてみたいとする |
|
かわいげのないパンダの絵ですが、絵心のない私が描いているので
突っ込みを入れないでください (^^)
|
だが、axlopeの初期状態では、ダウンロードして画像を開かないと
画像の中身が見れないので、確認するのに手間がかかる。
画像ファイルは、ファイル名しか表示されない |
|
gif画像の「panda.gif」が表示されたら、どんな画像かわかるので
便利だなぁと思ったりする。
|
そのため、Web上で画像の中身を見る事ができれば、ダウンロードして
確認する手間が省ける。
そこでファイル名を表示させるライブラリ(lib/axlope01.inc)を
改造してみる事にした。
lib/axlope01.inc の改造 |
変更前 |
//ファイル
foreach($files as $key => $val) {
if($c % 2 == 0) printf("\n<tr class=\"cEvenColor\">\n");
else printf("\n<tr class=\"cOddColor\">\n");
$DecodedFileName = urldecode($val->mName);
printf("<td><input type=\"checkbox\" name=\"nFiles[]\" value=\"$DecodedFileName\"></td>\n");
printf("<td><img src=\"{$gImg['file']}\" alt=\"$DecodedFileName\"><span class=\"cPseudLink\" onclick=\"SendCmdForm('download','$DecodedFileName')\">$DecodedFileName</span></td>\n");
printf("<td style=\"text-align:right;\">$val->mKBSize</td>\n<td style=\"text-align:right;\">$val->mDate</td>\n</tr>\n");
$c++;
}
|
変更後 |
//ファイル
foreach($files as $key => $val) {
if($c % 2 == 0) printf("\n<tr class=\"cEvenColor\">\n");
else printf("\n<tr class=\"cOddColor\">\n");
$DecodedFileName = urldecode($val->mName);
printf("<td><input type=\"checkbox\" name=\"nFiles[]\" value=\"$DecodedFileName\"></td>\n");
printf("<td><img src=\"{$gImg['file']}\" alt=\"$DecodedFileName\"><span class=\"cPseudLink\" onclick=\"SendCmdForm('download','$DecodedFileName')\">$DecodedFileName</span>\n");
if ( eregi("(gif|jpg|jpeg|png|bmp)$",$val->mName) == 1 )
{
print "<img src=\"data$val->mPath/$val->mName\">" ;
}
printf("</td>\n");
printf("<td style=\"text-align:right;\">$val->mKBSize</td>\n<td style=\"text-align:right;\">$val->mDate</td>\n</tr>\n");
$c++;
}
|
赤い部分は改造したり追加した部分だ。
ファイル名が画像データと判定した場合、<img>タグで、
画像を表示させるのだ。
|
早速、改造した結果を見てみる事にした。
すると・・・
見事、画像が表示された!! (^^)V
画像が表示された |
|
かわいげのないパンダの絵が表示されるようになった。
もっと、かわいい絵だったら良いかも (^^)
|
さて改造したため、画像の表示が出るようになった。
画像が表示するのは意外と簡単だなぁと思った。
だが、その気分も束の間だった。
日本語のファイル名「雪だるま.gif」をアップロードしてみる事にした。
日本語ファイル名「雪だるま.gif」の画像 |
|
くちばしのように赤くて長いのは、ニンジンのつもりです。
木炭を目にして、ニンジンを口にした、昔からある雪だるまを
描きました。でも、あまり、かわいげがないなぁ (^^;;
|
なぜなら、ファイル名が日本語の場合だと・・・
画像が表示できへん (TT)
画像が表示できない様子 |
|
拡大版 |
|
日本語のファイル名だと表示できない。
|
一体、なんでやねんと思いつつ、原因を探る事にした。
日本語のファイル名に着目した。
アップロードしたファイルは、日本語のファイル名のままで
保存しているわけではない。
URLエンコードで、アスキー文字に変換しているのだ。
ちなみに、この時点では、URLエンコードが何なのかはわからなかった。
保管ディレクトリーを見てみると |
[suga@server data]$ ls -l
合計 8
drwxr-xr-x 3 nobody nobody 4096 3月 3 21:58 %E9%9B%AA%E3%81%A0%E3%82%8B%E3%81%BE.gif
[suga@server data]$
|
「雪だるま.gif」というファイル名をURLエンコードを行っているため
「%E9%9B%AA%E3%81%A0%E3%82%8B%E3%81%BE.gif」に変換される。
日本語でも、文字コードが違う場合は、URLエンコードの結果が
異なるので注意が必要だ。
|
そこで、直接、アップロードしたファイルが正しく表示できるか
確かめるため、URLの部分に、直接、URLエンコードで変換された
ファイル名を打ち込む事にした。
すると・・・
表示できへんやん (--;;
URLにファイル名を書き込む様子 |
|
URLにファイル名を書き込んだ結果 |
|
「そんなファイルは存在しない」というエラーが出た。
エラーの内容を見た時、そんなバカなと思ったが、
何か原因があると思った。
|
存在しているはずのファイルが、存在しない。
そこで、URLエンコードとは何かを調べてみる事にした。
何やら次の記述が見つかった。
「%」の扱いに関する事 |
|
URLエンコードでは「%」を「%25」にするという記述だ。
axlopeでは、ファイル名をURLエンコードしているので
重要な部分だと思った。
|
そこで、URLを使って、ファイルを見る時、以下のように
「%」を「%25」に置き換えてみる事にした。
ファイル名の中の「%」を「%25」に置き換えてみる |
|
そこで、ブラウザで「%」を「%25」に置き換えた状態で、
直接、ファイル名を見る事にした。
すると・・・
見事、画像が表示された (^^)
URLにファイル名を書き込む様子 |
|
URLにファイル名を書き込んだ結果 |
|
URLの「%」の部分を「%25」に置き換えた結果、
見事の画像が表示された。
|
この時点では「%」を「%25」に置き換えたら良い理由が
わかっていなかったのだが、とりあえず、これで問題ないと思い、
ファイル名を表示させるライブラリ(lib/axlope01.inc)を次のように
改造してみる事にした。
lib/axlope01.inc の改造 |
初期状態 |
//ファイル
foreach($files as $key => $val) {
if($c % 2 == 0) printf("\n<tr class=\"cEvenColor\">\n");
else printf("\n<tr class=\"cOddColor\">\n");
$DecodedFileName = urldecode($val->mName);
printf("<td><input type=\"checkbox\" name=\"nFiles[]\" value=\"$DecodedFileName\"></td>\n");
printf("<td><img src=\"{$gImg['file']}\" alt=\"$DecodedFileName\"><span class=\"cPseudLink\" onclick=\"SendCmdForm('download','$DecodedFileName')\">$DecodedFileName</span></td>\n");
printf("<td style=\"text-align:right;\">$val->mKBSize</td>\n<td style=\"text-align:right;\">$val->mDate</td>\n</tr>\n");
$c++;
}
|
変更後 |
//ファイル
foreach($files as $key => $val) {
if($c % 2 == 0) printf("\n<tr class=\"cEvenColor\">\n");
else printf("\n<tr class=\"cOddColor\">\n");
$DecodedFileName = urldecode($val->mName);
printf("<td><input type=\"checkbox\" name=\"nFiles[]\" value=\"$DecodedFileName\"></td>\n");
printf("<td><img src=\"{$gImg['file']}\" alt=\"$DecodedFileName\"><span class=\"cPseudLink\" onclick=\"SendCmdForm('download','$DecodedFileName')\">$DecodedFileName</span>\n");
if ( eregi("(gif|jpg|jpeg|png|bmp)$",$val->mName) == 1 )
{
$mpath2 = ereg_replace("%","%25",$val->mPath);
$name2 = ereg_replace("%","%25",$val->mName);
print "<img src=\"data$mpath2/$name2\">" ;
}
printf("</td>\n");
printf("<td style=\"text-align:right;\">$val->mKBSize</td>\n<td style=\"text-align:right;\">$val->mDate</td>\n</tr>\n");
$c++;
}
|
赤と青の色の部分は改造したり追加した部分だ。
青はディレクトリ名とファイル名に「%」文字が含まれている場合
「%25」に置き換えるための処理だ。
そして、ファイル名が画像データと判定した場合、<img>タグで、
画像を表示させるのだ。
|
早速、改造した結果を見てみる事にした。
すると・・・
見事、画像が表示された!! (^^)V
日本語ファイル名「雪だるま.gif」の画像 |
|
どうやら「%」を「%25」に置き換えると、問題なく画像が表示されるようだ。
これで全て解決だと思った。
|
これで安心だと思ったのだが、これで終わっては良くない。
なぜなら・・・
なんで「%」を「%25」に置き換えたら、うまくいくのかが
説明できへんからや (^^;;
そうなのです。
システム奮闘記の連載初期の頃なら、遠山の金さんの最後のセリフのように
「これにて一件落着」で済ましても良かった。でも、今、それをすると
「アカンやん!」と突っ込まれそうになるからだ。
それに、表示がうまくいかなくなった場合、原因を探る必要があるため、
当てずっぽで成功した事を放置せずに、なぜ、成功しているのかを
キチンと把握しておく必要があると考えた。
そこで、URLエンコードについて、検索サイトで調べたりした。
URLエンコードとは |
URLに関する規定を満たすために行う文字変換の処理だ。
URLはASCIIコードの非予約文字以外では使えない事になっている。
そのため、GET型式で、2バイト文字をURLに付加したい場合は
文字変換を行い、URLの規定を満たすようにする役目を果たす。
|
そして、URLの規定については・・・
RFC3986なのらー!
日頃から英語嫌いで「鬼畜米英」と叫んでいる私なのだが、
悲しい現実として英語を読まなければならない (--;;
でも、じっくり読まずに、必要な所を探して見ると「%」について
書いてあった。
URLでは、直接「%」は使えない事になっている。
そのため、URLエンコードで「%」の文字を「%25」に変換するのだ。
そのため、URLでファイル名を指定した場合、「%」を「%25」に置き換えると
問題ない事が、ようやく、わかった (^^)
調べて行くと、URLエンコードは、空白を文字に置き換えてくれる。
そのため、ファイル名に半角スペース文字が存在しても、
「%20」に変換してくれる。スキマを補ってくれるのだ。
axlopeでは、日本語のファイル名をURLエンコードを使って
文字変換を行った上で、サーバーに保管している。
ファイル名の中には、空白文字が入る場合も考えられる。
そのため、URLエンコードで変換しているのだと思った。
ふと思った。
googleやyahooの検索サイトでも、検索結果を出力した際のページの
URLにもURLエンコードが使われているのではないか!
gogleで「神戸」と「ケーキ」で検索してみる |
|
お馴染みのgoogleの検索画面だ。
これに、検索したいキーワードを入力すれば
関連したホームページが出力される。
|
神戸といえば洋菓子。ケーキが美味しい地域だ。
神戸はケーキ激戦区のため、神戸で生き残れるケーキ屋さんは
全国どこでも通用するのだ。しかも、値段も手頃だ。
ちなみに、コーヒーショップのドトールでは、神戸でのケーキの売行きが
芳しくないという。
そりゃ、全国最高水準の神戸の美味しいケーキが手頃に食べれるので、
値段の変わらないトドールのケーキを食べたいとは思わなくなる。
gogleで「神戸」と「ケーキ」で検索した結果 |
|
神戸とケーキに関連したホームページのサイトが表示される。
夙川(西宮)〜ハーバーランド(神戸市中央区)辺りまでに
美味しいケーキ屋が多い。
私は勝手に「阪神間・ケーキベルト地帯」と呼んでいる (^^)
|
でも、今回は美味しいケーキが目的ではなく、検索した後の
ブラウザのURLに注目したいと思います。
検索した後のブラウザのURL |
|
ピンクで線を引いた所に注目。
なんだかURLエンコードで変換された文字列が続いている。
|
このURLの部分を全て表示してみると
検索した後のブラウザのURL |
|
青い線で引っ張った所に、検索キーワードがある。
2バイト文字をURLに付加する場合は、URLエンコードする必要がある。
|
こんな事、初めて知った (^^;;
知らず知らずのうちに、URLエンコードと接していたのだなぁと思った。
だが、まだ不満が残る。
表示される画像が大きい場合、見づらくなる。
例えば、普通にHTML言語を使って、大きな画像を表示させてみる事にする。
普通に画像を掲載するHTML |
<html>
<body>
<img src="testpic.jpg">
</body></html>
|
ただ単純に画像データを、そのまま表示させるだけだ。
|
するとブラウザの枠を簡単に、はみだしてしまう。
デカい画像を載せたら、完全に、はみだす |
|
これだと何の画像かわからない。
もちろん、ブラウザのスクロール機能で上下左右を行えば
画像全体を見る事はできるが、スクロールバーを操作するため
一目で、わかる大きさの画像で表示したくなる。
|
HTML言語では、画像の表示の大きさを変える事ができる。
<img>タグで、横幅の大きさの指定「width」を行えば良いのだ。
画像の横の大きさを200ピクセルにして掲載するHTML |
<html>
<body>
<img src="testpic.jpg" width="200">
</body></html>
|
すると画像が小さく表示(横幅200ピクセル)される。
横幅を200ピクセルにしたらブラウザの枠に収まる |
|
これだと動物園のパンダの画像だとわかる。
北京動物園のパンダです。(2008/1/13撮影)
ちなみに、撮影者は私なので、無断引用ではありません (笑)
|
これで画像の表示の大きさの問題が解消されると思う。
方法の1つではあるが、まだ問題がある。
何枚も大きな画像ファイルを表示させる時、以下の問題が発生する。
大きな画像は、画像データ自体も大きいからだ!
もし、大きな画像を表示させた場合 |
|
サーバーからクライアントへ画像データを送信するのだが
画像データそのものが大きいため、大量のデータ送信が行われる。
|
まだ本社のパソコンで見るなら、高速のLANがあるので、
データの読み込みに時間がかからないので良いのだが、
営業所の場合は、そうはいかない。
通信データは、通信回線を経由して見る事になるからだ。
営業所で見る場合 |
|
インターネットVPNで回線を結んでいるのだが、
画像が大きい物で、1Mとか2Mぐらいの大きさの画像を
何枚も掲載されると、画像を取り込んで表示されるまで
時間がかかるため、閲覧者はイライラする事が予想できる。
インターネットVPNに関しては「システム奮闘記:その35」を
ご覧ください。
|
仮に、イライラ感が少なくても、インターネットVPNで結んでいるため、
大量のデータ送信を、公共の場では行うのは、いかがな物かと思う。
<img>タグの「width」を使わずに、表示する画像を小さくできないか。
もう1つの方法がある。それは
表示する画像データそのものをプログラムで加工すれば、ええやないか!
大阪発のECサイトのオープンソース「EC-CUBE」を導入する際、
プログラム(PHP言語)を眺めていて、画像の大きさの加工処理を行う
プログラムがあり、それで掲載する商品の画像の大きさを加工している。
イメージ関数と呼ばれる物を使っているのだ。
なので、EC-CUBEのプログラムを見て初めて
PHPのイメージ関数の使い方を知ったのだ!
EC-CUBEについては「システム奮闘記:その65」をご覧ください。
北京動物園のパンダの写真は「jpg」型式の画像データだ。
なので、「jpg」型式の画像処理のプログラムを書いてみる事にした。
イメージ関数を使って画像の表示で
横幅を200ピクセルにするプログラム |
<?php
// ヘッダーに表示させるデータをJPGデータを指定
header('Content-type: image/jpeg');
// パンダの画像の大きさの情報を得る。
$result = getimagesize("testpic.jpg");
// URLやファイルから画像を生成する関数。
// ここでは加工したいファイル名を指定する。
// 返り値はイメージIDと呼ばれる物で、
// 加工される画像を識別するIDとなる。
// 「$im」に格納される。
$im = @imagecreatefromjpeg("testpic.jpg");
// 横幅を200ピクセルにした場合、縦の縮尺も合わせるため
// 縦幅のピクセル数を算出する。
// $result[0] は、元のファイルの横幅の大きさ(ピクセル数)だ。
$width = 200 ;
$per = $width / $result[0] ;
$height = $result[1] * $per ;
// 新規の画像を作成
// 絵で例えると、白いキャンパスを用意するのと同じだ。
// 白いキャンパスの横幅と縦幅を指定する。
// 返り値は、白いキャンパスを認識するIDだ。
$thumb = imagecreatetruecolor($width, $height);
// 画像のコピーとコピーの時に画像の大きさを変える関数。
// 加工したい画像ID($im)と、横幅($result[0])、縦幅を指定($result[0])。
// コピー先の画像ID($thumb)と、横幅($width)、縦幅($height)を指定。
imagecopyresized($thumb, $im, 0, 0, 0, 0,
$width, $height, $result[0], $result[1]);
// 上の関数で、元の画像をコピーすると同時に
// 画像の大きさを変える事ができたので
// その画像をブラウザに出力させる関数
imagejpeg($thumb);
?>
|
コメント文で、ゴチャゴチャした感じがあるのだが、
関数の説明という意味で書きました。
まぁ、私の知識の整理という意味合いの方が濃厚ですが (^^;;
|
早速、実行してみる。
結果は・・・
見事、成功 (^^)V
プログラム中で画像データを
横幅200ピクセルに加工して出力した結果 |
|
プログラム中で大きさを加工したパンダの画像が表示されている。
これで元のファイルの大きさが、どんなにデカくても
プログラム中で加工してデータ自体も小さくしてくれるため
データの読み込みに時間がかからなくなる上、
通信量も減らす事ができる。
|
さて、イメージ関数を使った画像の加工を、axlopeにも適用したい。
そこで、再びファイルを表示させるライブラリ(lib/axlope01.inc)の
改造を行う事になった。
そして、画像出力のためのプログラムも追加する事にした。
lib/axlope01.inc の改造 |
初期状態 |
//ファイル
foreach($files as $key => $val) {
if($c % 2 == 0) printf("\n<tr class=\"cEvenColor\">\n");
else printf("\n<tr class=\"cOddColor\">\n");
$DecodedFileName = urldecode($val->mName);
printf("<td><input type=\"checkbox\" name=\"nFiles[]\" value=\"$DecodedFileName\"></td>\n");
printf("<td><img src=\"{$gImg['file']}\" alt=\"$DecodedFileName\"><span class=\"cPseudLink\" onclick=\"SendCmdForm('download','$DecodedFileName')\">$DecodedFileName</span></td>\n");
printf("<td style=\"text-align:right;\">$val->mKBSize</td>\n<td style=\"text-align:right;\">$val->mDate</td>\n</tr>\n");
$c++;
}
|
変更後 |
//ファイル
foreach($files as $key => $val) {
if($c % 2 == 0) printf("\n<tr class=\"cEvenColor\">\n");
else printf("\n<tr class=\"cOddColor\">\n");
$DecodedFileName = urldecode($val->mName);
printf("<td><input type=\"checkbox\" name=\"nFiles[]\" value=\"$DecodedFileName\"></td>\n");
printf("<td><img src=\"{$gImg['file']}\" alt=\"$DecodedFileName\"><span class=\"cPseudLink\" onclick=\"SendCmdForm('download','$DecodedFileName')\">$DecodedFileName</span>\n");
if ( eregi("(gif|jpg|jpeg|png|bmp)$",$val->mName) == 1 )
{
$DirOut = ereg_replace("%","%25",$val->mPath);
$FileOut = ereg_replace("%","%25",$val->mName);
print "<br><img src=\"lib/axlope-pic.php?dir={$DirOut}&file={$FileOut}\">\n" ;
}
printf("</td>\n");
printf("<td style=\"text-align:right;\">$val->mKBSize</td>\n<td style=\"text-align:right;\">$val->mDate</td>\n</tr>\n");
$c++;
}
|
色を付けた部分は改造した部分だ。
赤い部分はファイル名の拡張子で、ファイルが画像かどうかの判定を行い、
画像ファイルの場合なら、ファイル名、ディレクトリ名の中に
「%」が含まれれば、「%25」に置き換える処理を行う。
青い部分が画像を表示させる<img>タグだ。
<img>タグの部分で、画像を加工・出力させるプログラムを走らせ
画像を表示させる方法にした。
|
さて、画像を加工・出力させるプログラムだ。
これは、axlope01.inc と同じ libディレクトリーに置いておく。
追加したプログラム(lib/axlope-pic.php) |
<?php
//---------------------------------------------------------------------------
//Charactor set is UTF-8
//漢字コードはUTF−8
//---------------------------------------------------------------------------
// 画像データの格納されているディレクリ
$dir = $_GET['dir'];
// 画像データのファイル名
$file = $_GET['file'] ;
// 画像データの拡張子を抽出する。
// 画像型式によって、画像加工に使うイメージ関数が異なるため
eregi("(gif|jpg|jpeg|png|bmp)$",$file , $form) ;
// jpgの場合、拡張子が「jpg」と「jpeg」になっている場合があるので
// 抽出した拡張子の中身を「jpeg」にまとめる。
if ( $form[1] == "jpg" ) $form[1] = "jpeg";
$form[1] = strtolower($form[1]) ;
// 画像データのディレクトリーとファイル名
$file = "../data".$dir."/".$file ;
// 画像データの大きさ
$result = getimagesize($file);
// 加工する画像データを読み込み、画像IDを割り当てる。
// この際、個々の画像型式別に関数を使い分ける。
if ( $form[1] == "jpeg" ) // jpgの場合
{
$im = @imagecreatefromjpeg($file);
}
else if ( $form[1] == "png" ) // pngの場合
{
$im = @imagecreatefrompng($file);
}
else if ( $form[1] == "gif" ) // gifの場合
{
$im = @imagecreatefromgif($file);
}
else if ( $form[1] == "bmp" ) // bmpの場合
{
$im = @imagecreatefromwbmp($file);
}
if ( $im )
{
// 画像IDが割り当てられた場合(加工したデータが読み込めた場合)
// 横幅を150ピクセルにして、縦の縮尺を合わせる。
$per = 150 / $result[0] ;
$width = 150 ;
$height = $result[1] * $per ;
// 加工した画像をコピーする先の画像IDを割り当てる。
$thumb = imagecreatetruecolor($width, $height);
// 画像データを加工して、それをコピー先にコピーする。
imagecopyresized($thumb, $im, 0, 0, 0, 0,
$width, $height, $result[0], $result[1]);
// 画像の出力のためのヘッダー
header('Content-type: image/$form[1]');
// 個々の画像型式に合わせて画像の出力
if ( $form[1] == "jpeg" )
{
imagejpeg($thumb);
}
else if ( $form[1] == "png" )
{
imagepng($thumb);
}
else if ( $form[1] == "gif" )
{
imagegif($thumb);
}
else if ( $form[1] == "bmp" )
{
imagewbmp($thumb);
}
imagedestroy($im);
imagedestroy($thumb);
}
else
{
// 画像データが読み込めなかった場合
// 「読み込めなかった」を表示する画像を作る
$im = @imagecreate(200, 40);
// 画像で使う色を指定。色をIDで返す。
// ここでは「読めなかった」の文字の色を青に指定
$textcolor = imagecolorallocate($im, 255 , 0 , 0);
// 「can't display picture!」という文字列を含んだ画像生成
imagestring($im, 4, 10, 15, "can't display picture!", $textcolor);
header('Content-type: image/png');
// png型式として画像を出力
imagepng($im);
imagedestroy($im);
}
?>
|
早速、動かしてみる。
さきほど、デカデカ(?)と表示させていた「雪だるま」の画像が
見事、縮小されて表示されている (^^)V
日本語ファイル名「雪だるま.gif」の画像 |
|
見事に、画像を縮小表示する事ができた。
これだと本社以外でアップロードされている画像を見る場合でも
営業所でデータを取り込むのに時間がかかって、イライラする問題は
発生しなくなる。
これで、うちの会社で使う場合での、axlopeの改造は終わった。
だが、オープンソースなので、用途に合わせて自由に改造できる、
自由に改造こそオープンソースの醍醐味だ!
自由に改造する度に、オープンソースの素晴らしさを感じる今日この頃 (^^)
まとめ
EC-CUBEに引続き、国産のオープンソース・axlopeを取り上げました。
日本発のWebファイルマネージャーだけに日本語の処理ができる。
axlopeを見つけるまでは、海外のWebファイルマネージャーの導入を
検討しましたが、日本語対応の問題がある上、今の私の実力では
とても対応できないため、諦めていました。
そのため、axlopeは、ありがたい存在に思えました。
私は、axlopeを応援したいと思います。
頑張れニッポン! 日出づる国・日本!
オープンソースの日(ソフト)が、続々と出てくる事を期待したいと思います。
そして、私も、できる限り、日本発のオープンソースを導入し、
システム奮闘記に取り上げたいと思います (^^)
次章:「セキュリティー入門」を読む
前章:「無料のオープンソースECサイト(EC-CUBE)でネット販売システム構築」を読む
目次:Linux、オープンソースの「システム奮闘記」に戻る