MVC控制器的一个示例

时间:2009-11-15 15:40:35

标签: php model-view-controller

我一直在阅读很多关于如何以及为什么在应用程序中使用MVC方法的内容。我已经看到并理解了一个模型的例子,我已经看到并理解了View的例子....但我仍然在控制器上有点模糊。我真的很想看到一个完整的控制器示例。 (如果可能,使用PHP,但任何语言都会有帮助)

谢谢。

PS:如果我能看到一个index.php页面的例子,它会决定使用哪个控制器以及如何使用。

编辑:我知道控制器的工作是什么,我真的不明白如何在OOP中完成这项任务。

6 个答案:

答案 0 :(得分:61)

请求示例

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');
        }
    }
}

如您所见,控制器负责应用程序的“流程” - 即所谓的应用程序逻辑。它不关心数据存储和表示。它收集所有必要的数据(取决于当前的请求)并将其分配给视图......

请注意,这不适用于我所知道的任何框架,但我相信你知道这些函数应该做什么。

答案 1 :(得分:1)

想象一下,用户界面中有屏幕,用户输入一些搜索条件的屏幕,显示匹配记录摘要列表的屏幕,以及一旦选择了记录就会显示以进行编辑的屏幕。

行上的初始搜索会有一些逻辑
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方法进行搜索。

答案 2 :(得分:0)

<?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;
            }

    }
}

答案 3 :(得分:0)

<?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();
    }
}

答案 4 :(得分:0)

  1. 创建文件夹结构
  2. 设置.htaccess&amp;虚拟主机
  3. 创建配置类以构建配置数组
  4. 控制器

    1. 创建带有受保护的非静态路由器类,带有getter
    2. 使用config include&amp;创建init.php自动加载和包含路径(lib,controlelrs,models)
    3. 使用路由,默认值(路由,控制器,操作)创建配置文件
    4. 在路由器中设置值 - 默认值
    5. 设置uri路径,爆炸uri并设置路径,控制器,动作,参数,处理参数。
    6. 通过传递uri创建app类来运行应用程序 - (protected router obj,run func)
    7. 创建控制器父类以继承所有其他控制器(受保护的数据,模型,参数 - 非静态) 设置数据,构造函数中的参数。
    8. 创建控制器并使用上面的父类扩展并添加默认方法。
    9. 在运行功能中调用控制器类和方法。方法必须带有前缀。
    10. 如果是exisist,请调用方法
    11. 浏览

      1. 创建父视图类以生成视图。 (数据,路径),默认路径,设置控制器,渲染功能 返回完整的tempalte路径(非静态)
      2. 使用ob_start()创建渲染函数,ob_get_clean返回并将内容发送到浏览器。
      3. 更改app类以解析数据以查看类。如果返回path,则也传递给视图类。
      4. Layouts..layout取决于路由器。重新解析布局html以查看和渲染

答案 5 :(得分:-2)

请检查:

    <?php
    global $conn;

    require_once("../config/database.php");

    require_once("../config/model.php");

    $conn= new Db;

    $event = isset($_GET['event']) ? $_GET['event'] : '';

    if ($event == 'save') {
        if($conn->insert("employee", $_POST)){
            $data = array(
                'success' => true,
                'message' => 'Saving Successful!',
            );
        }

        echo json_encode($data);
    }

    if ($event == 'update') {
        if($conn->update("employee", $_POST, "id=" . $_POST['id'])){
            $data = array(
                'success' => true,
                'message' => 'Update Successful!',
            );
        }

        echo json_encode($data);
    }

    if ($event == 'delete') {
        if($conn->delete("employee", "id=" . $_POST['id'])){
            $data = array(
                'success' => true,
                'message' => 'Delete Successful!',
            );
        }

        echo json_encode($data);
    }

    if ($event == 'edit') {
        $data = $conn->get("select * from employee where id={$_POST['id']};")[0];
        echo json_encode($data);
    }
?>