2012-08-02 71 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倍的路径。