{"id":16031677,"url":"https://github.com/razonyang/php-routing","last_synced_at":"2025-12-28T08:02:27.492Z","repository":{"id":98816073,"uuid":"122588123","full_name":"razonyang/php-routing","owner":"razonyang","description":"A fast, flexible and scalable HTTP router for PHP.","archived":false,"fork":false,"pushed_at":"2018-02-23T08:10:52.000Z","size":19,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-04-14T02:23:38.481Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/razonyang.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}},"created_at":"2018-02-23T07:33:36.000Z","updated_at":"2020-10-18T19:34:07.000Z","dependencies_parsed_at":"2023-05-25T14:00:15.990Z","dependency_job_id":null,"html_url":"https://github.com/razonyang/php-routing","commit_stats":{"total_commits":6,"total_committers":1,"mean_commits":6.0,"dds":0.0,"last_synced_commit":"80a29b304ea3b46396ca6ea358cfd62ed5ff73b5"},"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/razonyang%2Fphp-routing","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/razonyang%2Fphp-routing/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/razonyang%2Fphp-routing/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/razonyang%2Fphp-routing/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/razonyang","download_url":"https://codeload.github.com/razonyang/php-routing/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242962874,"owners_count":20213540,"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":[],"created_at":"2024-10-08T21:04:47.433Z","updated_at":"2025-12-28T08:02:22.457Z","avatar_url":"https://github.com/razonyang.png","language":"PHP","readme":"# PHP Routing\r\n\r\n[![Build Status](https://travis-ci.org/razonyang/php-routing.svg?branch=master)](https://travis-ci.org/razonyang/php-routing)\r\n[![Coverage Status](https://coveralls.io/repos/github/razonyang/php-routing/badge.svg?branch=master)](https://coveralls.io/github/razonyang/php-routing?branch=master)\r\n[![Latest Stable Version](https://poser.pugx.org/razonyang/php-routing/v/stable.svg)](https://packagist.org/packages/razonyang/php-routing)\r\n[![Total Downloads](https://poser.pugx.org/razonyang/php-routing/downloads.svg)](https://packagist.org/packages/razonyang/php-routing)\r\n[![License](https://poser.pugx.org/razonyang/php-routing/license.svg)](LICENSE)\r\n\r\nA fast, flexible and scalable HTTP router for PHP.\r\n\r\n## Features\r\n\r\n- **Easy to design RESTful API**\r\n- **Full Tests**\r\n- **Flexible and scalable**: it allows you to define your own handler to deal with [`Not Found`](#not-found-handler), [`Method Not Allowed`](#method-not-allowed-handler) and [`OPTIONS`](#options-handler) request.\r\n- **No third-party library dependencies**\r\n- **Named Param Placeholder**\r\n- **Detect all request methods of the specify path**\r\n- **Straightforward documentation**\r\n\r\n## Requirements\r\n\r\n- PHP - `7.0`, `7.1`, `7.2` and `master` are supported.\r\n\r\n## Install\r\n\r\n```\r\ncomposer require razonyang/php-routing\r\n```\r\n\r\n## Documentation\r\n\r\n```php\r\ninclude '/path-to-vendor/autoload.php';\r\n\r\nuse RazonYang\\Routing\\Router;\r\n\r\n// create an router instance\r\n$router = new Router();\r\n```\r\n\r\n### Register handler\r\n\r\n```php\r\nRouter::handle($method, $path, $handler);\r\n```\r\n\r\n- `method` - `string` or `array`, such as `GET`, `GET|POST`(split by `|`, without spaces), `['GET', 'POST']`\r\n- `path` - the path **MUST** start with slash `/`, such as `/`, `/users`, `/users/\u003cusername\u003e`.\r\n- `handler` - `mixed`, whatever you want.\r\n\r\n\r\nExamples\r\n\r\n| Method                     | Path                           | Handler | Matched                            | Unmatched                              |\r\n|:---------------------------|:-------------------------------|:--------|:-----------------------------------|----------------------------------------|\r\n| `GET`                      | `/`                            | handler | `GET /`                            | `POST /` `get /`                       |\r\n| \u003ccode\u003eGET\u0026#124;POST\u003c/code\u003e | `/users`                       | handler | `GET /users` `POST /users`         |                                        |\r\n| `['GET', 'POST']`          | `/merchants`                   | handler | `GET /merchants` `POST /merchants` |                                        |\r\n| `GET`                      | `/users/\u003cusername\u003e`            | handler | `GET /users/foo` `GET /users/bar`  |                                        |\r\n| `GET`                      | `/orders/\u003corder_id:\\d+\u003e`       | handler | `GET /orders/123456`               | `GET /orders/letters`                  |\r\n\r\nIt also provides a few shortcuts for registering handler:\r\n\r\n- `Router::delete`\r\n- `Router::get`\r\n- `Router::post`\r\n- `Router::put`\r\n\r\n```php\r\n$router-\u003eget('/', 'handler');\r\n\r\n$router-\u003ehandle('GET|POST', '/users', 'handler');\r\n\r\n$router-\u003ehandle(['GET', 'POST'], '/merchants', 'handler');\r\n\r\n$router-\u003eget('/users/\u003cusername\u003e', 'handler');\r\n\r\n$router-\u003eget('/orders/\u003corder_id:\\d+\u003e', 'handler');\r\n```\r\n\r\n### Dispatch request\r\n\r\n```php\r\nRouter::dispatch($method, $path);\r\n```\r\n\r\n- `method` - request method.\r\n- `path` - URI path.\r\n\r\nIf matched, a [`Route`](src/Route.php) instance will be returns, `null` otherwise or NotFoundException/MethodNotAllowedException will be thrown.\r\n\r\n```php\r\n$path = '/users/baz';\r\n$route = $router-\u003edispatch(Router::METHOD_GET, $path);\r\n\r\n// handle requset\r\n$handler = $route-\u003ehandler; // 'handler'\r\n$params = $route-\u003eparams; // ['username' =\u003e 'baz']\r\n```\r\n\r\n### Named Params Placeholder\r\n\r\nAs the examples shown above, Router has ability to detect the param's value of the path.\r\n\r\nIn general, an placeholder pattern MUST be one of `\u003cname\u003e` and `\u003cname:regex\u003e`, it will be \r\nconverted to `([^/]+)` and `(regex)` respectively.\r\nYou can also change it via replace the `Router::$replacePatterns` and `Router::$replacements`.\r\n\r\n| Pattern                                     | Path                                       | Matched | Params |\r\n|:--------------------------------------------|:-------------------------------------------|:--------|:-----------------------------------------------------------------|\r\n| `/guests/\u003cname\u003e`                            | `/guests/小明`                              | YES     | `['name' =\u003e '小明']`                                              |\r\n| `/guests/\u003cname:\\w+\u003e`                        | `/guests/foo`                              | YES     | `['name' =\u003e 'foo']`                                              |\r\n| `/guests/\u003cname:\\w+\u003e`                        | `/guests/小明`                              | NO      |                                                                  |\r\n| `/orders/\u003corder_id:\\d+\u003e`                    | `/orders/123`                              | YES     | `['order_id' =\u003e '123']`                                          |\r\n| `/orders/\u003corder_id:\\d+\u003e`                    | `/orders/letters`                          | NO      |                                                                  |\r\n| `/posts/\u003cyear:\\d{4}\u003e/\u003cmonth:\\d{2}\u003e/\u003ctitle\u003e` | `/posts/2017/10/hello-world`               | YES     | `['year' =\u003e '2017', 'month' =\u003e '10', title' =\u003e 'hello-world']`   |\r\n| `/posts/\u003cyear:\\d{4}\u003e/\u003cmonth:\\d{2}\u003e/\u003ctitle\u003e` | `/posts/201/10/hello-world`                | NO      |                                                                  |\r\n| `/posts/\u003cyear:\\d{4}\u003e/\u003cmonth:\\d{2}\u003e/\u003ctitle\u003e` | `/posts/2017/9/hello-world`                | NO      |                                                                  |\r\n| `/posts/\u003cyear:\\d{4}\u003e\u003cmonth:\\d{2}\u003e/\u003ctitle\u003e`  | `/posts/201710/hello-world`                | YES     | `['year' =\u003e '2017', 'month' =\u003e '10', title' =\u003e 'hello-world']`   |\r\n\r\n### RESTful API\r\n\r\nAs the examples shown above, it is obviously easy to design a RESTful API application.\r\n\r\n```php\r\n$router-\u003eget('/products', 'products');\r\n$router-\u003epost('/products', 'create product');\r\n$router-\u003eget('/products/\u003cproduct_id:\\d+\u003e', 'product detail');\r\n$router-\u003eput('/products/\u003cproduct_id:\\d+\u003e', 'update product');\r\n$router-\u003edelete('/products/\u003cproduct_id:\\d+\u003e', 'delete product');\r\n```\r\n\r\n### Not Found Handler\r\n\r\n```php\r\n$router-\u003enotFoundHandler = function($method, $path) {\r\n    throw new \\Exception('404 Not Found');\r\n};\r\n```\r\n\r\n### Method Not Allowed Handler\r\n\r\n```php\r\n$router-\u003emethodNotAllowedHandler = function($method, $path, $allowedMethods) {\r\n    throw new \\Exception('405 Method Not Allowed');\r\n};\r\n```\r\n\r\n### OPTIONS Handler\r\n\r\n```php\r\n$router-\u003eoptionsHandler = function($method, $path, $allowedMethods) {\r\n    header('Allow: ' . implode(',', $allowedMethods));\r\n};\r\n```\r\n\r\n## FAQ\r\n\r\n### Package Not Found\r\n\r\nPlease add the following repository into `repositories` when `composer` complains about\r\nthat `Could not find package razonyang/php-routing ...`.\r\n\r\n```json\r\n{\r\n    \"type\": \"git\",\r\n    \"url\": \"https://github.com/razonyang/php-routing.git\"\r\n}\r\n```","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frazonyang%2Fphp-routing","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frazonyang%2Fphp-routing","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frazonyang%2Fphp-routing/lists"}