https://github.com/inanepain/routing
HTTP Routing using attributes.
https://github.com/inanepain/routing
inane library php routing
Last synced: 9 months ago
JSON representation
HTTP Routing using attributes.
- Host: GitHub
- URL: https://github.com/inanepain/routing
- Owner: inanepain
- License: unlicense
- Created: 2022-06-05T23:43:19.000Z (over 3 years ago)
- Default Branch: develop
- Last Pushed: 2025-03-02T11:55:50.000Z (11 months ago)
- Last Synced: 2025-03-30T05:41:10.088Z (10 months ago)
- Topics: inane, library, php, routing
- Language: PHP
- Homepage:
- Size: 37.1 KB
- Stars: 1
- Watchers: 1
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
Awesome Lists containing this project
README
# Readme: Routing
> $Id$ ($Date$)
HTTP Routing using php **Attributes**.
NOTE: examples updated to use RouteMatch.
## Intro: Attributes
What is an **Attribute**? It's a class just like any other class only with the `Attribute` **Attribute**. So why are you treating it more like an `enum` or `Map` that can only hold a few values describing something? You don't do it with the classes you uses your custom attributes on! But I don't blame you, it all comes down to some pour choices in wording used by the documentation.
So how should I be think of **Attributes**? As classes naturally. Classes to object that get things done to be more exact. That `#[Route(name: 'home', path: '/')]` like might make more sense when you start looking at it like this: `$route = new Route('/', 'home');`. Here a fun experiment to try; remove the `Attribute` from `Route` then have the `Router` take an array of `Route` parameters as argument. Easy, wasn't it and you understand Attributes and with practice you spot many more classes you can use as such.
Hope that gets you thinking about **Attributes** in a new, more realistic manor that leads to you adding that `#[Attribute]` line to a good many more classes.
## Install
`composer require inanepain/routing`
## Usage
Quick overview showing the bits relating to the `Route` `Attribute` in two examples. Neither are complete, though the simple example would run with minimum fuss. Check the Appendix for the `.htaccess` file you will need to use with the `index.php` file.
## Example: Simple
Super simple example using **php** built in web server, `php -S localhost:8080 -t public index.php`.
**MainController.php:**
```php
class MainController {
...
#[Route(path: '/', name: 'home')]
public function home(): void {
...
echo <<addRoutes([MainController::class]);
if ($match = $router->match()) {
$controller = new $match->class();
$controller->{$match->method}($match->params);
} else {
throw new Exception('Request Error: Unmatched `file` or `route`!');
}
```
## Example: Application
Slightly more complex example.
#### The various pieces
**IndexController.php:**
```php
class IndexController extends AbstractController {
...
#[Route(path: '/', name: 'home')]
public function indexTask(): array {
...
}
...
#[Route(path: '/product/{product}', name: 'product', )]
public function productTask(): array {
...
}
...
#[Route(path: '/product/{product}/review/{id<\d+>}', name: 'product-review')]
public function reviewTask(): array {
...
}
...
}
```
**index.phtml (view template):**
```phtml
...
=$item['name_long']?>
...
```
**website (rendered view):**
```html
Mega Maid (Household Robot Helper)
```
#### Putting it all together
**Application.php:**
```php
class Application {
...
protected function initialise(): void {
...
$this->router = new Router([
IndexController::class,
...
WhoopsController::class,
...
]);
...
}
...
public function run(): void {
...
if ($match = $this->router->match()) {
$controller = new $match->class($match['params']);
$data = $controller->{$match['method']}();
...
// since 1.4.0: using the RouteMatch we can now easily get the template
$body = $this->renderer->render($match->template, $data);
...
}
...
}
...
}
```
## Appendix: .htaccess
You will also need to do some magic in your `.htaccess` file so that `index.php` handles all requests.
```appache
RewriteEngine On
# The following rule tells Apache that if the requested filename exists, simply serve it.
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [L]
# The following rewrites all other queries to index.php. The
# condition ensures that if you are using Apache aliases to do
# mass virtual hosting or installed the project in a subdirectory,
# the base path will be prepended to allow proper resolution of
# the index.php file; it will work in non-aliased environments
# as well, providing a safe, one-size fits all solution.
RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$
RewriteRule ^(.*) - [E=BASE:%1]
RewriteRule ^(.*)$ %{ENV:BASE}/index.php [L]
# Deprecated apache 2.2 syntax:
# Order Allow,Deny
# Allow from all
# Apache > 2.4 requires:
Require all granted
```