2012-08-02 59 views
0

我PHP創建我自己的MVC框架,以學習更高級的編程手段。我已經啓動並運行了框架,但是我有關於當前路由方法的問題。我希望框架支持後端cms來讚美前端網站。問題是,我的路由結構的工作原理是這樣 - mywebsite.com/controller/method/id 路由引擎排序信息轉換成這樣CMS路由在MVC

segments 0 => controller, 1 => method, 2 => id 

數組現在如果我訪問mywebsite.com/projects需要我什麼,我已經設置了作爲管理頁面。不僅我希望這是訪問只能從mywebsite.com/admin/projects,我希望mywebsite.com/projects帶我去前臺。

所以,如果我想訪問mywebsite.com/projects我想它呈現「前」控制器,推「項目」入法。如果我訪問mywebsite.com/admin/projects我希望它加載項目控制器。

下面是整個當前路由類,如下所示。

<?php 

class Request { 

    //url domain.com/controller/method/other 
    //holds url segments 0 => controller, 1 => method, 2 => other, etc 
    public $segments; 
    function __construct() { 
     $this->parse_globals(); 
    } 

    function parse_globals(){ 
     //$uri = preg_replace("|/(.*)|", "\\1", str_replace("\\", "/", $_SERVER['REQUEST_URI'])); 
     $uri = (empty($_GET['rt'])) ? '' : $_GET['rt']; 
     $this->segments = array_filter(explode('/', $uri)); 
     if (in_array("admin", $this->segments)) { 
      array_shift($this->segments); 
     } 
     print_r($this->segments); 
     //remove index php 
     if(reset($this->segments) == 'index.php') { 
      array_shift ($this->segments); 
     } 
    } 

    function controller(){ 
     return $this->segment(0); 
    } 

    function method(){ 
     return $this->segment(1); 
    } 

    function param($str){ 
     return isset($_REQUEST[$str]) ? $_REQUEST[$str] : false; 
    } 

    function segment($no){ 
     return isset($this->segments[$no]) ? $this->segments[$no] : false; 
    } 
} 
+0

目前尚不清楚你的問題是什麼。什麼不起作用? – 2012-08-02 02:17:08

+0

@Laurent我編輯了這篇文章,希望它能讓事情更清晰。 – 2012-08-02 02:29:32

回答

4

而不是簡單地使用explode()到URL的段分開的,你可以使用一組正則表達式模式。

例如,這下面的行話會盡力配合在首創action,並且,如果action存在這些檢查是否有controller設置前:

'/(:?(:?\/(?P<controller>[^\/\.,;?\n]+))?\/(?P<action>[^\/\.,;?\n]+))?/' 

大多數PHP框架用不同的方式來產生這樣的模式,簡化符號。通過這種方式,您可以設置每個圖案的哪些部分是必需的,哪些是可選的還可以爲可選部件提供故障預置值。

也就是說......

開始做的東西太複雜與框架CMS之前,你可能會投資一些額外的時間在研究OOP。我建議至少看MiškoHevery和Robert C. Martin的講座。僅僅因爲你認爲,你知道如何編寫一個類,並不意味着你理解了面向對象編程。

更新

我在this answer列出幾種材料。您可能會發現它們非常有用,

此外這裏還有兩個講座,是不是在回答以上:

+0

我會研究這些講座,我認爲學習OOP的最佳方式是強制自己使用它 - 因此是項目。還有很多東西要學,希望這些講座能幫助我更多地理解。乾杯 – 2012-08-02 04:30:46

+1

實踐練習是非常有用的,但是,如果你沒有新的結論/想法來實施,你只會做你一直做的相同的事情,並重申你的舊方法。 – 2012-08-02 14:38:13

+0

感謝您的建議。 – 2012-08-03 06:35:32

1

我的理解是,有三層路由情況:

基本一個:

/<controller>/<action>/<parameters>  

一個特殊的一個用於管理面板(其中,「管理」是一種獨立的模塊):

/<module>/<controller>/<action>/<parameters> 

最後是映射到「/ front/projects」的「/ projects」的特例。

在這種情況下,你需要讓你的路由類更靈活,以便它可以處理任何類型的路由方案。在這樣的Kohana框架,這將與規則,如來完成:

Route::set('adminModule', 'admin/projects') 
    ->defaults(array(
     'controller' => 'projects', 
     'action'  => 'admin', 
    )); 

Route::set('projectPage', 'projects') 
    ->defaults(array(
     'controller' => 'front', 
     'action'  => 'projects', 
    )); 

Route::set('default', '(<controller>(/<id>(/<action>)))') 
    ->defaults(array(
     'controller' => 'index', 
     'action'  => 'index', 
    )); 

顯然,這只是一個例子,但你的想法。基本上,你想提供一些合理的默認路由(例如controller/action/id),但你也需要允許用戶配置其他路由。

-1

我目前正在開發一個PHP路由器是針對極高性能。你可能會想看看。

https://github.com/c9s/Pux

我們還提供了一個模式編譯器,做同樣的事情,你的。但你可以寫一個簡單的路徑,而不是複雜的模式。

例如,你可能會寫這樣的事情:

/product/:id/:name  [ id => '\d+', name => '\w+' ] 

FYI:

PUX爲48.5x快於靜態路由調度symfony的路由器,31X更快的正則表達式調度。 (安裝了pux擴展)

Pux嘗試不消耗計算時間來動態構建所有路由(如Symfony/Routing)。相反,Pux將您的路由編譯爲純PHP數組進行緩存,編譯後的路由可以非常快地從緩存中加載。

使用Pux PHP Extension支持,您可以加載和發送比純PHP Pux快1.5〜2倍的路徑。