在非 Symfony 应用程序中使用 Symfony 路由

发布于 2024-09-30 19:20:00 字数 2665 浏览 5 评论 0原文

我真的很喜欢 symfony 处理路由的方式(内部 URI 和外部 URL,尤其是“反向查找”方面)。我一直在尝试实现类似的(独立的)路由作为练习(以及将来可能的用途)。然而,经过几个小时的尝试,我还差得很远。 :(

我可以看到 symfony 使用分词器来解析 uri。我正在尝试一种不同的方法(下面的代码)。

function url_for($page){
        if($page[0] == '@'){
            preg_match('/@([^\\.?]+)\??(.*)/', $page, $matches);
            list(, $label, $params_str) = $matches;
            parse_str($params_str, $params);
            $package = isset(self::$routes[trim($label)]['params']['package']) ? self::$routes[trim($label)]['params']['package'] : (isset($params['package']) ? $params['package'] : NULL);
            $module = isset(self::$routes[trim($label)]['params']['module']) ? self::$routes[trim($label)]['params']['module'] : (isset($params['module']) ? $params['module'] : NULL);
            $action = isset(self::$routes[trim($label)]['params']['action']) ? self::$routes[trim($label)]['params']['action'] : (isset($params['action']) ? $params['action'] : NULL);
        } else {
            preg_match('/([^\\.]+)\\\\([^\\.]+)\\\\([^\\.?]+)\??(.*)/', $page, $matches);
            list(, $package, $module, $action, $params_str) = $matches;
            parse_str($params_str, $params);
        }

        array_shift($matches);
        array_pop($matches);

        if($action == NULL) return '';

        $found = FALSE;

        foreach($routes as $route){
            preg_match_all('/:([^\\.\/]+)/', $route['pattern'], $possible_keys);
            $possible_keys = array_merge($route['params'], array_flip($possible_keys[1]));
            $given_keys = array_merge($route['params'], $params);
            $intersection = array_intersect_key($possible_keys, $given_keys);
            if(count($possible_keys) <= count($intersection)){
                $found = TRUE;
                break;
            }
        }

        if($found){
            return $route['pattern'];
        }

        return '';
    }

其中 $routes 数组如下:

array(
    'home' => array(
        'pattern' => '/',
        'params' => array(
            'package' => 'Module',
            'module' => 'Home',
            'action' => 'Index'
        )
    ),
    'user' => array(
        'pattern' => '/user/:action',
        'params' => array(
            'package' => 'Module',
            'module' => 'User'
        )
    ),
    'default' => array(
        'pattern' => '/:module/:action',
        'params' => array(
            'package' => 'Module'
        )
    )
);

有几件事让我感到困惑:

1)symfony 如何处理星号( “*”)模式?
2)路由器如何“确定”正确的路由?例如,作为内部 URI 发送的“额外”参数会发生什么情况?

希望 symfony 大师能够赐教! :p

I really like how symfony handles routing (internal URIs and external URLS, especially the "reverse lookup" side). I have been trying to implement a similar (standalone) routing as an exercise (and possible use in the future). However, after trying for hours, I am no-where close. :(

I can see that symfony uses a tokenizer to parse the uris. I am attempting a different approach (code below).

function url_for($page){
        if($page[0] == '@'){
            preg_match('/@([^\\.?]+)\??(.*)/', $page, $matches);
            list(, $label, $params_str) = $matches;
            parse_str($params_str, $params);
            $package = isset(self::$routes[trim($label)]['params']['package']) ? self::$routes[trim($label)]['params']['package'] : (isset($params['package']) ? $params['package'] : NULL);
            $module = isset(self::$routes[trim($label)]['params']['module']) ? self::$routes[trim($label)]['params']['module'] : (isset($params['module']) ? $params['module'] : NULL);
            $action = isset(self::$routes[trim($label)]['params']['action']) ? self::$routes[trim($label)]['params']['action'] : (isset($params['action']) ? $params['action'] : NULL);
        } else {
            preg_match('/([^\\.]+)\\\\([^\\.]+)\\\\([^\\.?]+)\??(.*)/', $page, $matches);
            list(, $package, $module, $action, $params_str) = $matches;
            parse_str($params_str, $params);
        }

        array_shift($matches);
        array_pop($matches);

        if($action == NULL) return '';

        $found = FALSE;

        foreach($routes as $route){
            preg_match_all('/:([^\\.\/]+)/', $route['pattern'], $possible_keys);
            $possible_keys = array_merge($route['params'], array_flip($possible_keys[1]));
            $given_keys = array_merge($route['params'], $params);
            $intersection = array_intersect_key($possible_keys, $given_keys);
            if(count($possible_keys) <= count($intersection)){
                $found = TRUE;
                break;
            }
        }

        if($found){
            return $route['pattern'];
        }

        return '';
    }

Where the $routes array is as follows:

array(
    'home' => array(
        'pattern' => '/',
        'params' => array(
            'package' => 'Module',
            'module' => 'Home',
            'action' => 'Index'
        )
    ),
    'user' => array(
        'pattern' => '/user/:action',
        'params' => array(
            'package' => 'Module',
            'module' => 'User'
        )
    ),
    'default' => array(
        'pattern' => '/:module/:action',
        'params' => array(
            'package' => 'Module'
        )
    )
);

A few things confuse me:

1) How does symfony handle the asterisk ("*") pattern?
2) How does the router "determine" the correct route? For e.g. what happens to "extra" parameters sent as the internal URI?

I hope some symfony guru can enlighten me! :p

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

枕花眠 2024-10-07 19:20:00

不要重新发明轮子。如果它已经写好了并且很好 - 使用它! Symfony 是一个开源项目。看一下代码;)

Symfony 1.4 比 1.0 解耦得多。事实上,你可以在没有 symfony 的情况下使用路由。查看此博客文章:http://pookey .co.uk/wordpress/archives/80-playing-with-symfony-routing-without-symfony

Don't reinvent the wheel. If it's already written and it's good - use it! Symfony is an open source project. Look at the code ;)

Symfony 1.4 is far more decoupled than 1.0. In fact you're able to use routing without symfony. Check out this blog post: http://pookey.co.uk/wordpress/archives/80-playing-with-symfony-routing-without-symfony

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文