doumi1912 2014-08-29 18:27
浏览 55
已采纳

如何在简单的php mvc示例中包含模型/视图和调用类

My question is how to dynamically include and call the model and view classes in a simple MVC model? I have no problem calling the controller, I have found various ways to do that, but I can't find a good solution for calling and passing in the model and view.

I have setup a .htaccess file to read the url as "www.domain.com/controller/method/id".

I was previously trying to do a check if a file exists for the model and view the same way I am doing the controller using the $cont variable, and then trying to load the model and pass it into the controller, then the view. The issue I had is that all the includes are using the $cont variable to call instantiate their classes and could not tell each other apart. I tried adding a suffic $cont . 'Controller', but then I couldn't load the class at all, let alone pass in the model or view.

Here is my latest example without model or view.

    <?php

//===============================================
// Debug
//===============================================
ini_set('display_errors','On');
error_reporting(E_ALL);

//===============================================
// Includes
//===============================================
require('coremvc.php');

//===============================================
// Constants & Globals
//===============================================
define('BASE_PATH', dirname(realpath(__FILE__)));
$GLOBALS['var'] = "";

//===============================================
// Session
//===============================================
session_start();

//===============================================
// Router
//===============================================

if ($_SERVER['REQUEST_URI'] !== '/') {
  $uri = $_SERVER['REQUEST_URI'];
  $uri = ltrim($uri, '/');
  $request = explode('/', $uri);

  foreach ($request as $key => $val) {
    if(empty($request[$key])) {
      unset($request[$key]);
    }
  }

  $request = array_values($request);

  if (isset($request[0])) { 
    $cont = $request[0];
  }

  if (isset($request[1])) { 
    $action = $request[1];
  }

} else {
  $cont = "home";
}

if (FILE_EXISTS('/controllers/' . $cont . 'Controller.php')) {
  require '/controllers/' . $cont . 'Controller.php';
} else {
  $cont = "home";
  require '/controllers/homeController.php';
}

//===============================================
// Start the controller
//===============================================
$controller = new $cont;

I have made the following changes to the example above, posted it below, as well as my super easy bake oven simple controller.

<?php

if (FILE_EXISTS('/controllers/' . $cont . 'Controller.php')) {
  require '/controllers/' . $cont . 'Controller.php';
} else {
  $cont = "home";
  $cont = ucfirst($cont) . 'Controller';
  require '/controllers/homeController.php';
}

//===============================================
// Start the controller
//===============================================
$controller = new  $cont('World');
$controller->world();

Controller, it is just extending an empty class which I was thinking I could use if I wanted to extend a common method to every class. That is what the coremvc.php is in the index.php above.

<?php

Class HomeController extends Controller
{

  function __construct($world) {
    echo "Hello ";
    $this->world = $world;
  }

  function world() {
    echo $this->world;
  }
}
  • 写回答

2条回答 默认 最新

  • duan32342 2014-08-30 10:34
    关注

    As it is already say you can have a look to use the spl_autoload_register which will require all your files in the given path. You can change this function to improve the load.

    Concerning the Model with your current code you can implement it as follow:

    $controllerPath = "/controllers/{$cont}Controller.php";
    $modelPath = "/model/{$cont}Model.php";
    if (FILE_EXISTS($controllerPath)) {
      require $controllerPath;
      if (FILE_EXISTS($modelPath)) {
          require $modelPath;
      }
      else {
          throw new \LogicException(
              sprintf("Your controller must implement a model. No model found: %s", $modelPath)
          );
      }
    } else {
      $cont = "home";
      require "/controllers/{$cont}Controller.php";
      require "/model/{$cont}Model.php";
    }
    
    //===============================================
    // Start the controller
    //===============================================
    $controller = new $cont($cont);
    

    In this sample of code, $cont is the name of the page like home. Which require the homeController and homeModel. Then in your __construct($modelName) just set the model.

    However, I don't recommand you tu use this because your controller can load many Models. Then, your controller could look like this:

    <?php
    namespace \App\Controller; // If you use namespace
    
    use App\Model\homeModel, // If you use namespace
        App\Model\productModel; // If you use namespace
    
    Class HomeController extends Controller
    {
    
      private $model;
    
      /* If this function is common to all controllers just move it 
      in the parent Controller class( one more time, I don't recommend to set
      the model using this way). */
      public function __construct($model) {
        $this->model= $model;
      }
    
      public function login() {
        $homeModel = new homeModel(); // If you use namespace
    
        // Example to call the view
        $myValue = 'Hello world';
        $this->render(array("myVariableName" => $myValue))
      }
    }
    

    In this second example $this->render can be a method in your Controller class (which by the way should be an abstract class). I'll give a last sample of code for the logic of the abstract controller.

    <?php
    
    namespace \App\Controller;
    
    abstract class AbstractController {
    
        /* Common code for all controllers */
        public function __construct() {
    
        }
    
        /* View renderer */
        protected function render($parameters) {
          /* Call the view here maybe an another class which manage the View*/
        }
    }
    

    To conclude, you can implement this MVC in many way, this code is just a suggestion and maybe its not the best way. I advise you to have a look with the spl_autoload that I put at the beginning of my answer.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥88 找成都本地经验丰富懂小程序开发的技术大咖
  • ¥15 如何处理复杂数据表格的除法运算
  • ¥15 如何用stc8h1k08的片子做485数据透传的功能?(关键词-串口)
  • ¥15 有兄弟姐妹会用word插图功能制作类似citespace的图片吗?
  • ¥200 uniapp长期运行卡死问题解决
  • ¥15 请教:如何用postman调用本地虚拟机区块链接上的合约?
  • ¥15 为什么使用javacv转封装rtsp为rtmp时出现如下问题:[h264 @ 000000004faf7500]no frame?
  • ¥15 乘性高斯噪声在深度学习网络中的应用
  • ¥15 关于docker部署flink集成hadoop的yarn,请教个问题 flink启动yarn-session.sh连不上hadoop,这个整了好几天一直不行,求帮忙看一下怎么解决
  • ¥15 深度学习根据CNN网络模型,搭建BP模型并训练MNIST数据集