先日ここで質問させて頂いたところMVCというモデルを紹介され、いろいろ調べて試しては見たのですが、わからない部分がありましたので質問させて頂きます。
一般的にはMV間でどのようにしてデータを共有するのでしょうか?
以下のような方法を考えては見たのですが、どれもしっくりこなかったので・・・。
・Modelの実行結果をViewの引数として使う(スマートじゃない気が?)
・$GLOBALSやglobalを使う(これもスマートではないような?)
・セッションを使う(Cookie使えなかったら・・)
・データベースを使う(そこまでする必要が!?)
・singletonなオブジェクトを使う(いまいち理解できていないのですがこれが一番近いような気がしてます)
本来なんらかの書籍を読むべきなのでしょうが、少し気になったので質問させて頂きました。
根本的に考え方が間違っているようであればお勧めの書籍等教えて頂けると助かります。
よろしくお願いします。
No.1ベストアンサー
- 回答日時:
MVCパターンなフレームワークのCakePHPですが、
FormHelperという、modelデータからフォームを形成するようなヘルパが用意されており、どうやってmodelを呼び出しているかを眺めてみると、ClassRegistryというクラスを使っているようですね。
k17sさんが最後にあげたsingletonパターンのクラスオブジェクトで、
こちらにmodelだとかクラスをゲッターで保存しておいて、
セッターで呼び出してあげるという手法です。
アクセス手段は、
[クラスを追加する] ClassRegistry::addObject($key, $object);
[クラスを呼び出す] ClassRegistry::getObject($key);
というもののようですね。
Cakeで実現していることを物凄くザックリ、且つ、PHP5で記述すると以下のようになります。
class MyRegistry{
private static $instance;
public $objects = array();
/*==================================
外からnewでインスタンスを作成できないようにprivateにする
==================================*/
private function __construct(){
}
/*==================================
通常はコレをpublicにして単一のインスタンスを呼ぶようにするわけですが
これもaddObject/getObject以外から呼べないようにする。
===================================*/
private static function getInstance(){
if(self::$instance === null){ //staticなメンバ変数が空だったら
self::$instance = new MyRegistry(); //クラス内部から自分自身をnewしてやる
}
return self::$instance; //で、それを返す。
}
public static function addObject($key, $object){
$self = self::getInstance(); //自分自身のインスタンスを読んできてやり
$self->objects[$key] = $object; //メンバ変数に名前とオブジェクトを格納
}
public static function getObject($key){
$self = self::getInstance(); //自分自身のインスタンスを読んできてやり
return $self->objects[$key]; //登録されている$keyのオブジェクトを呼ぶ
}
}
?>
これは、
<?php
//なんかどこぞでモデルが呼ばれた(controllerの中とか)
$model = new YourModel();
//レジストリに格納
MyRegistry::addObject('YourModel', $model);
//modelを使いたい(Viewの中とか)
$model = MyRegistry::getObject('YourModel');
?>
いかがでしょう。
回答ありがとうございます。
ずばり!期待していた答えそのものでした!
Singletonなクラスについてあまりよく知らなかったのですが、ソースをつけて頂いたおかげで非常にわかりやすかったです。
もう目から鱗です。久々にソースを見て興奮しております。
是非是非参考にさせて頂きたいと思います。
又、以後調べる際には既存のコードも参考にさせてもらおうと思います。
ありがとうございました。
No.4
- 回答日時:
下記内容が、しっくり来る内容として、
一応他のものも例示します。
>$GLOBALSやglobalを使う
これはPHP的には無いことではないと思います。結構様々なライブラリで見る手法ですね。
$GLOBALS['{ライブラリ名の接頭句}_CONFIG'] = 'hogehoge';
こんな感じで他の値と被らないようになっていたりとか。
MVCで分けた場合、クラス内部以外の場所にコードをベタ書きをすることも無いので、外の変数を使うというのもそんなに問題ないのかもしれないなぁという気もします。
CodeIgniterなんかは、Controllerを格納した変数を外においてあって、専用の関数を使ってアクセスする手法のようでした。
<?php
$CTRL = new YourController();
function get_instance(){
global $CTRL;
return &$CTRL;
}
?>
多分PHP4にも対応する為に考えられた手法なのかもしれません。
記述方法的にはシンプルです。
kichiwaveさんの仰られるとおり、実際はmodelが生成した実行結果を配列などで渡してViewは表示するだけ、というのが最も良いのかなとも思いますが、
モデル外のライブラリやコンポーネントという概念のセッティング及び演算を行うものを呼んできてViewで使用するヘルパ関数/ヘルパクラス(HTMLの出力や文字のエスケープなどをつかさどる奴らですね)
にその設定した値及びライブラリのメソッドを適用する、なんていった場合は、先のClassRegistryのようなものなどを利用したくなるかな、っと思います。
後は、趣味/嗜好ですかね。
最後に、今回、回答した内容は、有名フレームワークの実装方法をほぼそのまま紹介した内容でした。
MVCの実装に悩んだら、デザインパターンの書籍などを読むのは当然有用な方法ですが、既に実績のあるフレームワークを眺めてみると、同じMVCパターンでもCIとCakePHPの実装方法が大分違っているので、大いに自作したMVCパターンの助けになると思います。
>$GLOBALS['{ライブラリ名の接頭句}_CONFIG'] = 'hogehoge';
最初の回答を頂いた後、hogehoge78さんに倣ってEthnaというフレームワークでどういった手法が取られているのか自分なりにソースを読んでみたのですが、同じような実装だったと思います。
>後は、趣味/嗜好ですかね。
現在他言語にも興味がありOOPによるシステム構築が第一歩となるかなと思い、できる限り他言語でも通用するような実装というかパターン的な物を使用したいと考えていたので最初の回答にて質問当初の目標は達成できたのですが、今回のようにPHPでは各バージョンに対応する為にもこういった記述も可能とのこと大変参考になりました。
今回親切に回答して頂き、データ共有の実装以外にも考え方や勉強の仕方等、多くの事を学ばせて頂きました。
本当にありがとうございました!
No.3
- 回答日時:
・Modelの実行結果をViewの引数として使う(スマートじゃない気が?)
が一番近いのではないかと思いますよ
直接引数として使うというより
View用のクラスの変数にセットしてやるという形になると思います
Smartyを使うとModelの実行結果や表示させたい項目の連想配列をView用の変数にセットする(アサイン:assign)して使いますよ
回答ありがとうございます。
なるほどSmartyをViewにしてしまい、Model内からViewを使用する感じですね。
私の質問の仕方がわるかったのかもしれません。
少しずつ理解できてきたので質問を修正させて頂きますと
「Modelで得られた値をViewやその他複数のクラス内で共有する方法」
が知りたかったのです。
Modelの結果をすべてSmartyにあててしまうと
new someClass($smartyobject);や$someobject->setVariableObject($smartyobject);
としたり $GLOBALS['smarty'] = $smartyobject; しないといけなくなるのでは?
と思って質問させて頂きました。
説明下手ですみません。
#1にてCakePHPではSingletonクラス、その他にもStatic変数を使用すれば実現できるという事がわかったのでこれにて回答は締切らせて頂きます。
ご回答ありがとうございました。
No.2
- 回答日時:
スミマセン、書いてから少し考え直してみましたら、
PHP5では、メンバ変数にstatic変数が使えるので、がんばってSingletonを引かなくても実現できそうですね・・・
<?php
class MyRegistry{
private static $objects;
public static addObject($key, $object){
self::$objects[$key] = $object;
}
public static getObject($key){
return self::$objects[$key];
}
}
?>
内部にインスタンスを作る意味、もう少し複雑な処理が絡んでくる場合は何らかの意味も出てくるかもしれませんが、今回のようにいくつかのオブジェクトをただ入れて、出す、だけでしたら、上記のようにstaticなメンバ変数に突っ込んでやればよいですね。
なるほど!
たしかに単純な用途であればこれだけのコードで全然使えそうですね。
スタティックな変数というのを実はあまり使った事がなく、先日の回答で初めて「こういう使い方をするんだ!」と理解したばかりでして、今回の回答のように「じゃあこうすればもっとシンプルに・・・」とまでは考えられなかったです。
主題も含め、今回Singletonなクラス及びStaticなメンバ変数について少しは理解でき、大変参考になりました。
本当にありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・チョコミントアイス
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・あなたの習慣について教えてください!!
- ・ハマっている「お菓子」を教えて!
- ・高校三年生の合唱祭で何を歌いましたか?
- ・【大喜利】【投稿~11/1】 存在しそうで存在しないモノマネ芸人の名前を教えてください
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・家の中でのこだわりスペースはどこですか?
- ・つい集めてしまうものはなんですか?
- ・自分のセンスや笑いの好みに影響を受けた作品を教えて
- ・【お題】引っかけ問題(締め切り10月27日(日)23時)
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・架空の映画のネタバレレビュー
- ・「お昼の放送」の思い出
- ・昨日見た夢を教えて下さい
- ・ちょっと先の未来クイズ第4問
- ・【大喜利】【投稿~10/21(月)】買ったばかりの自転車を分解してひと言
- ・メモのコツを教えてください!
- ・CDの保有枚数を教えてください
- ・ホテルを選ぶとき、これだけは譲れない条件TOP3は?
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・【コナン30周年】嘘でしょ!?と思った○○周年を教えて【ハルヒ20周年】
- ・10秒目をつむったら…
- ・人生のプチ美学を教えてください!!
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
「クラス関数」「メンバ関数」...
-
・オブジェクト指向のメリット...
-
PHPのif文でその処理を途中で抜...
-
3つ以上の論理積は利用可能なの...
-
拡張子php画像をjpg画像等に変...
-
VBAでJPGサイズ変更
-
if文でisset
-
VB.NETでフリーメールアドレス...
-
エンコーディングについて
-
phpでメール送信できません 原...
-
違法アップロードについて
-
youtubeに音声のみのmp4ファイ...
-
透過PNGが透過されない!!
-
awsにApacheとPHPを入れて、何...
-
Xamppでindex.phpだけしか表示...
-
PHPでFilename cannot be empty...
-
PHPsendmailにて送信元を変更
-
phpスクリプトのみで定期実行
-
FTPコマンドでディレクトリごと...
-
phpでうまく画像がダウンロード...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
「クラス関数」「メンバ関数」...
-
phpのクラスにて別ファイルの変...
-
PHP4、PHP5 1ファイル複数クラ...
-
class定義のphpをファイル分割...
-
ラッパークラスって何ですか?
-
乱数のライブラリについて
-
'_'(アンダースコア)の使い方...
-
データベースで値をインクリメ...
-
クラス内でメソッド呼ぶ際、thi...
-
クラスと関数群のうまい使い方
-
Smartyの変数について
-
外部ファイルのクラスのインス...
-
php インスタンスとオブジェク...
-
配列とオブジェクトの違い
-
クラス
-
・オブジェクト指向のメリット...
-
ユーザー定義関数とクラスの違...
-
関数定義の関数名の前にある&(...
-
PHPフレームワーク理解に役立つ...
-
phpで$chars{$num};とした場合...
おすすめ情報