2012-06-19 83 views
4

我正在開發一個簡單的PHP MVC是會做最低限度的工作,但我需要怎麼太,它使用了prodcedural所以我學習,我去一個MVC方法我第一次..在PHP mvc中路由URL的最有效方法?

在開發我不小心把它建立在一個陌生的那種風格,目前主要.htaccess包含了幾乎所有的物理重寫,例如論壇:

RewriteRule ^forum/([a-zA-Z0-9_]+)_([0-9]+)/$     index.php?controller=forum&method=showThread&urlTitle=$1&threadId=$2 [L] 
RewriteRule ^forum/([a-zA-Z0-9_]+)_([0-9]+)/all/([0-9]+)$  index.php?controller=forum&action=showThread&urlTitle=$1&threadId=$2&page=$3 [L] 

它是如何工作的時刻是所有的url都被引導到index.php,然後它使用從url中使用的控制器和方法:

的index.php

$actionName = $_GET['action']; 
$controllerName = ucfirst(strtolower($_GET['type'])).'controller'; 

$controller = new $controllerName; 
$controller->$actionName(); 

控制器/ forumcontroller.php

class forumcontroller{ 

    function showThread() { 

     $thread = new Thread($_GET['threadId'], $_GET['uriTitle']); 
     require "templates/thread.php"; 
    } 

但這意味着有可能爲用戶轉到地方我不想讓他們有機會獲得例如:

/public_html/templates/index.php 

我認爲我需要什麼?

我認爲主要的.htaccess應該看起來像這樣?

RewriteEngine on 

RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-d 

RewriteRule ^(.*)$ index.php?url=$1 [L,QSA] 

,然後在index.php中你會使用類似:

$url = explode("/", `$_SERVER['QUERY_STRING']);` 

$controller = $url[0]; //Returns "forum" 
$data = $url[1];   //Returns the forum title and id 

,但這種做法我不明白你怎麼稱呼只用數據控制器內的行動?

不會,你必須做一些事情,如:

if(!$data) 
    $controller->loadForum(); 
elseif($data) 
    $controller->loadForumThread($data); 

結論

我只是不理解如何最好地做路由的,有很多搜索引擎友好的網站不同格式的網址,我理解mvc應該如何工作,但我正在努力掌握路由部分,我遇到的所有示例看起來都非常複雜!

我真的很努力,看看如何編寫的.htaccess和控制器來處理大量不同格式的URL,就像這樣:

domain.com 
domain.com/uploads 
domain.com/profiles/username 
domain.com/messages/inbox 
domain.com/messages/createnew/userId 
domain.com/forum/all/2 
domain.com/forum/title_1/ 
domain.com/forum/title_1/all/3 
+0

我發現在文件夾中使用.htaccess我不希望用戶有權訪問可能是一個更簡單的解決方案,上述路由方法的工作原理,並讓我更容易控制URL重寫。任何人不同意? – Dan

回答

3

這裏有一個方法,類似於你的第二個例子的.htaccess 。

$request = explode('/', substr($_SERVER['REQUEST_URI'], 1)); 
// Clean request array of empty elements 
foreach($request as $k => $v) 
    // Clear any empty elements 
    if(!$v) unset($request[$k]); 
$request = array_values($request); // Renumber array keys 

這給出了表示請求URI的數字索引數組。該應用程序可以假設在請求中的第一個值是控制器的名稱:

if(count($this->request) == 0) 
    $request[] = 'DefaultController'; // Responsible for homepage 
$this->controller = new $request[0]($request); 

我也傳遞一個$context變量控制器構造,但是這超出範圍了這個問題(它負責數據庫連接,當前用戶數據和會話數據)。

在此之後,它簡單地將請求分派:$this->controller->dispatch()

裏面的調度方法中,控制器本身是知道的請求陣列。在您的網址列表,例如,讓我們來看看第三個例子:domain.com/profiles/username

控制器將被命名爲「簡介」:

class Profiles { 
    private $request, $context; 
    public function __construct($request, $context) { 
     $this->request = $request; 
     $this->context = $context; 
    } 

    public function dispatch() { 
     if(count($this->request) == 2 && $this->request[1] == 'username') { 
      // Load data from model for the requested username ($this->request[1]) 

      // Show View 
     } 
    } 
} 

有更好的方法,你可以映射請求向量的行動,但希望你能得到jist。

+0

在你的例子中,'$ this-> context = $ context;'是什麼? – Dan

+0

爲了我的目的,我使用上下文來存儲請求的上下文。這不是100%適用於你的問題,所以我沒有詳細說明。它基本上只是一個包含對數據庫,會話和用戶對象的引用的關聯數組。 –

+0

@JeffLambert你好!我有一個關於PHP MVC路由的300點賞金問題。任何意見,你可以作出不勝感激。祝你有美好的一天! https://stackoverflow.com/questions/42172228/is-this-how-an-mvc-router-class-typically-works –