Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP路由:赋予预定义路由更高的优先级_Php_Regex_Url_Routing - Fatal编程技术网

PHP路由:赋予预定义路由更高的优先级

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

我正在创建一个PHP应用程序,使路由URL变得更容易

    // 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循环,在一个单独的数组上,使用这个函数的结果。我认为第一个解决方案可以工作,但是如果是用户设置的,那么它很容易被破坏。谢谢你的建议-非常感谢。你也可以选择最长的字符串:)