サーバーサイドMVC
まずクラスは使わない。なぜなら必要ないから。せっかくモジュラーな関数をわざわざそうじゃなくする意味がない。クラスはレアケースを除いて基本的には悪。
モデルはRead系のAPIとWrite系のAPIで名前空間を分ける。
<?php /* Articles.php */ namespace Articles\Write; function mkArticle ($title, $text, $tags) { /*バリデーションとかして連想配列を作って返す*/ } function addArticle ($article) {/*DBに保存*/} namespace Articles\Read; function getArticles ($filter=null) {/*DBから読み出し*/} function getArticle ($id) {}
ビューはモデルのRead系APIを直接見る。コントローラがモデルを読んでビューに値を渡す従来のやりかたは頭おかしい。
ここでrenderArticleは面倒だからインラインでhtml書いてるけど実際はテンプレートの呼び出しとかになる。
<?php /* ArticlesView.php */ namespace ArticlesView; use Articles\Read as Articles; function renderArticles () { $articles = Articles\getArticles(); array_map('renderArticle', $articles); } function renderArticle ($article) { ?> <div class="article"> <h2><?= $a["title"] ?></h2> <p><?= $a["text"] ?></p> </div> <? } function renderArticleOfId ($id) { renderArticle(Articles\getArticle($id)); }
コントローラはラウティングライブラリを使って書く。モデルのWrite系APIとビューのAPIにアクセスできる。
<?php /* index.php */ namespace App; use Articles\Write as Articles; use ArticleView; use Routy\Router; $app = new Router(); $app->post("articles", function () { Articles\addArticle(Articles\mkArticle($_POST["title"], $_POST["text"], $_POST["tags"])); redirect("/articles"); }); $app->get("articles", function () { ArticleView\renderArticles(); }); $app->get("articles/{alnum}", function ($id) { ArticleView\renderArticleOfId($id); }); $app->run();