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 DS18B20内部ADC模数转换器
  • ¥15 做个有关计算的小程序
  • ¥15 MPI读取tif文件无法正常给各进程分配路径
  • ¥15 如何用MATLAB实现以下三个公式(有相互嵌套)
  • ¥30 关于#算法#的问题:运用EViews第九版本进行一系列计量经济学的时间数列数据回归分析预测问题 求各位帮我解答一下
  • ¥15 setInterval 页面闪烁,怎么解决
  • ¥15 如何让企业微信机器人实现消息汇总整合
  • ¥50 关于#ui#的问题:做yolov8的ui界面出现的问题
  • ¥15 如何用Python爬取各高校教师公开的教育和工作经历
  • ¥15 TLE9879QXA40 电机驱动