dsfdsf46465 2011-12-06 22:15
浏览 74
已采纳

在我的PHP MVC框架中进行路由

For a couple of years I have been working on my own lightweight MVC framework for PHP. Which I may at some point release under an opensource license.

Here is what I have been using for handling routes:

function routes($routes, $uriPath) {

    // Loop through every route and compare it with the URI
    foreach ($routes as $route => $actualPage) {

        // Create a route with all identifiers replaced with ([^/]+) regex syntax
        // E.g. $route_regex = shop-please/([^/]+)/moo (originally shop-please/:some_identifier/moo)
        $route_regex = preg_replace('@:[^/]+@', '([^/]+)', $route);

        // Check if URI path matches regex pattern, if so create an array of values from the URI
        if(!preg_match('@' . $route_regex . '@', $uriPath, $matches)) continue;

        // Create an array of identifiers from the route
        preg_match('@' . $route_regex . '@', $route, $identifiers);

        // Combine the identifiers with the values
        $this->request->__get = array_combine($identifiers, $matches);
        array_shift($this->request->__get);

        return $actualPage;
    }

    // We didn't find a route match
    return false;
}

$routes is a passed array formatted like this:

$routes = array(
    // route => actual page
    'page/:action/:id' => 'actualPage',
    'page/:action' => 'actualPage',
)

$uriPath is the URI path without a leading forward-slash e.g. page/update/102

In my page controllers I can access the the route information like so:

echo $this->request->__get['action'];
// update

echo $this->request->__get['id'];
// 102

My question is essentially "can this be simplified or optimised?". With particular emphasis on simplifying the regex and the number of preg_replace and preg_match calls.

  • 写回答

1条回答 默认 最新

  • doupiai5597 2011-12-06 22:57
    关注

    I find use of regex in such scenario very unwise, mostly because this can be done without it. I've put up a simply code below that does exactly the same without regex.

    Code:

    <?php
    $routes             = array
    (
        // actual path => filter
        'foo'   => array('page', ':action', ':id'),
        'bar'   => array('page', ':action')
    );
    
    /**
     * @author Gajus Kuizinas <g.kuizinas@anuary.com>
     * @copyright Anuary Ltd, http://anuary.com
     * @version 1.0.0 (2011 12 06)
     */
    function ay_dispatcher($url, $routes)
    {
        $final_path         = FALSE;
    
        $url_path           = explode('/', $url);
        $url_path_length    = count($url_path);
    
        foreach($routes as $original_path => $filter)
        {
            // reset the parameters every time in case there is partial match
            $parameters     = array();
    
            // this filter is irrelevent
            if($url_path_length <> count($filter))
            {
                continue;
            }
    
            foreach($filter as $i => $key)
            {
                if(strpos($key, ':') === 0)
                {
                    $parameters[substr($key, 1)]    = $url_path[$i];
                }
                // this filter is irrelevent
                else if($key != $url_path[$i])
                {       
                    continue 2;
                }
            }
    
            $final_path = $original_path;
    
            break;
        }
    
        return $final_path ? array('path' => $final_path, 'parameters' => $parameters) : FALSE;
    }
    
    die(var_dump( ay_dispatcher('page/edit', $routes), ay_dispatcher('page/edit/12', $routes), ay_dispatcher('random/invalid/url', $routes) ));
    

    Output:

    array(2) {
      ["path"]=>
      string(3) "bar"
      ["parameters"]=>
      array(1) {
        ["action"]=>
        string(4) "edit"
      }
    }
    array(2) {
      ["path"]=>
      string(3) "foo"
      ["parameters"]=>
      array(2) {
        ["action"]=>
        string(4) "edit"
        ["id"]=>
        string(2) "12"
      }
    }
    bool(false)
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 使用C#,asp.net读取Excel文件并保存到Oracle数据库
  • ¥15 C# datagridview 单元格显示进度及值
  • ¥15 thinkphp6配合social login单点登录问题
  • ¥15 HFSS 中的 H 场图与 MATLAB 中绘制的 B1 场 部分对应不上
  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 虚心请教几个问题,小生先有礼了
  • ¥30 截图中的mathematics程序转换成matlab