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


How to include model/view and call classes in simple php mvc example

我的问题是如何在简单的MVC模型中动态地包括和调用模型和视图类?我调用控制器没有问题,我已经找到了各种方法来实现这一点,但我找不到一个好的解决方案来调用和传递模型和视图。

我已经设置了一个.htaccess文件,将url读取为"www.domain.com/controller/method/id"。

我之前试图检查模型和视图是否存在文件,就像我使用$cont变量检查控制器一样,然后尝试加载模型并将其传递到控制器,然后再传递到视图。我遇到的问题是,所有include都使用$cont变量来调用实例化它们的类,并且无法区分彼此。我试着添加一个足够的$contController,但之后我根本无法加载该类,更不用说传入模型或视图了。

这是我的最新例子,没有模型或视图。

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

我对上面的例子做了以下更改,并将其发布在下面,还有我的超简单烤箱简单控制器。

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

控制器,它只是扩展了一个空类,我想如果我想将一个通用方法扩展到每个类,我可以使用它。这就是上面index.php中的coremvc.php。

<?php
Class HomeController extends Controller
{
  function __construct($world) {
    echo "Hello ";
    $this->world = $world;
  }
  function world() {
    echo $this->world;
  }
}

您希望轻松地加载和调用类。我动态加载以".class.php"结尾的类。这对我来说很容易。

我把它放在我的index.php中…其中/app/是我的php类所在的位置:

<?php
define('CLASS_DIR', '/app/');
set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . CLASS_DIR);
spl_autoload_extensions('.class.php');
spl_autoload_register();

接下来,我需要我的路线:

require 'rte/myroute.php';

我让我的路线(控制器)将我的流量引导到我的模型,尽管有一些解析等。

我通常在PHP中开发基于REST的API,所以"视图"只是一个JSON响应。

HTML/JavaScript客户端使用响应。

我喜欢的一个好的框架是SlimPHP。我用Composer加载它。

http://www.slimframework.com/

https://getcomposer.org/

下面是一个将类作为实例静态调用的示例,因为您是自动加载的,所以不需要在顶部包含任何内容:

<?php
$param1 = 1;
$param2 = 2;
MyClass::myFunc($param1);
$myObj = new MyClass;
$myObj->myFunc2($param2);

正如前面所说,您可以查看使用spl_autoload_register,它将需要给定路径中的所有文件。您可以更改此功能以提高负载。

关于您当前代码的模型,您可以按照以下方式实现:

$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);

在这个代码示例中,$conthome一样是页面的名称。需要CCD_ 3和CCD_。然后在__construct($modelName)中设置模型。

但是,我不建议您使用它,因为您的控制器可以加载许多型号。然后,你的控制器可能看起来像这样:

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

在第二个例子中,$this->render可以是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*/
    }
}

总之,您可以通过多种方式实现这种MVC,这段代码只是一个建议,可能不是最好的方式。我建议你看看我在答案开头放的spl_autoload。