2013-11-02 46 views
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

UPDATE 如果我以這種方式改變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(); 

?> 

但這個解決方案仍然沒有satisfice我,這不是我想要的面向對象的解決方案。 Controller.php中沒有這樣做嗎?

+0

愚蠢的問題在這裏:要包括的文件是相同的路徑? –

+0

有沒有愚蠢的問題哥們;)。是的,我強烈檢查。 – 4gus71n

+0

您可能想閱讀[this](http://stackoverflow.com/a/19309893/727208)。 –

回答

0

您的問題可能是MainController.php您在定義類之前調用​​了include_once 'Controller.php'。那麼Controller.php將不再包含MainController.php,因爲include_once注意到它已被加載。如果再次使用包括MainController.phprequire,則MainController.php中的include_once將不包括Controller.php,並聲明該類並返回Controller.php。當Controller.php完成後,它將返回到原來的MainController.php,並且這無法再次聲明該類。

您可能能夠使用die()exit()Controller.php結束,但我寧願聲明一個函數,讓我們說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(); 
    } 
} 

?> 

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'); 

    } 
} 

Process(); 

?> 
+0

所以我必須在每個控制器的末尾加上'Process();'。有沒有辦法擺脫這一點?或者只把它放在一個地方。 – 4gus71n

+0

就像我說過的 - 你可能只需要在你的'Controller.php'的末尾添加'exit()' - 但這會有點骯髒的解決方案。如果你使用控制器的URL對你來說很重要,但是沒有那麼簡單的'Process()'調用,那對你來說可能沒問題。 – user3161380

相關問題