私は、アプリケーションでMVCアプローチを使用する方法と理由について多くのことを読んでいます。私はモデルの例を見て理解しましたが、ビューの例を見て理解しました。コントローラーの十分な例を見たいと思います。 (in PHP可能であれば、ただし、どの言語でも役立ちます)
ありがとうございました。
PS:どのコントローラーをどのように使用するかを決定するindex.phpページの例を見ることができたら素晴らしいと思います。
編集: 私はコントローラーの仕事が何であるかを知っていますが、OOPでこれを達成する方法を本当に理解していません。
リクエストの例
このようなものをindex.php
:
<?php
// Holds data like $baseUrl etc.
include 'config.php';
$requestUrl = 'http://'.$_SERVER['HTTP_Host'].$_SERVER['REQUEST_URI'];
$requestString = substr($requestUrl, strlen($baseUrl));
$urlParams = explode('/', $requestString);
// TODO: Consider security (see comments)
$controllerName = ucfirst(array_shift($urlParams)).'Controller';
$actionName = strtolower(array_shift($urlParams)).'Action';
// Here you should probably gather the rest as params
// Call the action
$controller = new $controllerName;
$controller->$actionName();
本当に基本ですが、あなたはアイデアを手に入れました...
シンプルなコントローラーの例(controllers/login.php):
<?php
class LoginController
{
function loginAction()
{
$username = $this->request->get('username');
$password = $this->request->get('password');
$this->loadModel('users');
if ($this->users->validate($username, $password))
{
$userData = $this->users->fetch($username);
AuthStorage::save($username, $userData);
$this->redirect('secret_area');
}
else
{
$this->view->message = 'Invalid login';
$this->view->render('error');
}
}
function logoutAction()
{
if (AuthStorage::logged())
{
AuthStorage::remove();
$this->redirect('index');
}
else
{
$this->view->message = 'You are not logged in.';
$this->view->render('error');
}
}
}
ご覧のとおり、コントローラーはアプリケーションの「フロー」、いわゆるアプリケーションロジックを処理します。データの保存と表示は考慮しません。むしろ、(現在のリクエストに応じて)必要なすべてのデータを収集し、ビューに割り当てます...
これは私が知っているどのフレームワークでも動作しないことに注意してください。しかし、関数が何をすべきかを知っていると確信しています。
UIの3つの画面、ユーザーが検索条件を入力する画面、一致するレコードの概要のリストが表示される画面、およびレコードが選択されると編集用に表示される画面を想像してください。最初の検索に関連するいくつかのロジックがあります
if search criteria are matched by no records
redisplay criteria screen, with message saying "none found"
else if search criteria are matched by exactly one record
display edit screen with chosen record
else (we have lots of records)
display list screen with matching records
そのロジックはどこに行くべきですか?確かにビューやモデルにはありませんか?したがって、これはコントローラーの仕事です。コントローラーは、基準を取得し、検索用のModelメソッドを呼び出すことも担当します。
<?php
class App {
protected static $router;
public static function getRouter() {
return self::$router;
}
public static function run($uri) {
self::$router = new Router($uri);
//get controller class
$controller_class = ucfirst(self::$router->getController()) . 'Controller';
//get method
$controller_method = strtolower((self::$router->getMethodPrefix() != "" ? self::$router->getMethodPrefix() . '_' : '') . self::$router->getAction());
if(method_exists($controller_class, $controller_method)){
$controller_obj = new $controller_class();
$view_path = $controller_obj->$controller_method();
$view_obj = new View($controller_obj->getData(), $view_path);
$content = $view_obj->render();
}else{
throw new Exception("Called method does not exists!");
}
//layout
$route_path = self::getRouter()->getRoute();
$layout = ROOT . '/views/layout/' . $route_path . '.phtml';
$layout_view_obj = new View(compact('content'), $layout);
echo $layout_view_obj->render();
}
public static function redirect($uri){
print("<script>window.location.href='{$uri}'</script>");
exit();
}
}
<?php
class Router {
protected $uri;
protected $controller;
protected $action;
protected $params;
protected $route;
protected $method_prefix;
/**
*
* @return mixed
*/
function getUri() {
return $this->uri;
}
/**
*
* @return mixed
*/
function getController() {
return $this->controller;
}
/**
*
* @return mixed
*/
function getAction() {
return $this->action;
}
/**
*
* @return mixed
*/
function getParams() {
return $this->params;
}
function getRoute() {
return $this->route;
}
function getMethodPrefix() {
return $this->method_prefix;
}
public function __construct($uri) {
$this->uri = urldecode(trim($uri, "/"));
//defaults
$routes = Config::get("routes");
$this->route = Config::get("default_route");
$this->controller = Config::get("default_controller");
$this->action = Config::get("default_action");
$this->method_prefix= isset($routes[$this->route]) ? $routes[$this->route] : '';
//get uri params
$uri_parts = explode("?", $this->uri);
$path = $uri_parts[0];
$path_parts = explode("/", $path);
if(count($path_parts)){
//get route
if(in_array(strtolower(current($path_parts)), array_keys($routes))){
$this->route = strtolower(current($path_parts));
$this->method_prefix = isset($routes[$this->route]) ? $routes[$this->route] : '';
array_shift($path_parts);
}
//get controller
if(current($path_parts)){
$this->controller = strtolower(current($path_parts));
array_shift($path_parts);
}
//get action
if(current($path_parts)){
$this->action = strtolower(current($path_parts));
array_shift($path_parts);
}
//reset is for parameters
//$this->params = $path_parts;
//processing params from url to array
$aParams = array();
if(current($path_parts)){
for($i=0; $i<count($path_parts); $i++){
$aParams[$path_parts[$i]] = isset($path_parts[$i+1]) ? $path_parts[$i+1] : null;
$i++;
}
}
$this->params = (object)$aParams;
}
}
}