-
Notifications
You must be signed in to change notification settings - Fork 3
4.データベースの接続
いよいよEnviからDBに接続してみます。
- EnviからDBに接続する
- フォームから入力された値をDBに保存する
- データベースから取り出した値を値をテンプレートで表示する
config/bbs_databases.yml を見てみましょう。 ここには、データベースへの接続情報がYAML形式で記述されています。
all:
default_master:
params:
dsn: "phptype=mysql&username=exampleuser&password=example&hostspec=localhost&database=example_master"
instance_pool: true
connection_pool: false
initialize_query: "set names utf8;"
default_slave:
params:
dsn: "phptype=mysql&username=exampleuser&password=example&hostspec=localhost&database=example_slave"
instance_pool: true
connection_pool: false
initialize_query: "set names utf8;"
default_stage:
params:
dsn: "phptype=mysql&username=exampleuser&password=example&hostspec=localhost&database=example_stage"
instance_pool: true
connection_pool: false
initialize_query: "set names utf8;"
今回は、default_masterの項目を修正して、DBの設定を作成します。
default_slave
、default_stage
は使用しないので、削除するか、単に無視してください。
複数のDBに接続する必要が有る場合は、default_slave
やdefault_stage
のように複数の設定を記述することもできます。
params
のそれぞれの項目は、
- dsn DB接続用のDSNを記載します
- instance_pool DBを接続したオブジェクトをプールするかどうかを決定します。 trueでオブジェクトの生成を1回のみとします。
- connection_pool コネクションプーリングを有効にするかどうかを決定します。 trueで有効となります。
- initialize_query 接続時に自動で発行するクエリを記述します。 必要がない場合は空にしておいてください。単に無視されます。
次にconfig/bbs_schema.yml を見てみましょう。 ここには、アプリケーション内で使用するテーブルの定義が記載されています。 これを、下記のように修正します。
SCHEMA:
## <?php $app_name = substr(basename(__FILE__), 0, strlen(basename(__FILE__))-strlen('_schema.yml')); ?>
# テーブル名
bbs:
schema:
bbs_id:
type: int(11)
default: null
primary: PRIMARY
not_null: true
auto_increment: true
name:
type: varchar(255)
not_null: true
default: null
email:
type: varchar(255)
default: null
comment_text:
type: longtext
not_null: true
default: null
insert_date:
type: datetime
default: null
not_null: true
time_stamp:
type: timestamp
default: null
not_null: true
DIRECTORY:
# モデルを保存するdirectory
model_dir: "<?php $ds = DIRECTORY_SEPARATOR; echo realpath(ENVI_BASE_DIR."..{$ds}..{$ds}apps{$ds}{$app_name}{$ds}libs{$ds}models").$ds; ?>"
SETTING:
#デフォルトのインスタンス名
default_instance_name: "default_master"
#マジックメソッドを利用したSetterGetterを使用するかどうか
default_magic_method: false
# データーベース定義
database_yaml: "<?php echo realpath(ENVI_BASE_DIR."..{$ds}..{$ds}config{$ds}").$ds.$app_name?>_databases.yml"
# 環境
env: "dev"
# デフォルトのauto_schema
default_auto_schema: false
# auto_schemaの結果を反映した、yamlファイルを出力するかどうか
reverse_yaml: false
修正したら、
envi build-query config/bbs_schema.yml
と打ってみましょう。
DROP TABLE IF EXISTS `bbs`;
CREATE TABLE `bbs` (
`bbs_id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL ,
`email` varchar(255) ,
`comment_text` longtext NOT NULL ,
`insert_date` datetime NOT NULL ,
`time_stamp` timestamp NOT NULL ,
PRIMARY KEY (bbs_id)) ENGINE=InnoDB;
Mysql準拠のCREATE文が発行されました。
これを使用してテーブルを作ってみてください。
mysql> CREATE TABLE `bbs` (
-> `bbs_id` int(11) NOT NULL AUTO_INCREMENT,
-> `name` varchar(255) NOT NULL ,
-> `email` varchar(255) ,
-> `comment_text` longtext NOT NULL ,
-> `insert_date` datetime NOT NULL ,
-> `time_stamp` timestamp NOT NULL ,
-> PRIMARY KEY (bbs_id)) ENGINE=InnoDB;
Query OK, 0 rows affected (0.04 sec)
できましたか?
テーブルができたら、次は、モデルの作成です。 今度は、
envi build-model config/bbs_schema.yml
と打ってみましょう。
/apps/bbs/libs/models//om/BaseBbsPeer.class.php
/apps/bbs/libs/models//om/BaseBbs.class.php
/apps/bbs/libs/models//Bbs.class.php
/apps/bbs/libs/models//BbsPeer.class.php
4つのファイルができましたか?
~Peerには、SQL文や、OrMapオブジェクトへの複雑な操作などを static
で記述します。
早速、 /apps/bbs/libs/models//BbsPeer.class.php に書き込みの処理を追加してみましょう。
/**
* +-- bbsテーブルに書き込む
*
* @static
* @access public
* @param string $name 名前
* @param string $email メールアドレス
* @param string $comment_text コメント
* @return boolean
*/
public static function write($name, $email, $comment_text)
{
try{
$bbs = new Bbs;
$bbs->setName($name);
$bbs->setEmail($email);
$bbs->setCommentText($comment_text);
$bbs->setInsertDate(date('Y-m-d H:i:s'));
$bbs->save();
} catch (Exception $e) {
return false;
}
return true;
}
/* ----------------------------------------- */
テーブルに対して、Insertを行うのは非常に簡単です。
該当するテーブルのオブジェクトを new
し、値をsetし set
するだけです。
トランザクションを貼りたい場合は、
/**
* +-- bbsテーブルに書き込む
*
* @static
* @access public
* @param string $name 名前
* @param string $email メールアドレス
* @param string $comment_text コメント
* @return boolean
*/
public static function write($name, $email, $comment_text)
{
$dbi = extension()->DBI()->getInstance('default_master');
$dbi->beginTransaction();
try{
$bbs = new Bbs;
$bbs->setName($name);
$bbs->setEmail($email);
$bbs->setCommentText($comment_text);
$bbs->setInsertDate(date('Y-m-d H:i:s'));
$bbs->save($dbi);
$dbi->commit();
} catch (Exception $e) {
$dbi->roleback();
return false;
}
return true;
}
/* ----------------------------------------- */
このようになります。
/apps/bbs/modules/index/actions/indexAction.class.php を開いて、execute
を下記のように変更します。
/**
* +-- validate()でEnvi::SUCCESSもしくはtrueが返った場合の処理。
*
* @see validate()
* @return Envi::DEFAULT | Envi::ERROR | Envi::SUCCESS | boolean
*/
public function execute()
{
$name = Request::getAttribute('name');
$email = Request::getAttribute('email');
$comment_text = Request::getAttribute('comment_text');
if (!BbsPeer::write($name, $email, $comment_text)) {
validator()->error()->setErrorMess('bbs_write', 'bbs_write', '書き込みに失敗した。');
return $this->handleError();
}
Controller::redirect($_SERVER['SCRIPT_NAME']);
return Envi::NONE;
}
/* ----------------------------------------- */
実際にフォームから投稿してみましょう。
問題なく投稿された場合は、エラーメッセージが表示されること無く、
http://bbs.example.jp/bbs.php
にリダイレクトされます。
正常にDBにインサートされているか、直接DBを参照して確認してみてください。
mysql> select * from bbs\G
*************************** 1. row ***************************
bbs_id: 1
name: example name
email: test@test.jp
comment_text: test comment
insert_date: 2012-07-18 05:31:21
time_stamp: 2012-07-18 05:31:21
1 row in set (0.00 sec)
今度は、 /apps/bbs/libs/models//BbsPeer.class.php にSelectの処理を記述しましょう。
今回はページャーを用意せず、bbs_id降順で、1000件を取得して表示するという形にします。
public static function get()
{
$dbi = extension()->DBI()->getInstance('default_master');
$sql = 'SELECT name,email,comment_text,insert_date FROM bbs ORDER BY bbs_id DESC LIMIT 1000';
$res = $dbi->getAll($sql);
return is_array($res) ? $res : array();
}
/apps/bbs/libs/models//BbsPeer.class.phpに追加したら、
/apps/bbs/modules/index/actions/indexAction.class.php を開いて、defaultAccess
を下記のように変更し、BbsPeer::get()
をコールします。
public function defaultAccess()
{
Request::setAttribute('bbs_data', BbsPeer::get());
return Envi::DEFAULT_ACCESS;
}
/apps/bbs/modules/index/templates/index.tplを 下記のように変更し、Selectした値を表示します。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>BBS</title>
</head>
<body>
<?php
if (isset($error)) {
foreach ($error['message'] as $val) {
echo htmlspecialchars($val);
}
}
?>
<br />
<form action="/bbs.php" method="post">
名前:<input type="text" name="name" /><br />
Email:<input type="text" name="email" /><br />
<textarea name="comment_text"></textarea><br />
<br />
<input type="submit" name="commit" value="送信" />
</form>
<?php
if (isset($bbs_data)) {
foreach ($bbs_data as $val) {
$val = array_filter($val, 'htmlspecialchars');
if (!isset($val['email'])) {
$val['email'] = '';
}
echo <<<EOD
■{$val['name']}<br />
<a href="mailto:{$val['email']}">{$val['email']}</a><br />
{$val['comment_text']}<br />
{$val['insert_date']}
<hr />
EOD;
}
}
?>
</body>
</html>
いかがでしたでしょうか?以上で、掲示板の作成が一通り終わりました。
チュートリアルの最後に、5.動作概要を参照してください。