私は楽しいために小さなPHP MVCフレームワークを作っています。私はフロントコントローラindex.php
を使用して、すべてのトラフィックをルーティングし、要求されたように新しいコントローラを呼び出します。しかし、私はコントローラの名前だけ(基本的にはファイル名、すなわちcontrollers/posts.php
)でユーザー生成のコントローラベースのインスタンスを作成する方法が必要です。ファイル名のみに基づいてクラスのインスタンスを作成する方法(PHP)
これを行う方法はありますか?
私は楽しいために小さなPHP MVCフレームワークを作っています。私はフロントコントローラindex.php
を使用して、すべてのトラフィックをルーティングし、要求されたように新しいコントローラを呼び出します。しかし、私はコントローラの名前だけ(基本的にはファイル名、すなわちcontrollers/posts.php
)でユーザー生成のコントローラベースのインスタンスを作成する方法が必要です。ファイル名のみに基づいてクラスのインスタンスを作成する方法(PHP)
これを行う方法はありますか?
これを行うにはいくつかの方法があります。 1つの方法は、クラスの名前がファイルの名前に基づいているような規約を確立することです。これを行う別の方法は、クラス名のファイルを解析することです。小さなコード例を見たいですか?
EDIT:簡単な例
我々はいくつかのコアMVCコントローラにいる私たちは、サードパーティのユーザによって提供コントローラをロードしたい想像してみてください。あなたがする必要がある2つのことがあります。
をインスタンス化ロードを使用すると、クラス名はそうファイルシステムにマップの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();
これで十分です。あなたがもっと必要ならば教えてください。
はいフロントコントローラまたはルータクラス内でコントローラファイルが存在することを確認したら、それを呼び出すことができます。 ここでは、ルータクラスからリッピングした2つの方法があります。クラスをロードしてメソッドやアクションを呼び出す方法を確認できます。
<?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
+1、この実装は驚く。ファイルを整理して見つけやすくするのに役立ちます。加えて、それはチャンピオンのような名前空間の衝突を避けます。 –
素晴らしいですね!ありがとう@quickshiftin – n0pe