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)
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?