Modify dynamic segments to a common placeholder to fix #1

This commit is contained in:
Sky Johnson 2024-09-07 22:34:34 -05:00
parent c9e3c3a2d5
commit 1a2aeff1d4
4 changed files with 2329 additions and 2708 deletions

View File

@ -6,8 +6,10 @@ class SegmentRouter implements Router
public function add(string $method, string $route, callable $handler): Router public function add(string $method, string $route, callable $handler): Router
{ {
// Expand the route into segments // Expand the route into segments and make dynamic segments into a common placeholder
$segments = explode('/', trim($route, '/')); $segments = array_map(function($segment) {
return str_starts_with($segment, ':') ? ':x' : $segment;
}, explode('/', trim($route, '/')));
// Push each segment into the routes array as a node // Push each segment into the routes array as a node
$node = &$this->routes; $node = &$this->routes;
@ -25,40 +27,40 @@ class SegmentRouter implements Router
$uriSegments = explode('/', trim($uri, '/')); $uriSegments = explode('/', trim($uri, '/'));
$node = $this->routes; $node = $this->routes;
$params = []; $params = [];
// Traverse the routes array to find the handler // Traverse the routes array to find the handler
foreach ($uriSegments as $segment) { foreach ($uriSegments as $segment) {
// Check if the segment exists in the node, or if there's a dynamic segment // Check if the segment exists in the node
if (!isset($node[$segment])) { if (isset($node[$segment])) {
$dynamicSegment = $this->matchDynamicSegment($node, $segment);
if ($dynamicSegment) {
$params[] = $segment;
$node = $node[$dynamicSegment];
} else {
return 404;
}
} else {
$node = $node[$segment]; $node = $node[$segment];
} else {
// Handle dynamic segments (starting with ":")
$dynamicSegment = null;
// Loop through the node and find the first dynamic segment
foreach ($node as $k => $v) {
if (str_starts_with($k, ':')) {
$dynamicSegment = $k;
break; // Break early as we only need one match
}
}
// If no dynamic segment was found, return 404
if ($dynamicSegment === null) return 404;
// Otherwise, store the parameter and move to the dynamic node
$params[] = $segment;
$node = $node[$dynamicSegment];
} }
} }
// If the HTTP method is not supported, return 405 // Check if the HTTP method is supported
if (!isset($node[$method])) return 405; if (!isset($node[$method])) return 405;
// Return the handler // Return the handler and parameters
return [$node[$method], $params]; return [$node[$method] , $params];
}
// Look through a node to find a dynamic segment
private function matchDynamicSegment(array $node, string $segment): string|false
{
foreach (array_keys($node) as $key) {
// If the key starts with a :, it's a dynamic segment
if (strpos($key, ':') === 0) return $key;
}
return false;
} }
public function clear(): Router public function clear(): Router
{ {

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +1,10 @@
/ /
├── / ├── /
│ └── GET │ └── GET
├── :slug ├── :x
│ └── GET │ └── GET
├── tags ├── tags
│ └── GET │ └── GET
└── tag └── tag
└── :tag └── :x
└── GET └── GET

View File

@ -1,22 +1,22 @@
/ /
├── authorizations ├── authorizations
│ ├── GET │ ├── GET
│ ├── :id │ ├── :x
│ │ ├── GET │ │ ├── GET
│ │ └── DELETE │ │ └── DELETE
│ └── POST │ └── POST
├── applications ├── applications
│ └── :client_id │ └── :x
│ └── tokens │ └── tokens
│ ├── :access_token │ ├── :x
│ │ ├── GET │ │ ├── GET
│ │ └── DELETE │ │ └── DELETE
│ └── DELETE │ └── DELETE
├── events ├── events
│ └── GET │ └── GET
├── repos ├── repos
│ └── :owner │ └── :x
│ └── :repo │ └── :x
│ ├── events │ ├── events
│ │ └── GET │ │ └── GET
│ ├── notifications │ ├── notifications
@ -32,27 +32,27 @@
│ │ └── DELETE │ │ └── DELETE
│ ├── git │ ├── git
│ │ ├── blobs │ │ ├── blobs
│ │ │ ├── :sha │ │ │ ├── :x
│ │ │ │ └── GET │ │ │ │ └── GET
│ │ │ └── POST │ │ │ └── POST
│ │ ├── commits │ │ ├── commits
│ │ │ ├── :sha │ │ │ ├── :x
│ │ │ │ └── GET │ │ │ │ └── GET
│ │ │ └── POST │ │ │ └── POST
│ │ ├── refs │ │ ├── refs
│ │ │ ├── GET │ │ │ ├── GET
│ │ │ └── POST │ │ │ └── POST
│ │ ├── tags │ │ ├── tags
│ │ │ ├── :sha │ │ │ ├── :x
│ │ │ │ └── GET │ │ │ │ └── GET
│ │ │ └── POST │ │ │ └── POST
│ │ └── trees │ │ └── trees
│ │ ├── :sha │ │ ├── :x
│ │ │ └── GET │ │ │ └── GET
│ │ └── POST │ │ └── POST
│ ├── issues │ ├── issues
│ │ ├── GET │ │ ├── GET
│ │ ├── :number │ │ ├── :x
│ │ │ ├── GET │ │ │ ├── GET
│ │ │ ├── comments │ │ │ ├── comments
│ │ │ │ ├── GET │ │ │ │ ├── GET
@ -62,23 +62,23 @@
│ │ │ └── labels │ │ │ └── labels
│ │ │ ├── GET │ │ │ ├── GET
│ │ │ ├── POST │ │ │ ├── POST
│ │ │ ├── :name │ │ │ ├── :x
│ │ │ │ └── DELETE │ │ │ │ └── DELETE
│ │ │ ├── PUT │ │ │ ├── PUT
│ │ │ └── DELETE │ │ │ └── DELETE
│ │ └── POST │ │ └── POST
│ ├── assignees │ ├── assignees
│ │ ├── GET │ │ ├── GET
│ │ └── :assignee │ │ └── :x
│ │ └── GET │ │ └── GET
│ ├── labels │ ├── labels
│ │ ├── GET │ │ ├── GET
│ │ ├── :name │ │ ├── :x
│ │ │ ├── GET │ │ │ ├── GET
│ │ │ └── DELETE │ │ │ └── DELETE
│ │ └── POST │ │ └── POST
│ ├── milestones │ ├── milestones
│ │ ├── :number │ │ ├── :x
│ │ │ ├── labels │ │ │ ├── labels
│ │ │ │ └── GET │ │ │ │ └── GET
│ │ │ ├── GET │ │ │ ├── GET
@ -87,7 +87,7 @@
│ │ └── POST │ │ └── POST
│ ├── pulls │ ├── pulls
│ │ ├── GET │ │ ├── GET
│ │ ├── :number │ │ ├── :x
│ │ │ ├── GET │ │ │ ├── GET
│ │ │ ├── commits │ │ │ ├── commits
│ │ │ │ └── GET │ │ │ │ └── GET
@ -111,22 +111,22 @@
│ │ └── GET │ │ └── GET
│ ├── branches │ ├── branches
│ │ ├── GET │ │ ├── GET
│ │ └── :branch │ │ └── :x
│ │ └── GET │ │ └── GET
│ ├── DELETE │ ├── DELETE
│ ├── collaborators │ ├── collaborators
│ │ ├── GET │ │ ├── GET
│ │ └── :user │ │ └── :x
│ │ ├── GET │ │ ├── GET
│ │ ├── PUT │ │ ├── PUT
│ │ └── DELETE │ │ └── DELETE
│ ├── comments │ ├── comments
│ │ ├── GET │ │ ├── GET
│ │ └── :id │ │ └── :x
│ │ ├── GET │ │ ├── GET
│ │ └── DELETE │ │ └── DELETE
│ ├── commits │ ├── commits
│ │ ├── :sha │ │ ├── :x
│ │ │ ├── comments │ │ │ ├── comments
│ │ │ │ ├── GET │ │ │ │ ├── GET
│ │ │ │ └── POST │ │ │ │ └── POST
@ -136,13 +136,13 @@
│ │ └── GET │ │ └── GET
│ ├── keys │ ├── keys
│ │ ├── GET │ │ ├── GET
│ │ ├── :id │ │ ├── :x
│ │ │ ├── GET │ │ │ ├── GET
│ │ │ └── DELETE │ │ │ └── DELETE
│ │ └── POST │ │ └── POST
│ ├── downloads │ ├── downloads
│ │ ├── GET │ │ ├── GET
│ │ └── :id │ │ └── :x
│ │ ├── GET │ │ ├── GET
│ │ └── DELETE │ │ └── DELETE
│ ├── forks │ ├── forks
@ -150,7 +150,7 @@
│ │ └── POST │ │ └── POST
│ ├── hooks │ ├── hooks
│ │ ├── GET │ │ ├── GET
│ │ ├── :id │ │ ├── :x
│ │ │ ├── GET │ │ │ ├── GET
│ │ │ ├── tests │ │ │ ├── tests
│ │ │ │ └── POST │ │ │ │ └── POST
@ -160,7 +160,7 @@
│ │ └── POST │ │ └── POST
│ ├── releases │ ├── releases
│ │ ├── GET │ │ ├── GET
│ │ ├── :id │ │ ├── :x
│ │ │ ├── GET │ │ │ ├── GET
│ │ │ ├── DELETE │ │ │ ├── DELETE
│ │ │ └── assets │ │ │ └── assets
@ -178,16 +178,16 @@
│ │ └── punch_card │ │ └── punch_card
│ │ └── GET │ │ └── GET
│ └── statuses │ └── statuses
│ └── :ref │ └── :x
│ ├── GET │ ├── GET
│ └── POST │ └── POST
├── networks ├── networks
│ └── :owner │ └── :x
│ └── :repo │ └── :x
│ └── events │ └── events
│ └── GET │ └── GET
├── orgs ├── orgs
│ └── :org │ └── :x
│ ├── events │ ├── events
│ │ └── GET │ │ └── GET
│ ├── issues │ ├── issues
@ -195,12 +195,12 @@
│ ├── GET │ ├── GET
│ ├── members │ ├── members
│ │ ├── GET │ │ ├── GET
│ │ └── :user │ │ └── :x
│ │ ├── GET │ │ ├── GET
│ │ └── DELETE │ │ └── DELETE
│ ├── public_members │ ├── public_members
│ │ ├── GET │ │ ├── GET
│ │ └── :user │ │ └── :x
│ │ ├── GET │ │ ├── GET
│ │ ├── PUT │ │ ├── PUT
│ │ └── DELETE │ │ └── DELETE
@ -211,7 +211,7 @@
│ ├── GET │ ├── GET
│ └── POST │ └── POST
├── users ├── users
│ ├── :user │ ├── :x
│ │ ├── received_events │ │ ├── received_events
│ │ │ ├── GET │ │ │ ├── GET
│ │ │ └── public │ │ │ └── public
@ -221,7 +221,7 @@
│ │ │ ├── public │ │ │ ├── public
│ │ │ │ └── GET │ │ │ │ └── GET
│ │ │ └── orgs │ │ │ └── orgs
│ │ │ └── :org │ │ │ └── :x
│ │ │ └── GET │ │ │ └── GET
│ │ ├── starred │ │ ├── starred
│ │ │ └── GET │ │ │ └── GET
@ -238,7 +238,7 @@
│ │ │ └── GET │ │ │ └── GET
│ │ ├── following │ │ ├── following
│ │ │ ├── GET │ │ │ ├── GET
│ │ │ └── :target_user │ │ │ └── :x
│ │ │ └── GET │ │ │ └── GET
│ │ └── keys │ │ └── keys
│ │ └── GET │ │ └── GET
@ -249,7 +249,7 @@
│ ├── GET │ ├── GET
│ ├── PUT │ ├── PUT
│ └── threads │ └── threads
│ └── :id │ └── :x
│ ├── GET │ ├── GET
│ └── subscription │ └── subscription
│ ├── GET │ ├── GET
@ -258,15 +258,15 @@
├── user ├── user
│ ├── starred │ ├── starred
│ │ ├── GET │ │ ├── GET
│ │ └── :owner │ │ └── :x
│ │ └── :repo │ │ └── :x
│ │ ├── GET │ │ ├── GET
│ │ ├── PUT │ │ ├── PUT
│ │ └── DELETE │ │ └── DELETE
│ ├── subscriptions │ ├── subscriptions
│ │ ├── GET │ │ ├── GET
│ │ └── :owner │ │ └── :x
│ │ └── :repo │ │ └── :x
│ │ ├── GET │ │ ├── GET
│ │ ├── PUT │ │ ├── PUT
│ │ └── DELETE │ │ └── DELETE
@ -288,19 +288,19 @@
│ │ └── GET │ │ └── GET
│ ├── following │ ├── following
│ │ ├── GET │ │ ├── GET
│ │ └── :user │ │ └── :x
│ │ ├── GET │ │ ├── GET
│ │ ├── PUT │ │ ├── PUT
│ │ └── DELETE │ │ └── DELETE
│ └── keys │ └── keys
│ ├── GET │ ├── GET
│ ├── :id │ ├── :x
│ │ ├── GET │ │ ├── GET
│ │ └── DELETE │ │ └── DELETE
│ └── POST │ └── POST
├── gists ├── gists
│ ├── GET │ ├── GET
│ ├── :id │ ├── :x
│ │ ├── GET │ │ ├── GET
│ │ ├── star │ │ ├── star
│ │ │ ├── PUT │ │ │ ├── PUT
@ -317,7 +317,7 @@
├── gitignore ├── gitignore
│ └── templates │ └── templates
│ ├── GET │ ├── GET
│ └── :name │ └── :x
│ └── GET │ └── GET
├── markdown ├── markdown
│ ├── POST │ ├── POST
@ -328,19 +328,19 @@
├── rate_limit ├── rate_limit
│ └── GET │ └── GET
├── teams ├── teams
│ └── :id │ └── :x
│ ├── GET │ ├── GET
│ ├── DELETE │ ├── DELETE
│ ├── members │ ├── members
│ │ ├── GET │ │ ├── GET
│ │ └── :user │ │ └── :x
│ │ ├── GET │ │ ├── GET
│ │ ├── PUT │ │ ├── PUT
│ │ └── DELETE │ │ └── DELETE
│ └── repos │ └── repos
│ ├── GET │ ├── GET
│ └── :owner │ └── :x
│ └── :repo │ └── :x
│ ├── GET │ ├── GET
│ ├── PUT │ ├── PUT
│ └── DELETE │ └── DELETE
@ -358,19 +358,19 @@
└── legacy └── legacy
├── issues ├── issues
│ └── search │ └── search
│ └── :owner │ └── :x
│ └── :repository │ └── :x
│ └── :state │ └── :x
│ └── :keyword │ └── :x
│ └── GET │ └── GET
├── repos ├── repos
│ └── search │ └── search
│ └── :keyword │ └── :x
│ └── GET │ └── GET
└── user └── user
├── search ├── search
│ └── :keyword │ └── :x
│ └── GET │ └── GET
└── email └── email
└── :email └── :x
└── GET └── GET