カテゴリー
Perl

掲示板を作ろう

この章では掲示板の作成方法について説明します。
掲示板を作成するためにはフォームが必要です。
フォームとは会員登録でお名前、住所などを入力したことがあると思いますが、これがフォームです。
フォーム自体はHTMLで作るのですが、その入力データをCGIに引き渡す方法などを学習します。
入力データをCGIに引き渡す方法として、GET方式とPOST方式があります。
この送信方法の指定は、HTMLの入力フォーム上で以下の通り指定します。111 つまり、get方式はフォームの送信データがURLとして渡されると言うことです。
そのため送信する情報には制限が有り、最大で約2000文字位です。
1POST方式の場合はフォームに入力したデータはHTTPプロトコル(下の補足を参考にしてください)という通信の機能によりリクエストボディつまり本体部分に入力されてサーバに送られます。
POSTの場合は送る文字数に制限はありません。
1では例をみてみましょう。
長いプログラムですので、分割して書きますが1つのプログラムです。111111 ここまでが掲示板の骨格です。
ここから下のプログラムはすべてサブルーチンになりますので、上の骨格の部分から呼び出しています。11111111 上のプログラムを実行しますと以下のフォームが表示されます。
1では、具体的な説明を始めます。
1=> 「require」は外部のファイルをプログラム内に挿入するために使います。「jcode.pl」は 文字コードを変換してくれるライブラリです。
ライブラリとは 複数のサブルーチンをまとめたファイルのことを言います。
ライブラリを皆が使えるように無料で公開している人や団体がいるのですが、1もその内の1つです。
このファイルは以下のURLで手に入れることが出来ますので、このファイルの中身をコピーして、名前を「jcode.pl」にして、このCGI プログラムと同じフォルダに置いてください。1 この「jcode.pl」は何に使うかと言いますと
ユーザーがフォームに入力する文字は1つの文字コードで決められているわけはありませんので、この「jcode.pl」を使って、文字を自身で決めた文字コードに変換します。
この例の場合には1に統一したいので、この文字列に変換します。
変換の方法は後で説明しますが、1のように書いて、「jcode.pl」の中のサブルーチンを呼び出して変換します。

2
1=>insertサブルーチンはフォームから出力されたデータを受け取るサブルーチンです。
詳しくは後ほど説明します。
1=>このプログラムは「board.dat」に投稿された記事を記録していきますので、「board.dat」というファイルを作成してCGIプログラムと同じフォルダに入れてください。
もしファイルが存在しないなどの問題がある場合にはerrorサブルーチンが作動します。
errorサブルーチンの具体的な内容は後ほど説明します。
errorサブルーチンの呼び出しはopen関数とサブルーチンの間にorを入れて1のように書きます。
そして「<FILE>」でファイルの中身を読み込んで@infoに入れています。初めてのアクセス時には@infoはカラなので何も入っていません。
1=>これはHTMLのhiddenを利用した方法です。
1フォームからデータが送信されるとこのhiddenも送信されるので、このhiddenの値がkakuの時にwritefileサブルーチンを起動させます。
このサブルーチンはフォームから送信されたデータを「board.dat」に記録するサブルーチンです。
writefileサブルーチンの具体的な内容は後ほど説明します。
111=>action属性の値に1という箇所がありますが、このハッシュには実行しているパスを含むファイル名が代入されています。
「SCRIPT_NAME」は環境変数と呼ばれていて、1という構文でパスを含むファイル名が取得できます。
環境変数は他にも多数ありますが、例えば以下のような環境変数があります。
1「SCRIPT_NAME」は著者の例では1に相当します。
つまり、action属性の値にはどのファイルに送信するのかを書きますので、この例では投稿ボタンを押すと再び1に戻ることを意味します。
ではURLにファイルを指定して、実行してください。
1もし、「board.dat」が存在しないのならばファイルエラーと表示されます。
1これはerrorサブルーチンが作動した結果です。
1の他に2か所errorサブルーチンがありますが、これはファイルが開けなかったときに実行されます。
サブルーチンの呼び出し側の引数には1が入っていますが、これが1に代入されますので、エラーが起きた時には1と出力されます。
エラーが無ければ以下のフォームが表示されますので、フォームに名前などを入力して、投稿をクリックします。
11このinsertサブルーチンは簡単に説明するとフォームから送られてくるデータを以下のハッシュに入れる機能を持っています。
1ではinsertサブルーチについて説明します。
postで送られているのならばread関数の中の$subにフォームから送られてきたデータを代入します。
11read関数はファイルハンドルから指定したバイト数のデータを読み込み変数に代入します。
この例の場合のファイルハンドルはSTDINを指定してください。
ファイルハンドルは通常はこれまで使用してきたようなファイルに関連づけされたファイルハンドルですが、STDINはPOSTでデータを送るときに使われる特殊なファイルハンドルです。
1にはPOSTで送られてきたデータの文字数が代入されています。これは先ほど説明した環境変数です。
基本構文は1です。
1もしpostではなくgetで送られてきたのならば1に送られてきたデータが代入されているので、それを$subに代入します。
これも先ほどと同じで環境変数です。
1getで送られる場合にはデータは1に代入されていると覚えてください。
次に以下の箇所の説明をします。
1=>フォームからデータが送られるときには以下のようにフォームの
1を&で繋げた状態でデータが送られてきますが、このままでは配列に入れることが出来ませんので、splitで切断します。splitで切断する作業は2回行うのですが、初めに「&」で区切ったものを配列に入れます。
1@dfrには分割したものが以下のようにして入ります。
1さらにこの@dfrの中の要素を「=」で区切ります。1111111

例えばフォームに「近藤」と、入力して送るとします。1111

splitで分割した後にすることはURLエンコードして送られてきたものをURLデコードしなくてはいけません。
URLデコードはURLエンコードされたものを元に戻すことを言います。
URLデコードは以下の部分で行います。
1=>半角スペースを表す「+」を元の空白に戻すには1と書きます。
次に以下の箇所を説明します。1 111111次は以下の箇所の説明をします。1 1111次の箇所の説明をします。
11なぜこの作業を行うかと言いますとHTMLのタグをそのまま送信してしまうと掲示板などにいたずらされる可能性がありますので、それを防ぐために変換を行う必要があります。
1次に以下の箇所の説明をします。
1=>最後に$inputというハッシュに分解した$keyと$value」を入れています。
1では説明をしていきます。
「投稿」ボタンを押しているので、以下のhiddenが実行され、if文がTRUEになり、writefileサブルーチンが呼び出されます。
1writefileサブルーチンではフォームから送信されたデータと日付をファイルに書き込みます。
ではwritefileサブルーチンの説明を始めます。
1=>ここではフォームから送信されたコメントがカラの場合にはerrorサブルーチンが呼び出され1が出力されます。
カラを表現するには1のようにダブルクォートを続けて書きます。
$inputにはinsertサブルーチンで取得したデータがハッシュの形式で保存されていますので、ここでデータが入っているかどうかを確認しています。
次に以下の箇所の説明をします。
1=>ここでは localtime関数とtime関数を使って日付や時刻を取得しています。
1time関数をこのままの状態で使っても、ただ数字が並んでいるだけで意味が分かりませんので、 localtime 関数の引数にtime関数を入れますと我々が分かりやすい数値をリスト形式で取り出すことが出来ます。
以下の基本構文の左辺を見ると月や分などのリストになっていますが、time関数の経過秒が月、分などに変換します。
1曜日を日本語で得たい場合には自身で曜日の配列を作成して、曜日の入った変数の数値を添え字にして配列からデータを得ます。
111111=>ここではlocaltime関数で取得した変数に書式を付け加えています。
つまり指定した値、例えば$year,$monなどをsprintf関数で
書式指定文字通りに変換します。
基本構文は以下の通りです。
111例のように% とアルファベットの間に1など数字がありますが、これは桁数を指定しています。
「%4d」であれば4桁の整数を意味します。
「%02d」であれば先頭に0を付けた2桁の整数を意味します。
11111次の箇所の説明をします。
1=>unshiftは配列の古いデータの先頭にデータを追加します。
これは常に新しいデータが画面表示の上に来た方が読みやすいので、unshiftを使ってデータを上に配置するようにしています。
@infoには以下のデータを入れています。
11次に以下の箇所の説明をします。
1=>ここではファイルにデータを書き込んでいます。
ここまで終わりますと「board.dat」には以下のように書き込まれます。
11111以下の箇所で「board.dat」に入っているデータを画面に表示します。
11ファイルに入っているデータを取り出すのですが、ファイルにはタブ区切りでデータが入っているので、splitで区切ります。
区切られたデータはそれぞれ$date, $head, $name,$contentsに代入されるので、あとはprint文でそれぞれを出力します。
結果は次のようになります。1

カテゴリー
Perl

正規表現を理解しよう

この章では正規表現について説明します。
ショッピングサイトでお買い物をする時、電子メールや住所などの個人情報を入力しますが、電子メールや郵便番号などが正しく入力されているのかを調べる必要があります。
そのような時に正規表現を使います。
正規表現とは電子メールや郵便番号などの文字の並びをパターン化して、正規表現特有の記号で表現する1つの形式です。
[基本構文]1 構文の中の「パターン」に正規表現特有の記号を記述します。
正規表現特有の記号は1で囲みます。
文字列に対してパターンが一致するかどうかをチェックし、一致すればTRUEになり、一致しなければFALSEになります。
では例を見てみましょう。111 このように正規表現と言うのは文字などが正しく入力されているのかをチェックする機能を持っています。
電話番号が正しく入力されているのかなど簡単にチェックできますので、とても便利な機能です。111111111111111111111111111111111111111111111111111111111111111
以下の例は正規表現を1に変更して、括弧を3つに増やしました(外側に括弧を増やしました)。1111文字列を正規表現のパターンで分割するsplit関数について説明します。
11次の例は第3引数を2に指定していますので、文字列を2つに分割します。1 結果は以下の通りです。
nakata
Japan,34
1この例は正規表現で指定したパターンにマッチした文字を指定した文字に置き換えますが、以下の構文を使っています。
11上の例でpenは2つありますが、初めに出てくるpenだけしか変換されませんが、以下のように1を指定することですべての文字列が対象になります。
1を指定すると大文字と小文字を区別しないで置換します。
11では次の例に進みます。
11111「tr/ / /」は文字を変換したり、削除するために使われます。
「s/ / /」と似た働きがありますが、違う働きがありますので、違いを説明します。11111111

カテゴリー
Perl

サブルーチンについて知ろう

この章ではサブルーチンについて説明します。
前の章で配列やハッシュや文字列を操作する関数について説明しましたが、例えばsubstr関数は切り取った文字列を返すという機能を持った関数でしたね。
これらはPerlの内部機構であらかじめ決められたものです。
しかし、プログラマ自身もsubstrのような機能を持つ関数を作ることが出来るのです。
これがサブルーチンです。
例えばsubstr関数のような切り取った文字列を返すというプログラムを以下のサブルーチンの定義に書いていきます。111 ではサブルーチンを使った例と使わない例を較べてみましょう。
以下の例は3科目の平均を求めるプログラムです。
サブルーチンを使わない場合には以下のように書きます。11 この「3科目の平均を求めるプログラム」をサブルーチンで定義しますと以下のようになります。
11Averageという名前のサブルーチンで3科目の平均を求めるプログラムを作成しましたので、これを実行させるためにはそのサブルーチンを呼び出さないといけません。
呼び出している箇所は1です。
ここでは3個の引数をサブルーチン側に渡しています。
サブルーチン側でこれらの引数を受け取るには1という特殊な配列を使います。1 「@_」には先頭から順番に引数が入っていますので1という記述で、$kには56が、$sには45が、$eには99が入ります。
この代入が終わりますと後は3科目の平均を求める計算が行われ、1が出力されます。
先ほどのサブルーチンを書き替えますと以下のようになります。
11次の例を見てみましょう。
1この例は引数の合計を行うサブルーチンです。
引数の数は何個でも対応できるサブルーチンです。
サブルーチンの呼び出しは1で行われています。
そして、foreachの中では引数の合計を行っています。
111しかし、実行した結果を呼び出し側に返す場合に必ずreturn を付けなくてはいけないわけではありません。
以下の例のようにreturnを付けなくても、$sumの値は呼び出し側に戻ります。
つまり、returnを付けない場合にはサブルーチンの最後の値をサブルーチンの呼び出し側に戻すことになります。

1次の例を見てみましょう。
1

このmaxサブルーチンは2つの値の中で大きい方を返してくれます。1次の例を見てみましょう。

1taxサブルーチンは引数の値を合計して、それに「0.05」を掛けて消費税を求めています。

サブルーチンの中にmyがありますが、これを付けた変数はブロック内だけが有効範囲になり、ブロックの外を出るとその変数の値を得ることが出来なくなります。
ブロックとは「{」から「}」までの間のまとまりの事を言います。1 例えばサブルーチンの外で以下のように出力させようと思っても、何も表示されません。1 myを付けた変数はサブルーチンに限らず、if文やfor文などブロックがある構文に対してはブロック内だけが有効範囲になります。

カテゴリー
Perl

アクセスカウンターを作成しよう

この章ではアクセスカウンターの作成方法について説明します。
アクセスカウンターはサイトに訪れた人数をカウントする機能です。
では例をみてみましょう。11新たに「count1.txt」というファイルを作成してください。
アクセスをカウントするためには「その数を保存する媒体」が必要になりますので、この例ではアクセス数をファイルに記録します。
そして「count1.txt」の先頭行の左端に0と入力し保存します。
「count1.txt」の保存先はperlファイルと同じにしてください。11 1111そこでseek 関数を使うと、現在のファイルの位置を移動することが出来ます。
seek 関数はファイルポインタを移動するための関数です。
ファイルポインタというのは、ファイルに書き込んだり、ファイルを読み込んだりする位置のことです。
つまり、ファイルの先頭や末尾など任意の位置まで移動させることが出来る関数です。
この例では読み書き用でファイルを開いているので書き込むときにはファイルポインタを先頭に戻さなくてはいけません。
seek関数を使ってファイルポインタを戻さないと以下のようにファイルポインタがずれてしまいカウントすることが出来ません。11 例えばファイルの先頭に移動するには以下のように書きます。
つまり、ファイルの先頭から0バイトなので先頭を意味します。1 ファイルの終端に移動するには以下のように書きます。
1つまり、ファイルの終端から0バイトなので末尾を意味します。11

カテゴリー
Perl

Perlプログラムでファイルを扱う方法を知ろう

この章ではPerlプログラムの中でファイルを扱う方法を学習します。
Perlプログラムの中でファイルを読み込んだり、書き込んだり、削除したりすることが出来ます。
プログラムでファイルを操作するには初めに、対象のファイルを開くことが必要です。
そして、その開いたファイルをプログラム上に表示させたり、プログラムの中のデータをファイルに書き込んだりする操作を加えて、
最後にその開いているファイルを閉じると言う過程をたどります。
1ではファイルの開き方から説明します。
1ファイルを開くにはopen関数を使います。ファイルハンドルとは今どのファイルを実行しているのかを区別するための名前のことを言います。
つまり、ファイルを操作するためのIDみたいなものです。
ファイルハンドル名を付けてからはこのファイルハンドル名で実行するための指示を出していきます。
ファイルハンドルは大文字で付けるのが慣習になっています。
ファイルを開いたとは閉じなくてはいけませんが、それにはclose関数を使います。
close関数の引数にはファイルハンドルを入れます。1 ではファイルにデータを書き込む例を見てみましょう。11 では説明を始めます。111 モードは「>」だけではないので、ファイルを開くときにはどのモードで開くのかを以下を参考に指定してください。111 次にflock関数について説明します。1 =>flock関数はファイルをロックする関数です。
ファイルに何かを記録するときに、複数の人が同時に同じファイルに書き込みを行うとファイルが壊れる可能性があるので、ファイルに書き込みを行う前にファイルをロックして、書き込んでいる間は他の人がファイルに書き込んだり読み込んだりを行えないようにすることが必要になります。
そのような時に使うのがflock関数です。ロックの種類は以下の通りですが、この例では書き込みを行っているので読み書き両方を禁止する2を指定してください。
ファイルロックは読み込み専用でファイルを開いている時にはflock関数は使う必要はありません。
つまりロックはしなくてもいいです。1 次にファイルに書き込む方法について説明します。1 ファイルに書き込みには以下の構文の通りprintを使います。
printの引数にはファイルハンドルと書き込む内容を書きます。
1最後にflock関数をノンブロックモードでファイルロックを解除して、ファイルを閉じます。つまり、ロック解除してから、close関数でファイルを閉じます。1 結果は以下のようにファイルに書き込まれます。1 次は書き込んだ内容を画面に出力します。1では解説をしていきます。1
=>読込み用で開きますので、「<」を使用します。1 =>ここではファイルの内容を読み込みます。
ファイルの内容を読み込むには以下の基本構文を使います。1 この例では「<OUT>」です。
「<ファイルハンドル>」はファイルから1行ずつ読み込みを行います。
読み込んだ1行の末尾には改行記号が付いています。
ファイルの内容を出力する方法は3つあります。11 1111そして、すべての内容を取り出したら、ファイルを閉じます。
11 1ファイルを削除するには、unlink関数を使います。
戻り値には、削除したファイルの個数が返ってきます。
複数のファイルを削除するには以下の構文で書きます。
1では例をみてみましょう。
1戻り値には、削除したファイルの個数が返ってきますので、例えばファイルが存在しないなどの理由で0が返ってきたらFALSEになり、以下のprint文が出力されます。
1ファイル名を変更したい場合はrename関数を使います。1 成功時には1、失敗時には 0を返します。
では例をみてみましょう。11

カテゴリー
Perl

コンテキストを理解しよう

この章ではコンテキストについて説明します。
Perl を理解するためにはコンテキストの知識は欠かせません。
例えば、プログラムを書いている時に配列を変数もしくは配列に代入しなくてはいけない場面があるとします。
この場合にどちらに代入するかで意味が全く違ってしまいます。
もう一つ例を挙げますと、if文の条件式の中に配列を入れた時、その配列の意味は配列の中身を示すのではなく、配列の中に入っている要素数という意味になります。
このように配列や変数は置かれている場所によって意味が違ってしまいます。
この場所の概念をコンテキストと言います。
では例を見てみましょう。11 最初の出力は配列の要素である1を出力していますが、次の出力は配列の要素数の5を出力しています。
このように変数もしくは配列に代入することにより解釈が変わってしまいます。
コンテキストの種類はリストコンテキストスカラーコンテキストの2種類ありまして、Perlは文脈により必ずどちらかで判断しています。
「@e=@p;」の場合は配列を配列に代入しているのでリストコンテキストで解釈して、1の場合は配列を変数に入れているのでスカラーコンテキストで解釈しています。
配列をスカラーコンテキストで判断すると配列の要素数を得ることが出来ます。1 ここからはたくさんの例を見ていただきます。
スカラーコンテキストから見てみます。1 左辺が変数のため、スカラーコンテキストで判断され、リストの最後の要素である7が出力されます。
変数は1つしか値を保持できないため、最後の要素が代入されていると考えてください。1 「+」、「-」、「*」、「/」の演算子は両辺にリストではなく、スカラーを要求するのでこの文はスカラーコンテキストで判断することになります。
その結果、@pはスカラーコンテキストで判断され、配列の要素数である5となりますので、28が出力されます。
これが思い通りの計算結果であればこれでいいのですが、もし、配列の要素の中の合計を期待しているのならば間違いになりますので気を付けてください。1 if文の条件式はスカラーコンテキストを要求しますので、@pは配列の要素数である5になります。
結果は「FALSEです」です。1 配列の要素にデータを代入する時にはスカラーコンテキストで判断します。
これは配列そのものに代入しているわけではなく、配列の中の0番目の要素に代入しているのでスカラーコンテキストで判断されます。
次はリストコンテキストの例を見てみましょう。1 左辺が($a,$b)のようにリストを要求しているので、これはリストコンテキストでこの文を判断することになります。
$aには2が入り、$bには3が入ります。1 これは($f)のように変数1つだけをカッコに囲んでいるだけですが、これはリストコンテキストで判断することになります。
結果は先頭の要素である2です。変数が1つしかないので、2以外の要素は捨てられます。1 foreachの括弧の中の@numは配列の要素を取り出す役割がありますので、リストコンテキストで判断することになります。1 sort文など配列を操作する関数は配列やリストの順番を変えるためにあるのでリストコンテキストで判断することになります。

カテゴリー
Perl

redo演算子を知ろう

この章ではredo演算子について説明します。
redo演算子は繰り返しの途中で発動したのならば条件式の判定を行わず、現在のループをやり直します。
while文、until文、for文、foreach文で使うことができます。
では例をみてみましょう。1 redoが実行されると1というコメントがあるところまで戻ります。
この時1の条件判断を行いません。
この例では234までは普通に出力していますが、$numが5になったのならばredoが発動して、1の位置まで戻るので、1で 5を出力することはありません。
「#redoにより、ここに戻ります」の位置まで戻ったら、1で1が足されて6になりますが、1の条件式の判定がFALSEなのでif文はスルーして1で 6を出力します。
そして、また最初に戻って1で条件判断をして6は10以内なのでまたループが始まると言う流れになります。
結果は「234678910」です。
1もう一つredoの例を見てみましょう。
1この例では$iが3になったら、1まで戻って、1を実行します。
次のif文は$iに10が入っているのでスルーして、最後に11を実行して終わりになります。1

カテゴリー
Perl

next演算子を知ろう

この章ではnext演算子について説明します。
next演算子は現在進行している周回を抜けても、ループ自体は続けたい場合に使います。
next演算子はwhile文、until文、for文、foreach文の中で使えます。
では例をみてみましょう。11 実行結果は1となり、1が抜けています。
つまり、「4つのリンゴ」の箇所だけを飛ばしていることになります。
以下のように、この例の中のnextをlastに変えてみますと、$iが4になったら、その後の1を実行することなく、for文を抜けてしまうので、結果は1になります。
1次はwhile文の中でnextを使います。
$iが3になったらwhileの先頭に戻って繰り返し文を続けます。11

カテゴリー
Perl

while文の中でlastを使おう

この章ではwhile文の中でlastを使う方法について説明します。
これまではfor文の中でlastを使っていましたが、ここではwhile文の中でlastを使います。
では例をみてみましょう。1 上の例はwhile文の中にif文が入っている構造です。
1111$iは上の5で2になっていますが、まだTRUEなので、whileの処理文を実行します。
111$iは上の9で3になっていますが、まだTRUEなので、whileの処理文を実行します。11

カテゴリー
Perl

last演算子を知ろう

この章ではlast演算子について説明します。
last演算子はfor文などの繰り返し処理の中で1に使います。
last演算子はfor文の他にwhile、until 、for 、foreach 、do-while などにも使えます。
では例をみてみましょう。
1 for文のブロックの中にif文が入っています。
このようにfor文にif文を入れることが出来ることを覚えてください。
この例のif文の中にはlastが入っているので、もし$iと$kがイコールになったら、繰り返しをやめますと言う意味です。
lastはこのように一連の流れを強制的に中止したい時に使います。
この例の場合には$kが4なので、4周目のif文の箇所でfor文を抜けますので、1が出力されることはありません。
つまり、lastで抜けるとそれ以降の文は実行されることはありません。
この例の場合は1の箇所です。
結果は1が出力されます。
for文は入れ子にすることができますが、外側のfor文も抜けたい場合にはラベル付きのlastを使います。
初めに入れ子のfor文の中でラベル付きのlastを使わないで実行する例を見てみましょう。
ラベル付きのlastの説明は後ほど行います。
つまり、for文の入れ子の中で通常のlastを使うとどうなるかを説明します。11 入れ子のfor文の上から2つ目のforでlastを使った場合、lastで抜けることができるのは内側のfor文、つまり上から2つ目のforだけです。
内側のfor文の条件部分が5を超えたらlastを実行するのですが、lastを実行した後はまた外側の1に戻ってきてループを繰り返します。
入れ子ではないfor文の場合には1の時点で条件部分の5を超えているので、for文を抜けるはずですが、for文の入れ子の場合には抜けるのはlastの属するfor文だけで、また先頭のfor文に戻って続きを繰り返し、1を出力します。1 外側のfor文も抜けたい場合にはラベル付きのlastを使いますので、以下の例を見てみましょう。11 2つfor文がありますが、すべてのループを抜けたいのであれば上の例のように外側のforに1を付けてください。
この例では1です。
そして、for文の中のlast にも1と記述してください。
「if($i*$j>=5)」の条件式に従って5より大きくなったのならば、ラベル付けされた一番前のfor文のループを抜けるので、ここで処理を終了します。
ラベル名には英文字と数字と下線が使えますが、先頭文字に数字は使えません。
また、ラベル名は大文字を使って書く習慣になっています。