MVC中的CMS路由


CMS Routing in MVC

我正在php中创建自己的MVC框架,以此学习更高级的编程。我已经启动并运行了该框架,但是我对当前的路由方法有一个问题。我希望该框架支持后端cms,以赞美前端网站。问题是我的路由结构是这样工作的——mywebsite.com/controller/method/id路由引擎将信息排序为一个数组,如

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

现在,如果我访问mywebsite.com/projects,它会把我带到我设置的管理页面。我不仅希望只能从mywebsite.com/admin/projects访问,我还希望mywebsitecom/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;
    }
}

您可以使用一组正则表达式模式,而不是简单地使用explode()来分隔URL的分段。

例如,以下模式将尝试在第一个action匹配,如果action存在,则检查其之前是否设置了controller

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

大多数PHP框架使用不同的方式来生成这样的模式,并简化了符号。通过这种方式,您可以设置每个模式的哪些部分是强制性的,哪些是可选的。还可以为可选部件提供回退值。

也就是说。。。

在开始用框架制作像cms这样复杂的东西之前,您可能会在研究OOP方面投入一些额外的时间。我建议至少看米什科·赫维尔和罗伯特·C·马丁的讲座。仅仅因为你认为,你知道如何编写一个类,并不意味着你理解面向对象编程。

更新

我在这个答案中列出了一些材料。你可能会发现它们很有用,

此外,这里还有两个讲座,上面没有回答:

  • Clean Code I:参数
  • Clean Code III:函数

我的理解是有三种路由情况:

基本的一个:

/<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),但也需要允许用户配置其他路由。

我目前正在开发一款php路由器,该路由器的目标是极高的性能。你可能想看看。

https://github.com/c9s/Pux

我们还提供了一个模式编译器,它可以做与您相同的事情。但是您可以编写一个更简单的路径,而不是复杂的模式。

例如,你可以写这样的东西:

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

FYI:

Pux在静态路由调度方面比symfony路由器快48.5倍,在正则表达式调度方面快31倍。(已安装pux扩展)

Pux尽量不消耗计算时间来动态构建所有路由(如Symfony/Routing)。相反,Pux将您的路由编译到普通的PHP数组中进行缓存,编译后的路由可以很快从缓存中加载。

有了Pux PHP扩展支持,您可以比纯PHP Pux更快1.5到2倍地加载和调度路由。