• ベストアンサー

このCGIサブルーチンを解説してください。

http://oshiete1.goo.ne.jp/kotaeru.php3?q=393199 の続きのようなかんじですが…。 下記のコードがわかりません。 おわかりになるかた解説してください。 sub setCookie{ local($tmp, $val); $val = $_[1]; $val =~ s/(\W)/sprintf("%%%02X", unpack("C",$1))/eg; $tmp = "Set-Cookie:"; $tmp . = "$_[0]=$val;"; $tmp . = "expires=Thu, 1-Jan-2030 00:00:00 GMT\n"; return($tmp); } 1行目:サブルーチン名 2行目:$tmp,$valをそれぞれローカル変数に設定。 3行目:? 4行目:$valを16進数から1バイトずつ変換? 5行目:$tmpに"Set-Cookie:"を代入。 6行目:$tmp.に"$_[0]=$val;"を代入。 7行目:$tmp.に"expires=Thu, 1-Jan-2030 00:00:00 GMT\n"を代入。 8行目:? というところまではなんとか解釈したのですが、「?」の部分がわかりません。 Set-Cookieヘッダを作成しているらしいのですが…。

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

  • ベストアンサー
  • wolfwood
  • ベストアンサー率50% (199/398)
回答No.2

とりあえず?の部分だけ。 >$val = $_[1]; これはサブルーチンの引数を取得しています。 $res=&sub_test(a,b); このような文でaとbが引数となります。 この引数は@_という配列に順番に格納されます。 この配列の2番目を表すのが$_[1]です。 そのため$_[1]には二番目のbが入ります。 >$val =~ s/(\W)/sprintf("%%%02X", unpack("C",$1))/eg; これはURLエンコードですね。特殊文字や漢字(2バイト文字)を%と16進表示(2桁)に変換しています。 >return($tmp); これはサブルーチンの返り値ですね。 先の例では$resに入る値です。 正確には&sub_test(a,b)自体がこの返り値そのものになります。 print &setCookie(); と print Set-Cookie:~; は同じ意味と言うことです。 以前の質問から$_[0]はクッキー名、$_[1]はその値になると思います。 その値だけをURLエンコードしてSet-Cookieの文を作って返しているということです。 ちなみに$tmp.ではなく.=で連結するという意味です。 $tmpに.=で内容をつなげているということです。

KODAMAR
質問者

お礼

回答ありがとうございます。 #1の方の回答と併せてみて、 >$val = $_[1]; の部分はおぼろげながら自分の中でわかってきたみたいです。 >$val =~ s/(\W)/sprintf("%%%02X", unpack("C",$1))/eg; このへんはまったくわかりません。 自分で変換するために文章をかけといわれたらできません。 コピペしてる状態です。 ~s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg; というのはよくみかけるのですが…。 print &setCookie("KAISUU",$time_new); ということは、 print "Set-Cookie:KAISUU=$time_new; expire・・・;" ということでいいのでしょうか? .は続けて、ということなのですか?

その他の回答 (3)

  • wolfwood
  • ベストアンサー率50% (199/398)
回答No.4

う~ん、とりあえず見直しはされた方が良いですよ。 まず、 read(STDIN, $cookie, $ENV{'CONTENT_LENGTH'}); これは必要ありません。 これはPOST受信時の処理です。 次に $value =~ s/%[0-9A-fA-f][0-9A-fA-f])/pack("C",hex($1))/ego; これは%のあとの括弧が足りません。 正確には $value =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack("C", hex($1))/ego; です。 あと $COOKIE{$name}=$value; これは$nameではなく$keyを使っているはずですから $COOKIE{$key}=$value; となります。 ほとんどケアレスミスなのでもう少し注意深くチェックすれば直せると思います。

KODAMAR
質問者

お礼

できました!!ありがとうございます!! だいぶケアレスミスが多いですね…。 かくときに自分の意志でかいてないからでしょうか。 (人がかいたのを自分でそこそこかんがえながら書いてるところです。) ここで一度締め切ります。 またわからないことがあったら、再度質問させていただきます。 その時はよろしくお願いします。 何度もありがとうございました。

  • wolfwood
  • ベストアンサー率50% (199/398)
回答No.3

>print &setCookie("KAISUU",$time_new); >ということは、 >print "Set-Cookie:KAISUU=$time_new; expire・・・;" >ということでいいのでしょうか? そうです。 >.は続けて、ということなのですか? そうですね。 $xxx .= $yyy; $xxx .= $zzz; で $xxx = $xxx$yyy$zzz; ということです。 変数の内容を後ろに連結していくと考えてください。 >>$val =~ s/(\W)/sprintf("%%%02X", unpack("C",$1))/eg; >このへんはまったくわかりません。 私も正直言って何も見ずに作れとか解説しろと言われても出来ません。 正規表現やpack関数は難しいので少しずつ理解して行けば良いと思いますので今はコピペで構わないと思いますよ。 こちらがエンコードについて詳しいです。 http://ash.jp/perl/tips_perl01.htm あと正規表現はこちらです。 http://www.din.or.jp/~ohzaki/regex.htm >~s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg; >というのはよくみかけるのですが…。 これはURLデコードですね。 URLエンコードで暗号変換したものを復元するための記述です。 GETやPOST送信では自動的にエンコードされますが、デコードはされないので記述されることが多いのでしょう。

KODAMAR
質問者

お礼

回答ありがとうございます。 ちゃんと自分で理解というかわかっているみたいなので安心しました。 >私も正直言って何も見ずに作れとか解説しろと言われても出来ません。 >正規表現やpack関数は難しいので少しずつ理解して行けば良いと思いますので今はコピペで構わないと思いますよ。 そうなんですか。安心しました。 そのうち見ないでかけるようになることを祈ります…。 さて、下記のようにかいてみました。 ※クッキーの書き込みではなく読み込みです。 #!/usr/local/bin/perl # Cookieを読み出す。 &getCookie(); $name=$COOKIE{'KAISUU'}; print "Content-type:text/html\n\n"; print $name; sub getCookie{ local($cookie,$cookie3,$key,$value); $cookie=$ENV{'HTTP_COOKIE'}; read(STDIN, $cookie, $ENV{'CONTENT_LENGTH'}); @cookie2=split(/; /,$cookie); foreach $cookie3(@cookie2){ ($key,$value)=split(/=/,$cookie3); $value =~ s/%[0-9A-fA-f][0-9A-fA-f])/pack("C",hex($1))/eg; $COOKIE{$name}=$value; } } exit; ですが、 '*****\cookie_test.cgi' script produced no output となってしまいます。 どこがおかしいのでしょうか? おわかりになりましたらよろしくお願いします。

  • alicia-y
  • ベストアンサー率40% (85/208)
回答No.1

$cookie = setCookie("name", "ほげ"); というように呼ばれていると思いますが 3行目は $var = "ほげ"; というようになります。 $_[0] は name が入る。 8行目は作成した文字列を返しています。 結果 "Set-Cookie:name=%A4%DB%A4%B2;expires=Thu, 1-Jan-2030 00:00:00 GMT\n" が返ります。

KODAMAR
質問者

お礼

回答ありがとうございます。 &setCookie("KAISUU",$time_new); のように使用しているみたいです。 となると、 $var=$time_new; $_[0]="KAISUU"; となっているのでしょうか? $valと$tmpの[0]と[1]はそれぞれ、配列の時に使用するような意味のそれぞれの数字なのでしょうか? (うまく説明できてなくてすいません。)

KODAMAR
質問者

補足

もう一つ追加です。 $tmpの後についている.は何を意味するのでしょうか?

関連するQ&A

専門家に質問してみよう