我的问题是如何在简单的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);
在这个代码示例中,$cont
和home
一样是页面的名称。需要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。