0

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

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;
    }
}
4

3 回答 3

4

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

例如,以下模式将尝试在 firsts 处匹配action,如果action存在,则检查其之前是否存在controller设置:

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

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

那就是说...

在开始使用框架制作像 cms 这样复杂的东西之前,您可能会花一些额外的时间来研究 OOP。我建议至少观看 Miško Hevery 和 Robert C. Martin 的讲座。仅仅因为您认为,您知道如何编写一个类,并不意味着您了解面向对象编程。

更新

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

此外,这里还有两堂课,上面没有回答:

于 2012-08-02T04:07:21.990 回答
1

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

基本的一个:

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

管理面板的特殊面板(其中“admin”是一种单独的模块):

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

最后是“/projects”的一个特例,它映射到“/front/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',
    ));

显然这只是一个例子,但你明白了。基本上,您希望提供一些合理的默认路由(例如控制器/操作/id),但您还需要允许用户配置其他路由。

于 2012-08-02T03:29:32.973 回答
-1

我目前正在开发一个针对极高性能的 php 路由器。你可能想看看。

https://github.com/c9s/Pux

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

例如,你可以这样写:

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

供参考:

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

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

借助 Pux PHP 扩展支持,您可以比纯 PHP Pux 快 1.5~2 倍地加载和调度路由。

于 2014-01-09T07:06:31.620 回答