★ 

インデックス

 ★
★ 

プログラムの説明

 ★

CGIスクリプトの配布とプログラミングの説明

 RSS XML
  • 玄関口
  • 占い診断
  • 萌え辞典
  • オタク遊戯
  • ネット小説
  • NEW秋華
  • CGIDL
  • CGI解説
--☆INFORMATION☆--
2017年6月6日【火】20時29分41秒
【(*´ω`*)】CGIの更新は現在無期限休止中です‥‥
2014年11月6日【木】13時47分00秒
【(*´ω`*)】確率収束診断スクリプト作りました!
2013年12月24日【火】17時47分50秒
【(*´∇`*)】最近ちょっとプログララマーに戻ってます♪
2013年11月4日【月】19時41分23秒
【(´・ω・`)】現在新しいCGIの作成は行っていません。
2013年1月7日【月】16時12分36秒
【(*´ω`*)】サイトをリニューアルしました。他も徐々に変更中です‥‥
--☆HOTLINK NOW☆--
【Kindle】電子書籍販売★秋華★
【楽天kobo】電子書籍販売★秋華★
【パブー】電子書籍販売★秋華★
CGI無料レンタルサーバ紹介
秋華エントランス

CGIスクリプト基本 [データ処理とデコード]

それでは次に、フォームから送られてきたデータと中身と、その処理を書きたいと思います。
フォームから送られてくるデータ、それは、名前だったり、掲示板の投稿記事だったり、全ては文字列データです。
しかし、サーチエンジンで検索した後のURLを見た事がある人ならわかると思いますが、文字そのものではなく、よくわからない文字列も交じっています。
それには訳がありまして、最初の方に書いたのですが、文字コードが関係しています。
そして、文字列には、文字として表示されない、エスケープシーケンスと呼ばれる文字では無い文字も含まれているのです。
それをいったん、全てに理解できる、目に見える文字にエンコード(変えて)して、送信して受信した後、デコード(戻す)する必要があります。
エンコードは勝手に行われますが、デコードは自分でやらなければなりません。
そのあたりをこの後に書きたいと思います。
その前に、フォームから送られてくるデータは、どのようなものかを書きます。
たとえば・・・

<form method="get" action="index.cgi">
<input type=text name="cname" size="40"><br>
<textarea name="chat" rows="14" cols="50"></textarea><br>
<input type="submit" value="送信">
</form>

このようなフォームに、名前と記事を書いて送信したとします。
分かりやすいように、とりあえずここでは文字化けしない(エンコードされない)、neko と love にしたいと思います。
受信したデータが変数 $buffer に入っているとして、その中身を見ると・・・
cname=neko&chat=love となっています。
フォームの中身と比べれば、どういう原理かはわかると思います。
1つ目の記入欄で設定した name に = をつけて、その後に記述データが書かれ、& でわけられ、再び次のデータが記述されています。
このデータで送信した行為は、以下のアドレスにアクセスしたのと同じ事になります。

http://syuka.com/index.cgi?cname=neko&chat=love

さて、受信したデータは、このまま利用できるものであれば、別にこのままでも構いません。
たとえば、受信データに、neko という文字列が含まれれば、猫ページを表示する、みたいな時です。
でもここでは、ちゃんとデータを分けて、名前と内容を、掲示板の投稿として、表示する為に必要な処理をしたいと思います。
まずはソースを書きたいと思います。

@pairs = split(/&/,$buffer);
foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$value =~ s/\n//g;
$FORM{$name} = $value;
}

とりあえず説明します。
まず1行目は、配列変数 @pairs に、$buffer を & で分けたデータを入れる作業です。
配列変数とは、今まで使ってきた、頭に $ がついている変数とは違い、複数データを入れる事が出来る変数で、頭に @ をつけます。
ここで、あくまで概念として理解して欲しい事があります。
今後データファイルに、データを複数保存していく事になります。
その時、データファイルに保存してあるデータは、1行で1つのデータと理解してください。
詳しくは今後説明しますが、私が一番手こずった事につながりますのでw
2行目は、@pairs に入れてあるデータを、$pair に1つずつ取り出し、データの数だけ後の { } このカッコ内をくり返す事を命令しています。
foreach 関数は、今後も頻繁に使われる、繰り返しを支持する関数ですので、覚えておいてください。
{ } このカッコ内1行目、全体で3行目は、$pair 内のデータを、= で分けて、$name と $value に入れる命令です。
ここでは、分けたデータが2つである事が決まっているので、こんな記述になります。
4行目は、送られてきたデータに、+ が含まれていたなら、それを半角スペースに変更する命令です。
目に見えない文字列データは、他の文字に変更されたりしていますので、それを元に戻します。
5行目は、送られてきたデータを、デコード(戻す)作業です。
この記述は、深く考える必要はありません。
この記述は決まっていますので、このまま利用できます。
6行目は、改行コードを削除する命令です。
ココが今回、一番伝えたかった事です。
私はずっとこの改行コードに悩まされてきました。
改行コードは、目に見えない文字のようなもので、Perl(CGI)では、\n であらわされます。
ブログにしても、掲示板の投稿にしても、おそらくは改行して、複数行になっていると思います。
そこには必ず、この改行コードが含まれているのです。
もしこの改行コードを削除しなければ、このデータをデータファイルに保存してとりだした時、改行ごとにデータが分けられる事になって、どこまでが本当の1つのデータだったのかわからなくなります。
だから、必ず改行コードは全て削除しておかなければならないのです。
そして保存する際に、1つのデータの最後にだけ \n をいれておく事になるのです。
しかしそれだと、複数行にわたる記事は、全て1行に表示される事になるような気がします。
ココがミソなのです。
実はウインドウズマシンは、改行コードが2つあるのです。
正確にいえば、2つで1つの改行命令だと考えてください。
ここはうろ覚えなのですが、行の先頭に戻る命令と、1行下に行く命令を合わせて、改行という事になるからなのです。
Perl の記述で書けば、\r\n です。
で、UNIXマシン(一般的なネットサーバー)では、\n だけで改行となるので、データ保存には、\n だけ削除すればいいのです。
そしてとりだしたデータの、\r を、HTMLの、 <br>に変更すれば、きちんと改行できるって寸法です。
もちろん、保存する前に、\r\n を、先に <br> に変えて保存する方法もあります。
もし今後、Perl でCGIプログラムを書き続けるなら、常にこの改行コードは意識してください。
私はこの改行コードで、何度もバグが出て、かなり悩まされましたからw
こんな事を教えてくれる人も、書籍も無かったですからねぇ~
と言うか、Perl の書籍を見ていて、CGIの書籍をあまり見ていなかったからかもしれませんが。(笑)
話が長くなりましたが、いよいよ7行目の説明です。
コレも実は、正確に話せば長くなります。
ハッシュ変数と言われる、複数のデータを入れられる変数に、整理したデータを入れる作業なのですが、配列変数との違いは、配列変数は、番号によってデータ管理される変数ですが、ハッシュ変数は、名前によってデータ管理される変数なのです。
たとえば配列変数の場合、@pairs の中の、3番目のデータを・・・のようにデータを指定します。
ハッシュ変数は、%pairs (ハッシュ変数の頭には、% がつく)の中の、cname の名前で管理されているデータを・・・のように指定します。
今回の場合は、cnameの名前で、neko を保存、chat の名前で、love を保存ってわけです。
今まで色々な関数や、色々と記述の方法などでてきていますが、細かい事は、大まかな概念の説明が終わった後に、1つずつ説明できればと思っています。
さて、これでデータを分けて、文字コードもデコードして、ハッシュ変数に保存する事ができました。
このソースは、今後も頻繁に使うので、そのまま利用できます。
この後に・・・

$cname = $FORM{'cname'};
$chat = $FORM{'chat'};

この2行を追加すれば、$cname には、"neko" が、$chat には、"love" が入っている状態になりました。
ここでひとつ、今まで文字を囲うのは、" " を使ってきましたが、ここでは ' ' を使っていますが、別に " " を使っても構いません。
違いは、" " は、文字としてでも、数字としてでも使えるデータを、' ' は、文字データを入れるものであるだけです。
さて、掲示板としての機能を完成させるには、後は今回のデータを、データファイルに追加する事、そして表示する際に、データファイルからデータを取り出し、それを表示するだけになりました。
次回それを書きたいと思います。
今回最後に、文字コードの事に少しだけ触れたいと思います。
今回文字を元に戻す作業、デコードを行いましたが、もしUTF-8 以外の文字コードを、たとえば sift-jis を使っていたなら、デコードした文字列を、sift-jis にする作業が必要になります。
それを自分で記述するとなると、どれだけの手間になるかわからないくらい面倒です。
もちろん、後2行追加しただけで、sift-jis にする方法もありますが、コンピュータの作業としては、かなりの処理になる可能性があります。
だからまあ、UTF-8 で書く事を勧めてきたわけなのです。
ちなみに違うコードのページ間で扱われたデータだったら、sift-jis に変更した後に、UTF-8 にする作業等も必要だったりして、とにかく面倒です。
そんなわけで、UTF-8 前提で、これからも話を進めますので、よろしくお願いします。
【<┃】 【┃┃】 【┃>】
このエントリーをはてなブックマークに追加
ドクダミ
Ver.5.00 CGIフリー配布サイト