Php 使用$服务器[';脚本名称';]实例化控制器
我在php webapp中使用MVC架构。我的架构非常简单,如果我以这种方式向url发送请求Php 使用$服务器[';脚本名称';]实例化控制器,php,model-view-controller,Php,Model View Controller,我在php webapp中使用MVC架构。我的架构非常简单,如果我以这种方式向url发送请求localhost/Dispatcher.php?class=SampleController&method=sampleMethod,这将实例化控制器SampleController,并调用此控制器的方法sampleMethod。顺便说一句,我不能使用.htaccess文件。现在我想去掉Dispatcher.php,所以我想如果我把url的sintax改成类似这样的东西,我就可以实现这一点了localh
localhost/Dispatcher.php?class=SampleController&method=sampleMethod
,这将实例化控制器SampleController
,并调用此控制器的方法sampleMethod
。顺便说一句,我不能使用.htaccess文件。现在我想去掉Dispatcher.php,所以我想如果我把url的sintax改成类似这样的东西,我就可以实现这一点了localhost/SampleController.php?method=sampleMethod
。为此,我必须使用$\u SERVER['SCRIPT\u 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();
}
}
?>
这里我试图点击这个urlMainController.php?method=index
所有名称都正常,路径也正常。顺便说一句,如果我硬编码的路径,我得到相同的错误,这可能是一个包括错误?如果我不能在Controller.php
中实现这一点,那么我可以在某个地方处理控制器实例化,而无需添加另一个.php文件?(我不想再使用Dispatcher.php
)
更新
如果我以这种方式更改Controller.php
,则可以正常工作,但我得到一个致命错误:无法在第9行的maincontroller.php中重新声明类maincontroller
<?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();
}
}
?>
但是这个解决方案仍然不能让我满意,这不是我想要的面向对象的解决方案。在
Controller.php
中不是这样做的吗?您的问题可能是在MainController.php
中调用了在类定义之前包含一次“Controller.php”
。然后Controller.php
将不再包含MainController.php
,因为include\u once
注意到它已经被加载。如果再次使用包含MainController.php的require
,则MainController.php中的include\u一次,下次将不包含Controller.php
,声明类并返回Controller.php
。当Controller.php
完成时,它将返回到原始的MainController.php
,并且无法再次声明该类
您可能可以在Controller.php
的末尾使用die()
或exit()
,但我更喜欢声明一个函数,比如说Process()
,它在初始化后执行所有操作,并将其作为MainController.php
的最后一行调用
Controller.php
<?php
//Enable errors
ini_set('display_errors',1);
ini_set('display_startup_errors',1);
error_reporting(-1);
function Process()
{
//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();
}
}
?>
<?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');
}
}
Process();
?>
Dumb question here:您包含的文件在同一路径中?没有Dumb questions,伙计;)。是的,我已经仔细检查过了。你可能想看看。@teresko很好的信息。但是我想要的是非常简单的:我想要能够向SampleController.php
发送请求那里的类,从Controller
扩展而来,这个类包含一个名为doRouting
的方法来做上述事情,我怎么能不在类定义之外添加一些额外的行来做呢,在SampleController.php
的末尾?。如果我能做到这一点,我想我将有能力解决这个问题代码>位于每个控制器的末尾。有没有办法摆脱它?或者只把它放在一个地方。就像我说的-你可以只把exit()
添加到你的Controller.php
的末尾-但是这是一个有点脏的解决方案。如果使用控制器的URL对您来说很重要,但不需要调用Process()
,那么这对您来说可能没问题。
<?php
include_once 'View.php';
class Controller {
public $view;
public function __construct() {
$this->view = new 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];
$controller = new $class();
$controller->$method();
?>
<?php
//Enable errors
ini_set('display_errors',1);
ini_set('display_startup_errors',1);
error_reporting(-1);
function Process()
{
//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();
}
}
?>
<?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');
}
}
Process();
?>