【发布时间】:2013-11-02 04:18:43
【问题描述】:
我在我的 php webapp 中使用 MVC 架构。我的架构非常简单,如果我以localhost/Dispatcher.php?class=SampleController&method=sampleMethod 这种方式向 url 发送请求,这将实例化控制器 SampleController 并调用此控制器的方法 sampleMethod。顺便说一句,我不能使用 .htaccess 文件。现在我想摆脱Dispatcher.php,所以我认为如果我将url的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");
?>
控制器.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 中不是有什么办法吗?
【问题讨论】:
-
这里的愚蠢问题:您包含的文件在同一路径中?
-
哥们没有愚蠢的问题;)。是的,我强烈检查过。
-
您可能想阅读this。
-
@teresko 不错的信息。但我想要的很简单:我希望能够向
SampleController.php那里的类发送请求,从Controller扩展,这个类包含一个名为doRouting的方法,可以完成上述工作,我该怎么做在SampleController.php? 的末尾,无需在类定义之外添加一些额外的行。如果我能做到这一点,我认为我有能力解决问题。