@@ -749,44 +749,37 @@ public static function findRoute(
749749 $ uri = $ uri ?? static ::getCurrentUri ();
750750 $ routes = $ routes ?? static ::$ routes [\Leaf \Http \Request::getMethod ()];
751751
752- foreach ($ routes as $ route ) {
753- // Replace all curly braces matches {} into word patterns (like Laravel)
754- $ route ['pattern ' ] = preg_replace ('/\/{(.*?)}/ ' , '/(.*?) ' , $ route ['pattern ' ]);
755-
756- // we have a match!
757- if (preg_match_all ('#^ ' . $ route ['pattern ' ] . '$# ' , $ uri , $ matches , PREG_OFFSET_CAPTURE )) {
758- // Rework matches to only contain the matches, not the orig string
759- $ matches = array_slice ($ matches , 1 );
760-
761- // Extract the matched URL parameters (and only the parameters)
762- $ params = array_map (function ($ match , $ index ) use ($ matches ) {
763- // We have a following parameter: take the substring from the current param position until the next one's position (thank you PREG_OFFSET_CAPTURE)
764- if (isset ($ matches [$ index + 1 ]) && isset ($ matches [$ index + 1 ][0 ]) && $ matches [$ index + 1 ][0 ][1 ] != -1 && is_array ($ matches [$ index + 1 ][0 ])) {
765- return trim (substr ($ match [0 ][0 ], 0 , $ matches [$ index + 1 ][0 ][1 ] - $ match [0 ][1 ]), '/ ' );
766- }
752+ // Preserve existing $_GET parameters
753+ $ existingQueryParams = $ _GET ;
767754
768- // Temporary fix for optional parameters
769- if (( $ match [ 0 ][ 1 ] ?? 1 ) === - 1 && ( $ match [ 0 ][ 0 ] ?? null ) === '' ) {
770- return ;
771- }
755+ // Extract query string and remove it from URI
756+ $ parsedUrl = parse_url ( $ uri );
757+ $ uriPath = $ parsedUrl [ ' path ' ] ?? ' / ' ;
758+ parse_str ( $ parsedUrl [ ' query ' ] ?? '' , $ queryParams );
772759
773- // We have no following parameters: return the whole lot
774- return isset ($ match [0 ][0 ]) ? trim ($ match [0 ][0 ], '/ ' ) : null ;
775- }, $ matches , array_keys ($ matches ));
776-
777- $ paramsWithSlash = array_filter ($ params , function ($ param ) {
778- if (!$ param ) {
779- return false ;
780- }
781-
782- return strpos ($ param , '/ ' ) !== false ;
783- });
784-
785- // if any of the params contain /, we should skip this route
786- if (!empty ($ paramsWithSlash )) {
787- continue ;
760+ foreach ($ routes as $ route ) {
761+ // Match named parameters in the pattern
762+ preg_match_all ('/{(\w+)}/ ' , $ route ['pattern ' ], $ paramNames );
763+ $ paramNames = $ paramNames [1 ] ?? [];
764+
765+ // Replace all curly braces {} with regex capture groups
766+ $ pattern = preg_replace ('/\/{(.*?)}/ ' , '/([^\/]+) ' , $ route ['pattern ' ]);
767+
768+ // Match current URI against the route pattern
769+ if (preg_match ('#^ ' . $ pattern . '$# ' , $ uriPath , $ matches )) {
770+ array_shift ($ matches ); // Remove full match
771+
772+ // Extract parameter values
773+ $ params = [];
774+ foreach ($ matches as $ index => $ value ) {
775+ $ paramName = $ paramNames [$ index ] ?? "var " . ($ index + 1 );
776+ $ params [$ paramName ] = trim ($ value , '/ ' );
788777 }
789778
779+ // Merge extracted route parameters with existing query parameters
780+ $ _GET = array_merge ($ existingQueryParams , $ params );
781+
782+ // Return matched route info
790783 $ routeData = [
791784 'params ' => $ params ,
792785 'handler ' => $ route ['handler ' ],
@@ -796,7 +789,7 @@ public static function findRoute(
796789 $ handledRoutes [] = $ routeData ;
797790
798791 if ($ returnFirst ) {
799- break ;
792+ return [ $ routeData ] ;
800793 }
801794 }
802795 }
0 commit comments