|
Perl/CGI研究室 'PERL-LABO' TOPへ |
戻る(History.Back) |
クッキーの書き込み、読み込みを処理する関数を作成します。
クッキーは1つの文字列です。 データが1つだけのときは、そのデータを直接クッキーに書き込んでおけばいいので 処理は簡単です。でもデータが複数あるときは、どうしたらいいのでしょうか。 複数のデータを扱うのに便利なものといえば、アレです。連想配列です。 ですから、クッキーを連想配列にする、連想配列をクッキーに書き込むという 処理をする関数を作ったら便利じゃないかな、と考えました。
クッキーの書き込みは、HTTPヘッダの Set-Cookie で行います。 ですので、クッキーを書き込む関数の仕様としては、次のようなものが考えられますね。
(2) と (3) は、クッキーの設定をHTTPヘッダの Set-Cookie で行うっていうのを知っていないと クッキーの処理ができません。 せっかく関数にするんだから、できるだけ使うのが簡単なものに したいですね。(1) の場合は、「HTTPヘッダを出力するときにその関数を呼び出さなければいけない」 という条件がつきますが、中では一番楽なような気がします。ですから (1) のような関数を作りましょう。
この関数は、クッキーに書き込む内容を連想配列で受け取ります。 あと必要なデータとしては、クッキーの有効期限があります。 ですので、関数の引数は (有効期限, 連想配列) としましょう。
関数の中では、まず Set-Cookie: を出力して、
その後 キー<>データ という形で連想配列の内容を <> 区切りで出力して、
最後に有効期限文字列を出力する、というものです。
今までの知識で作ることができました。
連想配列の内容が、キー1<>データ1<>キー2<>データ2<>… という形で
クッキーに書き込まれていますので、これをばらばらにして連想配列に入れて、
その連想配列を返す関数です。これも今までの知識で作ることができました。
#!/usr/bin/perl
require 'cookie.pl';
$cookie{'key1'} = "cookie1";
$cookie{'key2'} = "cookie2";
plab::setcookie(0, %cookie);
print "Content-type: text/html\n";
print "\n";
print "書き込みました。";
#!/usr/bin/perl
require 'cookie.pl';
%cookie = plab::getcookie();
print "Content-type: text/html\n";
print "\n";
foreach (keys(%cookie)) {
print "$_ = $cookie{$_}<br>";
}
package plab;
# クッキーの書き込み
# 引数 (有効期限, 連想配列)
# 有効期限は経過時間で与えます。0のときは有効期限設定無しになります。
# HTTPヘッダを出力するのでHTTPヘッダ出力の最初などに呼びます。
# <> を含むデータを書き込むとおかしなことになります。
sub setcookie
{
local($n, $i);
local $expire_delta_hour;
local($expires, @t, @m, @w);
$n = @_;
$expire_delta_hour = $_[0];
# 有効期限文字列の作成
if ($expire_delta_hour != 0) {
@t = gmtime(time() + $expire_delta_hour*60*60);
@m = ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
@w = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat');
$expires = sprintf(" expires=%s, %02d-%s-%04d %02d:%02d:%02d GMT;",
$w[$t[6]], $t[3], $m[$t[4]], $t[5]+1900, $t[2], $t[1], $t[0]);
}
# クッキーを出力します
# キー<>データ<>キー<>データ… という形になります
print "Set-Cookie: ";
for ($i = 1; $i < $n; ++$i) {
print "$_[$i]";
if ($i != $n - 1) {
print "<>";
}
}
print ";$expires\n";
}
# クッキーの読み込み
# 連想配列を返します
sub getcookie
{
local $cookie;
local %cookies;
local @data;
local($n, $i);
$cookie = $ENV{"HTTP_COOKIE"};
@data = split('<>', $cookie);
$n = @data;
for ($i = 0; $i < $n; $i += 2) {
$cookies{$data[$i]} = $data[$i + 1];
}
return %cookies;
}
1;
無事、動きました。 これで、クッキーを使って複数のデータを処理したいときなんかに楽ができそうですね。
例えば、前回の訪問日時と訪問回数をクッキーを使って処理するとしましょう。 その場合は、連想配列を使って、次のようにアクセスすることでこれらを 簡単に扱えるようになります。
%cookie = plab::getcookie();
$cookie{'前回の訪問日時'}、$cookie{'訪問回数'}を使ってなんか処理する
plab::setcookie(〜, %cookie);
なかなかよさげじゃないですか? 今までもそうでしたが、こうやって関数にすると、クッキーの処理の仕方の細かいこととか 忘れちゃっても平気っていうのが嬉しいですね。
なお、setcookie 関数の第一引数に 0 を指定した場合は、
有効期限を設定しなかったのと同じになります。つまり
有効期限はブラウザを閉じるまでになります。
あと、データの区切りに <> を使っているため、データの中に <> があるとおかしなことに
なってしまいます。その辺はご愛嬌…
これでクッキーの研究も一段落でしょうか。 クッキーに関してはまだ研究していないものもありますが、 今回の研究でなかなか実用的な関数の作成ができたと思います。
|
Perl/CGI研究室 'PERL-LABO' TOPへ |
戻る(History.Back) |
| Copyright (c) 'PERL-LABO' All Rights Reserved. リンクフリーです。 |