@@ -162,7 +162,7 @@ private function searchFirstController(): bool
162162 $ segment = array_shift ($ segments );
163163 $ controllerPos ++;
164164
165- $ class = $ this ->translateURIDashes ($ segment );
165+ $ class = $ this ->translateURI ($ segment );
166166
167167 // as soon as we encounter any segment that is not PSR-4 compliant, stop searching
168168 if (! $ this ->isValidSegment ($ class )) {
@@ -209,7 +209,7 @@ private function searchLastDefaultController(): bool
209209 }
210210
211211 $ namespaces = array_map (
212- fn ($ segment ) => $ this ->translateURIDashes ($ segment ),
212+ fn ($ segment ) => $ this ->translateURI ($ segment ),
213213 $ segments
214214 );
215215
@@ -307,7 +307,7 @@ public function getRoute(string $uri, string $httpVerb): array
307307
308308 $ method = '' ;
309309 if ($ methodParam !== null ) {
310- $ method = $ httpVerb . $ this ->translateURIDashes ($ methodParam );
310+ $ method = $ httpVerb . $ this ->translateURI ($ methodParam );
311311
312312 $ this ->checkUriForMethod ($ method );
313313 }
@@ -519,7 +519,17 @@ private function checkUriForMethod(string $method): void
519519 return ;
520520 }
521521
522- if (! in_array ($ method , get_class_methods ($ this ->controller ), true )) {
522+ if (
523+ // For example, if `getSomeMethod()` exists in the controller, only
524+ // the URI `controller/some-method` should be accessible. But if a
525+ // visitor navigates to the URI `controller/somemethod`, `getSomemethod()`
526+ // will be checked, and `method_exists()` will return true because
527+ // method names in PHP are case-insensitive.
528+ method_exists ($ this ->controller , $ method )
529+ // But we do not permit `controller/somemethod`, so check the exact
530+ // method name.
531+ && ! in_array ($ method , get_class_methods ($ this ->controller ), true )
532+ ) {
523533 throw new PageNotFoundException (
524534 '" ' . $ this ->controller . ':: ' . $ method . '()" is not found. '
525535 );
@@ -536,7 +546,10 @@ private function isValidSegment(string $segment): bool
536546 return (bool ) preg_match ('/^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$/ ' , $ segment );
537547 }
538548
539- private function translateURIDashes (string $ segment ): string
549+ /**
550+ * Translates URI segment to CamelCase or replaces `-` with `_`.
551+ */
552+ private function translateURI (string $ segment ): string
540553 {
541554 if ($ this ->translateUriToCamelCase ) {
542555 if (strtolower ($ segment ) !== $ segment ) {
0 commit comments