PHP路由:赋予预定义路由更高的优先级
我正在创建一个PHP应用程序,使路由URL变得更容易PHP路由:赋予预定义路由更高的优先级,php,regex,url,routing,Php,Regex,Url,Routing,我正在创建一个PHP应用程序,使路由URL变得更容易 // Define the routes $routes = [ '/programs', '/programs/{}', '/programs/{}/members', '/programs/{}/{}', '/programs/{}/{}/members' ]; // Example URL $url = '/prog
// Define the routes
$routes = [
'/programs',
'/programs/{}',
'/programs/{}/members',
'/programs/{}/{}',
'/programs/{}/{}/members'
];
// Example URL
$url = '/programs/test/members';
/*
* Split the URL at /
* Remove the first and last value from the returned array
*/
$parts = array_values( array_filter( preg_split( "/\//", $url ) ) );
// Loop over the defined routes
foreach($routes as $route){
// Split the route into parts, like we do with the url
$route_parts = array_values( array_filter( preg_split( "/\//", $route ) ) );
/*
* If the route parts is more than the parts of the url
* then continue to the next value in the routes array
*/
if( sizeof( $route_parts ) != sizeof( $parts ) ) continue;
// Loop over the route parts
for( $i=0; $i<sizeof( $route_parts ); $i++ ) {
/*
* Compare the route part to the url part and see if they match
* or if the route part is {}
*/
if ( $route_parts[ $i ] != '{}' && $route_parts[ $i ] != $parts[ $i ] ) continue;
}
// Echo the route if it passes all the above checks
echo 'got through: '. $route . '<br />';
}
//定义路由
$routes=[
“/程序”,
“/programs/{}”,
“/programs/{}/members”,
“/programs/{}/{}”,
“/programs/{}/{}/members”
];
//示例URL
$url='/programs/test/members';
/*
*将URL拆分为/
*从返回的数组中删除第一个和最后一个值
*/
$parts=array\u值(array\u过滤器(preg\u split(“/\/”,$url));
//在定义的路由上循环
foreach($routes作为$route){
//将路由拆分为多个部分,就像我们对url所做的那样
$route\u parts=数组值(数组过滤器(preg\u split(“/\/”,$route));
/*
*如果路由部分多于url的部分
*然后继续执行routes数组中的下一个值
*/
如果(sizeof($route_parts)!=sizeof($parts))继续;
//在路线部分上循环
对于($i=0;$i),在@Booboo和@freeek的帮助下,我得出了以下答案:
// Define the routes
$routes = [
'/programs',
'/programs/{}',
'/programs/{}/{}',
];
// Example URL
$url = '/programs/some_program/some_course';
/*
* Split the URL at /
* Remove the first and last value from the returned array
*/
$parts = array_values( array_filter( preg_split( "/\//", $url ) ) );
// Define valid routes array
$valid_routes = $routes;
// Loop over the defined routes
foreach($routes as $route){
// Split the route into parts, like we do with the url
$route_parts = array_values( array_filter( preg_split( "/\//", $route ) ) );
/*
* If the route parts is more than the parts of the url
* then continue to the next value in the routes array
*/
if( sizeof( $route_parts ) != sizeof( $parts ) ){
// Remove the route from the valid routes array
$valid_routes = array_values( array_diff( $valid_routes, [$route] ) );
}
// Loop over the route parts
for( $i=0; $i<sizeof( $route_parts ); $i++ ) {
/*
* Compare the route part to the url part and see if they match
* or if the route part is {}
*/
if ( $i >= sizeof( $parts ) || ( $route_parts[ $i ] != '{}' & $route_parts[ $i ] != $parts[ $i ] ) ){
// Remove the route from the valid routes array
$valid_routes = array_values( array_diff( $valid_routes, [$route] ) );
}
}
}
// Find the route with the least occurrence of the {} characters
$route = $this->leastOccurrence( $valid_routes, '{}' );
if( $route != null ){
// Route found, output the route
echo 'Found route: ' . $route;
} else {
// No route found, 404
echo '404, not found';
}
function leastOccurrence( $array, $characters ){
if( sizeof( $array ) < 1 ) return null;
$least = $array[0];
foreach( $array as $item ){
if( substr_count( $item, $characters ) < substr_count( $least, $characters ) ) $least = $item;
}
return $least;
}
//定义路由
$routes=[
“/程序”,
“/programs/{}”,
“/programs/{}/{}”,
];
//示例URL
$url='/programs/some_program/some_course';
/*
*将URL拆分为/
*从返回的数组中删除第一个和最后一个值
*/
$parts=array\u值(array\u过滤器(preg\u split(“/\/”,$url));
//定义有效的路由数组
$valid_routes=$routes;
//在定义的路由上循环
foreach($routes作为$route){
//将路由拆分为多个部分,就像我们对url所做的那样
$route\u parts=数组值(数组过滤器(preg\u split(“/\/”,$route));
/*
*如果路由部分多于url的部分
*然后继续执行routes数组中的下一个值
*/
if(sizeof($route_parts)!=sizeof($parts)){
//从有效路由数组中删除路由
$valid_routes=array_值(array_diff($valid_routes,[$route]);
}
//在路线部分上循环
对于($i=0;$i=sizeof($parts)| |($route_parts[$i]!='{}'和$route_parts[$i]!=$parts[$i])){
//从有效路由数组中删除路由
$valid_routes=array_值(array_diff($valid_routes,[$route]);
}
}
}
//查找{}字符出现最少的路由
$route=$this->leastOccurrence($valid_routes,{}');
如果($route!=null){
//找到路由,输出路由
回显“找到的路由:”。$route;
}否则{
//找不到路由,404
回音“404,未找到”;
}
函数leastToCurrence($array,$characters){
if(sizeof($array)<1)返回null;
$least=$array[0];
foreach($数组作为$项){
if(substr_count($item,$characters)
在您的$routes
表中,您将/programs/{}/members
列在/programs/{}/{}/{}
之前,因为它具有更高的优先级,所以第一个匹配的路由是“赢家”。或者它是匹配所需的通配符最少的匹配(即{}
),我有代码来找到通配符最少的那个,但我认为它有点效率低下,因为它是一个单独的for循环,在一个单独的数组上,使用这个函数的结果。我认为第一个解决方案可以工作,但是如果是用户设置的,那么它很容易被破坏。谢谢你的建议-非常感谢。你也可以选择最长的字符串:)