次のページ 前のページ 目次へ

Perl CGI HOWTO

Yoshio Shimamura <yoshios@green.ocn.ne.jp>

v1.0, 14 Aug. 2000
この文書は、PerlによるCGI作成のTips集です。 この文書の最新版は http://hp.vector.co.jp/authors/VA004572/index.html から入手可能です。

1 ライブラリを取り込む

2 メソッドを判別し文字列として格納する

3 送信された値の出コード

4 サブルーチンの定義

5 ヒアドキュメント

6 ロックファイル

7 汎用サブルーチン集


1 ライブラリを取り込む

良く使われるjcode.plなどのライブラリを取り込むには、次のようにする。
require 'jcode.pl';

2 メソッドを判別し文字列として格納する

次の例は、標準入力から受け取るべきPOSTと、環境変数として送られるGETの場合を識別し、適切な方法で$strに送信されたデータを格納している。
# post or get
if ($ENV{'REQUEST_METHOD'} eq "POST") {
    read(STDIN, $str, $ENV{'CONTENT_LENGTH'});
} else {
    $str = $ENV{'QUERY_STRING'};
}

3 送信された値のデコード

送信されたデータは、&によって連結されて送られるので、プログラム内で個々に用いる場合には、それを分解する必要がある。 次の例は、文字列を分解し、コード変換、HTMLタグの変換、プラットホームの改行コード差異の吸収などを行う汎用的なデコードルーチンである。 結果は、連想配列%dataに格納され、個々の値を取り出すには、$data{'key'}とすれば良い。 例では、個々の値をカンマで区切ってファイルに追加書き出しの処理を行っている。
# common CGI send data decode routine
@part = split('&', $str);
foreach $i (@part) {
    ($variable, $value) = split('=', $i);
    $value =~ tr/+/ /;
    $value =~ s/%([0-9a-fA-F][0-9a-fA-F])/pack("C", hex($1))/eg;
    &jcode'convert(*value, 'euc');
    $value =~ s//>/g;
    $value =~ s/\r\n/\n/g;
    $value =~ s/\r/\n/g;
    $data{$variable} = $value;
}

# write data to file
open(OUTFILE, ">>$outfile") || die "cannot write $outfile";
print OUTFILE "$data{'header'},$data{'key'},$data{'contents'}\n";
close(OUTFILE);

4 サブルーチンの定義

4.1 基本事項

サブルーチンは、次のように書く。
sub name-of-subroutine {
    サブルーチン内処理;
}
サブルーチンの呼び出しは、&を付けて次のように行う。
&name-of-subroutine;
ローカル変数はキーワードlocalを付けて次のように定義する。
sub name-of-subroutine {
    local $local-data;
    サブルーチン内処理;
}

4.2 値の引渡し

サブルーチンに値を引き渡すには、次のようにする。
# call
&name-of-subroutine($data1, $data2, $data3);

sub name-of-subroutine {
    local($arg1, $arg2, $arg3) = @_;
    print $arg1, $arg2, $arg3, "\n";
}

4.3 返値

サブルーチンからの戻値は、returnを用いて次のように書く。
sub sort_lines_of_file {
    local($file) = @_;
    open(DATA, "$file") || die "cannot open $file";

    $i = 0;
    while ($line = ) {
        $array[$i] = $line;
        $i++;
    }

    close(DATA);
    return (@array);
}

5 ヒアドキュメント

print関数によりEOFまでを標準出力に送り出す。

HTMLヘッダーを送出するサブルーチンの例

# send html header
sub send_html_header {
    print <<EOF;
Content-type: text/html

<html>
<head>
<title>Links</title>
</head>
<body>
EOF
}

6 ロックファイル

非同期によるファイル書き込み処理では、同時書き込みによるファイルの破損を防ぐための機構を組み込む必要がある。 厳密には、完全ではないが、その一つの手法としてロックファイルというものを用いるものがある。

ロックファイル作成、解除用サブルーチンの例

# directory access mode must be 777
$lock ="lock/lock";

# lock on
sub lock_on {
    $wait = 0;
    while (-f "$lock") {
        if ($wait++ >= 30) {
            unlink($lock);
            exit(0);
        }
        sleep(1);
    }
    open(LOCK, ">$lock");
    close(LOCK);
}

# lock off
sub lock_off {
    unlink("$lock");
}

7 汎用サブルーチン集

7.1 指定したファイルに配列に格納された値を一行づつ書き出す

# call
&write_lines_to_file($datafile, @data);

# write lines
sub write_lines_to_file {
    local($file, @array) = @_;
    open(DATA, ">$file") || die "cannot open $file";
    $i = 0;
    while ($array[$i]) {
        print DATA $array[$i];
        $i++;
    }
    close(DATA);
}

7.2 ファイルの行を要素とする配列を返す

呼び出し元では、受け取った配列のソートまで行っている。
# call
@data = &get_array_of_file($datafile);
@new = sort(@data);

# get array of lines in the file
sub get_array_of_file {
    local($file) = @_;
    open(DATA, "$file") || die "cannot open $file";

    $i = 0;
    while ($line = ) {
        $array[$i] = $line;
        $i++;
    }

    close(DATA);
    return (@array);
}

次のページ 前のページ 目次へ