如何确定 strpos 的优先级以找到最准确的结果
How to prioritize strpos to find me the most accurate result
我有一个数组:
$array_of_routes = ['users/', 'articles/more', 'users/get', 'homepage/'];
而且,例如我有一个字符串:
$route = "users/get/1";
所以我尝试使用 strpos 找到它,但是因为 'users/' 在 $array_of_routes 中出现了 'users/get' 的头部,所以我在 [=34= 中得到了 'users/' ] 而不是 'users/get',这是有道理的,因为这是我要求代码执行的操作。
但是在尝试查找字符串中的子字符串时,有没有一种方法可以优先排序或使结果更准确?
注意:从数组中删除 'users/' 时,我得到 'users/get'
这是我的代码:
foreach($array_of_routes as $uri){
if(strpos($current_uri, $uri) !== false)
return $uri;
}
感谢您的帮助!
简单!
对数组进行排序,使 users/get 位于 users/ 的前面。做一个$array_of_routes = rsort($array_of_routes);
这会将您较长的匹配放在首位,如果您最长的项目匹配函数 returns。
您需要拆分 $route
并将其与 $array_of_routes
中可用的最高特异性匹配
<?php
$array_of_routes = ['users', 'articles/more/', 'users/get', 'homepage'];
$route = "users/get/1/fgd/d/fg/";
// No reason to have trailing nor leading slashes or spaces; they are just noise
$array_of_routes = array_map(function($v){return trim(trim($v, '/'));}, $array_of_routes );
$route = trim(trim( $route, '/' ));
// Get the requested route pieces
$route_pieces = explode('/', $route);
// Make sure we loop enough times to account for all of the pieces
for($i = 0; $i<count($route_pieces); ++$i)
{
// With each loop, build the route with one piece less and check if it exists in $array_of_routes
if(in_array(implode('/', array_slice($route_pieces, 0, (count($route_pieces)-$i))), $array_of_routes))
{
echo 'Most specific route: '.implode('/', array_slice($route_pieces, 0, (count($route_pieces)-$i)));
echo 'Arguments: '.implode('/', array_slice($route_pieces, (count($route_pieces)-$i)));
break;
}
}
$route = "users/get/1/fgd/d/fg/";
的输出:
Most specific route: users/get
Arguments: 1/fgd/d/fg
鉴于
2条相同string-prefix的路由A和B可以是同级也可以是不同级
例1)同级(前缀=/users/
):
/users/get
/users/post
示例2)不同级别(前缀=/users
):
/users/get
/users
我们可以这样说:
以'longest-first'顺序存储路由,你得到这个语句:
2 条具有相同字符串前缀和不同级别的路由总是先存储更具体的级别。
获取方式:
$array_of_routes = ['users/', 'articles/more', 'users/get', 'homepage/', ...];
function sort_by_length($a,$b){
return strlen($b)-strlen($a);
}
usort($array_of_routes,'sort_by_length');
function findRoute($current_uri){
foreach($array_of_routes as $uri){
if(strpos($current_uri, $uri) === 0){
return $uri;
}
}
}
注意:strpos
函数必须 return 0,否则你会发现一些与你的 uri 匹配的错误路由。
我有一个数组:
$array_of_routes = ['users/', 'articles/more', 'users/get', 'homepage/'];
而且,例如我有一个字符串:
$route = "users/get/1";
所以我尝试使用 strpos 找到它,但是因为 'users/' 在 $array_of_routes 中出现了 'users/get' 的头部,所以我在 [=34= 中得到了 'users/' ] 而不是 'users/get',这是有道理的,因为这是我要求代码执行的操作。
但是在尝试查找字符串中的子字符串时,有没有一种方法可以优先排序或使结果更准确?
注意:从数组中删除 'users/' 时,我得到 'users/get'
这是我的代码:
foreach($array_of_routes as $uri){
if(strpos($current_uri, $uri) !== false)
return $uri;
}
感谢您的帮助!
简单!
对数组进行排序,使 users/get 位于 users/ 的前面。做一个$array_of_routes = rsort($array_of_routes);
这会将您较长的匹配放在首位,如果您最长的项目匹配函数 returns。
您需要拆分 $route
并将其与 $array_of_routes
<?php
$array_of_routes = ['users', 'articles/more/', 'users/get', 'homepage'];
$route = "users/get/1/fgd/d/fg/";
// No reason to have trailing nor leading slashes or spaces; they are just noise
$array_of_routes = array_map(function($v){return trim(trim($v, '/'));}, $array_of_routes );
$route = trim(trim( $route, '/' ));
// Get the requested route pieces
$route_pieces = explode('/', $route);
// Make sure we loop enough times to account for all of the pieces
for($i = 0; $i<count($route_pieces); ++$i)
{
// With each loop, build the route with one piece less and check if it exists in $array_of_routes
if(in_array(implode('/', array_slice($route_pieces, 0, (count($route_pieces)-$i))), $array_of_routes))
{
echo 'Most specific route: '.implode('/', array_slice($route_pieces, 0, (count($route_pieces)-$i)));
echo 'Arguments: '.implode('/', array_slice($route_pieces, (count($route_pieces)-$i)));
break;
}
}
$route = "users/get/1/fgd/d/fg/";
的输出:
Most specific route: users/get
Arguments: 1/fgd/d/fg
鉴于
2条相同string-prefix的路由A和B可以是同级也可以是不同级
例1)同级(前缀=/users/
):
/users/get
/users/post
示例2)不同级别(前缀=/users
):
/users/get
/users
我们可以这样说:
以'longest-first'顺序存储路由,你得到这个语句: 2 条具有相同字符串前缀和不同级别的路由总是先存储更具体的级别。
获取方式:
$array_of_routes = ['users/', 'articles/more', 'users/get', 'homepage/', ...];
function sort_by_length($a,$b){
return strlen($b)-strlen($a);
}
usort($array_of_routes,'sort_by_length');
function findRoute($current_uri){
foreach($array_of_routes as $uri){
if(strpos($current_uri, $uri) === 0){
return $uri;
}
}
}
注意:strpos
函数必须 return 0,否则你会发现一些与你的 uri 匹配的错误路由。