- ベストアンサー
このコードについて
普段自分でPerlを使いCGIを作成しますが、人のコードを読むのはいまだに苦手です(>_<) http://nais.to/~yto/tools/ssupload/ のサイトで発見したアップローダーを自分なりに解釈して、自分の言葉(コード)で書き直そうとしています。 ですが、いきなりわからないことだらけで…。 print $q->header(), $q->start_html(); って何でしょうか!? ここからここまでがHTMLですよ、みたいなことなのでしょうか? また、 my $fh = $q->param('uploaded_file'); は? 他にもわからないところだらけですが、上から順にやっていこうと思ってるので、上記のこと教えてください!! もしくは上記のサイトのコードじゃなくても、 ・見やすいコード ・モジュール不使用 ・Perl使用 のアップロードのコードがありましたらあわせて教えてください。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
> 拡張子による動作変化は必要ないので削除しました。 これで拡張子をファイルネームに追加する処理をご自身で削っていますが? >#拡張子部分を取出す為にデータの間処理を続ける のところで、拡張子を取り出し、$extにセットし、 >#許可されている拡張子なら書き込み処理をする のところの、 >#ファイル名と拡張子を結合する の部分で、送られてきたデータの拡張子を最初に決めておいたファイルネームに追加していますよね? サンプルスクリプトから、一部分削るのは別にかまわないとおもいますが、その削る部分がどういう処理を行っていて、本当に削ってもよいものかどうかはちゃんと判断しないと、バグの原因にしかならないでしょう。 冒頭のコメントだけではなく、ちゃんと処理の中身もみないと、その部分に最終的に必要な処理もはいっていたりするわけですから
その他の回答 (5)
- kalze
- ベストアンサー率47% (522/1092)
具体的に教えると、結局自作するという質問者さんの意思から外れるのでヒントを。 http://www.aimix.jp/cgi/acccgilibupfile.html このページにすべてかいてあるとおもいますが? 処理の流れの解説にファイル名がどこに入っているかは書かれていますから、それを表示してみるなりしてどう入っているかを確認してみれば後は自ずからわかるかと 結局何もかも聞いてばかりでは、自作したいという意図・意思から外れるようにおもいますが?
お礼
回答ありがとうございます。 そうですね、聞いてばかりでは力がつきませんので、がんばってみたいと思います。 ありがとうございました。
- kalze
- ベストアンサー率47% (522/1092)
ある程度習熟してくれば、モジュールの違いは短期間で習得できますので、あまり心配されなくてもよいかとおもいます。 個人的に一番よいのは、cgi-lib.plを使用しているものではないかなとおもいます。 cgi-lib.plも一緒に配布されている場合がほとんどですから、すぐに閲覧できますし。 標準モジュールなので、CGI.pmはだいたいのサーバで使えるとはおもいますが、サーバ側で使えるようにされてないと、使えるようにするのに面倒な場合もありますから。 まぁどれにしても、一つをじっくりみていって、手順を覚えて、どういうことをしなければいけないかを習得してしまえば、他のモジュールに変更しようというときには、手順を覚えるときほど苦労しないとおもいますよ できれば、独習Perlでもなんでもいいので、そういった本でPerlの基礎と、いつでもひけるようにリファレンスを持っておいたほうがよいとおもいます。
お礼
回答ありがとうございます。 cgi-libを使うもの http://www.aimix.jp/cgi/acccgilibupfile.html をダウンロードして実行してみました。 どうやらbmpは対応していない形式のようです。 (実際に試したらそう出たので) それはいのですが、jpgのファイルをアップデートすると、完了っぽいメッセージは出るのですが、 ファイルがアップロードされません。 何かフォルダ等を作成しないといけないのかな?と思い中身を見てみたのですが、思い当たる箇所がなく…。 どこか設定を行わないといけないのでしょうか? こんなところでひっかかっているようでは先が思いやられます。 手元に初心者用のPerl本とリファレンスはあるのですが、アップロードについての記述がみつかりませんでした。
補足
拡張子による動作変化は必要ないので削除しました。 こうすることでjpgでもbmpでも書き込める(実際アップデートができて、「書き込みが完了しました」が表示される)ようになりました。 ですが、アップデートされたものは「sample」という拡張子が未設定のものです。 ファイル名は #ファイル名を指定する $fnme = 'sample'; としているのが原因だと思うのですが、アップデートしたファイル名を取得したいのですが、どのように取得するべきなのでしょうか?
- hikomin
- ベストアンサー率63% (40/63)
これは、恐らくCGIモジュールのメソッドを呼び出しているものですね。オブジェクト指向と言う考え方で、データとその処理方法をひとまとめにして管理する手法です。 特徴的なのは矢印演算子(->)で、$q->headerと書かれていれば、$qのheaderメソッドを呼ぶ、という意味になります。メソッドと言うのは、サブルーチンだと思っていただいて構いません。(実際、実装的にはサブルーチンになります。)サブルーチンとデータをまとめたモノがオブジェクトと思えば良いでしょう。 今回はCGIモジュールなので、詳しい使い方はcpan等を参照していただければ良いのですが、簡単に解説すると、 $q->header(); headerサブルーチンを呼ぶ:Content-Type等のヘッダが出力されるだけ。 $q->start_html(); start_htmlサブルーチンを呼ぶ:<html><head><title>とかが書かれたHTMLの冒頭を出力するだけ。 my $fh = $q->param('uploaded_file'); これはちょっと難しいですが、<input type="file" name="uploaded_file" value="" />とかの形でアップロードを行なった時に、それを取り出すためのファイルハンドルを取得するという意味です。今ではuploadメソッドが用意されていて、同じように使用します。 my $fh = $q->upload('uploaded_file'); ファイルを開いて読み込んだり書き込んだりするあれと同じだと思ってください。while(my $data = <$fh>){###}とか、まぁ普通のファイルハンドルのように使う事が出来ます。 オブジェクトはデータも保管されているので、メソッドを呼ぶ事で内部のデータも変化します。例えば $q->header(); と直接ヘッダを出す場合と、 $q->charset('EUC-JP'); $q->header(); のように別のメソッドを呼んでからヘッダを出す場合とでは出力内容が違う筈です。この辺が、ただのサブルーチンの集まり(=ライブラリ)ではなく、データと処理法をカプセル化しているという意味になります。逆に言えば、適切にメソッドを呼んでいけば、勝手に都合の良い出力になるように出来ているわけです。
お礼
回答ありがとうございます。 教えていただいても、まだ難しいスクリプトですね(^^; 前回の質問で教えていただいたのが ライブラリ不要 http://nais.to/~yto/tools/ssupload/ cgi-libを使うもの http://www.aimix.jp/cgi/acccgilibupfile.html CGI.pmを使うもの http://www.harukaze.net/~mishima/perl/module/upload_by_CGI_pm.html なのですが、どれが一番初心者にやさしいでしょうか? 今までモジュールの使用を避けていたのですが、使ったほうが便利そうですので、使おうと思います。
- panick
- ベストアンサー率40% (26/64)
Perl5 の CGI標準モジュール CGI.pm を使っています。 ファイルのアップロードなどが簡単に出来るので重宝します。CGI.pm の解説サイトが多くありますので、使い方はすぐにマスターできると思います。その他には cgi-lib.pl なども使われることが多いです。
お礼
回答ありがとうございます。 前回の質問で教えていただいたのが ライブラリ不要 http://nais.to/~yto/tools/ssupload/ cgi-libを使うもの http://www.aimix.jp/cgi/acccgilibupfile.html CGI.pmを使うもの http://www.harukaze.net/~mishima/perl/module/upload_by_CGI_pm.html なのですが、どれが一番初心者にやさしいでしょうか? 今までモジュールの使用を避けていたのですが、使ったほうが便利そうですので、使おうと思います。
- kalze
- ベストアンサー率47% (522/1092)
一番無難だなとおもうのはKENT-WEBさんの配布してるものかなとおもいます。 Perl入門者にはちょっとつらいスクリプトですね。 use CGI; でCGIモジュールを使用可能にしています。 my $q = new CGI; で、実体を持たせています。 print $q->header(), $q->start_html(); 先ほど実体を持たせたCGIにある、header()関数とstart_html()関数を実行しています。 CGIモジュール使わないので推測ですが、ヘッダー情報などを吐き出す関数なのでしょう。 my $fh = $q->param('uploaded_file'); モジュールを見てないのでソース全体を見たうえでの推測ですが、paramの中に受け取ったデータが入っていて、uploaded_fileという項目名で受け取ったデータを、$fh変数にセットしているんでしょう。 このスクリプトはCGIモジュールを使っているので、CGIモジュールのソースも合わせて追って行くか、CGIモジュールの説明やリファレンスなどを見ながらおっかけていくしかないでしょう。 ファイルのアップロードは全部自力でやろうとすると結構例外処理も多くてめんどくさいので、最初はなんらかの(cgi-bin.plとか前の質問で#2さんが答えていたような)モジュールを使用してCGIを作成するのが普通ですね。 それができるようになってから、モジュールに任せていた受け取り部分を自分で構築していくと。 (モジュールを使っていないスクリプトの受け取り部分みても、わけわからんだけになりそうですから)
お礼
回答ありがとうございます。 難しいスクリプトですか…(^^; 前回の質問で教えていただいたのが ライブラリ不要 http://nais.to/~yto/tools/ssupload/ cgi-libを使うもの http://www.aimix.jp/cgi/acccgilibupfile.html CGI.pmを使うもの http://www.harukaze.net/~mishima/perl/module/upload_by_CGI_pm.html なのですが、どれが一番初心者にやさしいでしょうか? 今までモジュールの使用を避けていたのですが、使ったほうが便利そうですので、使おうと思います。
お礼
回答ありがとうございます。 確かに多く削りすぎてましたね! 元に戻し、いらないところを修正しまして、無事拡張子はつきました。 コードにない拡張子(bmpやxls等)は自分でつければなんとかなりそうです。 # 受信データの Content-type 部分から拡張子を探す # 受信データの filename= 部分から拡張子を探す ということで拡張子をさがしてるようですが、これの応用でファイル名も取得できそうな気がするのですが、どのようにすればファイル名を取得できるのでしょうか? 拡張子の場合は、ある程度予測できるのでifで分岐してるようですが、ファイル名となるとそうはいかないですよね? もし取得が難しいのであれば、ファイル名を自動で振り分ける(日付・時間で)という方法をとろうかと思ってます。