特集3̲1 04.1.21 20:24 ページ64

特集

第3 1 章DB 接続，セッション管理，デザインとロジックの分離…モジュールで解決！

基礎編： Perl 実行環境とモジュールの基礎知識
Tokyo Perl Mongers

小山浩之● OYAMA Hiroyuki ● oyama@cpan.org

Perl
最もポピュラーな選択肢

す．ニュースグループやメーリングリストではさまざ
まな情報が取り交わされ，出版される書籍の数からも利用者の多さをうかがい知ることができます．

Perlはその使い勝手の良さから，Webアプリケーシ

本章では，このPerlによるWebアプリケーションのョンを開発する最もポピュラーなプログラミング言語

実行環境と，開発に際して浮かび上がる課題へのモジの1 つに挙げられています．Perl のプログラマは，無ュールによる回答について述べていきます．

料で利用できる豊富なコンポーネントによって，Web アプリケーションの実行環境¡Web ブラウザからメールを閲覧¡ネットワーク越しにファイルをダウンロード・加工¡ネットワークプロトコルを直接操作

PerlによるWebアプリケーションを実行する環境には，代表的なものとして以下の3 つを挙げることがでといったことが容易に実現できます．
Perl は「インターネットの粘着テープ」と呼ばれ，まさに粘着テープのようにあらゆるものを結び付けるために利用されています．変化の激しいインターネッ

きます．
¡CGI
¡FastCGI ※1¡mod̲perl ※2

トの世界において，粘着テープのように簡単にコンポをリリースできるため，今日にいたるまでPerl が選ば

CGI（Common Gateway Interface）

れ続けていると考えられます．

Webアプリケーションを開発する環境としては言語ーネントを結び付け，短期間でWebアプリケーション

また，利用者と利用実績の多さも重要なポイントで本特集で使用しているスクリプトは，すべて弊誌 Web サ

を問わず，最もポピュラーなものです．ブラウザのリクエストを受け取ったhttpd がプログラムを起動して，

イト http://www.gihyo.co.jp/wdpress/からダウンロードでその出力結果をコンテンツとして送信する方法です

きます．ご活用ください．

（図1）．

※ 1）参考 URL ： FastCGI Home http://www.fastcgi.com/※ 2）参考 URL ： Apache/Perl Integration Project http://perl.apache.org/
参照書籍：『Apache 拡張ガイド（上）（下）』／ Lincoln Stein，Doug MacEachem 著／田辺茂也監訳／田和勝訳／オライリー・ジ
ャパン／ ISBN4-87311-018-1

64● WEB +DB PRESS Vol.1

特集3̲1 04.1.21 20:24 ページ65

第1章

基礎編： Perl 実行環境とモジュールの基礎知識●図 1

手軽にWebアプリケーションの開発を行うことがで

CGI の動作

Client

きる反面，プロセス起動・スクリプトのコンパイルに要するオーバーヘッドからパフォーマンスを確保しに

httpd

ScriptHTTP Request
Boot Perl

くく，トラフィックに比例して多くのリソースを消費

Perlしてしまう性質を持っています．

Load Script

FastCGI
Compile時

httpd と共にプログラムを起動・常駐させることにより，CGI で問題になるプロセスの起動と，スクリプ

間軸ExecuteContent

トのコンパイルに要するオーバーヘッドとリソース消HTTP Response

費を解消する方法です（図2）．
Java サーブレットのように魅力的なアーキテクチャ
ですが，常駐プロセスとして動作するため，スクリプ
トを修正した場合はhttpd の再起動による一時的なサ●図 2 FastCGI の動作

ービス停止が発生します．

Clienthttpdmod̲perl

ScriptBoot Perl

Perl

Apache モジュールの1 つで，httpd にPerl を組み込

Load Script

むことでhttpd が行っているURI（Uniform Resource
Identifiers）からファイル名への変換，認証，コンテンツの出力，ロギングなどの処理をPerlでカスタマイ

Compile時
間ズすることができます．

HTTP Request
Request軸

Apacheをカスタマイズする手段としてはもちろんでExecuteContent

すが，httpd によって直接スクリプトのコンパイルとHTTP Response

実行が行われるためにプロセス起動のオーバーヘッド
はなく，スクリプトのコンパイル結果をキャッシング
するために，CGI で問題になっていた実行に要するオ●図 3 mod̲perl の動作

ーバーヘッドのほとんどを解消することができます（図3）．

Clienthttpd+Perl

Scriptmod̲perlの実行環境の1つApache::Registryは，スHTTP Request

クリプトのコンパイル結果とグローバル変数をキャッLoad Script

シングして実行するため，CGI 用のスクリプトをほぼ
Compile

無修正のままに大幅な高速化が実現できます．ただし変数のキャッシングを行うため，グローバル変数に依存するスクリプトはうまく動作しなくなる場合があります．またhttpdにPerlを組み込むため，httpdのサイ

Execute時
間HTTP Response

軸
HTTP Request

ズが通常よりも大きくなる性質を持っています．
Apache::Registry のキャッシングによる動作の変化

ExecuteHTTP Response

を過度に心配し，導入をためらわれている方もいらっしゃると思いますが，グローバル変数に依存せずスコ

WEB +DB PRESS Vol.1 ● 65

特集3̲1 04.1.21 20:24 ページ66

Perl による ハイパフォーマンス
Web アプリケーションの開発

特集

3

Powered by mod_perl, Apache & MySQL

ープを意識したきれいなコードを使用している限りは問題にならないので，安心してください．

これはPOST したフォームの値をハッシュに格納するコードです．ひとつ大きな問題点として，このコー

ここで上げた3つの他にも，MicrosoftのIIS（Internet

ドは同じ名前のパラメータが複数入力された場合は正Information Server）へmod̲perl 同様にPerl を組み

しくハンドリングできなくなります．実際に<SELECT>込むものや，ZOPE※3のように，アプリケーションサ

タグで複数の項目を選択させる場面などでは，この問※4題が浮上してきます．また，HTTPのGETメソッドでーバとしての環境を提供するMasonなど，さまざまな環境が存在し利用されています．

Web アプリケーション開発
における課題Webアプリケーションを開発する際には，解決しなければならない以下の課題があります．
¡フォームの処理¡リレーショナルデータベースの操作¡セッション管理¡デザインとロジックの切り分け

渡された場合と，POST メソッドで渡された場合の2種類のデコード処理を記述する必要があります．
これらの変換処理はフォームの値を受け取るほとん
どの場面で行われる処理ですが，パラメータを受け取るための前処理でしかなく，コードの空間やコーディ
ングの手間として注力すべき処理とは言えません．
HTTP Cookie の操作やコンテンツの有効期限を設定する処理でも同様の問題が発生します．

◎解法
Perl のcore モジュールであるCGI.pm を利用するこ

Perlではこれらの複雑な問題を簡単に解決するモジとで，ブラウザから送信されたすべての情報の取得とュールが利用できます．各々の問題に対応するモジュ操作，出力する情報の操作にまつわる繁雑な処理をールを順に説明していきます．

カプセル化し，コードを簡略化することができます．

CGI.pm
CGI.pm※5◎結果

はフォームの入力値の取得や HTTP

定型的にもかかわらず繁雑な処理を記述する必要が

Cookie の操作など，CGI にまつわる繁雑な処理を簡なくなり，同時にコードも簡潔になり見通しが良くな

略化し，統一した見通しの良いコードを実現します．

ります．また，繁雑な処理手順を思い出し記述し直す必要もなくなります．モジュールの提供する機能とそ◎問題の呼び出し方を記憶するだけで良いのです．

流通しているCGI用のスクリプトを見ると，フォー
ムの値を取得するためのデコード処理をリスト1 のように記述しているものをよく見かけます．

◎利用方法
CGI.pm を利用するためには，まずインスタンスを生成します．

●リスト 1
my $input;
my %form;
read STDIN, $input, $ENV{'CONTENT_LENGTH'};foreach my $key_and_value (split /&/, $input) {my ($key, $value) = split /=/,$key_and_value;$form{$key} = $value;}

use CGI;
my $query = CGI->new;
クラスメソッドnew( )はCGI モジュールのインスタ
ンスを返します．フォームの値やHTTP Cookieは，こ※ 3）参考 URL ： Zope.org http://www.zope.org/，Zope Japan http://www.zope.ne.jp/※ 4）参考 URL ： Mason HQ http://www.masonhq.com/※ 5）参考 URL ： CGI.pm manual page http://www.perldoc.com/perl5.6/lib/CGI.html
CGI.pmマニュアル日本語訳 http://member.nifty.ne.jp/hippo2000/perltips/Cgi.htm

66● WEB +DB PRESS Vol.1

特集3̲1 04.1.21 20:24 ページ67

第1章

基礎編： Perl 実行環境とモジュールの基礎知識入力された値は自動的に解析され，$query の属性の生成したインスタンス（この場合は$query）を通として格納されます．param( )メソッドで参照したいパ

して操作します．
フォームの入力値は，フォームの属性名を指定する

ラメータ名を指定することで，入力された値を取得することができます．

だけで参照できます．

またGETメソッドのURIで指定されたパラメータも$query->param('NAME');

同様の手順で取り出すことができます．

CGIモジュールが提供する機能と機能を呼び出すメ
ソッドで主に利用するものを，表1 にまとめます．

http://hostname/sample.cgi?COMMENT=cool
print $query->param('COMMENT'); # it's "cool"◎サンプルコード92 ページに掲載の¡入力元となるHTML フォームの定義
入力元となるHTMLフォームの定義は，リスト2 を

Perl mini-Cookbook

ではCGI.pm を使用したファイルアップロードに関しての情報がまとめられていますので，そちらも合わせて参照することをお勧めします．

参照してください．

DBI.pm¡フォームを受け取るスクリプトの定義

DBI.pm はPerl からリレーショナルデータベースをフォームを受け取るスクリプトの定義は，リスト3

操作するための共通APIを提供し，異なる種類のリレを参照してください．

ーショナルデータベースも同じAPI で操作することが●リスト 2 入力元となる HTML フォームの定義<HTML><BODY><FORM method="POST" action="sample.cgi"><INPUT type="TEXT" name="COMMENT"><SELECT name="LANGUAGE"><OPTION value="Perl">Perl<OPTION value="Python">Python<OPTION value="Ruby">Ruby</SELECT></FORM></BODY></HTML>

できます（表2）．

●リスト 3

フォームを受け取るスクリプトの定義#!/usr/bin/perl
use CGI;
my $query = CGI->new;print $query->param('COMMENT');
print $query->param('LANGUAGE');__END__●表 1 CGI.pm 簡易 API 表
API

内容$obj = CGI->new;

CGI.pm のインスタンスを生成する．

例$obj->param;

受け取った HTML フォームの入力値を参照する．値の名称 my @name_list = $obj->param;$obj->param(NAME);を指定するとその値を返す．無指定で呼び出した場合は， my $value = $obj->param($name);
全フォームの属性名のリストを返す．同名の属性を複数受け取った場合は，値のリストを返す．

$obj->header;

HTTP レスポンスヘッダを生成する．無指定の場合は $obj->header($obj->header(CONTENT_TYPE); Content-Type: text/html が出力される．

-type$obj->header(LIST);-expires => '+1m',=> 'image/gif',);$obj->redirect(URL);

リダイレクションヘッダを生成する．

$obj->cookie(LIST)HTTP Cookie を生成する．Cookie の名称・値・有効期限 my $cookie = $obj->cookie(などを指定したハッシュを引数として受け取る．生成した-name=> 'session_id',

HTTP Cookie は header( )メソッドの-cookie パラメータに-value=> 'id_strings',

渡すことでブラウザに送信することができる．

-expires => '+1d',);
print $obj->header(-cookie => $cookie);

WEB +DB PRESS Vol.1 ● 67

特集3̲1 04.1.21 20:24 ページ68

Perl による ハイパフォーマンス
Web アプリケーションの開発

特集

3

Powered by mod_perl, Apache & MySQL◎問題

ーショナルデータベースを操作することができます．

重要なデータの保持や大量のデータを対象に操作・

インタフェースを定義するDBIと実際にデータベー

検索する場合，リレーショナルデータベースを利用す

スを操作するドライバのDBD から構成されます（図ることで，複雑な処理やパフォーマンスに関する多く

4，表3）．各種データベース用にDBD が開発されての問題を解決できます．

おり，最新のドライバリストはDBI のWeb サイト※6

リレーショナルデータベースを操作するSQLのインで参照することができます．

タフェースに関してはほぼ標準化されていますが，ネ
イティブAPI にはプロダクトごとに大きく差異があります．

◎結果Perl からリレーショナルデータベースの操作を可能

それらの差異を埋めるためWindows の世界ではにし，かつ異なるデータベースでも一貫したAPI で操ODBCが，Javaの世界ではJDBCが共通APIとして広作することができます．つまりテスト用にMicrosoft

く利用されています．

Access用に作成したコードをわずかな修正で，Oracle
用のコードとして利用することが可能になります．

◎解法

一般にリレーショナルデータベースへの接続処理に

DBI.pm を使用することでPerl からさまざまなリレ

要するオーバーヘッドは大きくなります．CGI では毎●表 2 DBI 簡易 API 表
API

内容

例

$handle = DBI->connect($data_ Database へ接続しデータベースハンドルを生成する．第 my $handle = DBI->connect($data_source,
source, $username, $passwd);

4 引数にハッシュのリファレンスでパラメータを指定でき $username, $passwd, {る．RaiseError ：問題発生時に例外を発生する．default

RaiseError => 1, AutoCommit => 0

off．AutoCommit ：データベースへの操作を自動的に });commit する．default on．トランザクションを使用する場
合は off にする．
$state = $handle->prepare(SQL); SQL をセットする．
SQL を実行する．

$state->execute;$state->execute(LIST);$state = $handle->do(SQL);

prepare( )と execute( )を一度に実行する．

$record = $state->fetchrow_arrayref; 検索結果 1 レコードを配列のリファレンスで受け取る．
データベースへの変更を反映する．使用するデータベース my $handle = DBI->connect($data_source,$handle->commit;

がトランザクションをサポートして，かつ AutoCommit が $username, $passwd, {Off(0)の場合に使用できる．
$handle->rollback;RaiseError => 1, AutoCommit => 0,

データベースへの変更を中止し破棄する．使用するデータ });ベ ー ス が ト ラ ン ザ ク シ ョ ン を サ ポ ー ト し て ， か つ eval {AutoCommit が Off(0)の場合に使用できる．

$handle->do(q{DELETE FROM table
WHERE status = 'DONE'});};
if ($@) {$handle->rollback;# clean up code
} else {$handle->commit;}$handle->disconnect;※ 6）参考 URL ： DBI - A Database Interface Module for perl5 http://www.symbolstone.org/technology/perl/DBI/
DBI マニュアル日本語訳 http://member.nifty.ne.jp/hippo2000/perltips/dbimemo.htm

68● WEB +DB PRESS Vol.1

特集3̲1 04.1.21 20:24 ページ69

第1章

基礎編： Perl 実行環境とモジュールの基礎知識
回接続処理を行う必要があり，実行効率が低下して

my $state = $handle->prepare(q{しまう恐れがありますが，mod̲perl の環境下ではApache::DBI を組み込むことで，スクリプトをまった

SELECT column1, column2 FROM table});く変更せずにデータベース接続を再利用し，この問題を回避することができます．

SQLの検索条件や値を動的に変更したい場合は，置き換える部分を ? で指定します．この ? の部分◎利用方法

をプレースホルダと呼びます．

DBI を使用してデータベースを操作する場合には，
まずデータベースに接続します．

my $state = $handle->prepare(q{SELECT name, email, age FROM table WHERE age == ?

use DBI;});

my $handle = DBI->connect($data_source, $username,$password);

prepare( )メソッドから返されるステートメントハンドル（この場合は$state）を使用して検索の実行や結connect( )メソッドの戻り値として返されるデータ

果の取得を行うことができます．
SQLの実行にはexecute( )を使用します．SQLにプ

ベースハンドル（この場合は $handle ）を通してデ

レースホルダが含まれる場合は，置き換えたい値のリータベースの操作を行います．
第1引数の $data̲source では，ドライバ名とデータベース名からなる文字列で接続するデータベース
を指定します．

ストを指定します．
$state->execute();$state->execute($age);dbi:DriverName:database_name

動的にSQL を変化させる場合に毎回 prepare( )で

dbi:DriverName:database_name@hostname:port
dbi:DriverName:database_name;host=hostname;port=port
ドライバ名の後に続く文字列は使用するデータベースによって異なりますので，DBDのマニュアルを参照

SQL をセットし使用していると，データベースエンジ
ンがSQLを解釈しなおすオーバーヘッドが増え，パフォーマンスを落とす原因になりますので意識的にプレースホルダを使用するようにします．
検索結果の取得には fetchrow̲arrayref( )メソッド

してください．
次にデータベースハンドルのprepare( )メソッドで，実行するSQL をセットします．

を使用します．
while (my $record = $state->fetchrow_arrayref) {print 'Name: ', $record->[0];●図 4 DBI のアーキテクチャ

print 'Email: ', $record->[1];print 'Age: ',ScriptPerl Script$record->[2];}DBI●表 3 DBI ドライバ一覧
DBI

DBD::Oracle

OracleDBD::Pg

PostgreSQL

DBD::ODBC

AccessRDBMS

ADOInformix

Solid

ASAny

IngresSybaseAdabasInterBase

Unify

Altera

ODBC

XBase

CSV

Oracle

mysql

DB2

Pg

mSQL

EmpressRAM

IllustraSearchServer

WEB +DB PRESS Vol.1 ● 69

特集3̲1 04.1.21 20:24 ページ70

Perl による ハイパフォーマンス
Web アプリケーションの開発

特集

3

Powered by mod_perl, Apache & MySQL
タベースに挿入するスクリプトをリスト4 に示します．

fetchrow̲arrayref( )メソッドは検索結果を1つずつ取り出し，配列のリファレンスを返します．すべての¡データの参照

要素を取り出し終えるとundefを返します．

テーブルの内容を表示するスクリプトをリスト5 にデータベースへの操作が終了したら，データベース

示します．

ハンドルのdisconnect( )メソッドを呼び出して切断を行います．

Apache::Session.pm$handle->disconnect();

Apache::Session.pm ※8 を使用するとセッション管理機能が利用できます（表4）．

以上が，DBI で検索処理を行う場合の例です．挿入や更新を行うINSERT やUPDATE などのSQL を発◎問題

行する場合は値を取り出す記述がなくなるだけで，ほぼ同じ手順で操作を行います．

Webアプリケーションにおいて最も頭の痛い問題がセッションの維持・管理です．受け取った情報をペー◎サンプルコード

ジを跨いで引き継いだり，過去の利用状況を参照して¡使用するデータベース

ページに反映させる場合にセッション管理機能が必要

MySQL

※7

になります．

のデータベース customer に含まれるテーブル language に，データを追加・検索する例

セッション管理を実現する方法にはデータをHTTPを示します．テーブル language には name ・Cookie に保存したり，フォームのhidden タグに埋め

version ・ url のカラムが含まれます（図5）．

込んだり，ファイルに保存したりとさまざまな方法がこのデータベースにはユーザID user ，パスワー

ありますが，どの方法も実装には大きな手間が生じま

ド password で接続します．

す．

¡データの挿入◎解法

標準入力からタブ区切りの文字列を受取り，デー●図 5 データベースの構造
language
nameversionurl●リスト 4

Apache::Session のサブクラスを利用することでこ
データ挿入スクリプト#!/usr/bin/perluse DBI;
my $handle = DBI->connect('dbi:mysql:customer','user', 'password');
my $state = $handle->prepare(q{INSERT INTO language (name, version, url) VALUES (?, ?, ?)});while (my $line = <>) {chomp $line;$state->execute(split /\t/, $line);}$handle->disconnect;__END__※ 7）参考 URL ： MySQL http://www.mysql.com/，Soft Agency（MySQL 日本総代理店）

http://www.SoftAgency.co.jp/

日本 MySQL ユーザ会 http://www.mysql.gr.jp/
参考書籍：『MySQL & mSQL』／ Randy jay Yarger，George Reese，Tim King 著／ソフトエージェンシー監訳／高見禎成，寺田美穂子訳／オライリー・ジャパン／ ISBN4-87311-011-4※ 8）参照 URL ： Apache::Session.pm manual page

http://www.perldoc.com/cpan/Apache/Session.html

Apache;Session マニュアル日本語訳

70● WEB +DB PRESS Vol.1

http://member.nifty.ne.jp/hippo2000/perltips/apache/Session.htm

特集3̲1 04.1.21 20:24 ページ71

第1章

基礎編： Perl 実行環境とモジュールの基礎知識
れらの繁雑な処理を記述することなく，セッション管

ます．サーバサイドに情報を蓄積することで，利用者理機能を利用することができます．

との間で不必要な情報の受け渡しが不要になります．

Apache::Sessionはセッション管理を実装するためのセッション情報をリレーショナルデータベースに格フレームワークで，セッション情報をMySQLやPostgre

納することで，複数のWeb サーバ間でセッション情SQL などのリレーショナルデータベースに格納する報を安全に共有することができます．これはクラスタ

Apache::Session::MySQL，Apache::Session::Postgres

リングしたWebサーバでWebアプリケーションを実行

や，テキストファイルに格納するApache::Session::File

する場合に有効です．

などさまざまな実装をバンドルしています．
Apache::Sessionはスカラー値をはじめとしてリファレンスによる複雑なデータ構造やオブジェクトなど，
データの型を問わずに格納・復元ができます．
また名称はApache::*ですがApache専用のモジュー
ルというわけではなく，他のhttpd でも問題なく動作
します．

◎利用方法
Apache::Sessionはtiedハッシュによりセッション情報の操作と格納を行います．このtiedハッシュを操作すると，自動的にデータベースやファイルの操作が行われます．
まずセッション管理を始めるために新しいセッションを開始します．

◎結果
セッション管理に関する繁雑な記述を簡略化できます．また，さまざまな管理方法を選択することができ

use Apache::Session::DB_File;my %session;tie %session, 'Apache::Session::DB_File',$session_id, {●リスト 5 テーブルの内容表示のスクリプト#!/usr/bin/perluse DBI;
my $handle = DBI->connect('dbi:mysql:customer','user', 'password');
my $state = $handle->prepare(q{SELECT name, version, url FROM language});$state->execute;
while (my $record = $state->fetchrow_arrayref) {printf "%s, %s, %s\n",$record->[0],# name$record->[1],# version$record->[3];# url}$handle->disconnect;__END__

FileName=> '/var/sessions.db',

LockDirectory => '/var/lock/sessions',};
ハッシュ%sessionにセッション情報を結び付けます．
新しくセッションを開始する場合，セッションID は
undefを指定します．
この例ではセッション情報を dbm に格納する
Apache::Session::DB̲File を使用していますので，セッション情報を格納するdbm ファイルへのパス名と，排他制御用のロックファイルを作成するディレクトリ
を指定します．リレーショナルデータベースなど独自●表 4 Apache::Session 簡易 API 表
API

内容

例

tie %hash, CLASS_NAME;%hash を指定したクラスに結合してセッション管理の対 use Apache::Session::MySQL;

tie %hash, CLASS_NAME, $session_id, 象にします．セッション ID に undef を指定すると新しいセ tie %session, 'Apache::Session::MySQL',\%option;ッションを開始します．

$session_id, {DataSource => 'dbi:mysql:sessions',};$hash{_session_id};

現在のセッション ID を参照します．

tied(%hash)->delete;

セッション情報を破棄します．

untie %hash;セッションを終了します．

WEB +DB PRESS Vol.1 ● 71

特集3̲1 04.1.21 20:24 ページ72

特集

3

Perl による ハイパフォーマンス
Web アプリケーションの開発
Powered by mod_perl, Apache & MySQLにロック機構を備えているものを利用する場合は，こ装を示します．セッション情報の管理にはdbm，セッの記述は必要ありません．

ションID の保持にはHTTP Cookie を使用します（リ後は通常のハッシュと同様に値の設定と参照を行う
ことができます．

スト6）．

HTML::Template.pm$session{name} = 'value';

HTML::Template.pm ※9 を使用するとテンプレート

print $session{name};を使用して，柔軟な動的HTML 生成が可能になりま

現在のセッションID は ̲session̲id から取得です．置換処理に関連する記述をカプセル化，デザインとプログラムロジックの分離が実現します．

きます．
print $session{_session_id};◎問題

この値をHTTP Cookie やパス情報に埋め込むことでページを跨いだ値の参照が可能になります．
セッション管理を終了する場合はtied ハッシュを
untie( )します．

Webアプリケーションの開発はロジックを記述する
プログラマと，利用者に対するGUIをデザインするデザイナの協調作業によって進行します．コードに直接HTMLを記述するとデザインとロジックが強く結びつき，変更に対して迅速な対応が難しくなってしまいま

untie %session;す．

再びセッション情報を取得する場合は，セッション
ID を指定してtied ハッシュを作成します．
Apache::Sessionはリファレンスやオブジェクトなど

PHP ※ 10 やASP（Active Server Pages）のように
HTMLへコードを埋め込む手法をとったとしても，同様の問題が起こり得ます．

データ型を問わずに格納と復元が可能ですが，リファ
レンスを格納する場合，Apache::Session は起点となるハッシュの値を変更したときのみデータを格納するということを意識する必要があります．

◎解法
HTML::Templateモジュールを使用することでデザインとロジックの分離が実現します．

たとえばリストのリファレンスを格納している場合，

HTML::Templateは要求を処理するスクリプトとはリファレンス先のリストに変更を行った場合でも「リ別にHTMLの雛型を定義するテンプレートファイルをファレンス自身」は何も変化していません．

使用します．動作時にテンプレートを読み込みデータ

このためセッション情報を格納する場合，起点のハを流し込むことで動的にHTMLを出力します．

ッシュにタイムスタンプを格納することが推奨されて

◎結果

います．

プログラムロジックとデザインの分離が実現し，そ$session{last_access} = time;

れぞれを個別に修正することができるようになります．

untie %session;

これによりプログラマとデザイナの作業範囲が明確になります．

◎サンプルコード

プログラムロジックからHTMLタグや置換処理を排¡アクセスカウンタ

除でき，見通しの良い保守しやすいコードが記述でき

Apache::Session を使用したアクセスカウンタの実るようになります．

※ 9）参照 URL ： HTML::Template.pm - SourceForge: CVS Repository http://sourceforge.net/cvs/?group_id=1075
HTML::Template マニュアル日本語訳 http://member.nifty.ne.jp/hippo2000/perltips/html/template.htm※ 10）参照 URL ： PHP: Hypertext Preprocessor

72● WEB +DB PRESS Vol.1

http://www.php.net/，日本 PHP ユーザ会 http://www.php.gr.jp/

特集3̲1 04.1.21 20:24 ページ73

第1章

基礎編： Perl 実行環境とモジュールの基礎知識●リスト 6 アクセスカウンタ#!/usr/bin/perl
use Apache::Session::DB_File;use CGI;
my $query = CGI->new;
my $session_id = $query->cookie(-name => 'session_id');
my %session
tie %session, 'Apache::Session::DB_File',$session_id, {FileName=> '/var/sessions.db',
LockDirectory => '/var/lock/sessions',};++$session{access};
my $html = <<__HTML_BODY__;<HTML><BODY>Your Access: $session{access}</BODY></HTML>__HTML_BODY__
my $state_cookie = $query->cookie(-name => 'session_id',-value => $session{_session_id},);
print $query->header(-cookie => $state_cookie);
print $html;__END__●リスト 7 HTML のテンプレートファイル定義●リスト 8 配列のリファレンス設定<HTML><BODY><TMPL_VAR name=LIST_NAME><TMPL_LOOP name=LANGUAGE>
Name: <TMPL_VAR name=NAME>
URL: <TMPL_VAR name=URL><HR></TMPL_LOOP></BODY></HTML>$html->param('LANGUAGE' => [{NAME => 'Perl',
URL => 'http://www.perl.com/',},{
NAME => 'Python',
URL => 'http://www.python.org/',},{
NAME => 'Ruby',
URL => 'http://www.ruby-lang.org/',},]);

コード記述の視点が「HTML タグ文字列の生成」
から「値の整形と代入」に変わることで，処理の内用が明確な見通しの良いコードを記述できます．またコのパスを指定し，HTML::Templateのインスタンスをード修正によるデザインへの影響，デザインの修正に生成します．

よるコードへの影響を最小限の範囲に閉じ込めることができます．

◎利用方法
HTMLのテンプレートファイルを定義します（リスト7）．
<TMPL̲VAR> と<TMPL̲LOOP> は
HTML::Template 用の特殊タグです．
new( )メソッドの引き数でテンプレートファイルへ

use HTML::Template;
my $html = HTML::Template->new(filename => '/path/to/template.html');
このインスタンス$html を通して値の設定や，置換結果の出力を行います．
<TMPL̲VAR> に対応する値を設定するために
param( )メソッドを使用します．テンプレートのパラ

WEB +DB PRESS Vol.1 ● 73

特集3̲1 04.1.21 20:24 ページ74

Perl による ハイパフォーマンス
Web アプリケーションの開発

特集

3

Powered by mod_perl, Apache & MySQL

メータ名と，設定する値を引数に指定します．
$html->param('LIST_NAME' => 'スクリプト言語');
HTML::Templateはテーブルなどループした要素の出力をサポートしています．<TMPL̲LOOP> タグの範囲がループ要素として扱い，ネストしたループも記指定したディレクトリのファイル一覧をHTMLで出力するテンプレートをリスト10 に示します．

¡ディレクトリ一覧を出力するスクリプトの定義
引数で指定したディレクトリの一覧をHTMLで出力するスクリプトをリスト11 に示します．

述可能です．
<TMPL̲LOOP>にはハッシュのリファレンスを出力まとめ順に列挙した配列のリファレンスを設定することで出力できます（リスト8）．

本章ではPerl の実行環境と，Web アプリケーショ

output( )メソッドでテンプレートへの処理結果を出力します．

ンの実装において問題に上がるフォームの処理，リレーショナルデータベースの操作，セッション管理，デ
ザインとロジックの分離に対応する解法をまとめましprint $html->output;

た．mod̲perl やFastCGI を使用すれば高速な実行環

この出力はリスト9 のようになります．
●リスト 11◎サンプルコード

指定ディレクトリ一覧を HTML で出力するスクリプト¡テンプレート directory.html の定義#!/usr/bin/perluse HTML::Template;●リスト 9my $directory = $ARGV[0] || './';
my $html = HTML::Template->new(filename => 'directory.html');

テンプレートへの出力結果<HTML><BODY>
スクリプト言語
Name: Perl
URL: http://www.perl.com/<HR>
Name: Python
URL: http://www.python.org/<HR>
Name: Ruby
URL: http://www.ruby-lang.org/<HR></TMPL_LOOP></BODY></HTML>●リスト 10

my $file_list = [];opendir DIR, $directory;
while (my $filename = readdir DIR) {push @{$file_list}, {NAME => $filename,
SIZE => -s $filename,};}$html->param(FILELIST => $file_list);$html->param(PATH => $directory);
print $html->output;__END__

指定ディレクトリ一覧を HTML で出力するテンプレート<HTML><HEAD><TITLE><TMPL_VAR name=PATH></TITLE></HEAD><BODY><TABLE><TR><TH>Name</TH><TH>Size</TH></TR><TMPL_LOOP name=FILELIST><TR><TD><A href="<TMPL_VAR name=NAME>"><TMPL_VAR name=NAME></A></TD><TD><TMPL_VAR name=SIZE></TD></TR></TMPL_LOOP></TABLE></BODY></HTML>

74● WEB +DB PRESS Vol.1

特集3̲1 04.1.21 20:24 ページ75

第1章

基礎編： Perl 実行環境とモジュールの基礎知識
境が手に入り，開発中に上がる課題のほとんどにはや保守性が要求されます．高速な実行環境と記述の「〜のモジュールを利用する」というシンプルかつ確

簡単さ，無料で使用できる豊富なコンポーネント，利実な回答が用意されています．

用者の多さ，オブジェクト指向のサポート等々．Perl

加速度的に発展するWeb アプリケーションの世界の持つこれらの特性は，変化の激しいWeb アプリケ

では，短期間に実装が完了することはもちろん，常にーションの世界で要求される要素と見事に合致してい変化・発展するサービスに柔軟に対応する機能拡張性

るのです．

◆

mod̲perlのインストール●パッケージのダウンロード
mod̲perl を使用するには，CPAN からパッケージをダ

同じ階層のディレクトリにパッケージを展開します．
> cd /usr/local/src

ウンロードしてインストールする必 要 があります．

> gzip -cd mod_perl-1.24.tar.gz | tar xvf -http://www.cpan.org/もしくは最寄りのCPAN ミラーサイ

mod_perl-1.24/

トにFTP で接続してパッケージをダウンロードします．

mod_perl-1.24/t/
mod_perl-1.24/t/docs/> ftp www.cpan.org
User: anonymous...
> cd mod_perl-1.24

331 Anonymous login ok, send your complete email address as password.
Password: your@email.address
ftp> cd /CPAN/modules/by-module/Apacheftp> ls mod_perl-*.tar.gz
mod_perl-1.21.tar.gz● Makefile.PL の実行
Makefile.PL ファイルを実行するとMakefile の生成と，Apache のconfigure スクリプトの実行によりhttpd にリンクするApache モジュールリストにmod̲perl が追加されます．

mod_perl-1.22.tar.gz
mod_perl-1.23.tar.gz> perl Makefile.PL

mod_perl-1.24.tar.gz

Configure mod_perl with ../apache_1.3.14/src

ftp>? [y] yShall I build httpd in ../apache_1.3.14/src for

ディレクトリ/CPAN/modules/by-module/Apache へ移動し，mod̲perl-*.tar.gz というファイルをダウンロード

you? [y] y...

します．この場合，最新バージョンのmod̲perl-1.24.tar.gz
をダウンロードします（Apache 1.3.14 を使用する場合

Makefile.PL は，まずApache のソースツリーの位置を

は mod̲perl-1.24̲01.tar.gz をダウンロードします．

確認を求めてくるので y と答えます．ソースツリーが/CPAN/

見つからない場合はパスを入力するように求めくるので，

authors/id/D/DO/DOUGM/mod̲perl-

1.24̲01.tar.gz）．

Apache のソースツリーへのフルパスを入力します．次にhttpd をビルドするか確認を求めてくるので yftp> get mod_perl-1.24.tar.gz

と答え

ます．

ftp> quit● make とmake test
●パッケージの展開
ダウンロードが完了したら，Apache のソースツリーとMakefile.PL が完了したら，make を実行してPerl モジ
ュールのビルドとmod̲perl を組み込んだhttpd のビルド

WEB +DB PRESS Vol.1 ● 75

特集3̲1 04.1.21 20:24 ページ76

Perl による ハイパフォーマンス
Web アプリケーションの開発

特集

3

Powered by mod_perl, Apache & MySQLを行います．

# cd ../apache_1.3.14/src# cp -p httpd /usr/local/apache/bin/> makemake が完了したらテストを実行します．テストの実行● Apache のconfigure スクリプトオプションの指にはLWP::UserAgent モジュールが必要です．テストを定必ず行う必要はありませんが，実行しておいた方が良い

Apache のconfigure スクリプトをオプションを指定しでしょう．

て実 行 する必 要 がある場 合 は， M a k e f i l e . P L のAPACI̲ARGS オプションを指定します．

> make test
> perl Makefile.PL APACI_ARGS="--enablemodule=rewrite,--disable-module=userdir"●インストール
テストが成功したらPerl モジュールのインストールを行います．
> su Password: xxxxxxxxx# make install

APACI̲ARGSで指定した文字列はApacheのconfigure
スクリプトに渡されます．

●プラットフォームごとの注意事項
mod̲perl のパッケージに含まれるINSTALL ドキュメ
ントには，インストールにおけるプラットフォームごとのこの時点では新しいhttpd はインストールされていませ注意事項がまとめられています．使用するプラットフォ

ん．Apacheのソースツリーへ移動して，新しくmod̲perl

ームについての記述に目を通しておくことをお勧めしまをリンクしたhttpd をコピーしインストールを完了します．

す．

mod̲perlの設定
mod̲perl はhttpd.conf で有効にしなければ機能しませAllowOverride Noneん．ここではCGI の高速化のためにmod̲perl を使用す

Options None

る設定について述べます．

Order allow,deny
Allow from all● Apache::Registry の使用</Directory>

Apache::RegistryはCGI用のPerlスクリプトをApacheのモジュールとして読み込み実行します．
Apache::Registry は1 度コンパイルしたスクリプトをキャッシングます．スクリプトを修正した場合このキャッシ
ュは破棄され，スクリプトを再度読み込みます．
スクリプトエイリアス/cgi-bin/をApache::Registry 用のディレクトリに修正する設定を行ってみましょう．
デフォルトのhttpd.conf には以下のようなScriptAlias
ディレクティブと，そのディレクトリに対する設定の記
述があります．

これを以下のように修正します．
<Directory "/usr/local/apache/cgi-bin">
SetHandler perl-script
PerlHandler Apache::Registry
AllowOverride None
Options +ExecCGI
Order allow,deny
Allow from all
PerlSendHeader Off</Directory><Directory "/usr/local/apache/cgi-bin">76● WEB +DB PRESS Vol.1

特集3̲1 04.1.21 20:24 ページ77

第1章

基礎編： Perl 実行環境とモジュールの基礎知識
SetHandler，PerlHandler，PerlSendHeader ディレ
クティブを追加し，Options ディレクティブに修正を加え● Apache::PerlRun の使用ました．これで/usr/local/apache/cgi-bin に設置したPerl

Apache::Registry はスクリプトのコンパイル結果と変スクリプトはApache::Resigtry の環境下で実行されます．

数のキャッシングにより高速なレスポンスを実現します

URL はhttp://hostname/cgi-bin/scriptname です．

が，グローバル変数に依存したスクリプトのほとんどは

1 度目のアクセスはスクリプトの読み込みとコンパイル

正しく動作しなくなります．

が行われるために，若干レスポンスが遅れますが，2 回目

Apache::PerlRun はApache::Registry とは異なり，コ以降のアクセスからは高速なレスポンスが帰ってくるはず

ンパイル結果とグローバル変数のキャッシングは行わず，です．

CGI と同様にリクエストの度にスクリプトをロードしコン
パイル・実行します．Perl インタープリタの起動に要す● Apache::DBI の追加
他のPerl モジュールを追加する場合は，PerlModule ディレクティブでモジュールを指定します．DBI によるデー
タベース接 続 を自 動 的 に再 利 用 するモジュール

るオーバーヘッドは発生しないため，Apache::Registry
程ではありませんがパフォーマンスアップが見込めます．
Apache::PerlRun の設定はApache::Registry とほぼ同じで，以下のように記述します．

Apache::DBI を追加してみましょう．
<Directory "/usr/local/apache/cgi-bin"><Directory "/usr/local/apache/cgi-bin">

SetHandler perl-script

SetHandler perl-script

PerlHandler Apache::PerlRun

PerlHandler Apache::Registry

AllowOverride None

PerlModule Apache::DBI

Options +ExecCGI

AllowOverride None

Order allow,deny

Options +ExecCGI

Allow from all

Order allow,deny

PerlSendHeader Off

Allow from all</Directory>

PerlSendHeader Off</Directory>

CGI 用に記述された大量のスクリプトも，
Apache::PerlRun を使用すれば高速化が可能なのです．

httpd.conf の修正後，httpd をリスタートすると設定がまたmod̲perl̲traps.pod にmod̲perl を利用するにあた

反映されます．接続処理に時間がかかるデータベースをって注意すべきポイントがまとめられていますので，目を使用する場合は，これだけで大幅な高速化が見込めます．

通しておくことをお勧めします．

CPANモジュールのインストール●パッケージのダウンロード
標準添付しているcore モジュール以外の物を使用する

http://www.cpan.org/modules/by-module/
Apache/mod_perl-1.24.tar.gz

ときには，CPAN からパッケージをダウンロードしてイン

http://www.cpan.org/modules/by-module/DBI/DBI-

ストールする必要があります．

1.14.tar.gz
http://www.cpan.org/modules/by-module/

http://www.cpan.org/
上記URL もしくは最寄のCPAN ミラーサイトにFTP で接続してパッケージをダウンロードします．

Apache/Apache-Session-1.53.tar.gz
http://www.cpan.org/modules/by-module/HTML/HTMLTemplate-2.0.tar.gz

WEB +DB PRESS Vol.1 ● 77

特集3̲1 04.1.21 20:24 ページ78

Perl による ハイパフォーマンス
Web アプリケーションの開発

特集

3

Powered by mod_perl, Apache & MySQL●インストール
それぞれのパッケージをダウンロードした後，パッケー
ジを解凍，Makefile.PL を実行し，make します．

まれるINSTALL やREADME などのドキュメントに必ず目を通してからインストール作業を行います．
以上でモジュールのインストールは完了です．また，
root 権限がない場合や，ホームディレクトリにインスト> gzip -cd package.tar.gz | tar xvf > cd package/ールしたい場合は Makefile.PL の PREFIX オプションでインストール先ディレクトリを指定してからmakeします．

> perl Makefile.PL> make> perl Makefile.PL PREFIX=/path/to/install/directory> make test

> make> make test

make とmake test が成功したらroot になってインスト> make installールします．
> su Password: xxxxxxxxxx# make install●マニュアルの参照
モジュールのマニュアルは perldoc で参照することができます．
> perldoc ModuleName●インストールに際しての注意
パッケージによっては別途ファイルが必要な物やインス
トール手順が異なる物もありますので，パッケージに含

また，http://www.perldoc.com/ などオンラインでマニ
ュアルを参照することも可能です．

オブジェクト指向プログラミング言語の中でも，Javaは比較的初学者が学習しやすい言語と言えます．
本書はJava初心者，とくにはじめてのプロ
グラミング言語としてJavaを選択したプログラマを対象に，文献や資料，コードを解読する際によく登場する用語をアルファベット
順に解説してあります．付録として，Java 2
SDKのクラス一覧やJava情報源を掲載しています．

村上列 監修Java用語研究会 著
四六判／400頁／本体価格2380円＋税

78● WEB +DB PRESS Vol.1