前回の記事では、解説を省略しました。
(Fuelphp version 1.1-RC1の記事です。)
私もPHPやFuel初心者ですが、もっと初心者の方のために、多少解説を付け加えます。全記事に対する、補足説明です。
(本当は、前記事に直接書けばいいのですが、このサイトのCMSで採用しているエディターの最新版はバグり気味で、プログラムなどをpreとcodeタグで囲んだ時の範囲が勝手に書き換えられて、修正が大変なのです。実際、前記事はビジュアルなエディティング機能を使わず、ほぼ、直接タグなどを変更して、修正しました。それで、一日取られてしまいました…;( )
PHPフレームワークを利用する一つの利点が、URLに指定された内容から、目的の動作をさせるための仕組みを、自分で考えなくて済むというものがあります。このURLなら、これをこの引数で…と設計する必要がありません。
例えば、http://domain.com/class/action/argというURLを指定されたときに、どのファイルの、どのクラスのどの関数を実行するか、フレームワークを使わない場合は全部自分でプログラムを書かなくてはなりません。
指定されたURLから、どの関数を呼び出すかを呼び出すことを、URLルーティングと言い、大抵のフレームワークでは、設定ファイルで指定します。
Fuelでも同様で、app/config/route.phpで指定します。
Fuelの場合、どのクラスの、どの関数を呼び出すかを指定する仕組みになっています。呼び出される関数をアクションと呼び、関数名にもaction_が前につきます。この設定ファイルで指定する時には、action_以降の名前だけ指定します。
クラスはapp/controller以下に設置します。クラス名はファイル名と同じ名前です。ファイル名は全部小文字、クラス名は各ファイル名の先頭を大文字にし、ディレクトリーの区切りをアンダーラインで区切った名前です。この設定ファイルに記述するのは、全部小文字で、controller以下のファ イル名をアンダーバーで区切って表記したものです。(PHP+オートロードで検索すると、ここらへんの話が説明されています。)
具体的には、ファイルがcontroller/aaa/bbb.phpであれば、クラス名はController_Aaa_Bbbで、ルーティングで指定するクラスの名前は、aaa_bbbになります。
ドメイン名だけで呼び出された場合、_root_で呼び出されたクラス/アクションが呼び出されます。
指定されたURLが見つからない、つまりルーティングで指定された中に一致するものがない場合、_404_で指定された、クラス/アクションが呼び出されます。
自分で直接PHPプログラムを書くのなら、DBの設定はどこに書いても勝手ですが、フレームワークの中では、別の人によって書かれた、あちこちのプログラムがDBを使用する可能性があります。ですから、決まった設定ファイルに、設定します。
Fuelの場合、DBの設定は他とは別のファイルに記述します。appの下だけでも設定ファイルが3つあります。config/development/db.php、config/production/db.php、config/db.phpです。
Fuelの場合、インストール後のデフォルトの場合、開発環境として認識され、development下のdb.phpが優先です。環境変数を切り替えて、本番環境にすれば、preduction/db.phpが有効になります。
上記2ファイルでは、設定項目が少なくなっています。それ以外の共通項目は、config/db.phpの内容が使用されます。つまり、開発中でも、本番環境でも、共通に使用される項目が書かれています。大抵の場合、どちらも同じ設定の項目が多いですから、config/db.phpのほうが、項目が多くなっています。
ユーザー認証もフレームワークを利用する、一つの理由です。
フレームワークによって、実現の仕方が異なります。軽いことを目指しているフレームワークには認証手段を持っていないものもあります。
Fuelでは、パッケージとして用意されています。認証を必要としていないシステムでは、これを切り離せ、少しでも軽く出来ますから、良い手法です。
Fuelで、デフォルトでは、パッケージは一つも使用しない設定になっています。
パッケージの使用はapp/config/config.phpで指定します。config.phpは色々な項目を指定していますから、項目が多くなっています。英語ですが、コメントは丁寧に入っていますので、理解はしやすいと思います。
前記事とこの記事で解説しているSimpleAuthとは、このパッケージに含まれている、認証プログラムのことで、ユーザー名と、パスワードによる認証機能を提供してくれます。
認証だけでしたら、自分で組んでも難しく有りません。あるユーザーにはこのページを見せたいが、このユーザーには見せたくない、ある人を管理者にして、管理ページを見せたいなど、そうしたコントロールを組み込もうとすると、ややややこしくなります。
本格的にこうしたコントロールを組むとしたら、関係した情報を全部DBにして、管理するのでしょうが、Feulのような、軽いフレームワークを利用する場合、それほどの管理は必要なく、また重すぎるでしょう。
そこで、SimpleAuthでは、ユーザーのログイン情報だけをDBとして、それ以外のコントロールに関する情報は、設定ファイルで指定しています。
なお、githubというサイトには、Fuel用のパッケージを開発しているgitのリポジトリが存在しています。そこには、oauthとoauth2という、oauth用認証パッケージがあり、twitterやgoogle、amazonなどを利用して、自分のサイトの認証を可能に出来ます。(私は試していません。)
SimpleAuthのアクセスコントロールは、ロール(役割)とグループによるものです。
あるユーザーは、特定のグループに割りつけられます。もちろん、このグループは自由に設定できます。
例として、サイトに登録してくれた一般ユーザーとサイトを管理する管理者を考えましょう。
サイトに登録してくれた人はuserグループとして登録しましょう。また、あなたを含めた、何人かを管理者としてadminグループとして登録しましょう。
userグループの方は、ログイン中、自分のパスワードの変更画面、パスワードリマインダー、再発行、自分の情報の書き換えなどのページへアクセスできるようにします。
そのため、userロールを作り、userロールにそうしたページを表示するクラス/アクションを指定します。ちなみに名前はuserでも、何でも可能です。今回の説明では、わかりやすくするために、同じ名前を使っています。
管理者は、ユーザー全体の管理や、サイト全体の管理画面が見られなくてはなりません。そうした管理者レベルでないと、アクセスされては困るページを表示するクラス/アクションは、adminロールを作成し、そこに登録します。
さて、サイトの中にはこうしたアクセス制限が必要ないページもあります。一般には、サイトのトップページや、ログインページ、ユーザーの新規登録ページなどです。こうしたページに対しては、2つの方法が考えられます。
一つは、こうした制限を受けないクラス/アクションとすること。これが一般的ですね。
もう一つは、このアクセスコントロールの管理下に置くが、誰でもアクセスできることを許す特別なロールを用意し、そこに登録します。この場合、後からアクセス権の変更が必要になった場合でも、コードを直接いじらなくてすみます。今回は、こちらを採用したとしましょう。
app/config/simpleauth.phpの中で、このロールの定義部分だけを記述すると、こうなります。
'#' => array(
'Controller_Everyone' => array(
'index','login','register',
),
),
'user' => array(
'Controller_User' => array(
'password_change', 'password_remainder',
'info_change', 'logoff',
),
),
'admin' => array(
'Controller_Admin' => array(
'user_admin','site_admin',
),
),
#は特別なロールで、誰でもアクセス可能なクラス/アクションを登録します。
ここでは、Everyone、User、Adminの3つのクラスを使っていますが、これらのクラスで、権限のチェックを行います。黙っていても、チェックが行われるわけではありません。(詳細は後ほど)
config/routes.phpですと、Controller_は省略して、先頭の大文字を小文字で指定しますが、このsimpleauth.phpではController_付きのフルクラス名で、アクションはroutesと同様に、関数名のプレフィックスaction_を取り去った形式で指定するようです。
さて、ロールは定義できました。グループに戻りましょう。
ここで考えなくてはならないのは、アドミングループの人は、一般エリアへアクセス出来るようにするべきでしょうか。それとも、できないようにするべきでしょうか。
一般的なサイトにおいては、出来るようになっていますね。CMSなどの管理方法は、通常このやり方です。
ただ、会社などのシステムでは、管理者のIDと一般ユーザーとしてのIDは分けたほうが、安全であると考えているかも知れません。そうした場合も考えられます。
ロールとグループが分かれているので、この調整は簡単です。ユーザーはある一つのグループにしか所属できませんが、グループはいくつかのロールを持つことができます。
管理者にユーザーエリアと、管理者エリアの両方にアクセスできるようにするには、adminグループに、adminロールとuserロールを登録します。
管理者は、管理者エリアだけアクセスさせるという場合は、adminグループに、adminロールだけを登録します。
ここでは、管理者は両方のロールを持つという、一般的な方法にしましょう。コードは、次のようになります。
1 => array('name' => 'ユーザー', 'roles' => array('user')),
10 => array('name' => '管理者', 'roles' => array('user', 'admin')),
最初の数字はグループを識別するための番号です。異なっていれば、大きさは関係ありませんが、一般的には権限が強くなるにつれ、大きくなる方が、わかりやす いですね。また、連番にせず、飛び飛びの数字にしておけば、ユーザーと管理者の中間の役割を後で追加したい場合など、そのアクセス権の強さによる、並び順 を保てます。そこで今回は1と10を選びました。
もし、管理者は管理者ロールで割りつけられたエリアにだけアクセスさせる場合は、こうなります。
10 => array('name' => '管理者', 'roles' => array('admin')),
追記:1.1RC版では、ロールに割りつけるクラス名の先頭に¥(円記号、もしくはバックスラッシュ)が必要です。正式版では、つけてはいけません。
Fuelではアクセスの制御は自動的に行われるわけでありません。フレームワークによっては、自動的に行われるものもあるかも知れません。でも、そうなると、自分で制御したい場合などは、かえって面倒な事になりそうですね。
さて、Fuelはルーティングで指定された、URLによって、特定のクラスの特定のアクション、つまり関数が呼び出されるわけでした。
アクセス制御とは、要するに、プログラムに制御が渡ってきたときに、ログイン済みであり、そのログインしたユーザーさんは、その関数を実行する権限を持っているかをチェックすることです。ログインしていなかったり、アクセスする権限がなければ、他のページを表示します。
アクションとして指定された関数に全部、このコードを書いていたら面倒です。関数を作成して、各アクション関数から呼び出すのは、ちょっとましですが、まだ手間です。
Fuelのコントローラークラスを呼び出されたときに、beforeという名前の関数を実行する機能があります。それを使いましょう。
前の設定ファイルでは、Everyone、User、Adminという3つのクラスを考えました。
その3つのクラスに次のコードを入れます。
public function before()
{
parent::before();
// コントローラーとアクションから、アクセス権チェック
$access = Auth::has_access(array(
$this->request->controller,
$this->request->action
));
if ($access == true)
{
// アクセス権有り、続いてログインしているかチェック
if (Auth::check())
{
// ログイン中
$this->user_id = Auth::instance()->get_user_id();
$this->user_id = $this->user_id[1];
}
}
else
{
// アクセス権なし
Session::set_flash('notice', 'このアドレスへアクセスする権限を持っていません。');
Response::redirect('test');
}
}
コメント入れてありますので、理解は難しく有りません。
このコードは、Stationwagonという、Fuelのサンプルコードを参考にしています。
ログイン時はユーザーIDを保存していますね。後ほど、各アクション関数のなかで、参照しやすいようにでしょう。
さて、クラスに親しんでいるかたは、まどろっこしく感じているでしょうね。
実は、前記事も継承を使わず、この直接書きこむスタイルを使いました。説明のためです。
実用的には、このbefore関数を含んだクラスを予め用意しておき、そのクラスを認証が必要なクラスで継承するというのが、正しいですね。
世の中にはテンプレートシステムがたくさんあります。デザインは苦手でもテンプレートを切り替えたい人には持ってこいですしね。
ただ、好みと普段のスタイルで、何を好むかが、違います。Fuelはこうしたテンプレートシステムを、取り込みやすいよう、parserパッケージが用意されています。
そうした、テンプレートシステムを利用しなくても、一応HTMLなどを表示しやすい仕組みをもっています。簡単なテンプレートシステムもあります。
要するに、htmlの中では<?php echo $message; ?>などの、簡単なコードを表示するようにしておいて、コントローラー側で表示したい情報を渡してあげる仕組みがあります。
app/viewsの下にビューを起きます。拡張子はphpですが、中身はほとんどHTMLです。
例えば、ビューがaisatu.phpで次のようなものだとしましょう。
<h1>あいさつ</h1>
<p>おはようございます。<?php echo $name; ?>さん。<p>
コントローラーはこんな感じになります。
class Controller_Aisatu extends Controller {
function action_index() {
$data = array('name'=>'田中');
return View::forge('aisatu', $data);
}
}
もしくは、こうも書けます。
class Controller_Aisatu extends Controller {
function action_index() {
$view = View::forge('aisatu', $data);
$view->name = '田中';
return $view;
}
}
手打ちなので間違っているかも知れません。ご了承ください。
ただ、普通のサイトの場合、HTMLはヘッダーが来て、本体が来て、メニューが来て、フッターが来てと、サイト内では同じ構成ですから、予め同じ部分はまとめておいて、異なった部分だけ書き換えるほうが、コードもすっきりし、メンテナンスも楽です。
tmpl.phpビューを用意します。だいたい、次のような感じです。
<h1><?php echo $title; ?></h1>
<p>ヘッダー</p>
<div><?php echo $content; ?></div>
<p>フッター</p>
コントローラーはこうなります。
class Controller_Aisatu extends Controller {田中';
function action_index() {
$tmpl = View::forge('tmpl');
$tmpl->title = 'テンプレートテスト';
$tmpl->content = View::forge('aisatu');
$tmpl->content->name = '
return$tmpl;
}
}
大抵のサイトはこうした、ヘッダーがあり、コンテンツがあり、フッターがある形式なので、Fuelでは予めController_Templateクラスが用意されています。
このクラスは、予めviews/template.phpを読み込んでくれます。つまり、自分がいつでも使用するビューをtemplate.phpという名前で用意しておき、コントローラーではController_templateクラスを拡張すれば、一手間省略できるというわけです。
先ほどのtmpl.phpをtemplate.phpに変え、コントローラーをこのクラスに変更してみます。
class Controller_Aisatu extends Controller_Template {田中';
function action_index() {
$this->title = 'テンプレートテスト';
$this->content = View::forge('aisatu');
$this->content->name = '
}
}
oilユーティリティーでコードを生成すると、まず最初にviews/template.phpが存在していない場合、自動的に作成してくれます。この自動的に作成されるテンプレートにも$titleと$contentが、含まれています。
前記事は、この自動的に作成される、template.phpを利用しています。このビューはSessionクラスのフラッシュデーターを利用して、次に表示するページにメッセージを渡せるようになっています。バリデーションのエラーなども、これを利用して表示しています。
この自動生成されるコードはフラッシュデーターはnoticeという名前だけを利用するようになっています。この名前にerrorなどと、バリエーションを付け、その名前によって表示方法を変更するしくみは、Stationwagonのtemplate.phpで行われています。ここらへんは工夫のしようがありますね。
| Fuelphpのテンプレートクラス< 前 | 次 >Fuelphp、SimpleAuthをシンプルに |
|---|
| < 前 | 次 > |
|---|