解説
前回はフロントコントローラーですべてのリクエストを index.php に集約しました。
結果、index.phpに全ての機能を実装するのは非現実的であることが明らかになりました。
今回はindex.phpから個別の処理部分を分離して各クラス(コントローラー)で管理するようにします。
例としてユーザー管理機能を実装していきます。
目次
- ディレクトリ再構成
- .htaccess修正
- Request.php修正
- ディスパッチャークラス作成
- Httpクラス作成
- コントローラー(親)クラス作成
- ユーザーコントローラー作成
- create.html修正
- index.php修正
- ブラウザで確認
ディレクトリ再構成
現在の構成
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;
ブラウザで確認
前の記事
[オレオレ08] フロントコントローラー
次の記事
[オレオレ10] ヘルパー関数