• ベストアンサー

このコードについて

普段自分でPerlを使いCGIを作成しますが、人のコードを読むのはいまだに苦手です(>_<) http://nais.to/~yto/tools/ssupload/ のサイトで発見したアップローダーを自分なりに解釈して、自分の言葉(コード)で書き直そうとしています。 ですが、いきなりわからないことだらけで…。 print $q->header(), $q->start_html(); って何でしょうか!? ここからここまでがHTMLですよ、みたいなことなのでしょうか? また、 my $fh = $q->param('uploaded_file'); は? 他にもわからないところだらけですが、上から順にやっていこうと思ってるので、上記のこと教えてください!! もしくは上記のサイトのコードじゃなくても、 ・見やすいコード ・モジュール不使用 ・Perl使用 のアップロードのコードがありましたらあわせて教えてください。

質問者が選んだベストアンサー

  • ベストアンサー
  • kalze
  • ベストアンサー率47% (522/1092)
回答No.5

> 拡張子による動作変化は必要ないので削除しました。 これで拡張子をファイルネームに追加する処理をご自身で削っていますが? >#拡張子部分を取出す為にデータの間処理を続ける のところで、拡張子を取り出し、$extにセットし、 >#許可されている拡張子なら書き込み処理をする のところの、 >#ファイル名と拡張子を結合する の部分で、送られてきたデータの拡張子を最初に決めておいたファイルネームに追加していますよね? サンプルスクリプトから、一部分削るのは別にかまわないとおもいますが、その削る部分がどういう処理を行っていて、本当に削ってもよいものかどうかはちゃんと判断しないと、バグの原因にしかならないでしょう。 冒頭のコメントだけではなく、ちゃんと処理の中身もみないと、その部分に最終的に必要な処理もはいっていたりするわけですから

w-inty
質問者

お礼

回答ありがとうございます。 確かに多く削りすぎてましたね! 元に戻し、いらないところを修正しまして、無事拡張子はつきました。 コードにない拡張子(bmpやxls等)は自分でつければなんとかなりそうです。 # 受信データの Content-type 部分から拡張子を探す # 受信データの filename= 部分から拡張子を探す ということで拡張子をさがしてるようですが、これの応用でファイル名も取得できそうな気がするのですが、どのようにすればファイル名を取得できるのでしょうか? 拡張子の場合は、ある程度予測できるのでifで分岐してるようですが、ファイル名となるとそうはいかないですよね? もし取得が難しいのであれば、ファイル名を自動で振り分ける(日付・時間で)という方法をとろうかと思ってます。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (5)

  • kalze
  • ベストアンサー率47% (522/1092)
回答No.6

具体的に教えると、結局自作するという質問者さんの意思から外れるのでヒントを。 http://www.aimix.jp/cgi/acccgilibupfile.html このページにすべてかいてあるとおもいますが? 処理の流れの解説にファイル名がどこに入っているかは書かれていますから、それを表示してみるなりしてどう入っているかを確認してみれば後は自ずからわかるかと 結局何もかも聞いてばかりでは、自作したいという意図・意思から外れるようにおもいますが?

w-inty
質問者

お礼

回答ありがとうございます。 そうですね、聞いてばかりでは力がつきませんので、がんばってみたいと思います。 ありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。
  • kalze
  • ベストアンサー率47% (522/1092)
回答No.4

ある程度習熟してくれば、モジュールの違いは短期間で習得できますので、あまり心配されなくてもよいかとおもいます。 個人的に一番よいのは、cgi-lib.plを使用しているものではないかなとおもいます。 cgi-lib.plも一緒に配布されている場合がほとんどですから、すぐに閲覧できますし。 標準モジュールなので、CGI.pmはだいたいのサーバで使えるとはおもいますが、サーバ側で使えるようにされてないと、使えるようにするのに面倒な場合もありますから。 まぁどれにしても、一つをじっくりみていって、手順を覚えて、どういうことをしなければいけないかを習得してしまえば、他のモジュールに変更しようというときには、手順を覚えるときほど苦労しないとおもいますよ できれば、独習Perlでもなんでもいいので、そういった本でPerlの基礎と、いつでもひけるようにリファレンスを持っておいたほうがよいとおもいます。

w-inty
質問者

お礼

回答ありがとうございます。 cgi-libを使うもの http://www.aimix.jp/cgi/acccgilibupfile.html をダウンロードして実行してみました。 どうやらbmpは対応していない形式のようです。 (実際に試したらそう出たので) それはいのですが、jpgのファイルをアップデートすると、完了っぽいメッセージは出るのですが、 ファイルがアップロードされません。 何かフォルダ等を作成しないといけないのかな?と思い中身を見てみたのですが、思い当たる箇所がなく…。 どこか設定を行わないといけないのでしょうか? こんなところでひっかかっているようでは先が思いやられます。 手元に初心者用のPerl本とリファレンスはあるのですが、アップロードについての記述がみつかりませんでした。

w-inty
質問者

補足

拡張子による動作変化は必要ないので削除しました。 こうすることでjpgでもbmpでも書き込める(実際アップデートができて、「書き込みが完了しました」が表示される)ようになりました。 ですが、アップデートされたものは「sample」という拡張子が未設定のものです。 ファイル名は #ファイル名を指定する $fnme = 'sample'; としているのが原因だと思うのですが、アップデートしたファイル名を取得したいのですが、どのように取得するべきなのでしょうか?

全文を見る
すると、全ての回答が全文表示されます。
  • hikomin
  • ベストアンサー率63% (40/63)
回答No.3

これは、恐らく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(); のように別のメソッドを呼んでからヘッダを出す場合とでは出力内容が違う筈です。この辺が、ただのサブルーチンの集まり(=ライブラリ)ではなく、データと処理法をカプセル化しているという意味になります。逆に言えば、適切にメソッドを呼んでいけば、勝手に都合の良い出力になるように出来ているわけです。

w-inty
質問者

お礼

回答ありがとうございます。 教えていただいても、まだ難しいスクリプトですね(^^; 前回の質問で教えていただいたのが ライブラリ不要 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)
回答No.2

Perl5 の CGI標準モジュール CGI.pm を使っています。 ファイルのアップロードなどが簡単に出来るので重宝します。CGI.pm の解説サイトが多くありますので、使い方はすぐにマスターできると思います。その他には cgi-lib.pl なども使われることが多いです。

w-inty
質問者

お礼

回答ありがとうございます。 前回の質問で教えていただいたのが ライブラリ不要 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)
回答No.1

一番無難だなとおもうのは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を作成するのが普通ですね。 それができるようになってから、モジュールに任せていた受け取り部分を自分で構築していくと。 (モジュールを使っていないスクリプトの受け取り部分みても、わけわからんだけになりそうですから)

w-inty
質問者

お礼

回答ありがとうございます。 難しいスクリプトですか…(^^; 前回の質問で教えていただいたのが ライブラリ不要 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 なのですが、どれが一番初心者にやさしいでしょうか? 今までモジュールの使用を避けていたのですが、使ったほうが便利そうですので、使おうと思います。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • ファイルのアップロード

    CGI初心者です。 http://nais.to/~yto/tools/ssupload/ NAIS.TOさんのサイトのファイルアップロードのソースを実際に試してみているのですが、 txtファイルやdatファイルはアップロード後開くことができるのですが、 pdfやxlsファイルは『ファイルが壊れています』と言われ、 フォルダに保存はされているのですが、開くことはできません。 html画面では文字コードがs-jisなのに cgiになるとISOになるのが原因だったりしますでしょうか。 ご回答宜しくお願いいたします。 環境 IE6 APACHE HTTP SERVER 2.0.58 ActivePerl 5.8.8

    • ベストアンサー
    • CGI
  • ファイルをアップロードするCGI

    ファイルをアップロードしたいCGIが欲しく サンプルをみつけたのですが、このCGIだと ファイルをアップロードしたときに、ファイル名がアップロードした時刻になってしまいます。 ファイル名を変更することなく、アップロードするにはどう変更すればよいのでしょうか? お願いします。ちなみにアップロードしたいファイルの種類はエクセル形式のファイルです。 プログラムは以下のようになってます。 #!/usr/bin/env perl use strict; use CGI; use CGI::Carp qw(fatalsToBrowser); use POSIX qw(strftime); my $q = new CGI; print $q->header(), $q->start_html(); #print $q->dump; # for debug my $outputdir = "log"; # ファイルを置く先 (ディレクトリ) my $fh = $q->param('uploaded_file'); my ($ex) = ($fh =~ m|(\.[^./\\]+)$|); # 拡張子 if ($fh ne "") { my $timestamp = strftime "%y%m%d%H%M%S", localtime; my $outputfn = "$outputdir/$timestamp$ex"; open(F, "> $outputfn") or die; flock(F, 2); if (defined $fh) { while (<$fh>) { print F $_; } } close F; print qq{saved as <a href="$outputfn">$outputfn</a>}; } print $q->start_multipart_form(-name => 'myform'), $q->filefield(-name => 'uploaded_file'), $q->submit("OK"), $q->endform, $q->end_html(), "\n";

  • コードの簡素化

    現在サイトを作成しておりFlashの音楽プレイヤーを設置してます。 プレイヤーは配布サイトからダウンロードしてきたものを使用しています。 クリックすると自作の音源が流れます。 Flashのソースは下記のようにしてます。 <object type="application/x-shockwave-flash" data="./sound/player.swf" id="audioplayer1" height="24" width="290"> <param name="movie" value="./sound/player.swf" /> <param name="FlashVars" value="playerID=1&amp;soundFile=./sound/sample.mp3" /> <param name="quality" value="high" /> <param name="menu" value="false" /> <param name="wmode" value="transparent" /> </object> 例えば1ページで20曲紹介する場合、上記のソースを20回貼り付けています。 違う部分は当然ファイル名のみです。 これを簡略化させたいのですが、何か方法はあるでしょうか? 以前こちらでJavascriptのソースを簡略化したかったので質問したら解決してもらえたので、この場合でも簡略化する方法があるのかな?と思いました。 ご存知の方いらっしゃいましたらご教示ください。 よろしくお願いします。

  • %stderr%の値が何をさしているのか

    Bareword "FH" not allowed while "strict subs" in use at C:/Apache Group/Apache2/cgi-bin/cgi.cgi line 1000. Perlを動かしたらこのような標準エラーが帰りました。 FHはファイルハンドルです。 はじめてみるエラーなので何を表しているのかわかりません。 該当のコードは $q = new CGI(FH); です。 open(FH,'<',$save_dir.$ID{$name}.'.dat'); $q = new CGI(FH); close FH; このようにして読み出しています。 new CGIはCGI.pmのクラス作成です。 何が問題なのでしょうか?

    • ベストアンサー
    • Perl
  • 単音のコード表記について

    http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1026965020 ↑ 上記の質問を見た上でお聞きしたいのですが ギターのTAB譜でコードを弾かないのに単音とかを弾いたりするときもコード・ネームが書いて在るのですがなぜなのですか? という問いに対して 単音でもコード表記があるのは、その単音のフレーズはその表記されているコードから出来てますという意味だからです。 とあります。しかし、 http://mimikopiscore.blog95.fc2.com/blog-entry-298.html ↑このサイトのようにコードだけかかれていてもアルペジオの単音の部分は コードしかのっていないのでどこの弦を弾いたらいいのかまったくわかりませんよね? これは自分でリズムも弾く弦も探らなければいけないということでしょうか?

  • タブページの中にframeページを作成できますでしょう?

    htmlとjavascriptについての質問です。 ページ遷移なしで表示内容を切り替えるために、タブによる表示内容の切り替えページを作成しております。 参考にしているサイトは、 ​http://nais.to/~yto/tools/css_tabs/​ です。 タブの作成までは問題なく完成しました。 しかし、切り替わる表示内容の入力で重要な問題に気づきました。 それは、frameを用いたページを切り替えようとしていたことです。 <body>の下にタブの切替があり、そして、そのタブの中に<frame>を使っていることになります。 通常、frameを使用するときはbodyを使えない(frameがbodyの代わりになる)ことになっているので、エラーが出て、frameを使った内容が表示されなくなってしまいました。 タブによるframeを使ったページを切り替える方法がありましたら、どなたかお教え頂けないでしょうか? インラインフレームの中にframeを使ったページを入れての切替はできるのですが、それだとインラインフレーム内でページ遷移してしまい都合が悪いのです。 お手数ですが、どなたかよろしくお願い致します。

  • utf8使用時のフォーム入力文字コード

    use utf8; binmode(STDIN,":encoding(shiftjis)"); をすると、入力時に内部変換がかかり、UTF-8として扱える という認識で使っていたのですが、下記のコードを実行してみると 入力した文字は普通に sjisで表示されます。 binmode(STDIN~ はどのような意味を持つのでしょうか。 http://www.lr.pi.titech.ac.jp/~abekawa/perl/perl_unicode.html http://www.hikoboshi.org/perl/doc/encode.html 他、いろいろなサイトで調べてみたのですが、いまひとつ 納得する回答を得ることができません。 //////////////////////////////////////////////////// use utf8; use open 'encoding(utf8)'; binmode(STDIN,":encoding(shiftjis)"); use CGI; print "content-type:text/html; charset=Shift_JIS \n\n"; print <<"EOM"; <form action="xxx.cgi"> <input type="text" name="hoe"> <input type="submit"> </form> ここは UTF-8文字列なので化ける<br> EOM $cgi = CGI->new; print $cgi->param('hoe'); //////////////////////////////////////////////////// 現在は下記のコードで自前で UTF-8に変換しています //////////////////////////////////////////////////// foreach( $cgi->param() ){ my $str = $cgi->param($_); $str = Encode::encode('utf-8', Encode::decode('shiftjis', $str)); $cgi->param( -name=>$_, -value=>$str ); }

    • ベストアンサー
    • Perl
  • サンプルコードを公開しているサイトについて

    今検索エンジンでサンプルコードを探しています。 多種様々なコードが掲載していて、 分り易い説明が掲載しているサイトとか。 自分はVB2008を使用していますが、種類豊富なサイトが見つかりません。 良いサイトありませんか? 数種類位教えて下さい 「私はこのサイトで様々なソースがあって便利だ」 「種類が豊富で良い」等の紹介もお願いします。 ●現在自分がブックマーク(お気に入り)に入れているサイト● @DOBON.NET プログラミング道@ ​http://dobon.net/vb/dotnet/index.html​ @これがほしかった!厳選サンプルツール集@ ​http://anetm.com/dev/tools/vbdotnet/​ @MSDN Home@ ​http://www.microsoft.com/japan/msdn/thisweek/wednesday/​ @VBレスキュー(花ちゃん)@ ​http://hanatyan.sakura.ne.jp/​

  • ファイルのアップローダーを動作させたい。

    ファイルをサーバーへ格納するプログラムを検索して作成しました。 見よう見まねなのでおかしい部分があるかもしれません。 entry.cgi #!/perl/bin/perl my $buffer; my $query = CGI->new; my $fh = $query->upload('file') or die(qq(Invalid file handle returned.)); # Get $fh my $file = $query->param('file'); my $file_name = ($file =~ /([^\\\/:]+)$/) ? $1 : 'uploaded.bin'; open(OUT, ">$file_name") or die(qq(Can't open "$file_name".)); binmode OUT; while (read($fh, $buffer, 1024)) { # Read from $fh insted of $file print OUT $buffer; } close OUT; sample.html <HTM><BODY> <FORM METHOD="POST" ENCTYPE="multipart/form-data" ACTION="./entry.cgi"> <TABLE BORDER="1"> <TR><TD ><B>CSVファイル</B></TD> <TD ><INPUT TYPE="FILE" NAME="filename"></TD></TR> <TR></TR> </TABLE> <BR> <BR> <INPUT TYPE="SUBMIT" NAME="GO" VALUE=" 登録の実行 "> </FORM> </BODY></HTML> 上記のプログラムを実行すると 「CGIWrap Error: Script Execution Failed」と表示されてしまいます。 500のサーバーエラーと同じと調べてわかったのですが、どこがどうおかしいのか?わかりません。 perlの記述が今まで自分が使用していたものと勝手が違うので分からない状態です。 アドバイスもらえると幸いです。

  • 受け取った変数がファイルに書き込めない

    Perlで質問があります。 Perlでフォームから受け取った変数の値($title = “333”)を別にCGI 投げます。Printでは問題なく変数の中身が表示されるのですが Txtに書き込もうとするとうまくいきません。 ちなみに行頭で$title = “333”;すると書き込めます。 うまく受け渡しができていないのでしょうか? 以下ソースです。 #!/usr/bin/perl -w require 'lib.pl'; #########i一応lib.plの中身######### $q = new CGI; $q->charset('EUC-JP'); print $q->header; $title = $q->param('title'); ################################## use CGI; my $fname = 'news.txt'; open(FILE, ">>$fname") or die; print FILE $title ; close(FILE);