UNIX
実験レポート
テーマ:RSS Reader
の作成
e015736
照屋 要介:Level2
e055725
自念 政司:Level1
e055726
島袋 拓也:Level4
e055727
條 寛之:Level2
e055729
新垣 翔太:Level3
e055743
仲里 直朗:Level4
2008
年 1 月 13 日 日曜日
1
Level1 RSS
について
ニュースサイトや、ブログなどの更新情報をまとめ、配信するための文章フォーマットの総称。 • RSS 0.9 – 1999年、ネットスケープコミュニケーション社が自社のポータルサイト「My Scape」 の「チャンネル」の詳細を記述するために策定した。RDF 構文が用いられているため、 RDF Site Summaryと呼ばれる。 • RSS 0.91 – RSS 0.9に要素を拡張する目的で作られたもので、RDF を用いずに、独自の XML で 記述されている。Rich Site Summary と改名された。• RSS 1.0 – RSSでよく使われる語彙や要素群を「コア」と定義し、それ以外は拡張する側がモジュー ルとして定義する。再び RDF が使われる。 • RSS 2.0 – RSS 0.91から 0.94 までの全てのフォーマットに対する互換性を保証した規格。Really Simple Syndicationと呼ばれる。RSS2.0 は RSS 0.9x の流れを汲む規格であり、RSS 1.0の後継規格ではない。 これらの他のフィード技術に Atom がある。
1.1
Atom
とは
Atomは Web 上の各種コンテンツを配信するための XML 文書フォーマット及び、コンテンツ の編集を行うための通信プロトコルなどの使用群。主な仕様は• Atom 配信フォーマット (Atom Syndication Format) • Atom 出版プロトコル (Atom Publishing Protocol)
の2つである。Atom 配信フォーマットはコンテンツを配信するためのフィードのフォーマットで あり、Atom 出版プロトコルは Web 上のコンテンツを編集するためのものである。ここでは Atom 配信フォーマットのついて説明する。
Atom配信フォーマットは、ウェブサイトの更新情報のメタデータやコンテンツの配信、保存を
受け持つ XML 文書の仕様。RSS リーダーで購読する際に用いられるファイルはこの形式で記述さ れている。
2
Level2
環境構築
PHP5,MySQL,Apache
のインストール
2.1
Apache
のインストールと設定の手順
2.1.1 Apacheインストール
[e055727@pw147 ~]# yum -y install httpd ← Apache インストール
[e055727@pw147 ~]# yum -y install php php-mbstring ← php、php-mbstring インス トール
2.1.2 Apache設定
[e055727@pw147 ~]# vi /etc/httpd/conf/httpd.conf ← Apache 設定ファイル編集 ServerTokens OS ↓ ServerTokens Prod ← エラーページ等で OS 名を表示しないようにする ServerAdmin root@localhost ↓ ServerAdmin [email protected] ← エラーページ等に表示される管理者 メールアドレスを指定 #ServerName www.example.com:80 ↓ ServerName pw147.cs.ie.u-ryukyu.ac.jp:80 ← サーバー名を指定 <Directory "/var/www/html"> #
# Possible values for the Options directive are "None", "All", # or any combination of:
# Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews #
# Note that "MultiViews" must be named *explicitly* --- "Options All" # doesn’t give it to you.
#
# The Options directive is both complicated and important. Please see # http://httpd.apache.org/docs-2.0/mod/core.html#options
# for more information. #
Options Indexes FollowSymLinks ↓
#
# AllowOverride controls what directives may be placed in .htaccess files. # It can be "All", "None", or any combination of the keywords:
# Options FileInfo AuthConfig Limit #
AllowOverride None ↓
AllowOverride All ← .htaccess の許可
#
# For a single logfile with access, agent, and referer information # (Combined Logfile Format), use the following directive:
#
SetEnvIf Request_URI "default\.ida" no_log ← 追加 (worm からのアクセスをログに記 録しない)
SetEnvIf Request_URI "cmd\.exe" no_log ← 〃 SetEnvIf Request_URI "root\.exe" no_log ← 〃 SetEnvIf Request_URI "Admin\.dll" no_log ← 〃 SetEnvIf Request_URI "NULL\.IDA" no_log ← 〃
SetEnvIf Remote_Addr 192.168.1 no_log ← 追加 (内部からのアクセスをログに記録しな い)
SetEnvIf Remote_Addr 127.0.0.1 no_log ← 追加 (自ホストからのアクセスをログに記録 しない)
CustomLog logs/access_log combined env=!no_log ← 上記以外のアクセスをログに記録 する
ServerSignature On ↓
ServerSignature Off ← エラーページ等で Apache のバージョンを表示しないようにする
#AddHandler cgi-script .cgi ↓
AddHandler cgi-script .cgi .pl ← CGI スクリプトに.pl を追加
\subsection{Perlコマンドへ/usr/local/bin/perl でもアクセスできるようにする。}
[e055727@pw147 ~]# ln -s /usr/bin/perl /usr/local/bin/perl ← /usr/local/bin/perl から/usr/bin/perl へリンクをはる
[e055727@pw147 ~]# whereis perl ← Perl のパスを確認
perl: /usr/bin/perl /usr/local/bin/perl /usr/share/man/man1/perl.1.gz ← Perl のパスに/usr/local/bin/perl が表示されることを確認
2.2
Apache
起動
[e055727@pw147 ~]# sudo /etc/rc.d/init.d/httpd start ← Apache 起動
httpd を起動中: [ OK ]
以上の手順で行った。
2.3
MySQL
のインストールと設定の手順
2.3.1 MySQLインストール
[e055727@pw147 ~]# yum -y install mysql-server ← mysql-server インストール
2.3.2 MySQL設定
[e055727@pw147 ~]# vi /etc/my.cnf ← MySQL 設定ファイル編集 [mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
# Default to using old password format for compatibility with mysql 3.x # clients (those using the mysqlclient10 compatibility package).
old_passwords=1
default-character-set = utf8 ← 追加 (MySQL サーバーの文字コードを UTF-8 にする)
以下を追加 (MySQL クライアントの文字コードを UTF-8 にする) [mysql]
default-character-set = utf8
2.3.3 MySQL起動
[e055727@pw147 ~]#sudo /etc/rc.d/init.d/mysqld start ← MySQL 起動
MySQL を起動中: [ OK ] 以上の手順で行った。
2.4
php
について
PHP は Web サーバに置かれるソフトウエアの Apache モジュールとして動作するスクリプ ト言語を実行する環境を指す。PHP は、HTML 埋め込み型のサーバサイド・スクリプト言語とし て分類され、この言語処理系自体は、C 言語で記述されている。ウェブサーバ上で動作し、ウェブ サーバ上の文書が要求されるたびに、この文書に記述された PHP のプログラムを実行し、その結 果をウェブブラウザに対して送信する。3
Level3 CakePHP
について
CakePHPは PEAR など外部ライブラリを必要としない、PHP4 と PHP5 で利用できる高性能 PHPフレームワークである。Ruby on Rails の良い所を取り入れ、たいていのサーバに入ってい る PHP での高速開発を可能にする。MVC,ActiveRecord, Association Data Mapping, フロントコ
ントローラといったよく使用されるパターンを採用している。「あらゆるレベルの PHP ユーザが、
堅牢な WEB アプリケーションを作成できること」を目標に開発が続けられており、Google トレ ンドでは現在のところ、PHP フレームワークとして 1 位である。
3.1
Cake
を用いたシンプルなブログアプリケーションの作成
Cakeを使って投稿(post)を list(一覧表示), add(追加), edit(編集), delete (削除)でき る最低限のアプリケーションを作成する。事前準備として MySQL によるデータベースの作成 (図 ??)と設定を済ませておく。 図 1: MySQL 階層は以下の様になっている。 /cake/app/models/post.php //データベースとやり取りする Cake モデル /cake/app/views/posts/add.thtml //投稿の追加 /cake/app/views/posts/edit.thtml //投稿の編集 /cake/app/views/posts/index.thtml /cake/app/views/posts/view.thtml //indexアクションに対するビュー /cake/app/controllers/posts_controller.php //post用のコントローラー
3.2
ソースファイルと相互関係
posts controller.phpのソースを以下に示す。 <?php
class PostsController extends AppController {
var $name = ’Posts’;
function index() { $this->set(’posts’, $this->Post->findAll()); } function view($id) { $this->Post->id = $id; $this->set(’post’, $this->Post->read()); } function add() { if (!empty($this->data)) { if ($this->Post->save($this->data)) {
$this->flash(’Your post has been saved.’,’/posts’); } } } function delete($id) { $this->Post->del($id);
$this->flash(’ id: ’.$id.’ の投稿は削除されました。’, ’/posts’); }
function edit($id = null) {
if (empty($this->data)) {
$this->Post->id = $id;
} else { if ($this->Post->save($this->data[’Post’])) { $this->flash(’投稿を更新しました。’,’/posts’); } } } } ?> ソース内の function に対応するアクションが app/veiws/posts/にそれぞれ定義されている。
3.3
ソースの解説
3.3.1 index() function index() { $this->set(’posts’, $this->Post->findAll()); } このアクションの中では、 set() という命令を使って、データをビューに渡している。この行に よって、ビューの中には、’posts’ という変数がセットされ、中身は、Post モデルの findAll() メ ソッドが返した値と同じである。Cake の命名規約に従っているため、 Post モデルは自動的に、 $this-¿Postで利用できるようになっている。 3.3.2 view() function view($id) { $this->Post->id = $id; $this->set(’post’, $this->Post->read()); } 投稿情報を一つしか必要としないため、先ほどの index ファンクションで用いた findAll() ではな く read() を使用する。この view アクションはパラメータを取る。このパラメータは、 URL が呼 ばれた時にアクションに渡される。ユーザが /posts/view/3 をリクエストすると、 ’3’ という値が $idとして渡される。/app/views/posts/view.thtml のソースは次のようになっている。<h1><?php echo $post[’Post’][’title’]?></h1>
<p><small>作成日: <?php echo $post[’Post’][’created’]?></small></p> <p><?php echo $post[’Post’][’body’]?></p>
3.3.3 add() function add() { if (!empty($this->data)) { if ($this->Post->save($this->data)) {
$this->flash(’Your post has been saved.’,’/posts’); }
} }
もし、フォームデータが empty (空)でない場合は、そのデータを post モデルに保存する。 ユーザがアプリケーションからフォームを使って POST データを送信した場合、その情報は $this-¿paramsでアクセスできる。$this-¿data は、 $this-¿params[’data’] の別名である。
呼んでいる $this-¿flash() 関数は、ユーザにメッセージを 1 秒表示し、その後、他の URL (こ の場合は、 /posts)に転送するコントローラの関数である。 3.3.4 delete() function delete($id) { $this->Post->del($id);
$this->flash(’ id: ’.$id.’ の投稿は削除されました。’, ’/posts’); }
$idで指定された投稿を削除し、/posts にリダイレクトする前に、 flash() を使ってユーザに確認 メッセージを表示する。
3.3.5 edit()
function edit($id = null) { if (empty($this->data)) { $this->Post->id = $id; $this->data = $this->Post->read(); } else { if ($this->Post->save($this->data[’Post’])) { $this->flash(’投稿を更新しました。’,’/posts’);
} } } 送信されたデータをチェックし、何も送信されていない場合には、投稿を見つけて、それをビュー に渡す。もしデータが送信されている場合には、Post model に保存する。 editビューは次のようになる。 <h1>投稿の編集</h1>
<form method="post" action="<?php echo $html->url(’/posts/edit’)?>"> <?php echo $html->hidden(’Post/id’); ?>
<p>
タイトル:
<?php echo $html->input(’Post/title’, array(’size’ => ’40’))?>
<?php echo $html->tagErrorMsg(’Post/title’, ’タイトルは必ず入力してくださ い。’) ?>
</p> <p>
本文:
<?php echo $html->textarea(’Post/body’, array(’rows’=>’10’)) ?>
<?php echo $html->tagErrorMsg(’Post/body’, ’本文は必ず入力してください。’) ?> </p> <p> <?php echo $html->submit(’保存’) ?> </p> </form>
3.4
動作確認
作成した web アプリケーションを実行してみる (図??)。データベースに入っている記事の一覧 が確認できる。それぞれの記事のタイトルをクリックすると、個別の記事を確認できる (図??)。図 2: ブログアプリケーション
4
level4:CakePHP
を利用した
RSS
リーダー「あるあるリスト」
の作成
CakePHPを利用した Web アプリケーション型の RSS リーダー「あるあるリスト」を作成する。 図 4: 動作中のあるあるリスト4.1
データベースの構築
RSSフィードの URL や利用者の情報を記録するためのデータベースを構築する。データベース名はサイト名と同じ「aruarulist」とした。データベース構築の際に使用した SQL 文は create tables.sql というファイルに記録してある。以下に SQL 文の一部を示す。
CREATE TABLE users (
id int NOT NULL auto_increment, name varchar(255) NOT NULL, passward varchar(50) NOT NULL, address varchar(50) NOT NULL, created datetime default NULL, modified datetime default NULL, UNIQUE KEY address (address), UNIQUE KEY name (name),
UNIQUE KEY passward (passward), PRIMARY KEY (id)
); これはユーザー情報を記録するためのテーブル「users」を作成する SQL 文である。テーブル名は CakePHPの規約によりい、英語の複数形でなくてはならない。また、レコードのプライマリキー は id とし、auto increment でなければならない。以下に各フィールドの概要を示す。 • id:プライマリキー • name:ユーザ名 • passward:ユーザパスワード • address:ユーザのメールアドレス • created:レコードの作成時刻 • modified:レコードの変更時刻
CREATE TABLE feeds (
id int NOT NULL auto_increment, user_id int NOT NULL,
url varchar(255) NOT NULL, title varchar(255) NOT NULL, click int default ’0’,
description text default NULL, created datetime default NULL, modified datetime default NULL, UNIQUE KEY url (url),
PRIMARY KEY (id) ); これは RSS フィードを登録するためのテーブルである。user id は users テーブルを参照するた めの外部キーである。CakePHP は後述するアソシエーションという機能があるため、外部キーに foreign keyと指定する必要はない。アソシエーションを利用する場合、外部キーは「参照するテー ブル名に単数形」 id とする必要がある。以下に各フィールドの概要を示す。 • id:プライマリキー • user id:users テーブルを参照するための外部キー • url:RSS フィードの URL • title:RSS フィードの配信元のサイト名 (任意) • click:フィードの参照数をカウントする • description:フィードの説明 • created:レコードの作成時刻 • modified:レコードの変更時刻
4.2
モデルの作成
CakePHPにおけるモデルは MVC パターンの M に当たり、データベースの特定のテーブルを 意味するものである。モデルファイルにはアソシエーションルールや、データバリデーションルー ルを記述する。モデルファイルは/app/models/の中に設置する。以下に users テーブルに対応す るモデル User を示す。 /app/models/user.php <?phpclass User extends AppModel {
var $name = ’User’;
var $hasMany = array(’Feed’ => array(’className’ => ’Feed’, ’order’ => ’Feed.created DESC’, ’foreignKey’ => ’user_id’, ’dependent’ => false, ’exclusive’ => false )
);
var $validate = array( ’name’ => VALID_NOT_EMPTY, ’passward’ => VALID_NOT_EMPTY, ); } ?> モデルファイル名はテーブル名の単数形、クラス名はテーブル名の単数形に頭文字を大文字にし たものにし、必ず AppModel を継承する必要がある。変数 name にはクラス名を指定する。変数 hasmanyにはアソシエーションルールを記述した連想配列を代入する。変数 validate にはデータ バリデーションルールを記述した連想配列を代入する。 4.2.1 アソシエーションとは CakePHPのアソシエーションは、モデル間の関連情報を記述するものである、アソシエーショ ンには hasOne、hasMany、belongsTo、hasAndBelongsToMany の四つがある。前述の user.php の場合、ユーザー hasMany フィードとなり、一人のユーザが 0 個以上のフィードを持っているこ とを意味する。例として、id が 1 のユーザ hoge がいるとする。このとき、feeds テーブルに user id が 1 のレコードがあった場合、後述の find や findAll といったメソッドを使って、ユーザ hoge の レコードを取得すると、feeds テーブルのレコードも同時に取得することができる。
4.2.2 データバリデーションとは CakePHPのデータバリデーションとは、データの検証ルールを記述するものである。データバ リデーションのルールは連想配列を使用し、キーにはデータを検証したいフィールド名を指定す る。データの検証は後述の save メソッドを実行する際に自動的に行われる。前述の user.php の場 合、name、passward が空の場合にエラーを返す。検証ルールには CakePHP 内で定義されている 定数の他に、自分で正規表現パターンを指定することも可能である。
4.3
コントローラーの作成
CakePHPにおけるコントローラはアプリケーションのロジックにあたる。コントローラのクラ ス名は「テーブルの名前 (頭文字は大文字)」Controller とし、AppController を継承しなければな らない。また、ファイル名は「テーブル名」 controller.php としなければならない。コントローラ は/app/controller/の中に設置する。以下に UsersController のソース一部を示す。 <?phpclass UsersController extends AppController {
var $name = ’Users’;
var $uses = array(’User’,’Feed’); var $helpers = array(’Html’); function index()
{
$this->checkSession();
$auth = $this->Session->read(’auth’); $cond = array(’id’ => $auth[’id’]);
$this->set(’user’,$this->User->find($cond,null,null,0)); } } function logout() { $this->Session->delete(’auth’); $this->set(’login_error’,false); $this->render("login"); } ....以下省略... } ?> 変数 name にはコントローラ名を代入する。変数 uses には使用するモデル名を指定する。何も指定し ない場合はコントローラに対応するモデルが自動的に適用される。この場合のモデルを使用するとい
うのは、データベースのテーブルにアクセスできるということを意味する。上記の UsersController の場合、このコントローラ内で users テーブルと feeds テーブルにアクセスできることになる。変 数 helpers にはコントローラ内で使用するヘルパー名を指定する。コントローラ内の各関数は関数 名と同じビューに対応している。ブラウザの URL フォームに http://ドメイン名/アプリケーショ ンのフォルダ名/コントローラ名/関数名と入力することで関数名と同じビューがブラウザに表示さ れる仕組みとなっている。 関数 index はユーザ情報を users テーブルから取得し、表示させる関数である。 • $this-¿checkSession()
checkSessionはセッション継続中かチェックするメソッドである。このメソッドは/app/app controller.php 内に自分で定義した。各コントローラは AppController を継承しているので、checkSessioon はど のコントローラ内でも使用できる。
• $auth = $this-¿Session-¿read(’auth’);
セッション変数を読み出し、変数 auth に代入する。Session は CakePHP 内で定義されているセッ ションを扱うためのクラスである。
• $cond = array(’id’ =¿ $auth[’id’]);
レコードを取得するための条件を記述している。この場合、上記のセッション変数から読み出した idとレコードの id が等しいという条件になる。 • $this-¿set(’user’,$this-¿User-¿find($cond,null,null,0)); setはビュー内の変数に値をセットするメソッドである。第一引数に変数名、第二引数にセットし たい値を指定する。セットした変数はビューの中で使用できる。find はテーブルからレコードを取 得するメソッドである。find はモデル別に存在する。上記の場合、users テーブルからレコードを 取得する。find の第一引数は取得条件、第二引数は取得したいフィールドであり、指定しない場合 は全てのフィールドを取得する。第三引数は取得順、第四引数は取得する階層である。第四引数の 階層は前述のアソシエーションと関係している。階層を指定することで、関連しているテーブルの データを取得するか否か選択することができる。上記の命令では users テーブルのレコードが取得 できれば十分なので、階層には 0 を指定している。特に指定する必要が無い引数は null にする。
4.4
ビューの作成
CakePHPにおけるビューは MVC パターンの V にあたる、実際にブラウザに表示される部分で ある。ビューのファイル名はコントローラの関数名と同じものにし、拡張子は.thtml でなければな らない。作成したファイルは/app/views/対応するコントローラ名/の中に設置する。デフォルトの 状態では views ディレクトリは空になっているため、自分で対応するコントローラのディレクトリ を作成する必要がある。Users コントローラに対応するビューの場合、/app/views/users/の中に設 置する。Users コントローラの関数 index に対応するビューの場合、/app/views/users/index.thtml となる。以下に index.thtml のソースを示す。<h1>ユーザ情報</h1> <table> <tr> <th>Id</th> <th>ユーザ名</th> <th>作成日</th> </tr> <tr> <td><?php echo $user[’User’][’id’]; ?></td> <td> <?php echo $user[’User’][’name’];?> </td> </td> <td><?php echo $user[’User’][’created’]; ?></td> </tr> </table> ビューの中では通常の PHP ファイルと同様に、PHP の命令が記述できる。index.thtml では Users コントローラの関数 index にて変数 user にセットされた users テーブルのレコードをユーザ情報 としてテーブルにして表示させている。 4.4.1 レイアウトについて CakePHPではビューとは別に、各ビューで共通している項目を表示させるためにレイアウトファ イルが存在する。html のヘッダやフッタもレイアウト内に記述する。レイアウトでもビューと同様に PHPの命令が使用できる。デフォルトの状態では/cake/libs/view/templates/layouts/default.thtml がレイアウトとして適用される。利用者がオリジナルのレイアウトを定義したい場合は、default.thtml を/app/views/layouts の中にコピーしそれを編集する。各ビューに個別のレイアウトを適用する ことも可能である。なお、ビューとレイアウトに適用する CSS ファイルは/app/webroot/css/に設 置し、画像ファイルは/app/webroot/img/内に設置する。以下にオリジナルのレイアウトに変更し た default.thtml のソースの一部を示す。 ...省略...
!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml">
<head>
<?php echo $html->charset("utf-8");?>
<title>あるあるリスト (RC) : <?php echo $title_for_layout;?></title>
<link rel="icon" href="<?php echo $this->webroot . ’favicon.ico’;?>" type="image/x-icon" />
<?php echo $html->css(’rss_list’);?> </head> <body> ...省略... <?php echo $content_for_layout;?> ...省略... <div id="footer">
copyright © 2008 ARUARULIST all rights reserved. </div>
</div> </body> </html>
レイアウトファイル内では charset や css は html ヘルパを使用して指定する必要がある。$con-tent for layout にはビューに記述された内容が入っている。この変数を呼びだす位置を変更するこ とで、レイアウトの変更ができる。変更したレイアウトは 2 カラムとなっており、ビューの内容は 左下に表示されるようになっている。