Object Oriented Perl DocumentWorkSpace

 Object Oriented Perl DocumentWorkSpace>>


<<CONTACT>>

下記フォームに必要事項を入力後、確認ボタンを押してください。

お問い合わせ内容
お名前 ※必須
電話番号(半角)
Mail(半角) ※必須
性別 男 
サイトを知ったきっかけ 友人・知人  検索エンジン
お問い合わせ内容

 

Ⅳ.Perl Catalyst PROGAMMING

1.Catalyst FormAction vol.01

前回はSQLiteデータベースを仕様したMVCパターンの実装を書かせて頂きましたが、今回はフォームからそのデータベースの操作を行うリクエストオブジェクトを使ったフォームの開発を進めていきます。ViewクラスはViewクラスは前回から引き続きそのまま使用して進めていきます。

(1) リクエストオブジェクトの実装-Formアクション-

 リクエストオブジェクトはCatalyst :: Engineによって実装されクライアント要求のデータをインターフェースに提供するCatalyst Requestクラスのことです。リクエストオブジェクトはコンテキストオブジェクトから[$c->req]又は[$c->request]と記述しリクエストメソッドによって要求したデータを画面に返します。リクエストオブジェクトを使って取得するリクエスト情報はこのリクエストメソッドによって実現されます。まずは簡単なポストデータを表示するフォームアクションを作成して説明をしていきます。  このフォームアクションはユーザーがフォームに入力したデータを画面に返すプログラムです。コントローラモジュールとViewテンプレートツールのみで作成します。まずコントローラクラスを次のとおりに作成してください。
C:\data\Hello\script>hello_create.pl controller request
 exists "C:\data\Hello\lib\Hello\Controller"
 exists "C:\data\Hello\t"
 exists "C:\data\Hello\lib\Hello\Controller\request.pm"
created "C:\data\Hello\lib\Hello\Controller\request.pm.new"
 exists "C:\data\Hello\t\controller_request.t"
 コントローラクラスが作成されたらフォームアクションとフォームからのポストデータを返すレスポンスアクションを作成します。今回、HTMLフォームから入力された名前/住所/メール/ドキュメントをresponse.ttで受け取り表示します。フォームアクションは空のアクションメソッドを使用します。ここではポストデータを取得するリクエストオブジェクトクラスのbody_params(body_parameters)メソッドを使用して受け取ったデータを表示しています。
sub form :Local { }

sub response :Local {
	my ( $self, $c ) = @_;
	#body_paramsメソッド[$c->request][$c->req]でサーバに送信する
	$c->stash->{nam1} = $c->request->body_params->{'nam1'};
	$c->stash->{add1} = $c->request->body_params->{'add1'};
	$c->stash->{mail1} = $c->request->body_params->{'mail1'};
	$c->stash->{document} = $c->request->body_params->{'document'};
}
 次にテンプレートファイルを作成します。入力フォームページとリクエスト情報を表示するレスポンスページを作成します。
[form.tt]
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="stylesheet.css" >
<meta charset="UTF-8">
<title>ポストデータ</title>
</head>
<body>
<h1>リクエストオブジェクトテスト</h1>
<p>
<form method="post" action="/request/response">
<ul><li>名 前:  <input type="text" name="nam1" size="20" maxlength="255"/></li>
<br>
<li>住 所:  <input type="text" name="add1" size="20" maxlength="255"/></li>
<br>
<li>E-Mail:  <input type="text" name="mail1" size="20" maxlength="255"/></li>
<br>
<li>お問い合わせ内容:<br><input type="text" name="document" size="80" maxlength="255"/></li></ul>
<input type="submit" value="送信"/>
</form>
</p>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="stylesheet.css" >
<meta charset="UTF-8">
<title>リクエスト情報表示</title>
</head>
<body>
<h1>リクエストオブジェクトテスト</h1>
<p>
Hello!! [% nam1 | html %]さん<br>
<ul><li>Name:[% nam1 | html %]</li>
<li>Address:[% add1 | html %]</li>
<li>E-mail:[% mail1 | html %]</li>
<li>Document:[% document | html %]</li></ul>
</p>
</body>
</html>
 最後に開発サーバーを立ち上げ、localhost:3000/request/formのアドレスを入力して表示内容を確認します。フォーム入力画面からデータを入力してレスポンスページでポストデータが表示されれば成功です。これが簡単なCatalyst リクエストオブジェクトの実装です。 (2) リクエストメソッドの種類  リクエストオブジェクトには次の種類があります。簡単にご紹介します。
●$c->request->address;
クライアントのIPアドレスを返します。
●$c->request->arguments;
引数を含む配列への参照を返します。
●$c->request->args;
引数を返します。
●$c->request->base;
URIベースを含むベースアドレスを返します。開発サーバで使用した場合はhttp://localhost:3000/が返されます。
●$c->request->body;
要求されたメッセージをHTTP:bodyに返します。
●$c->request->body_data;
JSON、XMLなどの古典的なHTMLフォームデータではないボディデータをPerl表現で返します。
●$c->request->body_parameters;
ボディ(POST)パラメータを含むハッシュへのリファレンスを返します。値は、スカラーまたはスカラーを含む配列参照のいずれかになります。
●$c->request->body_params;
body_parametersのショートカットです。
●$c->request->content_encoding;
$ req-> headers-> content_encodingのショートカットです。
●$c->request->content_length;
$ req-> headers-> content_lengthのショートカットです。
●$c->request->content_type;
$ req-> headers-> content_typeのショートカットです。
●$c->request->cookie;
Cookieにアクセスする方法です。
●$c->request->cookies;
クッキーを含むハッシュへのリファレンスを返します。例 $c->request->cookies->{mycookie}->value;でmycookieの値を返します。
●$c->request->header;
$ req-> headers->ヘッダーのショートカットです。
●$c->request->headers;
現在のリクエストのヘッダーを含むHTTP :: Headersオブジェクトを返します。
●$c->request->hostname;
クライアントのホスト名を返します。例 $c->request->uri->hostname ではサーバーのホスト名を取得するために使用します。
●$c->request->query_keywords;
クエリ文字列のキーワード部分を返します。
●$c->request->param;
CGI.pmと互換性のあるparamメソッドを使用してGETとPOSTのパラメータ値を返します。これは、$c-> req->parameters で取得するデータにアクセスする別の方法です。
●$c->request->parameters;
GETとPOSTのパラメータを含むハッシュへのリファレンスを返します。値は、スカラーまたはスカラーを含む配列参照のいずれかになります。
●$c->request->params;
$c->request->parameters;のショートカットです。
●$c->request->path;
$ req-> baseの後のURIの部分を返します。
●$c->request->protocol;
現在のリクエストに使用されているプロトコル(HTTP / 1.0またはHTTP / 1.1)を返します。
●$c->request->query_parameters;
クエリ文字列(GET)パラメータを含むハッシュのリファレンスを返します。
●$c->request->referer;
$ req-> headers-> refererのショートカットです。参照ページを返します。
●$c->request->query_parameters;
クエリ文字列(GET)パラメータを含むハッシュのリファレンスを返します。
●$c->request->secure;
httpsでの通信が安全かどうかを示すtrueまたはfalseを返します。信頼性はサーバーの構成によって異なる場合があります。CatalystはPSGIを利用して要求が安全であるかどうかを判断しています。
●$c->request->upload;
$req-> uploadsにアクセスする便利な方法です。
●$c->request->uploads;
アップロードを含むハッシュへのリファレンスを返します。
●$c->request->uri;
現在のリクエスト要求のURIオブジェクトを返します。
●$c->request->user_agent;
$ req-> headers-> user_agentへのショートカットです。ユーザーエージェント(ブラウザ)のバージョンの文字列を返します。

(3) フォームアクションからのデータベースアクセス

 では次に実際にフォームアクションからデータベースに接続するプログラムを作成します。データベースは前回同様のサンプルデータベースを使用します。
[サンプルデータベースSQL]
--
-- Create a very simple database to hold book and author information
--
PRAGMA foreign_keys = ON;
CREATE TABLE book (
        id          INTEGER PRIMARY KEY,
        title       TEXT ,
	review       TEXT ,
        rating      INTEGER,
	price 		INTEGER,
	published	BLOB
);
-- 'book_author' is a many-to-many join table between books & authors
CREATE TABLE book_author (
        book_id     INTEGER REFERENCES book(id) ON DELETE CASCADE ON UPDATE CASCADE,
        author_id   INTEGER REFERENCES author(id) ON DELETE CASCADE ON UPDATE CASCADE,
        PRIMARY KEY (book_id, author_id)
);
CREATE TABLE author (
        id          INTEGER PRIMARY KEY,
        first_name  TEXT,
        last_name   TEXT
);
---
--- Load some sample data
---
INSERT INTO book VALUES (1, 'CCSP SNRS Exam Certification Guide','Very Good',5,5000,'2010-10-1');
INSERT INTO book VALUES (2, 'TCP/IP Illustrated, Volume 1','Very Good', 5,1200,'2009-10-1');
INSERT INTO book VALUES (3, 'Internetworking with TCP/IP Vol.1','Good', 4,2200,'2008-5-5');
INSERT INTO book VALUES (4, 'Perl Cookbook','Good', 5,800,'2014-2-5');
INSERT INTO book VALUES (5, 'Designing with Web Standards','Very Good',5,3200,'2011-6-7');
INSERT INTO author VALUES (1, 'Greg', 'Bastien');
INSERT INTO author VALUES (2, 'Sara', 'Nasseh');
INSERT INTO author VALUES (3, 'Christian', 'Degu');
INSERT INTO author VALUES (4, 'Richard', 'Stevens');
INSERT INTO author VALUES (5, 'Douglas', 'Comer');
INSERT INTO author VALUES (6, 'Tom', 'Christiansen');
INSERT INTO author VALUES (7, 'Nathan', 'Torkington');
INSERT INTO author VALUES (8, 'Jeffrey', 'Zeldman');
INSERT INTO book_author VALUES (1, 1);
INSERT INTO book_author VALUES (1, 2);
INSERT INTO book_author VALUES (1, 3);
INSERT INTO book_author VALUES (2, 4);
INSERT INTO book_author VALUES (3, 5);
INSERT INTO book_author VALUES (4, 6);
INSERT INTO book_author VALUES (4, 7);
INSERT INTO book_author VALUES (5, 8);
 ではコントローラクラスモジュールの作成をします。コントローラモジュール[request.pm]に次のプログラムを追加してください。 このプログラムは前述同様にentry_formは空で作成し、[update_or_create_form]サブルーチンでレコードを登録又はデータが存在している場合には更新しています。 データを登録または更新する場合は[update_or_new]メソッドを使用します。また文字化け対応としてリクエストデータの[message]はデコードして表示しています。
[request.pm]
sub entry_form:Local { }

sub update_or_create_form :Local {
	my ( $self, $c ) = @_;

	#レコードの有無チェック、存在する場合は更新
	my $book = $c->model('BookDB::Book')->update_or_new({
	id=>$c->request->body_params->{'id'},
	title=>$c->request->body_params->{'title'},
	review=>$c->request->body_params->{'review'},
	rating=>$c->request->body_params->{'rating'},
	price=>$c->request->body_params->{'price'},
	published =>$c->request->body_params->{'published'}
	});

	#レコードがすでに存在していた場合はエラーメッセージを表示
	if($book->in_storage) {
    #body_paramsメソッド[$c->request][$c->req]でサーバに送信する
	$c->stash->{message} =decode('sjis','データを更新しました。');
	$c->stash->{id} = $c->request->body_params->{'id'};
	$c->stash->{title} = $c->request->body_params->{'title'};
	$c->stash->{review} = $c->request->body_params->{'review'};
	$c->stash->{rating} = $c->request->body_params->{'rating'};
	$c->stash->{price} = $c->request->body_params->{'price'};
	$c->stash->{published} = $c->request->body_params->{'published'};
	} else {
    #レコードが存在しない場合は登録
	$book->insert();
    #body_paramsメソッド[$c->request][$c->req]でサーバに送信する
	$c->stash->{message} =decode('sjis','データを新規に登録しました。');
	$c->stash->{id} = $c->request->body_params->{'id'};
	$c->stash->{title} = $c->request->body_params->{'title'};
	$c->stash->{review} = $c->request->body_params->{'review'};
	$c->stash->{rating} = $c->request->body_params->{'rating'};
	$c->stash->{price} = $c->request->body_params->{'price'};
	$c->stash->{published} = $c->request->body_params->{'published'};
	}
}
#######################################################################
次にデータ入力画面の[entry_form.tt]とリクエスト情報を表示する[update_or_create_form.tt]を記述します。
[entry_fom.tt]
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="stylesheet.css" >
<meta charset="UTF-8">
<title>リクエストオブジェクト</title>
</head>
<body>
<h1>エントリーフォーム―データベースアクセス―</h1>
<p>
<form method="post" action="/request/update_or_create_form">
<table><tr><td style="width:150px;">ID:</td><td><input type="text" name="id" size="4" maxlength="255"/></td></tr>
<tr><td>タイトル:</td><td><input type="text" name="title" size="40" maxlength="255"/></td></tr>
<tr><td>レビュー:</td><td><input type="text" name="review" size="80" maxlength="255"/></td></tr>
<tr><td>プライス:</td><td><input type="text" name="price" size="10" maxlength="255"/></td></tr>
<tr><td>レーティング:</td><td><input type="text" name="rating" size="20" maxlength="255"/></td></tr>
<tr><td>出版日:</td><td><input type="text" name="published" size="10" maxlength="255"/></td></tr></table>
<input type="submit" value="送信"/>
</form>
</p>
</body>
</html>
[update_or_create_form.tt]
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="stylesheet.css" >
<meta charset="UTF-8">
<title>リクエストオブジェクト</title>
</head>
<body>
<h1>リクエストフォーム―データベースアクセス―</h1>
<p>
[% message | html %]<br>
<ul>
<li>ID:[% id | html %]</li>
<li>title:[% title | html %]</li>
<li>Review:[% review | html %]</li>
<li>Rating:[% rating | html %]</li>
<li>Price:[% price | html %]</li>
<li>Published:[% published | html %]</li></ul>
</p>
</body>
</html>
 開発サーバーを立ち上げ[http://localhost:3000/request/entry_form]を開いてエントリーフォームからデータを入力してください。[update_or_create_form]ページが表示されれば、入力されたデータがデータベースにアクセスしておりデータ登録/更新ができていることになります。