Perl/ActivePerl For UNIX/Linux/Windows
 
TryThe Homepage
初めてのCGI
CGI 研究室
ダイナミックCGI
ダウンロード
サービス
サーバ構築(Windows)
データベースアクセス
有料サービス
FAQ
お問い合わせ
このページを印刷
Perl マニュアル
  第0章  基礎の基礎
  1. CGIに何をさせるのか
    どうしてCGIを使う必要があるのか?JavaScriptや、VBscriptでは絶対に出来ないことだからです。 また、JavaScriptや、VBscriptで出来ることはCGIでさせるべきではないのです。 むやみやたらにCGIを使用するとそれだけサーバーの負担が大きくなり、パフォーマンスが低下します。 インターネットを楽しむ数百、数千万のユーザーに迷惑をかけることになります。 それでは、どのようなことをさせるのか、答えは簡単です。 JavaScriptや、VBscriptでは絶対に出来ないことは、ファイル処理だけだからです。 あるCGIを学習するサイトで、時刻による挨拶文の変更をCGIで作成して公開しているサイトが有りましたが、 挨拶文はJavaScriptで十分事足ります。
    どうしてJavaScriptや、VBscriptでファイル処理が行なえないのでしょう。 CGIは、サーバーで動作し、ファイルもサーバーのハードディスクを使用しますが、 JavaScriptや、VBscriptはダウンロードしたブラウザで動作しています。 このブラウザでファイルを操作しようとすると、ダウンロードした一般のユーザーのハードディスクを使用することになり、 大変危険だからです。万が一不貞なやからが進入し、ユーザーのハードディスクを破壊することも簡単に行なえるようになります。 また、インターネットにアップロードするファイルは、個人のハードディスクにデータを貯えても何の意味も有りません。

  2. Perlのヘッダー
    当サイトで紹介するCGIスクリプトは、すべてPerl言語で書かれています。 CGIは、他にShellや、C言語でも作成できますが、Perlは、コンパイルする必要もなく、手軽で、今一番多く使用されています。 Perlで作成するスクリプトの先頭行には、必ずPerlが実行できるサーバーのパスを入力しなければなりません。

    #!/usr/local/bin/perl

    ほとんどのサーバーはこの記述で大丈夫だそうです。
    ちなみに、私の加入しているBIGLOBE、#!/usr/local/bin/perl
    高知県で一番多くの会員を持つinforyomaでも、#!/usr/local/bin/perlです。

    この時一行目の「#」は、コメント行とはみなされません。削除しないでください。

  3. 基本的な型
    CGIの計算結果のそのほとんどは、HTMLドキュメントとして返すか、GIF画像を返すか、何も返さないが、ファイルに記録するかです。 GIF画像を返すスクリプトの代表的なものがグラフィックアクセスカウンターです。 それ以外のほとんどのスクリプトは、ファイル操作をし、HTMLドキュメントを生成しています。

    HTMLドキュメント生成を宣言するヘッダー
    print "Content-type:text/html\n\n";
    このヘッダーより下に通常のHTMLタグでドキュメントを生成します。
    print "<html><head><title>サンプル</title></head>\n";
    print "<body>\n";
    print "<hr>\n";
    print "<font size=5>ようこそ私のホームページへ</font>\n";
    print "<hr>\n";
    print "</body>\n";
    print "</html>\n";

  4. perlの文法や特徴
    • 1行目以外の#で始まる行はコメントで実行されません。行の途中で「#」を使用すると、 それ以降がコメントになります。
    • 実行文の最後には、必ず「;」を置きます。
    • 変数は、いつでも、何処からでも使用する事ができます。 他の多くの言語のように、前もって使用する変数名を宣言しておく必要もなければ、エラーも発生しません。
    • 変数には、「数値」、「文字」どちらでも代入できます。
    • 処理の固まり(ブロック)は、「{」と「}」で囲みます。
    • 大文字小文字を判別します。あなたが使用しているWindowsや、 マックOSでは、大文字、小文字を判別しないと思いますが、UNIXでは、別物なのです。
  第1章  基礎講座
  1. エスケープシーケンス
    \n 改行
    \r リターン
    \t タブ
    \' シングルクォート
    \" ダブルクォート

  2. 引用符
    引用符には、" と ' の2種類があり、
    「"」は、可変定数で、引用符内で変数展開を行う事ができ、
    「'」は、固定定数で、引用符内で変数展開ができません。

    $color = "赤";
    print "この色は$colorです。";
    print 'この色は$colorです。';
    同じように見えますが、結果は

    この色は赤です。
    この色は$colorです。

    と違ってきます。

  3. 変数
    スカラ変数=「$」で始まる値を1つだけ記憶できるもっとも一般的な変数
    配列変数  =「@」で始まる複数の値を記憶できる変数
    連想配列変数または、ハッシュ変数
    「%」で始まり配列変数の添字に文字列を指定できる変数
    変数名は、英字または"_"で構成しなければなりません。
    当然「日本語」を使用することは出来ません。

  4. 特殊変数
    $! システムコール呼び出し時に発生したエラー番号
    $. ファイル読み込み時の現在の行数
    $_ 各処理時のデフォルトの引数
    $/ 入力レコードの区切り文字
    $, 出力フィールドの区切り文字
    $" ダブルクォーテーションの中の配列展開の区切り文字
    $\ printの最後につく文字
    $; 多次元配列のための区切り文字
    $数字 直前のパターンマッチの各括弧に対する文字列
    ...他にも有りますが、これだけ覚えておけば大丈夫でしょう。

  5. 演算子
    +,-,*,/ 加,減,剰,除
    % 剰余
    ** べき乗
    ++,-- インクリメント,デクリメント
    .. 範囲演算子 (1..5)は(1,2,3,4,5)と同じ。
    .  文字列連結 $name .= ".dat" --> $name に .dat を追加する
    && and
    || or
    == 又は、eq 等しい
    != 又は、ne  等しくない
    < 又は、lt  小さい
    > 又は、gt  大きい
    <= 又は、le  以下
    >= 又は、gt  以上
    <=>又は、cmp 比較

    代入演算子
    変数に、値を代入するには、「=」を使用します。
    $a = 2;    $aに2が格納されます。
    $a = 2 * 3;    $aに6が格納されます。
    $a = $b = 4;又は、$a = ($b = 4);    $aと$bに同時に4が格納されます。
    $a = 5 + ($b = 6);    $bに6を代入し、$aに11を格納します。
    $a = 5 + ($b = 6 + ($c = 7 + 8));    $cに15を、$bに21を、$aにを格納します。

    二項代入演算子
    $a = $a + 1;  のように両側に同じ変数名が現われるような式が頻繁に使用されます。
    この右側の変数名を省略して計算結果を代入する式を二項代入演算子といいます。

    $a = $a + 1;  =>  $a += 1;
    $a = $a - 1;  =>  $a -= 1;
    $a = $a * 1;  =>  $a *= 1;
    $a = $a / 1;  =>  $a /= 1;
    $a = $a . "abc";  =>  $a .= "abc";

    インクリメントとデクリメント
    上の式で、プラスかマイナスされる値が1の場合に限りさらに省略する事ができます。

    $a = $a + 1;  =>  ++$a;    インクリメント
    $a = $a + 1;  =>  $a++;
    この場合「++」を変数の前でも後ろでも同じ結果が得られますが、
    $a = ++$b;
    $a = $b++;
    では、結果が異なります。前置き「++」は、$aに1プラス後$bに代入しますが、後置き「++」は、$aを$bに代入後$aに1プラスします。

    $a = $a - 1;  =>  --+$a;    デクリメント
    $a = $a - 1;  =>  $a--;
    デクリメントも、インクリメント同様に、前置き「--」と、後置き「--」では、機能が異なります。

  6. 文字と数値の演算
    perlは、文字と数値を計算させても何も文句も言わず計算します。
    数値演算子「+」で文字を計算させると、
    $plus = "3.14" + "abc"の結果$plusには、3.14が代入され、
    $plus = "3.14" + "6.86abc"の結果は10になります。
    文字列は、10進数の数値に自動的に変換されるからです。

    同様に文字列連結演算子「.」を使ってみると、
    $string = "X" . (3 * 3)
    この結果は、文字「x」に3*3の結果「9」を連結して、「X9」になります。

  7. 正規表現
    正規表現は、次の検索・置換でよく使われます。

    英数字: a a にマッチ
    1 1 にマッチ
    test test にマッチ

    メタ文字: + ? . * ( ) [ ] { } |
    \s 空白文字1文字
    \w 英数字、「_」の1文字
    \d 数字1文字
    \n エスケープシーケンス
    ^ 行頭
    $ 行末
    \b 単語の区切り
    \B 単語の区切り以外

  8. 検索・置換
    [検索]
    STRING =~ /PERTERN/;
    文字列(STRING)がPATTERNに一致するかどうかを調べる。
    if ("abcdefg" =~ /"abc"/) { print "一致"; }
    else { print "不一致"; }

    この結果は、「一致」と表示されます。

    STRING =~ /[PERTERN]/
    一対のブラケット[]の中に並べた文字、どれか一つでもマッチすれば「真」で、
    フォームデータのデコードなどでよく使用されます。 $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;

    [置換]
    変数 =~ s/PATTERN/REPLACEMENT/;
    変数 =~ s/PATTERN/REPLACEMENT/g;
    変数 =~ s/PATTERN/REPLACEMENT/ig;

    変数の中で、PATTERNに一致する部分をREPLACEMENTで置換し、結果を変数に戻します。
    書式(1)は、最初一致した部分のみ置換し、
    書式(2)の最後に g を付けると、変数のPATTERN全てを置換します。
    書式(3)では、さらに大文字、小文字を区別しない「i」オプションを付けています。

    $string = "Tqeqrrqa";
    $string =~ s/'q'//;
    print $string;
    結果は、「Teqrrqa」となり、

    $string = "Tqeqrrqa";
    $string =~ s/'q'//g;
    では、「Terra」となります。

    これは、書き込みボードでタグを禁止する例です。
    $value =~ s/<!--#(.|\n)*-->//ig; #SSIの禁止
    $value =~ s/<image(.|\n)*>//ig; $value =~ s/<\/image>//ig; #イメージの禁止
    $value =~ s/<table(.|\n)*>//ig; $value =~ s/<\/table>//ig; #テーブルの禁止
    $value =~ s/<script(.|\n)*>//ig; $value =~ s/<\/script>//ig; #スクリプトの禁止
    $value =~ s/<frame(.|\n)*>//ig; $value =~ s/<\/frame>//ig; #フレームの禁止

  9. 文字列関数
    chop(STRING)
    文字列STRINGの最後の文字を切り落とし、結果を返します。

    length(STRING)
      文字列STRINGの長さをバイト数で返します。
      $str_len = length('早苗ちゃん');
      $str_lenには、2バイト文字ですのて10が代入されます。

    substr(STRING,OFFSET,LENGTH)
      文字列STRINGのOFFSETバイト目からLENGTHバイト取り出した文字列を返します。
      $first_name = substr('Yumi Itami'',5,5);
      $first_nameには、「Itami」が代入されます。
      OFFSET は、0 から数え、
      LENGTH を省略すると、OFFSET以降最後までの文字列が返されます。

    index(STRING,SUBSTR,OFFSET)
      文字列STRINGのOFFSET以降からSUBSTRで指定した文字列を探し、
      最初に  見つかった位置をバイト数で返します。
      見つからなければ、-1 を返します。

  第2章  制御構造
  1. if elsif else文
    if (条件) { ブロック; }
    elsif (条件) { ブロック; }
    else { ブロック; }
    if ($value = 'りんご') { print "りんごです"; }
    elsif ($value = 'バナナ') { print "バナナです"; }
    else { print "「くだもの」ではないかもね"; }

    または、
    if ($value = 'りんご') {
      print "りんごです";
    }
    elsif ($value = 'バナナ') {
      print "バナナです";
    }
    else {
      print "「くだもの」ではないかもね";
    }
    処理ブロックが多い場合は、書式(2)を使用したほうがスクリプトが見やすくなります。

  2. while文
    while (条件) {
      ブロック;
    }
    条件が真の間、ブロックを実行します。
    open(DT,"test.dat");
    while () {
      print;
    }
    close(DT);

  3. until
    until (条件) {
      ブロック;
    }
    untilは、whileの正反対の判断をし、条件が偽の間、ブロックを実行します。

  4. for文
    for (式1;式2;式3) {
      ブロック;
    }
    式1が、式2になるまで式3のステップでブロックを実行します。
    for ($i = 1; $i <= 10; $i++) {
      print "$i\n";
    }
    最初$iが1で、$iが10になるまで$iに1プラスしながら$iの値を表示しつづけます。

  5. do文
    do { ブロック; } while (条件)
    do { ブロック; } until (条件)

    書式(1)、(2)は、それぞれ while文とuntil文の判断がループの最後に行なわれるものです。
    $i = 1;
    do {
      print "$i\n";
      $i++;
      }
    while ($i <= 10)

  6. foreach文
    foreach 変数 (list) { ブロック; }

    listの1番から順に変数に代入し、ブロックを実行。listが終了した時ループから抜け出します。
    read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
    @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;
      $FORM{$name} = $value; }

  7. ループ制御コマンド
    last文
    ループの実行を即座に断ち切って抜け出します。

    next文
    残りのコードをスキップして判断文に制御を移します。

    redo文
    残りのコードをスキップしてループの先頭に戻ります。この時、制御判断を行ないません。
  第3章  配列
  1. 配列変数への値の代入
    @DATA = ('早苗ちゃん','ゆみちゃん','恵子ちゃん','美香ちゃん');
    または、
    $DATA[0] = '早苗ちゃん'
    $DATA[1] = 'ゆみちゃん'
    $DATA[2] = '恵子ちゃん'
    $DATA[3] = '美香ちゃん'
    とする事もでき、
    @DATA[0..3] = ('早苗ちゃん','ゆみちゃん','恵子ちゃん','美香ちゃん');
    としても同じです。

  2. 配列変数の値の参照
    print $DATA[0]
    print $DATA[1]
    print $DATA[2]
    print $DATA[3]  としても、

    print @DATA[0..3]としても同じ結果が得られます。
    @DATA = ('早苗ちゃん','ゆみちゃん','恵子ちゃん','美香ちゃん');

  3. 配列の添字
    配列の要素番号をあらわす数値または文字列を添字といいます。
    $DATA[3]の場合「3」が添字です。
    フォームデータを参照する場合の、
    $FORM{'name'}の「name」もいわば添字です。
    配列の添字は、0から始まり、使用した数で終わります。

    配列の要素数を調べるには、
    $count = @DATA;
    のように配列変数を通常の変数に代入するだけで得られます。

    この時、$countには、4が代入されますが、
    $DATA[4]の添字は有りません。あくまでも、添字は0から始まりますので、使用できる添字は、0から3の4個となるのです。

  4. 配列リスト操作関数
    • shift(@DATA)
      配列@DATAの最初の要素を取り出します。
      $name = shift(@DATA);
      $nameには、'早苗ちゃん'が格納されます。
      この時、各要素は1つずつシフトアップされ、要素数も1つ減ります。

    • unshift(@DATA, $list)
      配列@DATAの先頭に$listの値を追加します。
      $list = 'みゆきちゃん';
      unshift(@DATA, $list);
      今まで先頭にいた'早苗ちゃん'の前が'みゆきちゃん'になり、
      '早苗ちゃん'は、@DATA[1]にシフトされます。
      この時、要素数も1つ増えます。

    • pop(@DATA)
      配列@DATAの最後の要素を取り出します。
      $name = pop(@DATA);
      $nameには、'美香ちゃん'が格納されます。
      この時、要素数も1つ減ります。

    • push(@DATA, $list)
      配列@DATAの最後に$listの値を追加します。
      $list = 'みゆきちゃん';
      push(@DATA, $list);
      今まで最後にいた'美香ちゃん'の後に'みゆきちゃん'が追加され、
      要素数も1つ増えます。

    • sort(@DATA)
      配列@DATAを文字コード順(昇順)に並べ替えます。

    • reverse(@DATA)
      配列@DATAを逆に並べ替えます。

    [注意]
    配列変数全体をあらわす場合は、「@」を使用しますが、この配列変数の1要素(添字)を指定する場合は、 同じ変数名の記号が、「$」に代わります。

    他にも有りますが、私のような中級には必要ありません。
  第4章  ファイル操作
  1. ファイルのオープン
    open(HANDLE, filename);
    HANDLE ファイルハンドル名
    filename 実ファイル名
    • 入出力モードの指定
      ファイル名の前に、以下の記号を付けます。
      <または、省略入力モードでオープンopen(DB,"acbd.txt");
      >出力モードでオープンopen(DB,">abcd.txt");
      >>追加出力モードでオープンopen(DB,">>abcd.txt");
      +<読み書き両用でオープンopen(DB,"+
      +>ファイルを作成して読み書き両用open(DB,"+>abcd.txt");
      +>>ファイルをオープン又は、
      作成して読み書き両用
      open(DB,"+>>abcd.txt");
  2. ファイルの入出力
    • 入力
      <HANDLE>
      ハンドル名を< >でくくります。ダイヤモンド演算子といいます。

      ファイルを入力モードオープンし、最初の一行を$lineに代入
      open(DB,"abcd.txt");
      $line = <DB>;

      ファイルを入力モードでオープンし、ファイルの最後まで表示します。
      open(DB,"abcd.txt");
      while (<DB>) {
        print;
      }

      配列変数に一度に代入する事も出来ます。
      ropen(DB,"abcd.txt");
      @DATA = <IN>;
      close(IN);
      foreach $line(@DATA) {
        print;
      }

    • 出力
      print HANDLE STRING;
      HANDLE で指定したファイルにSTRINGを書き出します。

      ファイルを上書きモードオープンし、一行づつ書き出します。 open(DB,">abcd.txt");
        print DB '早苗ちゃん';
        print DB 'ゆみちゃん';
        print DB '恵子ちゃん';
        print DB '美香ちゃん';
      close(DB);

      ファイルを上書きモードでオープンし、配列を一度に書き出します。 open(DB,">abcd.txt");
        print DB @DATA;
      close(DB);

      ファイルを追加モードでオープンし、最後に一行追加します。 open(DB,">>abcd.txt");
        print DB 'みゆきちゃん';
      close(DB);
Copyright 2004 Terra. All rights reserved. No reproduction or republication without written