我正在製作一個小型的PHP MVC框架以獲得樂趣。我正在使用前端控制器index.php
來路由所有流量並根據請求調用新控制器。但是,我需要一種方法來創建一個僅由控制器名稱(基本上,文件名即controllers/posts.php
)的用戶生成的控制器庫的實例。如何僅基於文件名(PHP)創建類的實例
有沒有辦法做到這一點?
我正在製作一個小型的PHP MVC框架以獲得樂趣。我正在使用前端控制器index.php
來路由所有流量並根據請求調用新控制器。但是,我需要一種方法來創建一個僅由控制器名稱(基本上,文件名即controllers/posts.php
)的用戶生成的控制器庫的實例。如何僅基於文件名(PHP)創建類的實例
有沒有辦法做到這一點?
有幾種方法可以做到這一點。一種方法是建立一個約定,以便該類的名稱基於該文件的名稱。另一種方法是解析文件中的類名。你想看一些小代碼的例子嗎?
編輯:簡單的例子
想象一下我們在一些核心MVC控制器,我們想加載第三方用戶提供的控制器。有兩件事情你需要做的:
假設你有一個約定,比如Zend其中的類名映射到文件系統等等控制器可能是
MyProject/Controller/Login.php
的路徑登錄控制器,相對於項目的根。遵循Zend公約,這個類的名字是MyProject_Controller_Login
。如果你想實例化這個類所有你需要做的是:
// load class
require_once 'MyProject/Controller/Login.php';
// instantiate class
$oUserController = new MyProject_Controller_Login();
如果需要實例基於運行時數據的類,你可以用持有的類名稱的變量這樣做,所以
$sUserController = 'MyProject_Controller_Login';
$oUserController = new $sUserController();
希望這足以讓你滾動;讓我知道你是否需要更多。
在檢查控制器文件是否存在後,您可以調用它: 以下是我從路由器類中擷取的幾個方法,可以幫助您,它是一個例子,但如果您跟着你可以看到一個類可以如何加載和方法或行動可以被稱爲:
<?php
/**
* Load Class based on controller or action
*/
public function load_controller(){
/*Get the route*/
$this->getController();
/*Assign front controller to handle routes that dont have core controller
eg ./core/controllers/($this->file.Controller).php
*/
if (is_readable($this->file) === false){
$this->file = $this->path.'/frontController.php';
$this->subaction = $this->action;
$this->action = $this->controller;
$this->controller = 'front';
}
/*Include core controller file*/
include($this->file);
/*Create controllers class instance & inject registry*/
$className = $this->controller.'Controller';
$controller = new $className($this->registry);
/*Check the action method is callable within the class*/
if (is_callable(array($controller, $this->action)) === false){
//index() method because not found method
$action = 'index';
}else{
//action() method is callable
$action = $this->action;
}
/*Run the action method*/
$controller->$action();
}
private function getController() {
$route = (!isset($_GET['route']))?'':$this->registry->function->cleanURL($_GET['route']);
/*Split the parts of the route*/
$parts = explode('/', $route);
$this->request = $route;
$corefolders=array('core','templates');
if (empty($route) || in_array($parts[0],$corefolders)){
$route = 'index';
}else{
//Assign which controller class
$this->controller = $parts[0];
if(isset($parts[1])){
/* Site.com/action */
$this->action = $parts[1];
}
if(isset($parts[2])){
/* Site.com/action/subaction */
$this->subaction = $parts[2];
}
}
/*Set controller*/
if (empty($this->controller)){$this->controller = 'index';}
/*Set action*/
if (empty($this->action)){$this->action = 'index';}
/*Set the file path*/
$this->file = $this->path.'/'.$this->controller.'Controller.php';
}
?>
如果你不介意,我希望看到一些例子。我喜歡大會的想法 - 我認爲CodeIgniter使用它。但是,如何才能在另一個目錄中創建類/文件的新實例? – n0pe 2012-03-28 23:53:57
+1,這個實現很有用。它有助於保持文件的有序組織並易於查找。另外它避免了像冠軍一樣的命名空間衝突。 – 2012-03-29 00:14:08
看起來不錯!謝謝@quickshiftin – n0pe 2012-03-29 00:14:50