首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Php路由器,从uri提取密钥

Php路由器,从uri提取密钥
EN

Stack Overflow用户
提问于 2009-07-02 10:09:47
回答 5查看 4.1K关注 0票数 6

嘿,伙计们!我需要一些正则表达式等方面的帮助。我需要从url中提取虚拟关键字,应用程序中的某种路由器。下面是参数:

代码语言:javascript
复制
Rule: /books/:category/:id/:keyname
Data: /books/php/12345/this-is-a-test-keyname

输出应该是这样的:

代码语言:javascript
复制
array(
  'category' => 'php',
  'id' => '12345',
  'keyname' => 'this-is-a-test-keyname'
);

所以,问题是:我如何在php中做到这一点?

P.S规则的组合可能会有所不同。因此,主键是带有“:”符号的单词。例如:

代码语言:javascript
复制
/book-:id/:category/:keyname
/book/:id_:category~:keyname

附言2:这是我之前的一段代码。它是有效的,但不灵活。

代码语言:javascript
复制
function rule_process($rule, $data) {
        // extract chunks       
        $ruleItems = explode('/',$rule);
        $dataItems = explode('/',$data);

        // remove empty items
        array_clean(&$ruleItems);
        array_clean(&$dataItems);

        // rule and data supposed to have the same structure
        if (count($ruleItems) == count($dataItems)) {
            $result = array();

            foreach($ruleItems as $ruleKey => $ruleValue) {
                // check if the chunk is a key
                if (preg_match('/^:[\w]{1,}$/',$ruleValue)) {
                    // ok, found key, adding data to result
                    $ruleValue = substr($ruleValue,1);
                    $result[$ruleValue] = $dataItems[$ruleKey];
                }
            }

            if (count($result) > 0) return $result;
            unset($result);
        }

        return false;
    }

    function array_clean($array) {
        foreach($array as $key => $value) {
            if (strlen($value) == 0) unset($array[$key]);
        }   
    }

事实上,这个版本的路由器对我来说已经足够了,但我只是对如何制作灵活的解决方案感兴趣。顺便说一下,一些测试:( 10000次操作中的30次):

代码语言:javascript
复制
TEST #0 => Time:0.689285993576, Failures: 0
TEST #1 => Time:0.684408903122, Failures: 0
TEST #2 => Time:0.683394908905, Failures: 0
TEST #3 => Time:0.68522810936, Failures: 0
TEST #4 => Time:0.681587934494, Failures: 0
TEST #5 => Time:0.681943893433, Failures: 0
TEST #6 => Time:0.683794975281, Failures: 0
TEST #7 => Time:0.683885097504, Failures: 0
TEST #8 => Time:0.684013843536, Failures: 0
TEST #9 => Time:0.684071063995, Failures: 0
TEST #10 => Time:0.685361146927, Failures: 0
TEST #11 => Time:0.68728518486, Failures: 0
TEST #12 => Time:0.688632011414, Failures: 0
TEST #13 => Time:0.688556909561, Failures: 0
TEST #14 => Time:0.688539981842, Failures: 0
TEST #15 => Time:0.689876079559, Failures: 0
TEST #16 => Time:0.689854860306, Failures: 0
TEST #17 => Time:0.68727684021, Failures: 0
TEST #18 => Time:0.686210155487, Failures: 0
TEST #19 => Time:0.687953948975, Failures: 0
TEST #20 => Time:0.687957048416, Failures: 0
TEST #21 => Time:0.686664819717, Failures: 0
TEST #22 => Time:0.686244010925, Failures: 0
TEST #23 => Time:0.686643123627, Failures: 0
TEST #24 => Time:0.685017108917, Failures: 0
TEST #25 => Time:0.686363935471, Failures: 0
TEST #26 => Time:0.687278985977, Failures: 0
TEST #27 => Time:0.688650846481, Failures: 0
TEST #28 => Time:0.688835144043, Failures: 0
TEST #29 => Time:0.68886089325, Failures: 0

所以,这已经足够快了。我在普通的笔记本电脑上测试。因此,可以肯定的是,这一点可以在真实的网站中使用。

还有其他的解决方案吗?

EN

回答 5

Stack Overflow用户

发布于 2009-07-02 10:27:23

我不认为只有一个正则表达式可以做到这一点。Zend Framework的工作原理与您的示例类似。看看他们的source code吧。

票数 1
EN

Stack Overflow用户

发布于 2009-07-02 10:54:36

试试这个简单的解决方案:

代码语言:javascript
复制
    $data = Array (
            "/book/:id/:category/:keyname" => "/book/12345/php/this-is-a-test-keyname",
            "/book-:id/:category/:keyname" => "/book-12345/php/this-is-a-test-keyname",
            "/book/:id_:category~:keyname" => "/book/12345_php~this-is-a-test-keyname",
    );


    foreach ($data as $rule => $uri) {
            $reRule = preg_replace('/:([a-z]+)/', '(?P<\1>[^/]+)', $rule);
            $reRule = str_replace('/', '\/', $reRule);

            preg_match('/' . $reRule .'/', $uri, $matches);
            print_r($matches);
    }

唯一的缺点是,在这一点上您不能进行花哨的数据验证,所以您必须在其他地方进行验证。此外,如果规则与正则表达式语法冲突,它可能会变得混乱(在这里,您必须做一些繁重的转义工作)。

票数 1
EN

Stack Overflow用户

发布于 2009-09-26 19:22:00

我有另一个版本的脚本:http://blog.sosedoff.com/2009/09/20/rails-like-php-url-router/

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1073569

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档