{"id":19039601,"url":"https://github.com/windwalker-io/router","last_synced_at":"2026-03-14T01:43:25.104Z","repository":{"id":21109568,"uuid":"24410063","full_name":"windwalker-io/router","owner":"windwalker-io","description":"[READ ONLY] Simple / fast router to handle PHP routes. ","archived":false,"fork":false,"pushed_at":"2021-02-18T07:05:41.000Z","size":142,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-02-10T07:18:44.480Z","etag":null,"topics":["php","router","trie"],"latest_commit_sha":null,"homepage":"https://github.com/ventoviro/windwalker","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/windwalker-io.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-09-24T10:06:01.000Z","updated_at":"2024-12-16T13:47:48.000Z","dependencies_parsed_at":"2022-08-25T14:41:24.665Z","dependency_job_id":null,"html_url":"https://github.com/windwalker-io/router","commit_stats":null,"previous_names":["ventoviro/windwalker-router"],"tags_count":79,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/windwalker-io%2Frouter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/windwalker-io%2Frouter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/windwalker-io%2Frouter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/windwalker-io%2Frouter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/windwalker-io","download_url":"https://codeload.github.com/windwalker-io/router/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240100136,"owners_count":19747638,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["php","router","trie"],"created_at":"2024-11-08T22:17:48.269Z","updated_at":"2025-12-18T09:05:37.464Z","avatar_url":"https://github.com/windwalker-io.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Windwalker Router\n\n## Installation via Composer\n\nAdd this to the require block in your `composer.json`.\n\n``` json\n{\n    \"require\": {\n        \"windwalker/router\": \"~3.0\"\n    }\n}\n```\n\n## Getting Started\n\n``` php\nuse Windwalker\\Router\\Router;\n\n$router = new Router;\n```\n\n### Add Routes\n\n``` php\nuse Windwalker\\Route\\Route;\n\n// Route with name\n$router-\u003eaddRoute(new Route('sakura', 'flower/(id)/sakura', array('_controller' =\u003e 'SakuraController')));\n\n// Route without name\n$router-\u003eaddRoute(new Route(null, 'flower/(id)/sakura', array('_controller' =\u003e 'SakuraController')));\n```\n\n### Match Route\n\n``` php\n$route = $router-\u003ematch('flower/12/sakura');\n\n$variables = $route-\u003egetVariables(); // Array([_controller] =\u003e SakuraController)\n\n// Use variables\n$class = $variables['_controller'];\n\n$controller = new $class;\n```\n\n### Add More Options to Route\n\nRoute interface: '($name, $pattern[, $variables = array()][, $allowMethods = array()][, $options = array()])'\n\n``` php\n$route = new Route(\n    'name',\n    'pattern/of/route/(id).(format)',\n\n    // Default Variables\n    array(\n        'id'    =\u003e 1,\n        'alias' =\u003e 'foo-bar-baz',\n        'format' =\u003e 'html'\n    ),\n\n    // Allow methods\n    array('GET', 'POST'),\n\n    // Options\n    array(\n        'host'    =\u003e 'windwalker.io',\n        'scheme'  =\u003e 'http', // Only http \u0026 https\n        'port'    =\u003e 80,\n        'sslPort' =\u003e 443,\n        'requirements' =\u003e array(\n            'id' =\u003e '\\d+'\n        ),\n        'extra' =\u003e array(\n            '_ctrl' =\u003e 'Controller\\Class\\Name',\n        )\n    )\n);\n\n$router-\u003eaddRoute($route);\n\n// match routes\n$route = $router-\u003ematch(\n    'pattern/of/route/25.html',\n    array(\n        'host'   =\u003e $uri-\u003egetHost(),\n        'scheme' =\u003e $uri-\u003egetScheme(),\n        'port'   =\u003e $uri-\u003egetPort()\n    )\n);\n\n$variables = $route-\u003egetVariables();\n\n// Merge these matched variables back to http request\n$_REQUEST = array_merge($_REQUEST, $variables);\n\n// Extra is the optional variables but we won't want to merge into request\n$extra = $router-\u003egetExtra();\n\nprint_r($variables);\nprint_r($extra);\n```\n\nThe printed result:\n\n```\nArray\n(\n    [id] =\u003e 25\n    [alias] =\u003e foo-bar-baz\n    [format] =\u003e html\n)\n\nArray(\n    [_ctrl] =\u003e Controller\\Class\\Name\n)\n```\n\n### Build Route\n\n`build()` is a method to generate route uri for view template.\n\n``` php\n$router-\u003eaddRoute(new Route('sakura', 'flower/(id)/sakura', array('_controller' =\u003e 'SakuraController')));\n\n$uri = $router-\u003ebuild('sakura', array('id' =\u003e 30)); // flower/30/sakura\n\necho '\u003ca href=\"' . $uri . '\"\u003eLink\u003c/a\u003e';\n```\n\n### Quick Mapping\n\n`addMap()` is a simple method to quick add route without complex options.\n\n``` php\n$router-\u003eaddMap('flower/(id)/sakura', array('_controller' =\u003e 'SakuraController', 'id' =\u003e 1));\n\n$variables = $router-\u003ematch('flower/30/sakura');\n```\n\n## Rules\n\n### Simple Params\n\n``` php\nnew Route(null, 'flower/(id)-(alias)');\n```\n\n### Optional Params\n\n#### Single Optional Params\n\n``` php\nnew Route(null, 'flower(/id)');\n```\n\nMatched route could be:\n\n```\nflower\nflower/25\n```\n\n#### Multiple Optional Params\n\n``` php\nnew Route(null, 'flower(/year,month,day)');\n```\n\nMatched route could be:\n\n```\nflower\nflower/2014\nflower/2014/10\nflower/2014/10/12\n```\n\nThe matched variables will be\n\n```\nArray\n(\n    [year] =\u003e 2014\n    [month] =\u003e 10\n    [day] =\u003e 12\n)\n```\n\n### Wildcards\n\n``` php\n// Match 'king/john/troilus/and/cressida'\nnew Route(null, 'flower/(*tags)');\n```\n\nMatched:\n\n```\nArray\n(\n    [tags] =\u003e Array\n    (\n        [0] =\u003e john\n        [1] =\u003e troilus\n        [2] =\u003e and\n        [3] =\u003e cressida\n    )\n)\n```\n\n## Matchers\n\nWindwalker Router provides some matchers to use different way to match routes.\n\n### Sequential Matcher\n\nSequential Matcher use the [Sequential Search Method](http://en.wikipedia.org/wiki/Linear_search) to find route.\nIt is the slowest matcher but much more customizable. It is the default matcher of Windwalker Router.\n\n``` php\nuse Windwalker\\Router\\Matcher\\SequentialMatcher;\n\n$router = new Router(array(), new SequentialMatcher);\n```\n\n### Binary Matcher\n\nBinary Matcher use the [Binary Search Algorithm](http://en.wikipedia.org/wiki/Binary_search_algorithm) to find route.\nThis matcher is faster than SequentialMatcher but it will break the ordering of your routes. Binary search will re-sort all routes by pattern characters.\n\n``` php\nuse Windwalker\\Router\\Matcher\\BinaryMatcher;\n\n$router = new Router(array(), new BinaryMatcher);\n```\n\n### Trie Matcher\n\nTrie Matcher use the [Trie](http://en.wikipedia.org/wiki/Trie) tree to search route.\nThis matcher is the fastest method of Windwalker Router, but the limit is that it need to use an simpler route pattern \nwhich is not as flexible as the other two matchers.\n\n``` php\nuse Windwalker\\Router\\Matcher\\TrieMatcher;\n\n$router = new Router(array(), new TrieMatcher);\n```\n\n### Rules of TrieMatcher\n\n#### Simple Params\n\nonly match when the uri segments all exists. If you want to use optional segments, you must add two or more patterns.\n\n```\nflower\nflower/:id\nflower/:id/:alias\n```\n\n#### Wildcards\n\nThis pattern will convert segments after `flower/` this to an array which named `tags`:\n\n```\nflower/*tags\n```\n\n## Single Action Router\n\nSingle action router is a simple router that extends Windwalker Router. It just return a string if matched.\n\nThis is a single action controller example:\n\n``` php\n$router-\u003eaddMap('flower/(id)/(alias)', 'FlowerController');\n\n$controller = $router-\u003ematch('flower/25/sakura');\n\n$_REQUEST = array_merge($_REQUEST, $router-\u003egetVariables());\n\necho (new $controller)-\u003eexecute();\n```\n\nOr a controller with action name:\n\n``` php\n$router-\u003eaddMap('flower/(id)/(alias)', 'FlowerController::indexAction');\n\n$matched = $router-\u003ematch('flower/25/sakura');\n\n$_REQUEST = array_merge($_REQUEST, $router-\u003egetVariables());\n\nlist($controller, $action) = explode('::', $matched);\n\necho (new $controller)-\u003e$action();\n```\n\n## RestRouter\n\nRestRouter is a simple router extends to SingleActionRouter, it can add some suffix of different methods.\n\n``` php\n$router-\u003eaddMap('flower/(id)/(alias)', 'Flower\\\\Controller\\\\');\n\n$controller = $router-\u003ematch('flower/25/sakura', 'POST'); // Get Flower\\\\Controller\\\\Create\n\n(new $controller)-\u003eexecute();\n```\n\nDefault Suffix mapping is:\n\n```\n'GET'     =\u003e 'Get',\n'POST'    =\u003e 'Create',\n'PUT'     =\u003e 'Update',\n'PATCH'   =\u003e 'Update',\n'DELETE'  =\u003e 'Delete',\n'HEAD'    =\u003e 'Head',\n'OPTIONS' =\u003e 'Options'\n```\n\nYou can override it:\n\n``` php\n$router-\u003esetHttpMethodSuffix('POST', 'SaveController');\n```\n\n## Exception\n\nIf Router not matched anything, it throws `Windwalker\\Router\\Exception\\RouteNotFoundException`.\n\n``` php\ntry\n{\n    $route = $router-\u003ematch('flower/25');\n}\ncatch (RouteNotFoundException $e)\n{\n    Application::close('Page not found', 404);\n    \n    exit();\n}\ncatch (\\Exception $e)\n{\n    // Do other actions...\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwindwalker-io%2Frouter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwindwalker-io%2Frouter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwindwalker-io%2Frouter/lists"}