0
0

[オレオレ09] MVCのC コントローラー

Last updated at Posted at 2023-12-29

解説

前回はフロントコントローラーですべてのリクエストを index.php に集約しました。
結果、index.phpに全ての機能を実装するのは非現実的であることが明らかになりました。
今回はindex.phpから個別の処理部分を分離して各クラス(コントローラー)で管理するようにします。
例としてユーザー管理機能を実装していきます。

目次

  1. ディレクトリ再構成
  2. .htaccess修正
  3. Request.php修正
  4. ディスパッチャークラス作成
  5. Httpクラス作成
  6. コントローラー(親)クラス作成
  7. ユーザーコントローラー作成
  8. create.html修正
  9. index.php修正
  10. ブラウザで確認

ディレクトリ再構成

現在の構成
stampede/
    public/
        .htaccess
        index.php
    supplier/
        stampede/
            App/
                Http/
                    Request.php
                    View.php
    views/
        create.html
        hello.html
        thanks.html
    autoLoader.php
修正後の構成
stampede/
    app/
        Http/
            Controllers/
                Controller.php
                UserController.php
    public/
        .htaccess
        index.php
    supplier/
        stampede/
            App/
                Http/
                    Request.php
                    View.php
                    Dispatcher.php
                Http.php
    views/
        create.html
        hello.html
        thanks.html
    autoLoader.php
$ cd /opt/project/stampede/
$ mkdir -p app/Http/Controllers
$ touch app/Http/Controllers/Controller.php
$ touch app/Http/Controllers/UserController.php
$ touch supplier/stampede/App/Http.php
$ touch supplier/stampede/App/Http/Dispatcher.php

.htaccess修正

.htaccess
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L] # ?url=$1 を追記

Request.php修正

Request.php
    /* 以下追記 */
    /**
     * 
     */
    public $controller = '';
    
    /**
     * 
     */
    public $action = '';

    /**
     * 
     */
    public $params = [];

    /**
     * 
     */
    public $uri = '';

    // 中略

    private function __construct()
    {
        $this->uri = $_GET['url'] ?? ''; // 追記
        $this->get = $_GET;
        $this->post = $_POST;
    }

ディスパッチャークラス作成

Dispatcher.php
<?php

namespace Stampede\App\Http;

use Stampede\App\Http\Request;

class Dispatcher
{
    /**
     * 
     * 
     */
    public static $instance = null;

    /**
     * 
     * 
     */
    private function __construct()
    {
    }

    /**
     * 
     * 
     */
    public static function getInstance()
    {
        if (is_null(self::$instance) === true) {
            self::$instance = new self;
        }
        return self::$instance;
    }

    /**
     * 
     * 
     */
    public function dispatch(Request $request)
    {
        list($controller, $action) = explode('/', $request->uri);

        $request->controller = 'App\Http\Controllers\\' . ucfirst($controller) . 'Controller';
        $request->action = $action;

        return;
    }
}

Httpクラス作成

Http.php
<?php

namespace Stampede\App;

use Stampede\App\Http\Request;
use Stampede\App\Http\Dispatcher;

class Http
{
    /**
     * 
     * @var \Config
     */
    private static $instance = null;

    /**
     * コンストラクタ
     * 
     */
    private function __construct()
    {
    }

    /**
     * 
     * 
     */
    public static function getInstance()
    {
        if (is_null(self::$instance) === true) {
            self::$instance = new self;
        }
        return self::$instance;
    }

    /**
     * 
     * 
     */
    public function bootstrap($view)
    {
        // リクエストの処理
        $request = Request::getInstance();

        // ルートディスパッチ
        $dispatcher = Dispatcher::getInstance();
        $dispatcher->dispatch($request);

        // メソッド実行
        $app = new $request->controller([
            'request' => $request,
            'view' => $view
        ]);
        $app->{$request->action}();
    }
}

コントローラー(親)クラス作成

Controller.php
<?php

namespace App\Http\Controllers;

class Controller
{
    /**
     * 
     */
    protected $request = null;

    /**
     * 
     */
    protected $view = null;
    
    /**
     * 
     * 
     */
    public function __construct($params)
    {
        $this->request = $params['request'];
        $this->view = $params['view'];
    }
}

ユーザーコントローラー作成

UserController.php
<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;

class UserController extends Controller
{
    /**
     * 
     * 
     */
    public function create()
    {
        $this->view->display('create.html');
    }

    /**
     * 
     * 
     */
    public function store()
    {
        header('Location: /stampede/user/thanks');
    }

    /**
     * 
     * 
     */
    public function thanks()
    {
        $this->view->display('thanks.html');
    }
}

create.html修正

formタグのaction属性を修正

create.html
        <main>
            <form class="gy-5" method="post" action="/stampede/user/store">
                <div class="mb-3 col-4">

index.php修正

index.php
<?php

ini_set('display_errors', "On");

require_once('../autoLoader.php');

use Stampede\App\Http;
use Stampede\App\Http\View;

//
$root = '/opt/project/stampede/';

// オートローダー起動
$autoloader = new autoLoader($root);
$autoloader->register();

// ビュークラスのインスタンス取得
$view = View::getInstance();

//
$app = Http::getInstance();
$app->bootstrap($view);

exit;

ブラウザで確認

https://192.168.56.110/stampede/user/create


前の記事
[オレオレ08] フロントコントローラー
次の記事
[オレオレ10] ヘルパー関数

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0