{"id":20533054,"url":"https://github.com/ferrriii/newrouter","last_synced_at":"2025-09-05T11:50:50.010Z","repository":{"id":101857054,"uuid":"235742471","full_name":"ferrriii/NewRouter","owner":"ferrriii","description":"a simple, fast and powerful PHP router","archived":false,"fork":false,"pushed_at":"2020-08-16T06:03:28.000Z","size":1167,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-26T20:01:42.782Z","etag":null,"topics":["php","phprouter","route-handler","router"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ferrriii.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-01-23T07:11:38.000Z","updated_at":"2020-08-16T06:03:30.000Z","dependencies_parsed_at":null,"dependency_job_id":"605edaa3-65cb-4a86-b8f5-d82c137a8a2c","html_url":"https://github.com/ferrriii/NewRouter","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ferrriii/NewRouter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ferrriii%2FNewRouter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ferrriii%2FNewRouter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ferrriii%2FNewRouter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ferrriii%2FNewRouter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ferrriii","download_url":"https://codeload.github.com/ferrriii/NewRouter/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ferrriii%2FNewRouter/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273754048,"owners_count":25161912,"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","status":"online","status_checked_at":"2025-09-05T02:00:09.113Z","response_time":402,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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","phprouter","route-handler","router"],"created_at":"2024-11-16T00:18:26.115Z","updated_at":"2025-09-05T11:50:49.944Z","avatar_url":"https://github.com/ferrriii.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# NewRouter\na simple, fast and powerful PHP router.\n- Simple Syntax\n- Light Weight (single file, ~160 LOC)\n- Feature Full\n- Tested \u0026 Fast\n------------------\n**Table of contents**\n- [Installation](#installation)\n- [Hello World](#hello-world)\n- [Routes](#routes)\n  - [Any method](#Any-method)\n  - [Parameterized Route](#parameterized-route)\n  - [Using patterns in route URL](#using-patterns-in-route-url)\n- [Callbacks](#callbacks)\n  - [Callback return value](#callback-return-value)\n  - [Callback arguments](#callback-arguments)\n  - [Multiple callbacks](#multiple-callbacks-for-a-route)\n- [Prefixing Routes (grouping)](#prefixing-routes-grouping)\n- [Middleware](#middleware)\n- [No Match](#no-match)\n- [Serving Static Files](#serving-static-files)\n- [Examples](#examples)\n- [Tests](#tests)\n\n----------------\n## Installation\n```php\nrequire('newrouter.php');\n```\nPHP \u003e= 5.3\n## Hello World \n```php\nrequire('newrouter.php');\n\n$router = new NewRouter();\n$router-\u003eroute('GET /', function(){\n\techo 'Hello World!';\n});\n\n$router-\u003edispatch();\n```\n## Routes\nRoutes can be added by `route()` method. First argument of this method can be a string combined of HTTP method and URL path and second argument is a callback for the specified route.\n```php\n$router-\u003eroute('GET /some/path', function(){});\n$router-\u003eroute('POST /some/path', function(){});\n$router-\u003eroute('PUT /some/path', function(){});\n```\nRoutes will be tested in the same order they are added.\n### Any method\nNot specifying a method will match all HTTP methods.\n```php\n$router-\u003eroute('/some/path', function(){}); // this will match GET, POST, PUT, DELETE, etc.\n```\n### Parameterized Route\nUse `:parameterName:` syntax to define parameterized routes. `parameterName` will be available in arguments passed to callback function.\n```php\n$router-\u003eroute('GET /user/:id:', function($request){\n\t// this route will match:\n\t//    http://site.com/user/123\n\t//    http://site.com/user/abc\n\t//    etc.\n\techo 'user id is ' . $request-\u003eparams['id']; // id is either 123 or abc\n});\n```\n### Using patterns in route URL\nYou can use below patterns in routings.\n\n| Pattern | Meaning                | Example Route     | Example Match |\n| ------- | ---------------------- | ----------------- | ------------- |\n| *       | Anything or nothing    | `GET /users/*`    | site.com/users/\u003cbr/\u003esite.com/users/profile\u003cbr/\u003esite.com/users/profile/images |\n| +       | Anything but not empty | `GET /users/+`    | site.com/users/profile\u003cbr/\u003esite.com/users/profile/images |\n| :param: | Anything except /      | `GET /users/:id:` | site.com/users/profile\u003cbr/\u003esite.com/users/123 |\n\n## Callbacks\nRoute callbacks can be a [Closure](https://www.php.net/manual/en/class.closure.php), a [Callable](https://www.php.net/manual/en/language.types.callable.php) string or an instance of `NewRouter`.\n```php\n// closure example\n$router-\u003eroute('GET /', function(){\n\t// this will be executed on GET /\n});\n\n// class method example\nclass Foo {\n\tstatic public function bar() {\n\t\t// this will be executed on GET /\n\t}\n}\n$router-\u003eroute('GET /', 'Foo::bar');\n```\nSee [Prefixing Routes](#prefixing-routes-grouping) for router instance as callback example.\n### Callback return value\nReturn value of callback can change routing behavior. An explicit `True` tells NewRouter to continue trying to match next routes.\nAn implicit `False` or `Null` means next routes should be stopped.\n\n*Note:* Not returning anything inside a callback is same as returning `Null`.\n### Callback arguments\nAn instance of `stdClass` will be passed to callbacks when a route is matched. Below is list of defined properties in this object.\n\n| Property | Description |\n| -------- | ------------ |\n| params   | An associative array where keys are captured parameters when using parameterized routes. See [Parameterized routing](#parameterized-route) for example. |\n| url      | The URL part that route has matched. |\n| path     | The whole URI without queries. |\n\n*Note:* Callbacks can capture `$request` by reference and manipulate it. See [Middleware](#middleware) for more.\n### Multiple callbacks for a route\nA route can have multiple callbacks. Callbacks will be executed in the same order they are added.\n```php\n$router-\u003eroute('GET /user/profile', $callback1, $callback2, $callback3);\n```\nIn above example, callback1 is executed first. Then if it returns true, callback2 gets executed and so on.\nThis is useful for use cases like authorization, see below example.\n```php\n$isRequestAuthorized = function() {\n\t// do checkings here and return true or false\n}\n$showUserProfile = function() {\n\t// show profile here\n}\n$router-\u003eroute('GET /user/profile', $isRequestAuthorized, $showUserProfile);\n```\n## Prefixing Routes (grouping)\nBy passing an instance of `NewRouter` as callback, you can delegate all routes to that instance. This is useful when prefixing/grouping routes.\n```php\n// define a router for user APIs\n$userRouter = new NewRouter();\n$userRouter-\u003eroute('GET /', function(){\n\t// this route is prefixed with /users/\n});\n$userRouter-\u003eroute('GET /profile/:id:', function($request){\n\t// this route is prefixed with /users/\n});\n\n// define the main router\n$mainRouter = new NewRouter();\n// delegate all requests to /users/* to $userRouter\n$mainRouter-\u003eroute('/users/*', $userRouter); // prefix $userRouter with /users/ path\n//define other routes\n\n$mainRouter-\u003edispatch();\n```\nIn above example routes like `/users/` and `/users/profile/123` will be handled by `userRouter`.\n## Middleware\nYou can omit route string and only pass callbacks. This kind of callbacks will get executed on all requests.\n```php\n$router-\u003eroute(function(){}); // this will get executed on all requests\n```\nThis could be useful for uses case like logging and intercepting. Below is an example for parsing JWT token.\n```php\n$router-\u003eroute(function(\u0026$request){ // notice the capture by reference\n\t$request-\u003edecodedJWT = '{\"sub\": \"1234\", \"name\": \"John Doe\", \"iat\": 1516239022}'; // in real-world you need to actually read JWT from headers and decode it\n\treturn true; // this is necessary to continue next routes\n});\n\n$router-\u003eroute('GET /profile', function($request) {\n\t// $request-\u003edecodedJWT is {\"sub\": \"1234\", \"name\": \"John Doe\", \"iat\": 1516239022} here\n});\n```\nYou can also define middlewares for a specific HTTP method. Below example defines a callback which gets executed on all POST requests.\n```php\n$router-\u003eroute('POST', function(){\n\t// this is executed on all POST requests\n});\n```\n## No Match\nYou can use a middleware as final route to capture no match.\nexample:\n```php\n// define routes\n$route-\u003eroute('GET /a', function(){});\n$route-\u003eroute('GET /b', function(){});\n// ...\n$route-\u003eroute(function() {\n\t// no routes matched\n\techo 'invalid route';\n});\n```\n## Serving Static Files\nTo serve static files such as images, CSS files, and JavaScript files, use the `NewRouterStatic::serve` method. You just need to include `newrouterstatic.php` and call `NewRouterStatic::serve` as callback for a route. The function signature is:\n```php\nNewRouterStatic::serve($root, [$options]);\n```\nFor example, use the following code to serve static files in a directory named asset for routes starting with /public/:\n```php\nrequire('newrouterstatic.php');\n\n$router-\u003eroute('/public/*', NewRouterStatic::serve('./asset/'));\n```\nAbove  example will map all routes to virtual path `/public/*` to static files under `./asset/` directory. For example the route `/public/logo.jpg` will be mapped as `/asset/logo.jpg`.\n\n*Note:* You can have several static routes.\n### Options\nThe second argument of `NewRouterStatic::serve` can be an assosiative array of options. The following table describes the keys for `options` argument\n\n| Key | Description | Default |\n| --- | --------- | --------- |\n| lastModified | A boolean value specifying if last-modified HTTP header should be provided | `true` |\n| etag | a Boolean value specifying if etag HTTP header should be provided | `true` |\n\n## Examples\nSee example directory for more detailed examples.\n## Tests\nRun below commands in shell to run all tests (210 tests).\n```\ncd test\nphp index.php\n```\nRun performance tests only\n```\nphp performance.php\n```\n\n## TODO\n - import/export routes\n - regex patterns\n - numbers only pattern\n - JSON parser middleware\n - CORS middleware\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fferrriii%2Fnewrouter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fferrriii%2Fnewrouter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fferrriii%2Fnewrouter/lists"}