Php 使用正则表达式将URL与模式匹配,返回一个键数组
我正在用PHP组装一个路由器,它将一个模式(如“users/:id”)与一个路由(如“users/123”)相匹配,返回类似“id”=>123的内容。这就是我目前所拥有的Php 使用正则表达式将URL与模式匹配,返回一个键数组,php,regex,Php,Regex,我正在用PHP组装一个路由器,它将一个模式(如“users/:id”)与一个路由(如“users/123”)相匹配,返回类似“id”=>123的内容。这就是我目前所拥有的 function match_path($path, $pattern){ if ($path == $pattern){ return true; } // check for :replacements if (strpos($pattern, ":")!== false) { // split path &
function match_path($path, $pattern){
if ($path == $pattern){
return true;
}
// check for :replacements
if (strpos($pattern, ":")!== false) {
// split path & pattern into fragments
$split_path = explode('/',$path);
$split_pattern = explode('/', $pattern);
// check that they are the same length
if (count($split_path) !== count($split_pattern)){
return false;
}
// iterate over pattern
foreach ($split_pattern as $index => $fragment) {
// if fragment is wild
if (strpos($fragment, ":") == 0){
$params[substr($fragment, 1)] = $split_path[$index];
// if fragment doesn't match
} elseif ($fragment !== $split_path[$index]) {
return false;
}
// continue if pattern matches
}
// returns hash of extracted parameters
return $params;
}
return false;
}
我确信一定有一种方法可以用正则表达式干净地实现这一点
更好的是,可能有一个PHP函数可以实现这一点。PHP on Rails,嗯?;-)
有关strpos行为的重要注意事项:您应该使用strict==
运算符进行检查,因为它可能返回false(来源:
).经过粗略的阅读/测试,我只看到脚本有问题
<?php
// routes-test.php
echo "should be [ id => 123 ]:\n";
var_dump( match_path( 'user/123', 'user/:id' ) );
function match_path($path, $pattern) { ... }
?>
// cmd line
$ php routes-test.php # your implementation
should be [ id => 123 ]:
array(2) {
["ser"]=>
string(4) "user"
["id"]=>
string(3) "123"
}
$ php routes-test.php # using ===
should be [ id => 123 ]:
array(1) {
["id"]=>
string(3) "123"
}
//命令行
$php routes-test.php#您的实现
应该是[id=>123]:
阵列(2){
[“ser”]=>
字符串(4)“用户”
[“id”]=>
字符串(3)“123”
}
$php routes-test.php#使用===
应该是[id=>123]:
阵列(1){
[“id”]=>
字符串(3)“123”
}
您应该采用YAGNI方法来使用正则表达式。如果你所要做的就是匹配像
/^:\w+$/
这样的东西,那么你可以更快地完成它,并且在与strpo和朋友相当数量的行中完成。使用这样的东西怎么样
/**
* Compares a url to a pattern, and populates any embedded variables
* Returns false if the pattern does not match
* Returns an array containing the placeholder values if the pattern matches
* If the pattern matches but does not contain placeholders, returns an empty array
*/
function checkUrlAgainstPattern($url, $pattern) {
// parse $pattern into a regex, and build a list of variable names
$vars = array();
$regex = preg_replace_callback(
'#/:([a-z]+)(?=/|$)#',
function($x) use (&$vars) {
$vars[] = $x[1];
return '/([^/]+)';
},
$pattern
);
// check $url against the regex, and populate variables if it matches
$vals = array();
if (preg_match("#^{$regex}$#", $url, $x)) {
foreach ($vars as $id => $var) {
$vals[$var] = $x[$id + 1];
}
return $vals;
} else {
return false;
}
}
这用于将模式转换为正则表达式并捕获占位符列表,然后根据生成的正则表达式计算url并提取占位符值
一些用法示例:
checkUrlAgainstPattern('/users/123', '/users/:id');
// returns array('id' => '123')
checkUrlAgainstPattern('/users/123/123', '/users/:id');
// returns false
checkUrlAgainstPattern('/users/123/details', '/users/:id/:page');
// returns array('id' => '123', 'page' => 'details')
我不确定你打算用它做什么,但是
.htaccess
甚至可能是可能的,这通常用于奇特的url'看起来他正试图在应用程序级别实现路由.htaccess
速度更快,但从开发角度来看,灵活性较差。