我在php webapp中使用MVC架构。我的架构非常简单,如果我以这种方式向URL发送请求localhost/Dispatcher.php?class=SampleController&method=sampleMethod
,这将实例化控制器SampleController
并调用此控制器的方法sampleMethod
。顺便说一句,我不能使用.htaccess文件。现在我想摆脱Dispatcher.php
,所以我认为如果我将网址的sintax更改为类似localhost/SampleController.php?method=sampleMethod
的内容,我就可以实现这一点。为此,我必须使用$_SERVER['SCRIPT_NAME']
来获取控制器类名。我的所有控制器都来自Controller
。我认为我可以在Controller.php
中实例化那里的控制器。所以,我的Controller.php
看起来像这样。
<?php
//Enable errors
ini_set('display_errors',1);
ini_set('display_startup_errors',1);
error_reporting(-1);
//Include the controller
$include = explode("/",$_SERVER['SCRIPT_NAME'])[2]; //This return MainController.php
include_once $include;
//Get the method (Like this is an example I don't care the validations)
$method = $_GET['method'];
$class = explode(".",$include)[0]; //Get rid of the *.php extention
$controller = new $class();
$controller->$method(); // I get Class 'MainController' not found
include_once 'View.php';
class Controller {
public $view;
public function __construct() {
$this->view = new View();
}
}
?>
这是我的MainController.php
<?php
include_once 'Controller.php';
include_once 'MainModel.php';
class MainController extends Controller {
public $model;
public function __construct() {
parent::__construct();
$this->model = new MainModel();
}
public function index(){
$this->view->render('mainView','headerMain','footerMain');
}
}
?>
我在这里尝试点击此网址MainController.php?method=index
所有名字都没问题,路径也可以。顺便说一句,如果我硬编码路径我得到相同的错误,这可能是一个包含错误?如果我无法在Controller.php
中实现这一点,那么在某些地方我可以处理控制器实例化而无需添加另一个.php文件? (我不想回到使用Dispatcher.php
)
更新
如果我以这种方式更改Controller.php
,则有效,但我得到Fatal error: Cannot redeclare class maincontroller in MainController.php on line 9
<?php
include_once 'View.php';
//Enable errors
ini_set('display_errors',1);
ini_set('display_startup_errors',1);
error_reporting(-1);
//Include the controller
$include = explode("/",$_SERVER['SCRIPT_NAME'])[2]; //This return MainController.php
//Get the method (Like this is an example I don't care the validations)
$method = $_GET['method'];
$class = explode(".",$include)[0];
require($include);
$controller = new $class();
$controller->$method();
class Controller {
public $view;
public function __construct() {
$this->view = new View();
}
}
?>
解决方法
我以这种方式实现了我的目标:
MainController.php
<?php
//Enable errors
ini_set('display_errors',1);
ini_set('display_startup_errors',1);
error_reporting(-1);
include_once 'Controller.php';
include_once 'MainModel.php';
class MainController extends Controller {
public $model;
public function __construct() {
parent::__construct();
$this->model = new MainModel();
}
public function index(){
$this->view->render('mainView','headerMain','footerMain');
}
}
require_once("Core.php");
?>
Controller.php这样
<?php
include_once 'View.php';
class Controller {
public $view;
public function __construct() {
$this->view = new View();
}
}
?>
core.php中
<?php
//Enable errors
ini_set('display_errors',1);
ini_set('display_startup_errors',1);
error_reporting(-1);
//Include the controller
$include = explode("/",$_SERVER['SCRIPT_NAME'])[2]; //This return MainController.php
//Get the method (Like this is an example I don't care the validations)
$method = $_GET['method'];
$class = explode(".",$include)[0];
$controller = new $class();
$controller->$method();
?>
但是这个解决方案仍然不能让我满意,这不是我想要的面向对象的解决方案。在Controller.php
?
答案 0 :(得分:0)
您的问题可能是MainController.php
在您的课程定义之前调用了include_once 'Controller.php'
。然后,Controller.php
将不再包含MainController.php
,因为include_once
已注意到它已加载。如果您再次使用包含require
的{{1}},MainController.php
中的include_once
将不再包含MainController.php
,请声明该类并返回{{1} }}。完成Controller.php
后,它将返回原始Controller.php
,但无法再次声明该类。
您可以在Controller.php
的末尾使用MainController.php
或die()
,但我更愿意声明一个函数,让我们说exit()
,它可以完成所有这些工作初始化后,将其称为Controller.php
的最后一行。
<强> Controller.php这样强>
Process()
<强> MainController.php 强>
MainController.php