1

我在我的 php webapp 中使用 MVC 架构。我的架构非常简单,如果我以这种方式向 url 发送请求,localhost/Dispatcher.php?class=SampleController&method=sampleMethod这将实例化控制器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();
    }
}
?>

解决方法

我以这种方式实现了我想要的:

主控制器.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();
    }
}
?>

核心.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

4

1 回答 1

0

您的问题可能出在您在定义类之前MainController.php调用​​。include_once 'Controller.php'然后Controller.php将不再包含MainController.php,因为include_once注意到它已经加载了。如果你再次使用require那个包含MainController.php,那么include_onceinMainController.php将不再包含Controller.php另一个时间,声明类并返回到Controller.php. 完成Controller.php后,它将返回原始状态MainController.php,并且无法再次声明该类。

您可能可以使用die()orexit()在结尾处,Controller.php但我更喜欢声明一个函数,比如说Process(),它在初始化后完成所有工作,并将其作为MainController.php.

控制器.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

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

?>
于 2014-01-05T13:53:50.207 回答