Роутинг с иерархической структурой.
Решение:
Для максимальной гибкости, решил отказаться от декларативной реализации, остановившись на рекурсивной спецификации. Термин сложный, но если понять, то получите очень мощный инструмент.
Функция:
function route(){                                                                                                                                      
  $rules = func_get_args();                                                        
                                                                                   
  return function() use($rules){                                                   
    $args = func_get_args();                                                       
                                                                                   
    foreach($rules as $rule){                                                      
      if(is_callable($rule)){                                                      
        $rule = call_user_func_array($rule, $args);                                
      }                                                                            
                                                                                   
      if($rule === true){                                                          
        continue;                                                                  
      }                                                                            
      elseif($rule === false){                                                     
        return true;                                                               
      }                                                                            
                                                                                   
      return $rule;                                                                
    }                                                                              
  };                                                                               
}Используется так:
$router = route(                                                                
  // Обработка запроса вида: /article/view
  route(                                                                        
    preg_match('~^/article/view~', $_SERVER['REQUEST_URI']) == 1,                                 
    function(){                                                                 
      return 'Просмотр статьи';                                                    
    }                                                                           
  ),                                                                            
  route(                                                                        
    preg_match('~^/article~', $_SERVER['REQUEST_URI']) == 1,                                      
    // Обработка запроса вида: POST /article    
    route(                                                                      
      $_SERVER['REQUEST_METHOD'] == 'POST',                                                        
      function(){                                                               
        return 'Создание статьи';                                                
      }                                                                         
    ),                                                                          
    // Обработка запроса вида: GET /article    
    route(                                                                      
      $_SERVER['REQUEST_METHOD'] == 'GET',                                                         
      function(){                                                               
        return 'Список статей';                                                  
      }                                                                         
    )                                                                           
  )                                                                             
);                                                                              
                                                                                
echo $router(); // Выполнение роутинга 
                         
                        

