プロが教えるわが家の防犯対策術!

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ヘッダを作成しているらしいのですが…。

A 回答 (4件)

とりあえず?の部分だけ。


>$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に.=で内容をつなげているということです。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

#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・・・;"
ということでいいのでしょうか?

.は続けて、ということなのですか?

お礼日時:2002/11/01 16:20

う~ん、とりあえず見直しはされた方が良いですよ。


まず、
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;
となります。
ほとんどケアレスミスなのでもう少し注意深くチェックすれば直せると思います。
    • good
    • 0
この回答へのお礼

できました!!ありがとうございます!!

だいぶケアレスミスが多いですね…。
かくときに自分の意志でかいてないからでしょうか。
(人がかいたのを自分でそこそこかんがえながら書いてるところです。)

ここで一度締め切ります。
またわからないことがあったら、再度質問させていただきます。
その時はよろしくお願いします。

何度もありがとうございました。

お礼日時:2002/11/01 17:45

>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送信では自動的にエンコードされますが、デコードはされないので記述されることが多いのでしょう。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

ちゃんと自分で理解というかわかっているみたいなので安心しました。

>私も正直言って何も見ずに作れとか解説しろと言われても出来ません。
>正規表現や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
となってしまいます。

どこがおかしいのでしょうか?
おわかりになりましたらよろしくお願いします。

お礼日時:2002/11/01 17:03

$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"
が返ります。

この回答への補足

もう一つ追加です。

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

補足日時:2002/11/01 15:53
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

&setCookie("KAISUU",$time_new);
のように使用しているみたいです。
となると、

$var=$time_new;
$_[0]="KAISUU";

となっているのでしょうか?


$valと$tmpの[0]と[1]はそれぞれ、配列の時に使用するような意味のそれぞれの数字なのでしょうか?
(うまく説明できてなくてすいません。)

お礼日時:2002/11/01 15:51

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!