質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.38%

独自フレームワークのアクションにviewを紐付けたい

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 420
退会済みユーザー

退会済みユーザー

検索してもなかなか出てこなかったので、質問させていただきます。

phpもある程度理解できるようになったので、
すごく簡易的なMVCの独自フレームワークを作成しています。

現在、以下のサイトを参考にしながら独自フレームワークを作成しています。
<http://www.objective-php.net/mvc/framework>

そこで、Viewとcontrollerのアクションの紐付けに関してなのですが、
先ほどのサイトよりViewのセクションで、Smartyを使用してテンプレートと紐付けをしていると思います。
<http://www.objective-php.net/mvc/view>
おそらく、以下の記述かと思います。

$smarty->display('sample.tpl');

しかし、今回はphpのみで完結させたいなと考えており、
smartyを組み込んでのフレームワーク作成は次回にしようと思っています。

Smartyを使用せずに、controllerのactionとテンプレートを紐づけるには
どのような実装をしたら良いでしょうか?

ちなみにURLは

  • http://192.168.33.10/myapp/?cont=[Controller名]:[Action名] 

で、コントローラーとアクションを識別しています。


具体的にした方が、より明確な回答を得られるとアドバイスをいただいたので
追記いたします。

私のイメージしているcontrollerのactionとテンプレートの紐付けとは
以下のような感じです。

<?php
//sample_controler.php

/**
 * AppControllerはControllerを継承しています。
 * 
 * Controllerでは、PDOのinstance化などの
 * 主要な機能を使えるようにする処理を書いています。
 */
class sample_controller extends AppController
{
    function something()
    {
        $view->assign($msg,'post送信です。');
        $view->setTmp('sample.php');
    }
}
//sample.php
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>sample</title>
</head>
<body>
    <form action="?cont=sample:something" method="post" accept-charset="utf-8">
        <input type="text" name="something">
        <button type="submit">送信</button>
    </form>
    <?=$msg?>
</body>
</html>

不足していることがありましたら、修正します。
よろしくお願いいたします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • hentaiman

    2019/06/20 18:46

    この質問文だと考え方の問題なので方法も自由過ぎて回答し辛いと思うな
    コントローラー(?)というファイルの中ではこういう記載をしたい、テンプレート(htmlのこと?)はこういう風に呼び出したいまたは明記しないがコントローラー(?)のアクション(?)名から判断するようにしたくて今はこういう作りをしている、とか
    コードを載せたらきっとナイスな回答者達がエクセレントな回答してくれるよ

    キャンセル

  • 退会済みユーザー

    退会済みユーザー

    2019/06/20 18:48

    コメントいただきまして、ありがとうございます。
    おっしゃる通り、考え方は色々ありますね。
    もう少し、具体的な質問になるように修正します!
    ありがとうございます。

    キャンセル

  • hentaiman

    2019/06/20 19:10

    追記見ました。
    極端なやり方で言うと明示的にテンプレートに相当するファイルを指定するなら$view->setTmp('sample.php');に相当する個所でファイルをrequire_onceでもすれば済む事だからね。
    そういったところに対する感覚もまだまだ曖昧だと思うので、とりあえず参考にしてるサイトそのまんま真似してみた方がいいかもしんないですね。その後に自分ならここをこうした方が使いやすいとか色々考えが出てくると思うので、その時に改造していくのが近道だと思います

    キャンセル

回答 2

+1

検索してもなかなか出てこなかったので

検索しても出てこないのは当然かと思います。
独自フレームワークなのであればそれこそドンピシャな情報は載っていません。
基本はどうすればできるか自分で考えることです。

Smartyを使用せずに、controllerのactionとテンプレートを紐づけるには
どのような実装をしたら良いでしょうか?

独自フレームワークなのであればお好みのようにすれば良いと思います。
おおよそはコントローラーのアクションに紐づかせるものですし。

どのような構成か分からないので思うように答えますが、
例えば、設定を配列か何かで持っておいて紐づかせるやり方でもいいですし

$viewSetting = [
 "コントローラA"=>["アクション1"=>"ビュー","アクション2"=>"ビュー",],
 "コントローラB"=>["アクション1"=>"ビュー","アクション2"=>"ビュー",]
];

いっそアクションに直に書いてもいいのではと。

アクションでどういう処理を書こうとしているのか分からないですが、
ビューのテンプレートを作っておいてアクションではコンテンツ部分を作るだけに終始して、
同じ変数で受け取ってテンプレートに流すでも良いですし。

↓アクションからは必要なデータをreturnさせる

echo <<<HTML
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>{$data["title"]}</title>
</head>
<body>
 {$data["contents"]}
</body>
</html>
HTML;

幾らでもやりようはあるので、自分がやりやすい方法を考えたら良いかと思います。


既存フレームワークを参照するのが最も参考になると思いますよ。
Smartyなり何なりテンプレートエンジンを使ってたとしても、
結局は「ビューに必要な情報を準備して、渡す」のがコントローラのアクションが行うことなので。
ビューは基本は来たデータを表示するだけです。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/06/20 19:03

    おっしゃる通り、様々な方法がありますね。

    ただ、処理と表示は分けたいので、
    コードリーディングを磨くためにも、既存フレームワークを参考にしてみます。
    ありがとうございます!

    キャンセル

  • 2019/06/20 19:06

    それにSmartyもPHPで作られてますからね…
    結局動いてるのは全部phpです。

    キャンセル

  • 2019/06/20 19:11

    それに、自分でルールを設ければいいだけなので如何様にもできるんですよ。
    例えば、viewディレクトリのコントローラ名ディレクトリ配下のアクション名.phpを読むってルールを設けてそのように作れば設定ファイルで紐づける必要もないわけですしね。決めた命名規則にそってviewファイルを置くだけです。
    先にルールを決めてください。

    キャンセル

  • 2019/06/20 19:19

    わかりました。。。
    命名規則等などの設計からやってみます!
    ありがとうございます。

    キャンセル

check解決した方法

0

以下のようにして、ActionとViewを紐付けました。

<?php
/**
 * Controller
 * sample_controller.php
 */

class sample_controller extends AppController
{
    function index()
    {
        $name = "こんにちは";

        $this->view_assing('name',$name);
        $this->view_display('index.php');
        return true;
    }
}
/**
 * sample_controllerの親クラス
 * AppController.php
 */
<?php
class AppController extends Controller
{    
    /**
     * View instance
     * @var Object
     */
    private $_view;




    /**
     * Viewクラスのインスタンス生成。
     * 生成元は、Controller.php
     */
    function set_view()
    {
        $this->_view = $this->intance_view();
        return true;
    }



    /**
     * View Objectに渡して指定のTemplateをincludeしてもらう
     */
    function view_display($tmp_name)
    {
        $this->_view->_setTemplate($tmp_name)->include_template();
    }



    /**
     * Templateに使う変数を指定
     * @param  [string] $str      key
     * @param  [mixed]  $variable value
     */
    function view_assing($str,$variable)
    {    
        $this->set_view();
        $this->_view->assign_param($str,$variable);
    }
}
/**
 * View
 * sample.php
 */
<!DOCTYPE html>
<html lang="ja">
<head>
    <title>sample</title>
</head>
<body>
    <h1>indexです。</h1>
    <?= View::$view['name']);?>
</body>
</html>
<?php
class View
{
    private $_tmp_name;
    private $_controller;
    public static $view;

    /**
     * Templateをset
     */
    public function _setTemplate($tmp_name)
    {
        $this->_tmp_name = $tmp_name;

        return $this;
    }


    /**
     * 現段階では使わない 2019/06/21
     */
    public function _setController($controller_name)
    {
        $this->_controller = $controller_name;
    }



    /**
     * テンプレートをrequire
     */
    public function include_template()
    {
        $tmp_is = $this->file_check('tmp');
        if(!$tmp_is) return false;

        require_once $tmp_is;
    }



    /**
     * ViewでControllerから受け取った値を使えるようにする
     * Template側では、View::$viewで値を使う
     */
    public function assign_param($string,$parameter)
    {
        View::$view = array(
            $string => $parameter
        );
    }



    /**
     * ファイル存在チェック
     */
    private function file_check($string)
    {
        switch ($string) {
            case 'tmp':    
                $view_tmp = MVC_V .'/' .$this->_tmp_name;
                return (!file_exists($view_tmp)) ? false : $view_tmp;

                break;

            case 'cont':
                $cont_timp = MVC_C .'/' .$this->_controller;
                return (!file_exists($cont_timp)) ? false : $cont_timp;
                break;
        }

    }

}

Viewクラスで一度templateをincludeして、
controllerから渡したい値がある場合は、
Viewクラスのstaticプロパティである$viewに値をkeyとvalueで保持してあげて、
template側では、View::$view['key']で呼び出せるようにしました。

まだまだ修正する予定で、
本当にこれが効率が良いかわかりませんが、問題は解決できました。

ご回答してくださった方、ありがとうございました。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/06/21 14:52

    なるほど...
    確かにこれまでも、modelなどに分けられるはずの処理をcontrollerに書いてしまってました。
    私もまだまだ勉強が足りませんね。。。

    フレームワークを作る側も、使う側もなんの処理を実装しているかを明確にして
    処理を適切に分ける必要がありますね。

    ありがとうございます!

    キャンセル

  • 2019/06/21 14:57

    自身で作ってみることで分かることもたくさんありますしオブジェクト指向への理解も深まると思います(私もそうでした)
    がんばってください。

    キャンセル

  • 2019/06/21 17:02

    ありがとうございます!
    もっとたくさんのコードに触れて、自分で作成してみて理解を深めていきます!

    ご親切にありがとうございました。
    とても勉強になりました!!!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.38%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る