スケルトンアプリケーションを作り、データベースの設計が終わりました。 このセクションでは実際にデータベースを作成し、スケルトンアプリケーションと接続します。
データベースはSQLiteを使います。 YiiのデータベースサポートはPDOの上に構築されているため、 アプリケーションコードを変更することなく、MySQLやPostgreSQLといった異なるDBMSを利用することができます。
データベースファイルとして、blog.dbを作ります。このファイルは/wwwroot/blog/protected/dataに置きます。
ディレクトリとファイルはともにWebサーバプロセスとSQLiteにより書き込み可能である必要があります。
ここでは単に/wwwroot/yii/demos/blog/protected/data/blog.dbにあるブログデモのデータベースファイルをコピーすることにします。
もしくは/wwwroot/yii/demos/blog/protected/data/schema.sqlite.sqlにある、SQLファイルを実行することでもデータベースを生成できます。
sqlite3コマンドラインツールを利用できます。
詳しくはSQLiteの公式ウェブサイトを参照してください。
ブログデータベースを使うには、アプリケーションの設定を変更する必要があります。
設定ファイルは/wwwroot/blog/protected/config/main.phpにあります。
このスクリプトはキーと値のペアで構成された連想配列を返します。
これらの値はアプリケーションインスタンスを初期化するために使われます。
以下のようにアプリケーションのcomponentプロパティに、dbという名前のエントリを追加します。
return array(
......
'components'=>array(
......
'db'=>array(
'class'=>'CDbConnection',
'connectionString'=>'sqlite:/wwwroot/blog/protected/data/blog.db',
),
),
......
);
上記の設定は、CDbConnectionクラスのdbコンポーネントを持つことを示します。
dbコンポーネントのconnectionStringプロパティはsqlite:/wwwroot/blog/protected/data/blog.dbに初期化されます。
訳者注:yii-1.0.3以降のデモでは、'class'=>'CDbConnection'の記述はなくなっています。
この設定の場合、Yii:app()->dbを通じてDBコネクションオブジェクトにアクセスすることができます。
Yii::app()が、エントリスクリプトで作成されたアプリケーションインスタンスを返すことに注意して下さい。
DBコネクションのメソッドやプロパティに興味があれば、クラスリファレンスを参照して下さい。
しかし、多くの場合このDBコネクションを直接利用することはありません。
そのかわりにいわゆるActiveRecordを利用してデータベースにアクセスします。
作成、読み出し、更新、そして削除(CRUD)はデータベースにおける四つの基本操作です。
ブログアプリケーションでは、記事とコメントに対してCRUD操作を実装することが主なタスクになります。
このセクションではyiicツールを用いてこのタスクを完了します。
このプロセスはまたスキャッフォールディング(足場生成)として知られています。
コマンドプロンプトを開き、以下のコマンドを実行します。
% /wwwroot/yii/framework/yiic shell /wwwroot/blog/index.php
Yii Interactive Tool v1.0
Please type 'help' for help. Type 'exit' to quit.
>> model User
......
>> model Post
......
>> model Tag
......
>> model Comment
......
>> crud Post
......
>> crud Comment
......
>> exit
情報:PHPのインストール状態によっては、コマンドラインのPHPコマンドに異なったphp.iniを使っていることがあります。
その結果、yiicコマンドを実行する際に、"YiiBase::include(PDO.php): failed to open stream..." もしくは "...could not find driver"といったエラーが発生することがあります。
その場合、以下のようにしてCLI PHPの設定を再チェックしてください。
php -r "phpinfo();"
このコマンドの結果は、使用されているphp.iniを表示します。
もしことなったphp.iniが使われている場合、以下のコマンドを実行することで正しいファイルを指定することができます。
php -c php.ini /wwwroot/yii/framework/yiic.php shell /wwwroot/blog/index.php
上記コマンドによって二つのタスクが達成されます。まず一つ目は、modelコマンドによって、
各データベーステーブルに対応するmodelクラスが生成されます。
二つ目に、crudコマンドによって、PostモデルとCommentモデルのCRUD操作に必要なコードが生成されます。
以下のURLにアクセスすることで生成されたコードをテストすることができます。
http://www.example.com/blog/index.php?r=post
http://www.example.com/blog/index.php?r=comment
自動生成されたコードによる記事とコメントの機能は、それぞれ完全に独立していることに注意してください。
また、新しい記事やコメントを作る際に、authIdやcreateTimeといった情報を入力する必要があります。
これらの情報は実際のアプリケーションではプログラムによって設定するべきです。
しかし心配することはありません。次のマイルストーンまでにこれらの問題を解決します。
今のところは、このプロトタイプがほぼすべての機能をそなえていることに、それなりに満足すべきでしょう。
次のマイルストーンへの準備として、生成されたファイルを少し詳しく見てみましょう。
すべてのファイルは/wwwroot/blog/protected以下にあります。
説明のため、ファイルをモデルファイル、コントローラファイル、ビューファイルに分類します。
models/User.php ファイルはUserクラスを含み、CActiveRecordを継承しています。
このクラスはUserテーブルにアクセスするのに使われます。
models/Post.php ファイルはPostクラスを含み、CActiveRecordを継承しています。
このクラスはPostテーブルにアクセスするのに使われます。
models/Tag.php ファイルはTagクラスを含み、CActiveRecordを継承しています。
このクラスはTagテーブルにアクセスするのに使われます。
models/Comment.php ファイルはCommentクラスを含み、CActiveRecordを継承しています。
このクラスはCommentテーブルにアクセスするのに使われます。
controllers/PostController.php ファイルはPostControllerクラスを含みます。
このコントローラは記事のCRUD操作を受け持ちます。
controllers/CommentController.php ファイルはCommentControllerクラスを含みます。
このコントローラはコメントのCRUD操作を受け持ちます。
views/post/create.php ファイルは新しい記事を作るフォームを表示します。
views/post/update.php ファイルは記事の更新を行うフォームを表示します。
views/post/show.php ファイルは記事の詳細情報を表示します。
views/post/list.php ファイルは記事のリストを表示します。
views/post/admin.php ファイルは記事の管理画面を表示します。
views/post/_form.php ファイルは記事情報を集めるフォームを表示する部分ビューファイルです。
このファイルはcreateビューとupdateビューに埋め込まれます。
これらのファイルがどう使われるかをよりよく理解するために、記事の一覧が表示される場合のワークフローを示します。
PostControllerのインスタンスを作成し、実行します。PostControllerは要求されたlistアクションを、actionList()メソッドを呼ぶことで実行します。actionList()メソッドはデータベースに問い合わせを行い、最近の記事リストを取り出します。actionList()メソッドは、listビューを表示します。このブログアプリケーションでは、システムオーナとゲストユーザの区別が必要です。 したがって、ユーザ認証機能を実装する必要があります。
スケルトンアプリケーションにはすでにユーザ認証機能が備わっています。
demo/demoもしくはadmin/adminでログインすることができます
このセクションでは、認証をUserテーブルに基づいて行うよう、対応するコードを修正します。
ユーザ認証はIUserIdentityインターフェイスを実装するクラスで行われます。
スケルトンアプリケーションは/wwwroot/blog/protected/components/UserIdentity.phpにあるUserIdentityクラスを使っています。
規約により、クラスファイル名は対応するクラス名に接尾辞に拡張子.phpをつけたものになります。
この規約に従って、path aliasを使ったクラス参照が可能になります。
例えば、UserIdentityクラスを、application.components.UserIdentityというエイリアスで参照することができます。
Yiiの多くのAPIにおいて、パスエイリアスを利用可能です。(例:application.components.UserIdentity)。
そして、パスエイリアスを使うことは、絶対パスを埋め込む必要をなくします。
絶対パスを記述することはしばしばアプリケーション配置の際のトラブルの元になります。
UserIdentityクラスを以下のように修正します。
<?php
class UserIdentity extends CUserIdentity
{
private $_id;
public function authenticate()
{
$username=strtolower($this->username);
$user=User::model()->find('LOWER(username)=?',array($username));
if($user===null)
$this->errorCode=self::ERROR_USERNAME_INVALID;
else if(md5($this->password)!==$user->password)
$this->errorCode=self::ERROR_PASSWORD_INVALID;
else
{
$this->_id=$user->id;
$this->username=$user->username;
$this->errorCode=self::ERROR_NONE;
}
return !$this->errorCode;
}
public function getId()
{
return $this->_id;
}
}
authenticate()メソッドにおいて、Userクラスを用いてUserテーブルの行を参照しています。
Userテーブルのusername列は与えられたusernameという大文字小文字を区別しないものと同一です。
Userクラスは前のセクションでyiicツールによって作られたものであることを思い出してください。
UserクラスはCActiveRecordを継承しているため、
ActiveRecordの機能を、オブジェクト指向にのっとったやり方で利用することができます。
UserIdentityクラスでは、元の実装はusernameを返すようになっていましたが、getId()メソッドをオーバーライドしてユーザのidを返すようにしています。
usernameとidはともにユーザセッションに保存され、コードのどこからでもYii::app()->userでアクセスすることが可能です。
UserIdentityクラスにおいて、対応するクラスファイルを読み込むことなくCUserIdentityを参照しています。
これはCUserIdentityがYii frameworkのコアクラスであるためです。
Yiiはコアクラスのファイルが最初に参照されたときに、自動的のそのファイルを読み込みます。Userでも同じことが行われています。
なぜなら、Userクラスファイルが、/wwwroot/blog/protected/models以下にあり、このディレクトリ設定ファイルでPHPのinclude_pathに追加されているからです。
return array(
......
'import'=>array(
'application.models.*',
'application.components.*',
),
......
);
上記の設定は/wwwroot/blog/protected/modelsか/wwwroot/blog/protected/componentsの下にあるいかなるクラスファイルも、最初に参照された時点で自動的に読み込まれることを示します。
UserIdentityクラスは主にLoginFormクラスで、ユーザ名とパスワードを元にユーザを認証するために使われます。
以下コードフラグメントはどのようにUserIdentityが使われるのかを示します。
$identity=new UserIdentity($username,$password);
$identity->authenticate();
switch($identity->errorCode)
{
case UserIdentity::ERROR_NONE:
Yii::app()->user->login($identity);
break;
......
}
identityとuserコンポーネントはしばしば混同されます。
前者は認証を行う方法のことであり、後者は現在のユーザに関する情報をあらわします。
アプリケーションがもてるuserコンポーネントはひとつだけですが、identityクラスは複数持つことができます。
identityクラスはどのような認証方法がサポートされるかによります。
いったん認証されると、identityインスタンスからuserコンポーネントへ情報が渡され、
アプリケーション全体から Yii::app()->user を用いてアクセス可能になります。
修正後のUserIdentityクラスを確認するため、ブラウザでhttp://www.example.com/blog/index.phpにアクセスし、Userテーブルのユーザ名とパスワードでログインしてみてください。
ブログデモではdemo/demoでアクセスできるはずです。このブログシステムにはユーザ管理機能はありません。ユーザ管理機能は将来の機能拡張として検討されるでしょう。
マイルストーン1が完了しました。
これまでにやったことをまとめてみましょう。
Userテーブルに対してチェックするようにしました新しいプロジェクトでは、多くの場合1から4の手順をこなすことになるでしょう。