2014-02-18 45 views
0

我想要做的是自动匹配URI,并为它们分配正确的描述。可以说,我有如下的URI:用星号匹配URI

test 
something/action 
controller/test 
controller/another 
controller/action/something 
action 
action/test 
controller/another/somethingelse 

他们真的是随机的,但现在我想用下面的数组(数组,因为我认为这将是最好的解决方案),与它们匹配:

$config = array(
    'test' => 'The description of test', 
    'something/action' => 'Some action description', 
    'controller/another' => 'Another description', 
    'controller/action/*' => 'This should match the `controller/action/blah` and everything similar like: `controller/action/something` and give this description' 
    'action' => 'Action description', 
    'action/*' => 'As the 2nd above, this should match the `action/test` itself, and similar like `action/anothertest` URI 
); 

这将是容易的,在没有星号的情况下......(简单$config[$uri]相匹配的描述),但我想匹配的星号,以及...所以,如果有一个像controller/another/name控制器和我会使用像controller/another/*这样的配置,它将匹配这个数组密钥的描述。

任何人有怎么可能做的想法?我基本上需要想法,但欢迎任何其他答案!

回答

1

$str=file_get_contents(/*... URIs ...*/); 
$config = array(
    'test' => 'The description of test', 
    'something/action' => 'Some action description', 
    'controller/another' => 'Another description', 
    'controller/action/*' => 'This should match the `controller/action/blah` and everything similar like: `controller/action/something` and give this description', 
    'action' => 'Action description', 
    'action/*' => 'As the 2nd above, this should match the `action/test` itself, and similar like `action/anothertest` URI' 
); 
foreach(explode("\n",$str) as $line) 
{ 
    $line=trim($line); 
    $dkey=array_filter(array_keys($config),function($key)use($line){return fnmatch($key,$line);}); 
    if(count($dkey)<=0) 
    { 
     echo "(no description)"; 
    } 
    else 
    { 
     echo $config[reset($dkey)]; 
    } 
    echo "\n"; 
} 

Online demo

上面的代码输出:可通过组合fnmatch和类似array_filter完成

The description of test 
Some action description 
(no description) 
Another description 
This should match the `controller/action/blah` and everything similar like: `controller/action/something` and give this description 
Action description 
As the 2nd above, this should match the `action/test` itself, and similar like `action/anothertest` URI 
(no description) 

上面的代码可以改进:你可以缓存外循环的array_keys结果所以不需要一遍又一遍的调用。

+0

这就是聪明! Did not知道'fnmatch'函数,这真棒。谢谢 :) – Lucas

1

你想要的是.*.是在正则表达式the character class, that matches any character(由除换行符默认设置),然后你需要的quantifier*说匹配任何字符0次或更多次。

所以,你的正则表达式看起来像

controller/action/.* 

匹配

控制器/动作/
控制器/动作/等等
控制器/动作/东西
...

1

建议的解决方案:

这将返回所有可与uri比较的描述。这里有改进的余地。干杯!

<?php 

    $uris = array(
     'test', 
     'something/action', 
     'controller/test', 
     'controller/another', 
     'controller/action/something', 
     'action', 
     'action/test', 
     'controller/another/somethingelse' 
    ); 

    $sUri = $uris[4]; 
    print_r(
     getConfigBasedOnKey($sUri) 
    ); 

    function getConfigBasedOnKey($sUri) { 

     $config = array(
      'test' => 'The description of test', 
      'something/action' => 'Some action description', 
      'controller/another' => 'Another description', 
      'controller/action/*' => 'This should match the controller/action/blah and everything similar like: controller/action/something and give this description', 
      'action' => 'Action description', 
      'action/*' => 'As the 2nd above, this should match the `action/test` itself, and similar like action/anothertest URI' 
     ); 

     $descriptions = array(); 
     foreach($config as $configKey => $configDescription) { 
      $configKey = preg_replace("/\*/",".*",$configKey); 

      preg_match("|^$configKey$|",$sUri,$matches); 
      if(count($matches) > 0) { 
       $descriptions[] = $configDescription; 
      } 
     } 

     return $descriptions; 
    } 

?> 

输出:

Array 
(
    [0] => This should match the controller/action/blah and everything similar like: controller/action/something and give this description 
)