@@ -98,9 +98,9 @@ class Router
9898 protected static $ namespace = '' ;
9999
100100 /**
101- * The Server Base Path for Router Execution
101+ * The Server Base Path for Router Execution (null = not yet resolved)
102102 */
103- protected static $ serverBasePath = '' ;
103+ protected static $ serverBasePath = null ;
104104
105105 /**
106106 * Cached URI for the current request
@@ -787,8 +787,17 @@ public function registerMiddleware(string $name, callable $middleware)
787787 */
788788 public static function getBasePath (): string
789789 {
790- if (static ::$ serverBasePath === '' ) {
791- static ::$ serverBasePath = implode ('/ ' , array_slice (explode ('/ ' , $ _SERVER ['SCRIPT_NAME ' ]), 0 , -1 )) . '/ ' ;
790+ if (static ::$ serverBasePath === null ) {
791+ $ scriptDir = implode ('/ ' , array_slice (explode ('/ ' , $ _SERVER ['SCRIPT_NAME ' ] ?? '' ), 0 , -1 )) . '/ ' ;
792+ $ requestPath = rawurldecode (parse_url ($ _SERVER ['REQUEST_URI ' ] ?? '/ ' , PHP_URL_PATH ) ?: '/ ' );
793+
794+ // the script directory is only a base path when the request actually
795+ // lives under it (classic subfolder deployments) — under php -S or
796+ // the CLI it usually isn't, and stripping it would eat URI segments
797+ // https://github.com/leafsphp/leaf/issues/323
798+ static ::$ serverBasePath = ($ scriptDir !== '/ ' && strncmp ($ requestPath , $ scriptDir , strlen ($ scriptDir )) === 0 )
799+ ? $ scriptDir
800+ : '/ ' ;
792801 }
793802
794803 return static ::$ serverBasePath ;
@@ -802,7 +811,7 @@ public static function getBasePath(): string
802811 */
803812 public static function setBasePath ($ serverBasePath )
804813 {
805- static ::$ serverBasePath = $ serverBasePath ;
814+ static ::$ serverBasePath = ( $ serverBasePath === '' || $ serverBasePath === null ) ? ' / ' : $ serverBasePath ;
806815 static ::$ currentUri = null ;
807816 }
808817
@@ -822,16 +831,11 @@ public static function getCurrentUri(): string
822831 $ requestPath = parse_url ($ requestUri , PHP_URL_PATH ) ?: '/ ' ;
823832 $ requestPath = rawurldecode ($ requestPath );
824833
825- // Early exit If base path doesn't match
834+ // if an explicit base path doesn't prefix the request, don't strip
835+ // anything (and never fire handlers from a getter) — unmatched routes
836+ // 404 through the normal dispatch flow
826837 if (strncmp ($ requestPath , $ basePath , strlen ($ basePath )) !== 0 ) {
827- if (!static ::$ notFoundHandler ) {
828- static ::$ notFoundHandler = function () {
829- \Leaf \Exception \General::default404 ();
830- };
831- }
832- static ::invoke (static ::$ notFoundHandler );
833-
834- return '/ ' ;
838+ return static ::$ currentUri = '/ ' . trim ($ requestPath , '/ ' );
835839 }
836840
837841 // Get the current Request URI and remove rewrite base path from it (= allows one to run the router in a sub folder)
@@ -1107,7 +1111,7 @@ public static function reset(): void
11071111 static ::$ sitemapOptions = [];
11081112 static ::$ groupRoute = '' ;
11091113 static ::$ namespace = '' ;
1110- static ::$ serverBasePath = '' ;
1114+ static ::$ serverBasePath = null ;
11111115 static ::$ currentUri = null ;
11121116 static ::$ currentMethod = null ;
11131117 }
0 commit comments