PHP宿題 MVC の勉強
頂いた宿題勉強日誌。今日は「MVC」について。(MVC - Google 検索)
フレームワークを利用する前にきっちり理解しておくといい内容とのこと。
実は前にSmartyを使ったことがあって、デザインとロジックを分ける主旨についてはイメージできるのだけれど、MVCと言われると「C」の役割がいまいち分からない。(MとCの境目がイマイチ分からない)
MVCについて検索してるとフレームワークのお話に行き着く事が多くてなかなか初心者向けの簡単な説明が見つからないのだけれど、いろいろ調べた結果を自分なりに解釈すると、
- 表示担当がView
- 入力された内容についてModelに処理をお願いしたり、Viewに表示をお願いしたり、橋渡し的な役割をするのがController
- データの処理がModel(こっちでは入力されたデータの受取とか処理後の結果を直接Viewに渡したりはしない)
という事でいいのかな。オススメして頂いた下記ページを参考にちゃんとやる!
>>PHPでMVC第1回:前編
>>PHPでMVC第2回:後編(Modelの作成/DAOパターン)
・・・読んでる途中で何度も心が折れそうになったけど、頑張って最後まで読みました。こういう専門的なサイトで文字の圧力にくじけそうになった時はブラウザの文字サイズを少し大きくすると不思議と難易度が下がった気分になる傾向がある便利な性格なので、そんな錯覚に陥りながら、10%くらいは理解はできました。
が、やはりやってる内容が難しい。というか、多分字が多すぎて圧倒されてる。
初歩レベルでMVCの考え方、やってみます
ちょっと・・・その・・・あんまり難しい事できないので、私レベルでMVCの考え方だけ、やってみます。間違ってるかも知れんけど、とりあえず普通にこういうファイルがあるという前提で・・・。
単純に名前を入力して送信ボタンを押すと「○○さん、こんにちわ。」という文が表示されるだけの内容なんですが、これをMVC役割分担を考えてみますね。
あ。これは余談ですが、この前勉強したオブジェクト指向の件なんですが、↑上のような内容をclassを作って考えるとしたらコレで合ってますかね・・・。表示される内容自体は同じ結果になるし、変なとこがあっても初心者には分からないという罠。
んでは、本題に戻って・・・
Model部分
機能担当ファイル。
名前が入力されてたら、されてなかったら、それぞれの内容を返す機能。
View部分
デザイナ・コーダーさんが主に触るであろうファイル。テンプレート的な。
「<?=$Hello?>」の部分、{$Hello}みたいな分かりやすい書き方したい。(→だからテンプレートエンジンとかフレームワーク使えばいいよってこと?)途中で今回みたいな場合だと<?=$_SERVER["PHP_SELF"]?>はいらないって気付いたけどまぁ・・・そのまま。
Controller部分
入力データを受け取ってModelに処理をお願いして結果をViewに渡したりとか。
という感じでMVC役割分担を考えてみたのですが、考え方が間違ってたら教えてください><
<< PHP宿題 PDFライブラリを使う | PHPを勉強する事についてデザイナが思う事。 >>
トラックバック
このエントリーのトラックバックURL:
http://redline.hippy.jp/cgi/mt/mt-tb.cgi/253
コメント (10)
おしい!MVCのとこもクラスだったらよかた^^
MVCとオブジェクト指向プログラムは相性がいいのです。近々、上記サンプルに似たものをクラスを使用して自分のブログに書いてみようと思います。PHPはほとんど触ってないので自信はまったくないですがw
すみません、私が勧めた「PHPでMVC」のサイトは難しいですね。。これはとりあえず忘れた方がいいです。混乱させてしまって( TДT)ゴメンヨー
投稿者: きのこ | 2010年02月15日 00:36
>きのこる先生
>おしい!MVCのとこもクラスだったらよかた^^
えっと、では
【Model部分】
class Hello{
public $name;
function aisatu(){
if($this->name){
$this->name = htmlspecialchars($this->name);
return "<p>" . $this->name . "さん、こんにちわ。</p>";
}else{
return "<p>名前を入力してください。</p>";
}
}
}
【Controller部分】
require_once("sample_model.php");
$name = isset($_POST["name"]) ? $_POST["name"] : NULL;
$sample = new Hello;
$sample->name = $name;
$Hello = $sample->aisatu();
require_once("sample_view.html");
こんな感じで大丈夫でしょうか?なんか変かな・・・。
投稿者: Red | 2010年02月15日 10:22
おお、だいぶ良いんじゃないでしょうか^^
ちょっと気がついた部分を少々。。
(1)Helloモデルの「public $name」の部分は「private $name」がよい。setterで値セット、getterで値取り出し。setter,getterを使うことで複数人で開発時に"誰かが勝手なルールで"$nameの値を変更してしまうことを防げる。
※PHPではsetter,getterがない例も多い。小規模開発時はsetter,getterがうざいときもあるwと思ったらこんな便利ツールがあった。
http://www.shuchow.com/gettersetter.html
(2)Helloモデル中でhtmlspecialchars()やPタグを使ってるが、これはviewに任せるべき。modelでやってしまうと後で表示のみ変更したいのにロジックを弄らなければならなくなる。
(3)1クラス1ファイルにしてクラス名とファイル名を一致させるとよい。
例)「class Hello」は「Hello.php」などとする。これをするとソースが見やすくなるのと__autoload()関数なんかが使えて便利!
投稿者: きのこ | 2010年02月16日 02:44
すません。ちと修正。PHP5からは__set,__getというマジックメソッドがありますね。プロパティをprivateで宣言すれば、このマジックメソッドが自動で実行されるらしい。
自分のルールでset,getしたい場合はこれらのメソッドをオーバーロードすればよいです。
参考:
http://hain.jp/index.php/tech-j/2006/10/30/__get__set%E3%81%AE%E5%A4%89%E3%81%AA%E6%8C%99%E5%8B%95
投稿者: きのこ | 2010年02月16日 22:17
たびたびすみません。__get,__setメソッドは、未定義のプロパティを取得・設定しようとしたタイミングで呼び出されるメソッドなので、getter,setterとはちょっと違いますね。
getter,setterとして使用している例もありますが、私だったら自前で用意します。
getter,setterについてはここにもあるように、臨機応変でよいかと^^;
http://chindoutyuzakki.blog64.fc2.com/blog-entry-29.html
私なんかはJava出身なのでgetter,setterがないと気持ち悪いですがw
どうもお騒がせしました。。
投稿者: きのこ | 2010年02月17日 00:01
>きのこ先生
先生すみません。勢い余って最後のコメントに気付く前に次のエントリ、アップしてしまいました(汗
アップしてからこのコメントに気付くまでは、すごく短い時間だったんですが、__get,__setについてもアップしてしまったので、一応『間違えたー』文は追加してそのままにしてます><
ごめんなさいごめんなさい!
でもめっちゃ勉強になってます!ありがとうございます!
投稿者: Red | 2010年02月17日 01:17
>きのこ先生
お教え頂いた3点に気をつけて再度見直ししてみました。
【Model部分 ファイル名をClass_Hello.phpに変更】
class Hello{
private $name;
public function getName() { return $this->name;}
public function setName($x) { $this->name = $x;}
function aisatu(){
if($this->name){
return $this->name . "さん、こんにちわ。";
}else{
return "名前を入力してください。";
}
}
}
【Controller部分】
function __autoload($class){
require_once("Class_" . $class . ".php");
}
$name = isset($_POST["name"]) ? $_POST["name"] : NULL;
$sample = new Hello;
$sample->setName($name);
$Hello = $sample->aisatu();
require_once("sample_view.html");
【View部分】
<form action="<?=$_SERVER["PHP_SELF"]?>" method="post">
<p><input type="text" name="name" /></p>
<p><input type="submit" name="submit" value="送信" /></p>
</form>
<p><?=htmlspecialchars($Hello,ENT_QUOTES)?></p>
少しはマシになったでしょうか・・・。
投稿者: Red | 2010年02月21日 15:10
おおお!だいぶ良くなったと思います!
後は変数の命名規則に気をつけるとよいです。
$Helloという変数名は違和感があります^^;
この辺が参考になるかな。
http://blogs.yahoo.co.jp/nob_ll/46611277.html
私は変数名、関数名はCamel記法を使ってます。クラス名はUpper Camel記法です。こんな感じ。
$helloWorld = new HelloWorld();
今回の例でMVCのつかみはOKだと思います。
最初指摘したように、表示に関する部分はモデルで実装しないようにしましょう。モジュール間を疎結合にするという事が大事です。例えば、モデルだけ取り出してWeb以外のシステムにも使用できるのが理想。その辺が分かってるか分かってないかで今後記述するコードにも差がでると思ってます。がんばってください!
また、何かあったらコメントします^^
投稿者: きのこ | 2010年02月22日 17:36
MVCとは無関係ですが・・・
<form action="<?=$_SERVER["PHP_SELF"]?>" method="post">
ここがXSSの脆弱性を持っちゃってます。エスケープした方がいいですよ~
投稿者: れっど | 2010年02月24日 09:18
>れっどさん
ありがとうございますー!
htmlspecialcharsを使うか、今回みたいな場合ならactionの値を空にするか、ですよね。
セキュリティ関連の事はすごく気になってたので助かりましたー。ありがとうございました!
投稿者: Red | 2010年02月24日 09:50