[WebP Vol.026] Q&A式 CGI入門:アクセスカウンターを作ろう!~今回は画像を表示するぜよ~

■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
【 Webプログラミング Code Sample 】                          Since2001/11/23

           Code026: Q&A式 CGI入門:アクセスカウンターを作ろう!
                       〜今回は画像を表示するぜよ〜

■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
                                                    Produced by ichikoro.com

           ▼毎週月曜日と金曜日に配信しています。
           ▼等幅フォントでご覧いただくとキレイに見えます。
           ▼登録・解除はこちらから可能です。
               < http://www.ichikoro.com/webp/ >
                  ※バックナンバーへのリンクもあります。
                  ※お友達にもぜひお勧めください(^^)/


─【Contents】───────────────────────────────
    01.Answer ............... 前回の回答
    02.Tips ................. Q&A式 CGI入門(Perl編)
    03.News ................. ネット業界の一週間
    04.From Editor .......... 編集後記


                   【 Webプログラミングは毎週2本立て! 】

             ・月曜日版はWebの実際の活用方法などを特集します。
             ・金曜日版はHTMLやCGIなど一つの分野について最初から
              解説する講座になっています。現在はC言語入門です。


こんにちは、編集者の勝部です。

日曜日は久々に新宿へお買い物に出かけてました。ついでに会社で頼まれたMac版の
ノートン先生を買い、そのままMac売り場を堪能してました。目当てはもちろんアイ
ツです。

    コイツ↓
    http://www.apple.co.jp/imac/index.html

もう写真を見てからという物、ずっと根っこの丸いところが触りたくてしょうがなか
ったのです。ふう〜、満足、満足(#^.^#) もっとナメラカさを期待していたのですが、
ちょっとプスチックっぽさが目立ちますな。

実はMacOSXをじっくりといじくり回したのは今日が初めてだったりするのですが、こ
れスゴイですね!WindowsXPなんて目じゃないんですよ、もうホントに。ちょっと感動
です。昔イメージしてた「コンピューター」ってきっとこんな感じだったんだろうなぁ
というのが見事に実現されている感じです。うぐぅー、ほしいぞー。

そうそう、Suicaも体験してみました。関東圏の人はご存知だと思いますが、「たっち・
あんど・ごー!」のあれです。改札の後ろ側で観察していると(←さぞや怪しかったろう)
結構使ってる人いるんですよね。負けてられるかと速攻で購入(イオカード版)、ドキドキ
しながら改札をくぐりました。おお、開くじゃないか、おお、通れるじゃないか。むひょ
ほーって感じです。楽しいぞ〜。

    ・Suica
      http://www.jreast.co.jp/suica/


ご満悦な一日でございました。
ではでは、今週も行ってみましょう!

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  01.Answer  「前回の回答」
──────────────────────────────────────

金曜日版で出題した問題の回答例です。


    Q. 次に示す実行結果になるよう、以下のコードを修正しなさい。

        ■コード

            #include<stdio.h>

            int main(void)
            {
                int i = 1230123;

                /*一番下の桁を一個ずつ取り払っていく*/
                while( i / 10 ){
                    printf("i = %d\n", i);

                    i = i / 10;
                }

                /*ループが終了した時の条件を見てみる*/
                printf("----------------\n");
                printf("i = %d\n", i);
                printf("i/10 = %d\n", i/10);

                return(0);
            }

        ■実行結果
            C:\>bcc32 loop.c
            Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
            loop.c:
            Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland

            C:\>loop
            i = 123012
            i = 12301
            i = 1230
            i = 123
            i = 12
            i = 1
            ----------------
            i = 1
            i/10 = 0


    A. 簡単すぎたでしょうか?
       さぁ、どこか違うでしょう(^-^)

            #include<stdio.h>

            int main(void)
            {
                int i = 1230123;

                /*一番下の桁を一個ずつ取り払っていく*/
                while( i / 10 ){
                    i = i / 10;
                    printf("i = %d\n", i);
                }

                /*ループが終了した時の条件を見てみる*/
                printf("----------------\n");
                printf("i = %d\n", i);
                printf("i/10 = %d\n", i/10);

                return(0);
            }


よく、これが原因のバグで悩んでる人見かけます(^^;


━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  02.Tips  「ちょっとがんばれば分かる FAQ式CGI入門 Perl編」
──────────────────────────────────────

前回から始まったアクセスカウンター。
今回は画像を使った物になるよう、がんばろう!

■前回のプログラム

        #!/usr/bin/perl

        #-------------------------------------#
        #           前回の値を取得            #
        #-------------------------------------#
        open(DAT, "count_value.dat");
        $count = <DAT>;
        close(DAT);

        #-------------------------------------#
        #        前回の値に+1して保存         #
        #-------------------------------------#
        $count = $count + 1;                #取得した値に+1する
        open(DAT, ">count_value.dat");
        print DAT $count;
        close(DAT);

        #-------------------------------------#
        #              値を表示               #
        #-------------------------------------#
        print "Content-type: text/html\n\n";
        print "<H2>$count</H2>\n";

        exit(0);


    これを見て分からないところがある場合は、もう一度前回のメルマガを
    見直しましょう。

        ・Code24
          http://ichikoro.com/webp/back_list/?cd=00024


■画像を表示するには?

    [Q]. そもそもCGIから画像を表示させるにはどうしたらいいんですか?
    [A]. まずはimage.gifという名前の画像ファイルを用意し、下記のプログラム
         を実行してください。
          ※直接ブラウザから訪れてください。

        #!/usr/bin/perl

        #-------------------------------------#
        #        画像ファイルから情報取得     #
        #-------------------------------------#
        open(IMG, "image.gif");
        @buff = <IMG>;
        close(IMG);

        #-------------------------------------#
        #              GIFを表示              #
        #-------------------------------------#
        print "Content-type: image/gif\n\n";
        foreach $i (@buff){
            print $i;
        }

        exit(0);


    [Q]. ちなみにこれはIMGタグから呼び出せたりするんですか?
    [A]. もちろんできます!
         このCGIを適当なHTMLから呼び出してみてください。

            <IMG src="preview_image.cgi" alt="画像をそのまま表示します">


    [Q]. IMGタグは画像だけだと聞いたことがありますが、CGIを指定できるのですか?
    [A]. CGIから渡される情報が画像であれば問題ありません。
         ブラウザにとっては、CGIだろうが画像だろうが関係ないのです。

         ブラウザが一番気にしているのは

            Content-type: image/gif

         この部分なのです。


    [Q]. でも画像ファイルやHTMLには、どこにもこんなこと書いてないですよ?
    [A]. あらかじめWebサーバに登録されている拡張子がついているファイル場合、サ
         ーバが自動的に、この情報を付加してブラウザに送っているのです。


    [Q]. つまり、「何とか.gif」だったら

            Content-type: image/gif

         何てのが前もってブラウザに伝わっているということですか?

    [A]. その通りです。
         サーバが自動的に「これはGIFのファイルです」ということを伝えているのです。


    [Q]. 設定次第では「何とか.gifの場合はJPEGだぞ」という事も出来るんですか?
    [A]. できます(^^;


    [Q]. じゃぁじゃぁ何でCGIの時はこの情報を、意図的につける必要があるんですか?
    [A]. CGIからは、どんな情報が出てくるか分からないからです。
         掲示板(BBS)の場合、HTMLがブラウザに渡されますが、前述の様に画像を渡す
         場合もあります。場合によってはEXCELのデータを渡すこともできます。


■プログラムを理解しよう!

    [Q]. 今回も順番に説明してください。まずはこいつ

>        #-------------------------------------#
>        #        画像ファイルから情報取得     #
>        #-------------------------------------#
>        open(IMG, "image.gif");
>        @buff = <IMG>;
>        close(IMG);

    [A]. 一行ずついきましょう。
         これは前回説明しましたよね。

>        open(IMG, "image.gif");

        ファイル“image.gif”を開いています。
        これ以降IMGという名前(ファイルハンドル)で操作できるようになります。


    [Q]. 次の行は前回と微妙に違いませんか??

>        @buff = <IMG>;

    [A]. スルドイ!
         まずは前回のものを見てみましょう。

>        $count = <DAT>;

         これはファイルから「一行」取得し、変数$countに格納すると言うものでした。
         Perlでは変数を表す際には、変数名の前に“$(ダラー)”を書かないといけません。

         ところが今回の物は先頭に“@(アッとマーク)”がくっついています。
         難しいことは後から説明しますが、これはファイルから「全ての行」を取得し、
         配列@buffに格納すると言う意味です。


    [Q]. 変数と配列ってどう違うんですか?
    [A]. 変数をたくさん集めた物が配列だと思ってください。


    [Q]. うーん、変数よりも便利な点って何ですか?
    [A]. 例えば、5行の情報が記録されているファイルがあるとします。
         これを配列を使う場合と使わない場合でどう違うか見てみましょう。

            #-- 変数バージョン --#
            open(DAT, "sample.txt");
            $buff1 = <DAT>;    #一行目
            $buff2 = <DAT>;    #二行目
            $buff3 = <DAT>;    #三行目
            $buff4 = <DAT>;    #四行目
            $buff5 = <DAT>;    #五行目
            close(DAT);

            #-- 配列バージョン --#
            open(DAT, "sample.txt");
            @buff = <DAT>;
            close(DAT);


    [Q]. おー!短い!!
    [A]. しかも一行ごとに別の変数を用意して、その中に情報を入れる何てことを
         しなくてすむのです。


    [Q]. ところで、それぞれの行の情報を見たい時ってどうすればいいんですか?
    [A]. これも変数と配列の両方を見てみましょう。

            #-- 変数バージョン --#
            open(DAT, "sample.txt");
            $buff1 = <DAT>;    #一行目
            $buff2 = <DAT>;    #二行目
            $buff3 = <DAT>;    #三行目
            $buff4 = <DAT>;    #四行目
            $buff5 = <DAT>;    #五行目
            close(DAT);


            #-- 配列バージョン --#
            open(DAT, "sample.txt");
            @buff = <DAT>;
            close(DAT);


            #-- それぞれ三行目を表示してみる --#
            print "$buff3\n";                #こっちは変数バージョン
            print "$buff[2]\n";              #こっちは配列バージョン


    [Q]. 表示する時は変数みたいなのですね??
    [A]. そうです!

             $配列名[順番]

         という感じです。


    [Q]. ん?三行目を表示とあるのに、順番が2となってますよ??
    [A]. 順番は 0 から始まるのです。
         ここ、最初のうちは大変間違いやすいので注意ですよ!


    [Q]. 最後も前回出てきましたよね!

>        close(IMG);

    [A]. その通り。ここではファイルを閉じています。
         ようの無くなったファイルはキチンと閉じましょうね。


■ここまでは大丈夫?

    ここまでは大丈夫でしょうか?
    ちょっと自信がない場合はもう一度上の文章を読んでくださいね。

>        #-------------------------------------#
>        #        画像ファイルから情報取得     #
>        #-------------------------------------#
>        open(IMG, "image.gif");
>        @buff = <IMG>;
>        close(IMG);

    バッチリだったら次へ行きましょう!


■画像を表示だ!

    [Q]. 次はコイツですね!

>        #-------------------------------------#
>        #              GIFを表示              #
>        #-------------------------------------#
>        print "Content-type: image/gif\n\n";
>        foreach $i (@buff){
>            print $i;
>        }

    [A]. ここでも順番に見ていきましょう。


    [Q]. お、これはブラウザにこれから送る情報を教えてるんですね!

>        print "Content-type: image/gif\n\n";

    [A]. 素晴らしい(*^^)//。・:*:・°'★,。・:*:♪・°'☆ パチパチ
         今回のメルマガの冒頭で出てきたとおり、一番最初にどんな情報をこれから
         送るのか、ブラウザ君に教えてあげないといけません。


    [Q]. うーん、次は何ですか??

>        foreach $i (@buff){
>            print $i;
>        }

    [A]. これは、順番にどういう処理をしているのか追って見ましょう。
         まず、@buffの中には画像の情報が入っています。これは何行になっている
         か分かりませんが、以下のようにたくさんの行がつまっていることと思いま
         す。

                $buff[0]
                $buff[1]
                $buff[2]
                $buff[3]
                $buff[4]
                    :
                    :
                    :
                $buff[n-1]
                $buff[n]

         foreachはこの配列の行分、括弧('{')から括弧('}')の間のプログラムを実行しま
         す。その際に、配列の値が順番に 変数$i へと格納されます。


    [Q]. いまいちピンと来ないんですけど(ーー;)
    [A]. じゃぁ、下のCGIを実行してみてください。

            #!/usr/bin/perl

            #-------------------------------------#
            #           配列に値をこめる          #
            #-------------------------------------#
            $a[0] = "abcd";
            $a[1] = "efgh";
            $a[2] = "ijkl";
            $a[3] = "mnop";
            $a[4] = "qrstu";

            #-------------------------------------#
            #         配列の値を順番に表示        #
            #-------------------------------------#
            print "Content-type: text/html\n\n";
            foreach $i (@a){
                print "$i<BR>";
            }


■ここまでは大丈夫?
    今回の内容はバッチシでしょうか?

        #!/usr/bin/perl

        #-------------------------------------#
        #        画像ファイルから情報取得     #
        #-------------------------------------#
        open(IMG, "image.gif");
        @buff = <IMG>;
        close(IMG);

        #-------------------------------------#
        #              GIFを表示              #
        #-------------------------------------#
        print "Content-type: image/gif\n\n";
        foreach $i (@buff){
            print $i;
        }

        exit(0);

    日本語で言うなら下のような感じです。

        (1)ファイルを開く
        (2)配列@buffに、ファイルの情報を全て詰め込む
        (3)ファイルを閉じる

        (4)ブラウザにこれからGIFを送ると教える
        (5)配列@buffの情報を、順番にブラウザに送る


■さぁお次は?

    [Q]. で、これをカウンターにするにはどうしたらいいんですか?
    [A]. 次のようなプログラムを作ればいいのです。

        (1)前回のカウント値のつまったファイルを開く
        (2)変数$countに、ファイルの情報を詰め込む
        (3)ファイルを閉じる

        (4)変数$count にあった画像を作成し、画像の内容を変数$count_imageに格納

        (5)ブラウザにこれからGIFを送ると教える
        (6)変数$count_imageをブラウザに送る


    [Q]. 何気なーく書いてありますが、(4)ってどうやるんですか??
    [A]. おっと時間だ(ヘリの音)。というわけでさらばだQ君!

    [Q]. ちょっと待てーい!今日はカウンターまで行くんじゃなかったのかーー!
    [A]. お願いします、眠いので勘弁してください(現在3月25日AM04:11)

    [Q]. オホホホ( ^^)/~~~~~~~~~νピシッ!
    [A]. イ、イヤー.....(以下エコー&フェードアウト)


さてさて、すでに[Q].が生き物みたいに動いているので、次回はシュチュエーション
コメディー風にお届けしようかなぁと画策中だったりするとかしないとか(笑)

そういえば何気に探偵学園Qって面白いですな。金田一君よりいいね(現実逃避)
http://www.shonenmagazine.com/tantei-q/



---【PR】-------------------------------------------------------------------
                CGIで困った、腕を上げたいならまずはココ
                  『CGIプログラミングメーリングリスト』

                   < http://www.ichikoro.com/cgi/ml/ >
                                                    Produced by ichikoro.com
-------------------------------------------------------------------【PR】---

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  03.News  「今週の気になるニュース
                インターネット業界の一週間」
──────────────────────────────────────

いよいよ.NETが発売されましたね! ←詳しくは来週。
そうそう、20日には「おさかな天国」のCDが発売されたみたいですね。スーパーに行
くとこの曲が流れまくってるんですよね。もう、聞き飽きました(笑)


───────
  3月18日(月)
───────

・進むネット広告のテレビCM化
  http://www.zdnet.co.jp/news/0203/18/e_eyewonder.html
    「バナー広告を越えるWeb広告を求める顧客の需要に対するわれわれの答えは,
     リッチメディアとストリーミング技術のエレメントに尽きる」

    とありますが、それにいたるプロセスがもっと大事です。例えばカーセンサーや
    住宅情報など、お金を出してまで広告を買う場合もあれば、専用ソフトを入れて
    までバナーを出したくないという場合もあります。同じ「広告」なんですけどね。
    気がついていないフリはそろそろ通用しなくなります。

・品切れ続出の新型iMac,ネットなら見つかるかも?
  http://www.zdnet.co.jp/news/0203/18/e_imac.html
    アメリカでは売れている模様です。

・地域情報提供、根強い地域クーポン誌
  http://japan.internet.com/research/20020318/1.html

・家庭からの電子納税、前年度比40%近い伸び
  http://japan.internet.com/public/news/20020318/19.html
    日本も早く対応してほしいですね。

・“宗男効果”で国会インターネット中継のアクセスが急増〜衆議院調査
  http://www.watch.impress.co.jp/internet/www/article/2002/0318/muneo.htm
    “宗男”騒ぎで、本命の構造改革の話がウヤムヤになってるような気がするので
    すが(^^; どうなってるんだ?>自民党


───────
  3月19日(火)
───────
・「時間や場所を選ばないが、強制力は今いち」 〜eラーニングに関する意識調査で〜
  http://www.watch.impress.co.jp/internet/www/article/2002/0319/gart.htm
    ネットだけで全てを完結させようとするから無理が生じるんじゃないでしょうか?
    (というのはこれまで散々語り尽くされてきたような気がしますが(^^; リアルな世
    界をメインに、ネットはその補完といった立ち位置が自然のような気がします。

・コンテンツ有料化、険しい前途
  http://japan.internet.com/wmnews/20020319/10.html
    なんでWebに金出したくないか考えて見ると、その一つに「無形」であることが
    上げれると思います。ストリーミングの画像には手で触れることは出来ないです
    よね。つまりこの様に無形の物にお金を出す習慣が、まだ世界の人々に定着して
    いないからじゃないでしょうかと思います。これも世代を超えていけば、次第に
    価値観が違ってくるのでしょうが.....。

・Yahoo! 次なる有料サービスはコンテンツストリーミングか
  http://www.zdnet.co.jp/news/0203/19/e_yahoo.html

・NTTドコモ、4G携帯電話の実験装置試作を開始
  http://www.hotwired.co.jp/news/news/technology/story/20020319303.html
    FOMAの、さらに次のお話です。

・岡山市、 掲示板への有害情報書き込み禁止条例を制定
  http://japan.internet.com/public/news/20020319/5.html

・ソニー、小型2足歩行エンターテインメントロボット
  『SDR-4X』を開発——今度は歌って踊れます
  http://ascii24.com/news/i/hard/article/2002/03/19/634534-000.html


───────
  3月20日(水)
───────

・AII、Web上で大学の正規単位が取得できる共同授業を開講
  http://www.watch.impress.co.jp/internet/www/article/2002/0320/aii.htm

・iモード,米国上陸
  http://www.zdnet.co.jp/news/0203/20/e_imode.html
    さぁ、ついに来ましたね。
    お手並み拝見です。

・大阪府警、写メール等による目撃画像の受付を4月から開始
  http://japan.internet.com/public/news/20020320/3.html

・ヤフーがPS2向けBBサービスのプロモサイトを開設
  http://cnet.sphere.ne.jp/Broadband/News/2002/Item/020320-3j.html


───────
  3月21日(木)
───────

※祝日のためお休みです。


───────
  3月22日(金)
───────

・揺れるICANN〜「ICANNの役割は終わった」のか?
  http://www.watch.impress.co.jp/internet/www/article/2002/0322/icann.htm

・米「Yahoo!Mail」でPOP3、転送サービスを4月末から有料化
  http://www.watch.impress.co.jp/internet/www/article/2002/0322/yahoo.htm

・BluetoothがIEEE標準規格「802.15.1」として採択される
  http://www.watch.impress.co.jp/internet/www/article/2002/0322/ieee.htm

・Symantec、未知の新ウィルスを検知する技術で米国特許を取得
  http://www.watch.impress.co.jp/internet/www/article/2002/0322/symantec.htm

・プログラマーがミロシェビッチ前大統領の戦争犯罪を暴く
  http://www.hotwired.co.jp/news/news/culture/story/20020322206.html


━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
                           編    集    後    記
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

眠いっす(__)。。ooOZZZZ
ただいまAM5:10でござます。宇宙人なことを書いていたらごめんなさい(^^;



高校の頃に演劇やってたんですが、先日同じ職場に舞台歴のある子を発見!これが意
外にいるのですよ、うちの会社。社内誌の編集者さんもやったことあるって言ってた
し。まだまだ同じニオイのする人が隠れてそうな気配がします(^^;

そうそう、今歌舞伎に夢中らしく今度つれてってもらえることになりました。
未体験ゾーンなだけに楽しみです。はまりそうで怖いなぁ(^^ゞ
詳しくはコチラでリポート予定。お楽しみに。


後、制覇してないのは劇団四季と宝塚ですね。四季はともかく、さすがに宝塚に男一人
では入りづらいなぁ。かといって男が徒党を組んでいくのも当事者にはなりたくないっ
て感じ?(笑)


ではでは、そんな感じで(どんな感じや)次回は金曜日にお会いしましょう(^.^)/~~~


■Information
 「Webプログラミングからのお知らせ」

    【相互広告募集のお知らせ】
      読者数を増やしたいメルマガ発行者さんを募集しています。お互いに一定期間(1〜
      3回程度)広告を掲載し合いませんか?詳細はご相談ください(無料)

         お問い合わせ: mm-webp@ichikoro.com

    【コラム募集のお知らせ】
      Webプログラミングでは、寄稿していただけるコラムやプログラムなどを募集して
      います。たくさんの読者の方にあなたをアピールする場にもなります。ぜひ有意義
      な情報やご意見をお送りください。

         お問い合わせ: mm-webp@ichikoro.com



■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■

                   【 Webプログラミング Code Sample 】

                    発  行 : ichikoro.com
                発行責任者 : 勝部 麻季人
                              < katsube@ichikoro.com >
                  発行部数 : 1848部(前回)
                 Webサイト : < http://www.ichikoro.com/webp/ >
            お問い合わせ先 : < mm-webp@ichikoro.com >

                            Powerd by まぐまぐ
    All Right Reserved, CopyRight(C) 2001 Webプログラミング Code Sample
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■