フレームワークのメイン処理は、データ(ベース)の操作となります。
MVCでは、アプリケーションのメイン処理をモデルとして定義します。
データの操作は、データベースへの接続と、そのデータベースへの登録や検索などの具体的なデータ操作を行う処理の2つがあり、ここでは2つのモデルに分けて説明します。
MVCにおける2つのモデル
冒頭文にあるように、2つのモデルとして、接続処理を行うConnectModelクラスと、データ操作を行うExecuteModelクラスとして定義します。
ExecuteModelクラスには、SQL文の実行と結果を取得するメソッドを定義します。また、実際のSQL文はExecuteModelクラスのサブクラスにて設定します。
データベースへの接続を確立する
データベースへの接続は、フロントコントローラーにおいてアプリケーション本体のクラスをインスタンス化する際に確立します。
アプリケーションクラスのコンストラクターがConnecModelクラスをインスタンス化し、connectメソッドを呼び出すことで接続を確立します。
データベースの操作を行う
データベースの操作は、アプリケーション側で作成するControllerのサブクラスで行います。
コントローラーのアクションメソッドにおいて接続オブジェクトであるPDOを取得し、ExecuteModelサブクラスで定義されたメソッドを実行することで、データの登録や取得などを行います。
データベースへの接続を管理するConnectModelクラス
まず、データベースを操作するPDOオブジェクトを生成するメソッドを定義します。
ConnectModelクラスでは具体的に以下の機能を実装します。
- データベース接続用のPDOオブジェクトを生成(connectメソッド)
- 上記PDOオブジェクトを返す(getConnectメソッド)
- 接続名に対応するデータベース接続用PDOオブジェクトを取得(getModelConnectメソッド)
- データモデルのサブクラスのオブジェクトを取得する(getメソッド)
- PDOオブジェクトとデータモデルオブジェクトを破棄する
モデルクラスでのみデータベースにアクセスする形になり、アプリケーションのメインロジックは全てここに書かれることになります。
ですので、データベースに関する処理はモデルに記述していくことになります。
データベース接続用のPDOオブジェクトを生成(connectメソッド)
まず、PDOオブジェクトを保持する配列や接続名保持するプロパティを用意します。そしてPDOオブジェクトを生成するために、接続名やデータベース接続情報をアプリケーション側から受け取るようパラメータを用意します。そしてconnect()メソッドの処理の中で、PDOオブジェクトの生成とエラー発生時に例外を投げるための属性をPDOオブジェクトに登録する処理を記述します。
<?php
class ConnectModel {
protected $_dbConnects = array(); //PDOオブジェクトを保持する
protected $_connectName;
public function connect($name, $connectStrings) { //$nameは接続を設定するための接続名を取得するパラメータ
try{
//$conにPDOオブジェクトを格納
$con = new PDO($connectStrings['string'], $connectStrings['user'], $connectStrings['password']);
}catch(PDOException $e){
//PDOオブジェクトの生成時にエラーが発生したときの処理
exit("データベースへの接続に失敗しました。 : {$e->getMessage()}");
}
//PDOオブジェクトエラー発生時に例外を投げる属性を設定
$con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
//$nameの接続名をキーにして、値に$conを指定して$_dbConnectsに格納
$this->_dbConnects[$name] = $con;
this->_connectName = $name;
}
}
データベース接続用のPDOオブジェクトを返す(getConnectメソッド)
ここでは生成済みのPDOオブジェクトをアプリケーション側に返すメソッドを定義しましょう。
PDOオブジェクトの受け渡しは$_dbConnectsプロパティのキーを設定することで行います。
もしキーが指定されなかった場合はcurrent()関数で1番初めの要素を返します。current関数はデフォルトで先頭の要素を返す。
public function getConnect($name = null) {
if(is_null($name)){
return current($this->_dbConnects);//先頭要素を返します
}
return $this->dbConnects[$name];//$nameをキーにオブジェクトを返します
}
接続名に対応するデータベース接続用PDOオブジェクトを取得(getModelConnectメソッド)
先程定義したgetConnect()メソッドは、ここで定義するgetModelConnect()メソッドの中で呼び出します。
PDOオブジェクトは$_dbConnectsプロパティに、接続名をキーにして格納していますね。この接続名は$_connectNameプロパティに格納していますが、プロパティが空の場合も想定して処理を分けます。
public function getModelConnect(){
if(isset($this->_connectName)){
// $_connectNameに値があれば$nameに入れて、接続名$nameのPDOオブジェクトを取得
$name = $this->_connectName;
$con = $this->getConnect($name);
} else {
$con = $this->getConnect();//なければそのまま呼び出す
}
return $con;
}
データモデルのサブクラスのオブジェクトを取得する(getメソッド)
アプリケーション側では、ExecuteModelクラスのサブクラスを作成し、アプリケーションごとのデータアクセスを定義します。
フレームワーク側ではサブクラス名がわからないとインスタンス化する際に困るので、データモデル名+Modelというサブクラス名にします。
<?php
class ConnectModel {
//省略
protected $_modelList = array();//配列で保持する
//省略
public function get($model_name) {
if(!isset($this->_modelList[model_name])){
//データモデル名に'MODEL'を連結します
$model_class = $model_name . self::MODEL;
//データモデルに対応するPDOオブジェクトを取得します
$con = $this->getModelConnect();
//データモデルクラスのサブクラスをインスタンス化
$obj = new $model_class($con);
//_modelListプロパティにインスタンスを格納します
$this->_modelList[$model_name] = $obj;
}
$modelObj = $this->_modelList[$mode_name];
return $modelObj;
}
}
PDOオブジェクトとデータモデルオブジェクトを破棄する
最後に破棄するデストラクターを定義します。
破棄するのは$_modeListに保持されてるインスタンスと、$_dbConnectプロパティに保持されてるPDOのインスタンスです。
public function __destruct(){
foreach ($this->_modelList as $mdl) {
unset($model);
}
foreach (this->_dbConnect as $conn) {
unset($conn);
}
}
ConnectModelクラスのまとめ(コード)
<?php
class ConnectModel {
protected $_dbConnects = array(); //PDOクラスのインスタンスを保持する
protected $_connectName;//接続名を保持する
protected $_modelList = array();//モデルクラスのインスタンスを保持する
const MODEL = 'Model';//定数で保持する
public function connect($name, $connectStrings) { //$nameは接続を設定するための接続名を取得するパラメータ
try{
//$conにPDOオブジェクトを格納
$con = new PDO($connectStrings['string'], $connectStrings['user'], $connectStrings['password']);
}catch(PDOException $e){
//PDOオブジェクトの生成時にエラーが発生したときの処理
exit("データベースへの接続に失敗しました。 : {$e->getMessage()}");
}
//PDOオブジェクトエラー発生時に例外を投げる属性を設定
$con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
//$nameの接続名をキーにして、値に$conを指定して$_dbConnectsに格納
$this->_dbConnects[$name] = $con;
this->_connectName = $name;
}
public function getModelConnect(){
if(isset($this->_connectName)){
// $_connectNameに値があれば$nameに入れて、接続名$nameのPDOオブジェクトを取得
$name = $this->_connectName;
$con = $this->getConnect($name);
} else {
//なければそのまま呼び出して先頭要素のPDOインスタンスを取得
$con = $this->getConnect();
}
return $con;
}
public function getConnect($name = null) {
if(is_null($name)){
//先頭要素を返します
return current($this->_dbConnects);
}
//$nameをキーにオブジェクトを返します
return $this->dbConnects[$name];
}
public function get($model_name) {
if(!isset($this->_modelList[model_name])){
//データモデル名に'MODEL'を連結します
$model_class = $model_name . self::MODEL;
//データモデルに対応するPDOオブジェクトを取得します
$con = $this->getModelConnect();
//データモデルクラスのサブクラスをインスタンス化
$obj = new $model_class($con);
//_modelListプロパティにインスタンスを格納します
$this->_modelList[$model_name] = $obj;
}
$modelObj = $this->_modelList[$mode_name];
//戻り値でデータモデルクラスのインスタンスを返します
return $modelObj;
}
public function __destruct(){
foreach ($this->_modelList as $mdl) {
unset($model);
}
foreach (this->_dbConnect as $conn) {
unset($conn);
}
}
}
コメント